Skip to content

Commit e91271b

Browse files
authored
add vander function (#646)
* add vander function
1 parent c6a7f75 commit e91271b

File tree

8 files changed

+164
-3
lines changed

8 files changed

+164
-3
lines changed

doc/reference/creation.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Basic creation routines
2020
dpnp.zeros_like
2121
dpnp.full
2222
dpnp.full_like
23+
dpnp.vander
2324

2425

2526
Creation from other data

dpnp/backend/include/dpnp_iface.hpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,20 @@ template <typename _DataType_input1, typename _DataType_input2, typename _DataTy
871871
INP_DLLEXPORT void dpnp_trapz_c(
872872
const void* array1_in, const void* array2_in, void* result1, double dx, size_t array1_size, size_t array2_size);
873873

874+
/**
875+
* @ingroup BACKEND_API
876+
* @brief Implementation of vander function
877+
*
878+
* @param [in] array_in Input array.
879+
* @param [out] result Output array.
880+
* @param [in] size_in Number of elements in the input array.
881+
* @param [in] N Number of columns in the output.
882+
* @param [in] increasing Order of the powers of the columns.
883+
*
884+
*/
885+
template <typename _DataType_input, typename _DataType_output>
886+
INP_DLLEXPORT void dpnp_vander_c(const void* array1_in, void* result1, const size_t size_in, const size_t N, const int increasing);
887+
874888
/**
875889
* @ingroup BACKEND_API
876890
* @brief Implementation of zeros function

dpnp/backend/include/dpnp_iface_fptr.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ enum class DPNPFuncName : size_t
201201
DPNP_FN_TRIL, /**< Used in numpy.tril() implementation */
202202
DPNP_FN_TRIU, /**< Used in numpy.triu() implementation */
203203
DPNP_FN_TRUNC, /**< Used in numpy.trunc() implementation */
204+
DPNP_FN_VANDER, /**< Used in numpy.vander() implementation */
204205
DPNP_FN_VAR, /**< Used in numpy.var() implementation */
205206
DPNP_FN_ZEROS, /**< Used in numpy.zeros() implementation */
206207
DPNP_FN_ZEROS_LIKE, /**< Used in numpy.zeros_like() implementation */

dpnp/backend/kernels/dpnp_krnl_arraycreation.cpp

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,59 @@ void dpnp_ones_like_c(void* result, size_t size)
127127
dpnp_ones_c<_DataType>(result, size);
128128
}
129129

130+
template <typename _DataType_input, typename _DataType_output>
131+
void dpnp_vander_c(const void* array1_in, void* result1, const size_t size_in, const size_t N, const int increasing)
132+
{
133+
if ((array1_in == nullptr) || (result1 == nullptr))
134+
return;
135+
136+
if (!size_in || !N)
137+
return;
138+
139+
const _DataType_input* array_in = reinterpret_cast<const _DataType_input*>(array1_in);
140+
_DataType_output* result = reinterpret_cast<_DataType_output*>(result1);
141+
142+
if (N == 1)
143+
{
144+
dpnp_ones_c<_DataType_output>(result, size_in);
145+
return;
146+
}
147+
148+
if (increasing)
149+
{
150+
for (size_t i = 0; i < size_in; ++i)
151+
{
152+
result[i * N] = 1;
153+
}
154+
for (size_t i = 1; i < N; ++i)
155+
{
156+
for (size_t j = 0; j < size_in; ++j)
157+
{
158+
result[j * N + i] = result[j * N + i - 1] * array_in[j];
159+
}
160+
}
161+
}
162+
else
163+
{
164+
for (size_t i = 0; i < size_in; ++i)
165+
{
166+
result[i * N + N - 1] = 1;
167+
}
168+
for (size_t i = N - 2; i > 0; --i)
169+
{
170+
for (size_t j = 0; j < size_in; ++j)
171+
{
172+
result[j * N + i] = result[j * N + i + 1] * array_in[j];
173+
}
174+
}
175+
176+
for (size_t i = 0; i < size_in; ++i)
177+
{
178+
result[i * N] = result[i * N + 1] * array_in[i];
179+
}
180+
}
181+
}
182+
130183
template <typename _DataType>
131184
class dpnp_tri_c_kernel;
132185

