Skip to content

Commit 9e7d63d

Browse files
committed
Test refactoring: trigonometric functions
1 parent dc7d05c commit 9e7d63d

File tree

2 files changed

+186
-0
lines changed

2 files changed

+186
-0
lines changed

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ set(XSIMD_TESTS
156156
test_poly_evaluation.cpp
157157
test_power.cpp
158158
test_rounding.cpp
159+
test_trigonometric.cpp
159160
test_utils.hpp
160161
#[[ xsimd_api_test.hpp
161162
xsimd_api_test.cpp

test/test_trigonometric.cpp

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
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 "test_utils.hpp"
12+
13+
template <class B>
14+
class trigonometric_test : public testing::Test
15+
{
16+
protected:
17+
18+
using batch_type = B;
19+
using value_type = typename B::value_type;
20+
static constexpr size_t size = B::size;
21+
using vector_type = std::vector<value_type>;
22+
23+
size_t nb_input;
24+
vector_type input;
25+
vector_type ainput;
26+
vector_type atan_input;
27+
vector_type expected;
28+
vector_type res;
29+
30+
trigonometric_test()
31+
{
32+
nb_input = size * 10000;
33+
input.resize(nb_input);
34+
ainput.resize(nb_input);
35+
atan_input.resize(nb_input);
36+
for (size_t i = 0; i < nb_input; ++i)
37+
{
38+
input[i] = value_type(0.) + i * value_type(80.) / nb_input;
39+
ainput[i] = value_type(-1.) + value_type(2.) * i / nb_input;
40+
atan_input[i] = value_type(-10.) + i * value_type(20.) / nb_input;
41+
}
42+
expected.resize(nb_input);
43+
res.resize(nb_input);
44+
}
45+
46+
void test_trigonometric_functions()
47+
{
48+
// sin
49+
{
50+
std::transform(input.cbegin(), input.cend(), expected.begin(),
51+
[](const value_type& v) { return std::sin(v); });
52+
batch_type in, out;
53+
for (size_t i = 0; i < nb_input; i += size)
54+
{
55+
detail::load_batch(in, input, i);
56+
out = sin(in);
57+
detail::store_batch(out, res, i);
58+
}
59+
size_t diff = detail::get_nb_diff(res, expected);
60+
EXPECT_EQ(diff, 0) << print_function_name("sin");
61+
}
62+
// cos
63+
{
64+
std::transform(input.cbegin(), input.cend(), expected.begin(),
65+
[](const value_type& v) { return std::cos(v); });
66+
batch_type in, out;
67+
for (size_t i = 0; i < nb_input; i += size)
68+
{
69+
detail::load_batch(in, input, i);
70+
out = cos(in);
71+
detail::store_batch(out, res, i);
72+
}
73+
size_t diff = detail::get_nb_diff(res, expected);
74+
EXPECT_EQ(diff, 0) << print_function_name("cos");
75+
}
76+
// sincos
77+
{
78+
vector_type expected2(nb_input), res2(nb_input);
79+
std::transform(input.cbegin(), input.cend(), expected.begin(),
80+
[](const value_type& v) { return std::sin(v); });
81+
std::transform(input.cbegin(), input.cend(), expected2.begin(),
82+
[](const value_type& v) { return std::cos(v); });
83+
batch_type in, out1, out2;
84+
for (size_t i = 0; i < nb_input; i += size)
85+
{
86+
detail::load_batch(in, input, i);
87+
sincos(in, out1, out2);
88+
detail::store_batch(out1, res, i);
89+
detail::store_batch(out2, res2, i);
90+
}
91+
size_t diff = detail::get_nb_diff(res, expected);
92+
EXPECT_EQ(diff, 0) << print_function_name("sincos(sin)");
93+
diff = detail::get_nb_diff(res2, expected2);
94+
EXPECT_EQ(diff, 0) << print_function_name("sincos(cos)");
95+
}
96+
// tan
97+
{
98+
std::transform(input.cbegin(), input.cend(), expected.begin(),
99+
[](const value_type& v) { return std::tan(v); });
100+
batch_type in, out;
101+
for (size_t i = 0; i < nb_input; i += size)
102+
{
103+
detail::load_batch(in, input, i);
104+
out = tan(in);
105+
detail::store_batch(out, res, i);
106+
}
107+
size_t diff = detail::get_nb_diff(res, expected);
108+
EXPECT_EQ(diff, 0) << print_function_name("tan");
109+
}
110+
}
111+
112+
void test_reciprocal_functions()
113+
{
114+
// asin
115+
{
116+
std::transform(ainput.cbegin(), ainput.cend(), expected.begin(),
117+
[](const value_type& v) { return std::asin(v); });
118+
batch_type in, out;
119+
for (size_t i = 0; i < nb_input; i += size)
120+
{
121+
detail::load_batch(in, ainput, i);
122+
out = asin(in);
123+
detail::store_batch(out, res, i);
124+
}
125+
size_t diff = detail::get_nb_diff(res, expected);
126+
EXPECT_EQ(diff, 0) << print_function_name("asin");
127+
}
128+
// acos
129+
{
130+
std::transform(ainput.cbegin(), ainput.cend(), expected.begin(),
131+
[](const value_type& v) { return std::acos(v); });
132+
batch_type in, out;
133+
for (size_t i = 0; i < nb_input; i += size)
134+
{
135+
detail::load_batch(in, ainput, i);
136+
out = acos(in);
137+
detail::store_batch(out, res, i);
138+
}
139+
size_t diff = detail::get_nb_diff(res, expected);
140+
EXPECT_EQ(diff, 0) << print_function_name("acos");
141+
}
142+
// atan
143+
{
144+
std::transform(atan_input.cbegin(), atan_input.cend(), expected.begin(),
145+
[](const value_type& v) { return std::atan(v); });
146+
batch_type in, out;
147+
for (size_t i = 0; i < nb_input; i += size)
148+
{
149+
detail::load_batch(in, atan_input, i);
150+
out = atan(in);
151+
detail::store_batch(out, res, i);
152+
}
153+
size_t diff = detail::get_nb_diff(res, expected);
154+
EXPECT_EQ(diff, 0) << print_function_name("atan");
155+
}
156+
// atan2
157+
{
158+
std::transform(atan_input.cbegin(), atan_input.cend(), input.cbegin(), expected.begin(),
159+
[](const value_type& v, const value_type& r) { return std::atan2(v, r); });
160+
batch_type in, rhs, out;
161+
for (size_t i = 0; i < nb_input; i += size)
162+
{
163+
detail::load_batch(in, atan_input, i);
164+
detail::load_batch(rhs, input, i);
165+
out = atan2(in, rhs);
166+
detail::store_batch(out, res, i);
167+
}
168+
size_t diff = detail::get_nb_diff(res, expected);
169+
EXPECT_EQ(diff, 0) << print_function_name("atan2");
170+
}
171+
}
172+
};
173+
174+
TYPED_TEST_SUITE(trigonometric_test, batch_float_types, simd_test_names);
175+
176+
TYPED_TEST(trigonometric_test, trigonometric)
177+
{
178+
this->test_trigonometric_functions();
179+
}
180+
181+
TYPED_TEST(trigonometric_test, reciprocal)
182+
{
183+
this->test_reciprocal_functions();
184+
}
185+

0 commit comments

Comments
 (0)