Skip to content

Commit 7a4f44c

Browse files
committed
Test refactoring: complex trigonometric functions
1 parent 9717ffa commit 7a4f44c

File tree

2 files changed

+224
-0
lines changed

2 files changed

+224
-0
lines changed

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ set(XSIMD_TESTS
150150
test_batch_int.cpp
151151
test_complex_exponential.cpp
152152
test_complex_hyperbolic.cpp
153+
test_complex_trigonometric.cpp
153154
test_error_gamma.cpp
154155
test_exponential.cpp
155156
test_fp_manipulation.cpp
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
/***************************************************************************
2+
* Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and *
3+
* Martin Renou *
4+
* Copyright (c) QuantStack *
5+
* *
6+
* Distributed under the terms of the BSD 3-Clause License. *
7+
* *
8+
* The full license is in the file LICENSE, distributed with this software. *
9+
****************************************************************************/
10+
11+
#include "xsimd/math/xsimd_math_complex.hpp"
12+
#include "test_utils.hpp"
13+
14+
template <class B>
15+
class complex_trigonometric_test : public testing::Test
16+
{
17+
protected:
18+
19+
using batch_type = B;
20+
using real_batch_type = typename B::real_batch;
21+
using value_type = typename B::value_type;
22+
using real_value_type = typename value_type::value_type;
23+
static constexpr size_t size = B::size;
24+
using vector_type = std::vector<value_type>;
25+
26+
size_t nb_input;
27+
vector_type input;
28+
vector_type ainput;
29+
vector_type atan_input;
30+
vector_type expected;
31+
vector_type res;
32+
33+
complex_trigonometric_test()
34+
{
35+
nb_input = size * 10000;
36+
input.resize(nb_input);
37+
ainput.resize(nb_input);
38+
atan_input.resize(nb_input);
39+
for (size_t i = 0; i < nb_input; ++i)
40+
{
41+
input[i] = value_type(real_value_type(0.) + i * real_value_type(80.) / nb_input,
42+
real_value_type(0.1) + i * real_value_type(56.) / nb_input);
43+
ainput[i] = value_type(real_value_type(-1.) + real_value_type(2.) * i / nb_input,
44+
real_value_type(-1.1) + real_value_type(2.1) * i / nb_input);
45+
atan_input[i] = value_type(real_value_type(-10.) + i * real_value_type(20.) / nb_input,
46+
real_value_type(-9.) + i * real_value_type(21.) / nb_input);
47+
}
48+
expected.resize(nb_input);
49+
res.resize(nb_input);
50+
}
51+
52+
void test_sin()
53+
{
54+
std::transform(input.cbegin(), input.cend(), expected.begin(),
55+
[](const value_type& v) { using std::sin; return sin(v); });
56+
batch_type in, out;
57+
for (size_t i = 0; i < nb_input; i += size)
58+
{
59+
detail::load_batch(in, input, i);
60+
out = sin(in);
61+
detail::store_batch(out, res, i);
62+
}
63+
size_t diff = detail::get_nb_diff(res, expected);
64+
EXPECT_EQ(diff, 0) << print_function_name("sin");
65+
}
66+
67+
void test_cos()
68+
{
69+
std::transform(input.cbegin(), input.cend(), expected.begin(),
70+
[](const value_type& v) { using std::cos; return cos(v); });
71+
batch_type in, out;
72+
for (size_t i = 0; i < nb_input; i += size)
73+
{
74+
detail::load_batch(in, input, i);
75+
out = cos(in);
76+
detail::store_batch(out, res, i);
77+
}
78+
size_t diff = detail::get_nb_diff(res, expected);
79+
EXPECT_EQ(diff, 0) << print_function_name("cos");
80+
}
81+
82+
void test_sincos()
83+
{
84+
vector_type expected2(nb_input), res2(nb_input);
85+
std::transform(input.cbegin(), input.cend(), expected.begin(),
86+
[](const value_type& v) { using std::sin; return sin(v); });
87+
std::transform(input.cbegin(), input.cend(), expected2.begin(),
88+
[](const value_type& v) { using std::cos; return cos(v); });
89+
batch_type in, out1, out2;
90+
for (size_t i = 0; i < nb_input; i += size)
91+
{
92+
detail::load_batch(in, input, i);
93+
sincos(in, out1, out2);
94+
detail::store_batch(out1, res, i);
95+
detail::store_batch(out2, res2, i);
96+
}
97+
size_t diff = detail::get_nb_diff(res, expected);
98+
EXPECT_EQ(diff, 0) << print_function_name("sincos(sin)");
99+
diff = detail::get_nb_diff(res2, expected2);
100+
EXPECT_EQ(diff, 0) << print_function_name("sincos(cos)");
101+
}
102+
103+
void test_tan()
104+
{
105+
test_conditional_tan<real_value_type>();
106+
}
107+
108+
void test_asin()
109+
{
110+
std::transform(ainput.cbegin(), ainput.cend(), expected.begin(),
111+
[](const value_type& v) { using std::asin; return asin(v); });
112+
batch_type in, out;
113+
for (size_t i = 0; i < nb_input; i += size)
114+
{
115+
detail::load_batch(in, ainput, i);
116+
out = asin(in);
117+
detail::store_batch(out, res, i);
118+
}
119+
size_t diff = detail::get_nb_diff(res, expected);
120+
EXPECT_EQ(diff, 0) << print_function_name("asin");
121+
}
122+
123+
void test_acos()
124+
{
125+
std::transform(ainput.cbegin(), ainput.cend(), expected.begin(),
126+
[](const value_type& v) { using std::acos; return acos(v); });
127+
batch_type in, out;
128+
for (size_t i = 0; i < nb_input; i += size)
129+
{
130+
detail::load_batch(in, ainput, i);
131+
out = acos(in);
132+
detail::store_batch(out, res, i);
133+
}
134+
size_t diff = detail::get_nb_diff(res, expected);
135+
EXPECT_EQ(diff, 0) << print_function_name("acos");
136+
}
137+
138+
void test_atan()
139+
{
140+
std::transform(atan_input.cbegin(), atan_input.cend(), expected.begin(),
141+
[](const value_type& v) { using std::atan; return atan(v); });
142+
batch_type in, out;
143+
for (size_t i = 0; i < nb_input; i += size)
144+
{
145+
detail::load_batch(in, atan_input, i);
146+
out = atan(in);
147+
detail::store_batch(out, res, i);
148+
}
149+
size_t diff = detail::get_nb_diff(res, expected);
150+
EXPECT_EQ(diff, 0) << print_function_name("atan");
151+
}
152+
private:
153+
154+
void test_tan_impl()
155+
{
156+
std::transform(input.cbegin(), input.cend(), expected.begin(),
157+
[](const value_type& v) { using std::tan; return tan(v); });
158+
batch_type in, out;
159+
for (size_t i = 0; i < nb_input; i += size)
160+
{
161+
detail::load_batch(in, input, i);
162+
out = tan(in);
163+
detail::store_batch(out, res, i);
164+
}
165+
size_t diff = detail::get_nb_diff(res, expected);
166+
EXPECT_EQ(diff, 0) << print_function_name("tan");
167+
}
168+
169+
template <class T, typename std::enable_if<!std::is_same<T, float>::value, int>::type = 0>
170+
void test_conditional_tan()
171+
{
172+
test_tan_impl();
173+
}
174+
175+
template <class T, typename std::enable_if<std::is_same<T, float>::value, int>::type = 0>
176+
void test_conditional_tan()
177+
{
178+
#if (XSIMD_ARM_INSTR_SET >= XSIMD_ARM7_NEON_VERSION)
179+
#if DEBUG_ACCURACY
180+
test_tan_impl();
181+
#endif
182+
#else
183+
test_tan_impl();
184+
#endif
185+
}
186+
};
187+
188+
TYPED_TEST_SUITE(complex_trigonometric_test, batch_complex_types, simd_test_names);
189+
190+
TYPED_TEST(complex_trigonometric_test, sin)
191+
{
192+
this->test_sin();
193+
}
194+
195+
TYPED_TEST(complex_trigonometric_test, cos)
196+
{
197+
this->test_cos();
198+
}
199+
200+
TYPED_TEST(complex_trigonometric_test, sincos)
201+
{
202+
this->test_sincos();
203+
}
204+
205+
TYPED_TEST(complex_trigonometric_test, tan)
206+
{
207+
this->test_tan();
208+
}
209+
210+
TYPED_TEST(complex_trigonometric_test, asin)
211+
{
212+
this->test_asin();
213+
}
214+
215+
TYPED_TEST(complex_trigonometric_test, acos)
216+
{
217+
this->test_acos();
218+
}
219+
220+
TYPED_TEST(complex_trigonometric_test, atan)
221+
{
222+
this->test_atan();
223+
}

0 commit comments

Comments
 (0)