@@ -439,6 +492,13 @@ void func_map_init_arraycreation(func_map_t& fmap)
439492
fmap[DPNPFuncName::DPNP_FN_ONES_LIKE][eft_BLN][eft_BLN] = {eft_BLN, (void*)dpnp_ones_like_c<bool>};
440493
fmap[DPNPFuncName::DPNP_FN_ONES_LIKE][eft_C128][eft_C128] = {eft_C128,
441494
(void*)dpnp_ones_like_c<std::complex<double>>};
495+
496+
fmap[DPNPFuncName::DPNP_FN_VANDER][eft_INT][eft_INT] = {eft_LNG, (void*)dpnp_vander_c<int, long>};
497+
fmap[DPNPFuncName::DPNP_FN_VANDER][eft_LNG][eft_LNG] = {eft_LNG, (void*)dpnp_vander_c<long, long>};
498+
fmap[DPNPFuncName::DPNP_FN_VANDER][eft_FLT][eft_FLT] = {eft_DBL, (void*)dpnp_vander_c<float, double>};
499+
fmap[DPNPFuncName::DPNP_FN_VANDER][eft_DBL][eft_DBL] = {eft_DBL, (void*)dpnp_vander_c<double, double>};
500+
fmap[DPNPFuncName::DPNP_FN_VANDER][eft_BLN][eft_BLN] = {eft_LNG, (void*)dpnp_vander_c<bool, long>};
501+
fmap[DPNPFuncName::DPNP_FN_VANDER][eft_C128][eft_C128] = {eft_C128, (void*)dpnp_vander_c<std::complex<double>, std::complex<double>>};
442502

443503
fmap[DPNPFuncName::DPNP_FN_TRI][eft_INT][eft_INT] = {eft_INT, (void*)dpnp_tri_c<int>};
444504
fmap[DPNPFuncName::DPNP_FN_TRI][eft_LNG][eft_LNG] = {eft_LNG, (void*)dpnp_tri_c<long>};
@@ -460,15 +520,15 @@ void func_map_init_arraycreation(func_map_t& fmap)
460520
fmap[DPNPFuncName::DPNP_FN_ZEROS][eft_FLT][eft_FLT] = {eft_FLT, (void*)dpnp_zeros_c<float>};
461521
fmap[DPNPFuncName::DPNP_FN_ZEROS][eft_DBL][eft_DBL] = {eft_DBL, (void*)dpnp_zeros_c<double>};
462522
fmap[DPNPFuncName::DPNP_FN_ZEROS][eft_BLN][eft_BLN] = {eft_BLN, (void*)dpnp_zeros_c<bool>};
463-
fmap[DPNPFuncName::DPNP_FN_ZEROS][eft_C128][eft_C128] = {eft_C128, (void*)dpnp_ones_c<std::complex<double>>};
523+
fmap[DPNPFuncName::DPNP_FN_ZEROS][eft_C128][eft_C128] = {eft_C128, (void*)dpnp_zeros_c<std::complex<double>>};
464524

465525
fmap[DPNPFuncName::DPNP_FN_ZEROS_LIKE][eft_INT][eft_INT] = {eft_INT, (void*)dpnp_zeros_like_c<int>};
466526
fmap[DPNPFuncName::DPNP_FN_ZEROS_LIKE][eft_LNG][eft_LNG] = {eft_LNG, (void*)dpnp_zeros_like_c<long>};
467527
fmap[DPNPFuncName::DPNP_FN_ZEROS_LIKE][eft_FLT][eft_FLT] = {eft_FLT, (void*)dpnp_zeros_like_c<float>};
468528
fmap[DPNPFuncName::DPNP_FN_ZEROS_LIKE][eft_DBL][eft_DBL] = {eft_DBL, (void*)dpnp_zeros_like_c<double>};
469529
fmap[DPNPFuncName::DPNP_FN_ZEROS_LIKE][eft_BLN][eft_BLN] = {eft_BLN, (void*)dpnp_zeros_like_c<bool>};
470530
fmap[DPNPFuncName::DPNP_FN_ZEROS_LIKE][eft_C128][eft_C128] = {eft_C128,
471-
(void*)dpnp_ones_like_c<std::complex<double>>};
531+
(void*)dpnp_zeros_like_c<std::complex<double>>};
472532

473533
return;
474534
}

dpnp/dpnp_algo/dpnp_algo.pxd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName": # need this na
174174
DPNP_FN_TRIL
175175
DPNP_FN_TRIU
176176
DPNP_FN_TRUNC
177+
DPNP_FN_VANDER
177178
DPNP_FN_VAR
178179
DPNP_FN_ZEROS
179180
DPNP_FN_ZEROS_LIKE

dpnp/dpnp_algo/dpnp_algo_arraycreation.pyx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,14 @@ __all__ += [
5454
"dpnp_tri",
5555
"dpnp_tril",
5656
"dpnp_triu",
57+
"dpnp_vander",
5758
"dpnp_zeros",
5859
"dpnp_zeros_like"
5960
]
6061

6162

62-
ctypedef void(*custom_1in_1out_func_ptr_t)(void * , void * , const int , size_t * , size_t * , const size_t, const size_t)
63+
ctypedef void(*custom_1in_1out_func_ptr_t)(void *, void * , const int , size_t * , size_t * , const size_t, const size_t)
64+
ctypedef void(*ftpr_custom_vander_1in_1out_t)(void *, void *, size_t, size_t, int)
6365
ctypedef void(*custom_indexing_1out_func_ptr_t)(void * , const size_t , const size_t , const int)
6466

