Skip to content

Commit 9b7c4c9

Browse files
committed
pyvectorize c++ unit test
1 parent 94e9f39 commit 9b7c4c9

File tree

2 files changed

+82
-1
lines changed

2 files changed

+82
-1
lines changed

test/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,9 @@ include_directories(${GTEST_INCLUDE_DIRS})
106106

107107
set(XTENSOR_PYTHON_TESTS
108108
main.cpp
109-
test_pytensor.cpp
110109
test_pyarray.cpp
110+
test_pytensor.cpp
111+
test_pyvectorize.cpp
111112
)
112113

113114
set(XTENSOR_PYTHON_TARGET test_xtensor_python)

test/test_pyvectorize.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/***************************************************************************
2+
* Copyright (c) 2016, Johan Mabille and Sylvain Corlay *
3+
* *
4+
* Distributed under the terms of the BSD 3-Clause License. *
5+
* *
6+
* The full license is in the file LICENSE, distributed with this software. *
7+
****************************************************************************/
8+
9+
#include "gtest/gtest.h"
10+
#include "test_common.hpp"
11+
#include "xtensor-python/pytensor.hpp"
12+
#include "xtensor-python/pyvectorize.hpp"
13+
#include "pybind11/pybind11.h"
14+
#include "pybind11/numpy.h"
15+
16+
namespace xt
17+
{
18+
19+
double f1(double a, double b)
20+
{
21+
return a + b;
22+
}
23+
24+
using shape_type = std::vector<std::size_t>;
25+
26+
TEST(pyvectorize, function)
27+
{
28+
auto vecf1 = pyvectorize(f1);
29+
shape_type shape = { 3, 2 };
30+
pyarray<double> a(shape, 1.5);
31+
pyarray<double> b(shape, 2.3);
32+
pyarray<double> c = vecf1(a, b);
33+
EXPECT_EQ(a(0, 0) + b(0, 0), c(0, 0));
34+
}
35+
36+
TEST(pyvectorize, lambda)
37+
{
38+
auto vecf1 = pyvectorize([](double a, double b) { return a + b; });
39+
shape_type shape = { 3, 2 };
40+
pyarray<double> a(shape, 1.5);
41+
pyarray<double> b(shape, 2.3);
42+
pyarray<double> c = vecf1(a, b);
43+
EXPECT_EQ(a(0, 0) + b(0, 0), c(0, 0));
44+
}
45+
46+
TEST(pyvectorize, complex)
47+
{
48+
using complex_t = std::complex<double>;
49+
shape_type shape = { 3, 2 };
50+
pyarray<complex_t> a(shape, complex_t(1.2, 2.5));
51+
auto f = [](const pyarray<complex_t>& t) {
52+
return std::make_tuple(pyvectorize([](complex_t x) { return std::abs(x); })(t),
53+
pyvectorize([](complex_t x) { return std::arg(x); })(t));
54+
};
55+
56+
auto res = f(a);
57+
double expected_abs = std::abs(a(1, 1));
58+
double expected_arg = std::arg(a(1, 1));
59+
EXPECT_EQ(expected_abs, std::get<0>(res)(1, 1));
60+
EXPECT_EQ(expected_arg, std::get<1>(res)(1, 1));
61+
}
62+
63+
TEST(pyvectorize, complex_pybind)
64+
{
65+
using complex_t = std::complex<double>;
66+
shape_type shape = { 3, 2 };
67+
pyarray<complex_t> a(shape, complex_t(1.2, 2.5));
68+
auto f = [](const pyarray<complex_t>& t) {
69+
return pybind11::make_tuple(pyvectorize([](complex_t x) { return std::abs(x); })(t),
70+
pyvectorize([](complex_t x) { return std::arg(x); })(t));
71+
};
72+
73+
auto res = f(a);
74+
double expected_abs = std::abs(a(1, 1));
75+
double expected_arg = std::arg(a(1, 1));
76+
77+
EXPECT_EQ(expected_abs, res[0].cast<pyarray<double>>()(1, 1));
78+
EXPECT_EQ(expected_arg, res[1].cast<pyarray<double>>()(1, 1));
79+
}
80+
}

0 commit comments

Comments
 (0)