Lightmetrica  0.0.1.50dbee3 (yosakoi)
 All Classes Functions Variables Typedefs Enumerations Enumerator
base.math.h
1 /*
2  Lightmetrica : A research-oriented renderer
3 
4  Copyright (c) 2014 Hisanari Otsu
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #pragma once
21 #ifndef LIB_LIGHTMETRICA_TEST_BASE_MATH_H
22 #define LIB_LIGHTMETRICA_TEST_BASE_MATH_H
23 
24 #include "base.h"
25 #ifndef LM_ENABLE_MULTI_PRECISION
26 #define LM_ENABLE_MULTI_PRECISION
27 #endif
28 #include <lightmetrica/math.types.h>
29 #include <lightmetrica/math.basic.h>
30 #include <lightmetrica/align.h>
31 
32 namespace mp = boost::multiprecision;
33 
34 LM_NAMESPACE_BEGIN
35 LM_TEST_NAMESPACE_BEGIN
36 
37 typedef ::testing::Types<float, double, Math::BigFloat> MathTestTypes;
38 
39 template <typename T>
40 class MathTestBase : public TestBase {};
41 
42 template <typename T>
43 inline ::testing::AssertionResult ExpectNearRelative(const T& expected, const T& actual, const T& epsilon)
44 {
45  T diff = Math::Abs(expected - actual) / Math::Abs(expected);
46  if (diff > epsilon)
47  {
48  return ::testing::AssertionFailure()
49  << "Expected " << expected << ", "
50  << "Actual " << actual << ", "
51  << "Diff " << diff << ", "
52  << "Epsilon " << epsilon;
53  }
54  else
55  {
56  return ::testing::AssertionSuccess();
57  }
58 }
59 
60 template <typename T>
61 inline ::testing::AssertionResult ExpectNear(const T& expected, const T& actual, const T& epsilon)
62 {
63  T diff = Math::Abs(expected - actual);
64  if (diff > epsilon)
65  {
66  return ::testing::AssertionFailure()
67  << "Expected " << expected << ", "
68  << "Actual " << actual << ", "
69  << "Diff " << diff << ", "
70  << "Epsilon " << epsilon;
71  }
72  else
73  {
74  return ::testing::AssertionSuccess();
75  }
76 }
77 
78 template <typename T>
79 inline ::testing::AssertionResult ExpectNear(const T& expected, const T& actual)
80 {
81  return ExpectNear(expected, actual, Math::TConstants<T>::EpsLarge());
82 }
83 
84 template <>
85 inline ::testing::AssertionResult ExpectNear<Math::BigFloat>(const Math::BigFloat& expected, const Math::BigFloat& actual)
86 {
87  Math::BigFloat diff = mp::abs(expected - actual);
88  Math::BigFloat epsilon = Math::TConstants<Math::BigFloat>::EpsLarge();
89  if (diff > epsilon)
90  {
91  return ::testing::AssertionFailure()
92  << "Expected " << expected.str() << ", "
93  << "Actual " << actual.str() << ", "
94  << "Diff " << diff.str() << ", "
95  << "Epsilon " << epsilon.str();
96  }
97  else
98  {
99  return ::testing::AssertionSuccess();
100  }
101 }
102 
103 template <typename T>
104 inline ::testing::AssertionResult ExpectVec2Near(const Math::TVec2<T>& expect, const Math::TVec2<T>& actual)
105 {
106  for (int i = 0; i < 2; i++)
107  {
108  auto result = ExpectNear(expect[i], actual[i]);
109  if (!result)
110  {
111  return result;
112  }
113  }
114 
115  return ::testing::AssertionSuccess();
116 }
117 
118 template <typename T>
119 inline ::testing::AssertionResult ExpectVec3Near(const Math::TVec3<T>& expect, const Math::TVec3<T>& actual, const T& epsilon)
120 {
121  for (int i = 0; i < 3; i++)
122  {
123  auto result = ExpectNear(expect[i], actual[i], epsilon);
124  if (!result)
125  {
126  return result;
127  }
128  }
129 
130  return ::testing::AssertionSuccess();
131 }
132 
133 template <typename T>
134 inline ::testing::AssertionResult ExpectVec3Near(const Math::TVec3<T>& expect, const Math::TVec3<T>& actual)
135 {
136  for (int i = 0; i < 3; i++)
137  {
138  auto result = ExpectNear(expect[i], actual[i]);
139  if (!result)
140  {
141  return result;
142  }
143  }
144 
145  return ::testing::AssertionSuccess();
146 }
147 
148 template <typename T>
149 inline ::testing::AssertionResult ExpectVec4Near(const Math::TVec4<T>& expect, const Math::TVec4<T>& actual)
150 {
151  for (int i = 0; i < 4; i++)
152  {
153  auto result = ExpectNear(expect[i], actual[i]);
154  if (!result)
155  {
156  return result;
157  }
158  }
159 
160  return ::testing::AssertionSuccess();
161 }
162 
163 template <typename T>
164 inline ::testing::AssertionResult ExpectMat3Near(const Math::TMat3<T>& expect, const Math::TMat3<T>& actual)
165 {
166  for (int i = 0; i < 3; i++)
167  {
168  for (int j = 0; j < 3; j++)
169  {
170  auto result = ExpectNear(expect[i][j], actual[i][j]);
171  if (!result)
172  {
173  return result;
174  }
175  }
176  }
177 
178  return ::testing::AssertionSuccess();
179 }
180 
181 template <typename T>
182 inline ::testing::AssertionResult ExpectMat4Near(const Math::TMat4<T>& expect, const Math::TMat4<T>& actual)
183 {
184  for (int i = 0; i < 4; i++)
185  {
186  for (int j = 0; j < 4; j++)
187  {
188  auto result = ExpectNear(expect[i][j], actual[i][j]);
189  if (!result)
190  {
191  return result;
192  }
193  }
194  }
195 
196  return ::testing::AssertionSuccess();
197 }
198 
199 LM_TEST_NAMESPACE_END
200 LM_NAMESPACE_END
201 
202 #endif // LIB_LIGHTMETRICA_TEST_BASE_MATH_H
Definition: base.math.h:40
Definition: base.h:9