6567

@@ -317,6 +319,20 @@ cpdef dparray dpnp_triu(dparray m, int k):
317319
return result
318320

319321

322+
cpdef dparray dpnp_vander(dparray x1, int N, int increasing):
323+
cdef DPNPFuncType param1_type = dpnp_dtype_to_DPNPFuncType(x1.dtype)
324+
325+
cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(DPNP_FN_VANDER, param1_type, DPNP_FT_NONE)
326+
327+
result_type = dpnp_DPNPFuncType_to_dtype(< size_t > kernel_data.return_type)
328+
cdef dparray result = dparray((x1.size, N), dtype=result_type)
329+
330+
cdef ftpr_custom_vander_1in_1out_t func = <ftpr_custom_vander_1in_1out_t > kernel_data.ptr
331+
func(x1.get_data(), result.get_data(), x1.size, N, increasing)
332+
333+
return result
334+
335+
320336
cpdef dparray dpnp_zeros(result_shape, result_dtype):
321337
return call_fptr_1out(DPNP_FN_ZEROS, result_shape, result_dtype)
322338

dpnp/dpnp_iface_arraycreation.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
"tri",
7878
"tril",
7979
"triu",
80+
"vander",
8081
"zeros",
8182
"zeros_like"
8283
]
@@ -1135,6 +1136,47 @@ def triu(m, k=0):
11351136
return call_origin(numpy.triu, m, k)
11361137

11371138

1139+
def vander(x1, N=None, increasing=False):
1140+
"""
1141+
Generate a Vandermonde matrix.
1142+
1143+
For full documentation refer to :obj:`numpy.vander`.
1144+
1145+
Examples
1146+
--------
1147+
>>> import dpnp as np
1148+
>>> x = np.array([1, 2, 3, 5])
1149+
>>> N = 3
1150+
>>> np.vander(x, N)
1151+
array([[ 1, 1, 1],
1152+
[ 4, 2, 1],
1153+
[ 9, 3, 1],
1154+
[25, 5, 1]])
1155+
>>> x = np.array([1, 2, 3, 5])
1156+
>>> np.vander(x)
1157+
array([[ 1, 1, 1, 1],
1158+
[ 8, 4, 2, 1],
1159+
[ 27, 9, 3, 1],
1160+
[125, 25, 5, 1]])
1161+
>>> np.vander(x, increasing=True)
1162+
array([[ 1, 1, 1, 1],
1163+
[ 1, 2, 4, 8],
1164+
[ 1, 3, 9, 27],
1165+
[ 1, 5, 25, 125]])
1166+
"""
1167+
if (not use_origin_backend(x1)):
1168+
if not isinstance(x1, dparray):
1169+
pass
1170+
elif x1.ndim != 1:
1171+
pass
1172+
else:
1173+
if N is None:
1174+
N = x1.size
1175+
return dpnp_vander(x1, N, increasing)
1176+
1177+
return call_origin(numpy.vander, x1, N=N, increasing=increasing)
1178+
1179+
11381180
def zeros(shape, dtype=None, order='C'):
11391181
"""
11401182
Return a new array of given shape and type, filled with zeros.

tests/test_arraycreation.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,3 +217,29 @@ def test_triu_size_null(k):
217217
expected = numpy.triu(a, k)
218218
result = dpnp.triu(ia, k)
219219
numpy.testing.assert_array_equal(expected, result)
220+
221+
222+
@pytest.mark.parametrize("array",
223+
[[1, 2, 3, 4],
224+
[],
225+
[0, 3, 5]],
226+
ids=['[1, 2, 3, 4]',
227+
'[]',
228+
'[0, 3, 5]'])
229+
@pytest.mark.parametrize("type",
230+
[numpy.float64, numpy.float32, numpy.int64,
231+
numpy.int32, numpy.bool, numpy.complex128],
232+
ids=['float64', 'float32', 'int64', 'int32', 'bool', 'complex128'])
233+
@pytest.mark.parametrize("n",
234+
[0, 1, 4, None],
235+
ids=['0', '1', '4', 'None'])
236+
@pytest.mark.parametrize("increase",
237+
[True, False],
238+
ids=['True', 'False'])
239+
def test_vander(array, type, n, increase):
240+
a_np = numpy.array(array, dtype=type)
241+
a_dpnp = dpnp.array(array, dtype=type)
242+
243+
expected = numpy.vander(a_np, N=n, increasing=increase)
244+
result = dpnp.vander(a_dpnp, N=n, increasing=increase)
245+
numpy.testing.assert_array_equal(expected, result)

0 commit comments

Comments
 (0)