Skip to content

Commit 100cd40

Browse files
committed
polyval operator
1 parent 4bab040 commit 100cd40

File tree

5 files changed

+162
-0
lines changed

5 files changed

+162
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
.. _polyval_func:
2+
3+
polyval
4+
=======
5+
6+
Evaluate a polynomial given an input sequence and coefficients
7+
8+
.. doxygenfunction:: polyval(const Op &op, const Coeffs &coeffs)
9+
10+
Examples
11+
~~~~~~~~
12+
13+
.. literalinclude:: ../../../test/00_operators/OperatorTests.cu
14+
:language: cpp
15+
:start-after: example-begin polyval-test-1
16+
:end-before: example-end polyval-test-1
17+
:dedent:
18+

include/matx/operators/operators.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
#include "matx/operators/percentile.h"
7979
#include "matx/operators/permute.h"
8080
#include "matx/operators/planar.h"
81+
#include "matx/operators/polyval.h"
8182
#include "matx/operators/pwelch.h"
8283
#include "matx/operators/qr.h"
8384
#include "matx/operators/r2c.h"

include/matx/operators/polyval.h

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
////////////////////////////////////////////////////////////////////////////////
2+
// BSD 3-Clause License
3+
//
4+
// Copyright (c) 2021, NVIDIA Corporation
5+
// All rights reserved.
6+
//
7+
// Redistribution and use in source and binary forms, with or without
8+
// modification, are permitted provided that the following conditions are met:
9+
//
10+
// 1. Redistributions of source code must retain the above copyright notice, this
11+
// list of conditions and the following disclaimer.
12+
//
13+
// 2. Redistributions in binary form must reproduce the above copyright notice,
14+
// this list of conditions and the following disclaimer in the documentation
15+
// and/or other materials provided with the distribution.
16+
//
17+
// 3. Neither the name of the copyright holder nor the names of its
18+
// contributors may be used to endorse or promote products derived from
19+
// this software without specific prior written permission.
20+
//
21+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24+
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25+
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26+
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27+
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28+
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29+
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
/////////////////////////////////////////////////////////////////////////////////
32+
33+
#pragma once
34+
35+
36+
#include "matx/core/type_utils.h"
37+
#include "matx/operators/base_operator.h"
38+
39+
namespace matx
40+
{
41+
42+
/**
43+
* Returns the polynomial evaluated at each point
44+
*/
45+
namespace detail {
46+
template <typename Op, typename Coeffs>
47+
class PolyvalOp : public BaseOp<PolyvalOp<Op, Coeffs>>
48+
{
49+
private:
50+
Op op_;
51+
Coeffs coeffs_;
52+
53+
public:
54+
using matxop = bool;
55+
using scalar_type = typename Op::scalar_type;
56+
57+
__MATX_INLINE__ std::string str() const { return "polyval()"; }
58+
__MATX_INLINE__ PolyvalOp(const Op &op, const Coeffs &coeffs) : op_(op), coeffs_(coeffs) {
59+
MATX_STATIC_ASSERT_STR(coeffs.Rank() == 1, matxInvalidDim, "Coefficient must be rank 1");
60+
MATX_STATIC_ASSERT_STR(op.Rank() == 1, matxInvalidDim, "Input operator must be rank 1");
61+
};
62+
63+
__MATX_INLINE__ __MATX_DEVICE__ __MATX_HOST__ auto operator()(index_t idx) const
64+
{
65+
// Horner's method for computing polynomial
66+
scalar_type ttl{coeffs_(0)};
67+
for(int i = 1; i < coeffs_.Size(0); i++) {
68+
ttl = ttl * op_(idx) + coeffs_(i);
69+
}
70+
71+
return ttl;
72+
}
73+
74+
static __MATX_INLINE__ constexpr __MATX_HOST__ __MATX_DEVICE__ int32_t Rank()
75+
{
76+
return 1;
77+
}
78+
constexpr __MATX_INLINE__ __MATX_HOST__ __MATX_DEVICE__ index_t Size([[maybe_unused]] int dim) const
79+
{
80+
return op_.Size(0);
81+
}
82+
};
83+
}
84+
85+
86+
/**
87+
* @brief Evaluate a polynomial
88+
*
89+
* Currently only allows 1D input and coefficients
90+
*
91+
* @tparam Op Type of input values to evaluate
92+
* @tparam Coeffs Type of coefficients
93+
* @param op Input values to evaluate
94+
* @param coeffs Coefficient values
95+
* @return polyval operator
96+
*/
97+
template <typename Op, typename Coeffs>
98+
__MATX_INLINE__ auto polyval(const Op &op, const Coeffs &coeffs) {
99+
return detail::PolyvalOp(op, coeffs);
100+
}
101+
} // end namespace matx

test/00_operators/OperatorTests.cu

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3274,6 +3274,33 @@ TYPED_TEST(OperatorTestsFloatNonComplexAllExecs, Sphere2Cart)
32743274
MATX_EXIT_HANDLER();
32753275
}
32763276

3277+
TYPED_TEST(OperatorTestsFloatNonComplexNonHalfAllExecs, PolyVal)
3278+
{
3279+
MATX_ENTER_HANDLER();
3280+
using TestType = std::tuple_element_t<0, TypeParam>;
3281+
using ExecType = std::tuple_element_t<1, TypeParam>;
3282+
3283+
auto pb = std::make_unique<detail::MatXPybind>();
3284+
pb->InitAndRunTVGenerator<TestType>("00_operators", "polyval_operator", "run", {4, 100});
3285+
3286+
ExecType exec{};
3287+
auto x = make_tensor<TestType>({100});
3288+
auto c = make_tensor<TestType>({4});
3289+
auto out = make_tensor<TestType>({100});
3290+
3291+
pb->NumpyToTensorView(x, "x");
3292+
pb->NumpyToTensorView(c, "c");
3293+
3294+
// example-begin polyval-test-1
3295+
(out = polyval(x, c)).run();
3296+
// example-end polyval-test-1
3297+
cudaStreamSynchronize(0);
3298+
MATX_TEST_ASSERT_COMPARE(pb, out, "out", 0.01);
3299+
3300+
MATX_EXIT_HANDLER();
3301+
}
3302+
3303+
32773304
TYPED_TEST(OperatorTestsNumericAllExecs, Upsample)
32783305
{
32793306
MATX_ENTER_HANDLER();

test/test_vectors/generators/00_operators.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@
44
import scipy.signal as ss
55
from typing import Dict, List
66

7+
class polyval_operator:
8+
def __init__(self, dtype: str, size: List[int]):
9+
self.size = size
10+
pass
11+
12+
def run(self) -> Dict[str, np.array]:
13+
c = np.random.rand(self.size[0])
14+
x = np.random.rand(self.size[1])
15+
16+
return {
17+
'c': c,
18+
'x': x,
19+
'out': np.polyval(c, x),
20+
}
21+
722

823
class kron_operator:
924
def __init__(self, dtype: str, size: List[int]):

0 commit comments

Comments
 (0)