source: src/Fragmentation/Exporters/unittests/SphericalPointDistributionUnitTest.cpp@ 0ae114

Last change on this file since 0ae114 was 0ae114, checked in by Frederik Heber <heber@…>, 11 years ago

Adding QuaternionTest for SphericalPointDistributionUnitTest, fixed tests.

  • Property mode set to 100644
File size: 16.3 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2014 Frederik Heber. All rights reserved.
5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/*
24 * SphericalPointDistributionUnitTest.cpp
25 *
26 * Created on: May 29, 2014
27 * Author: heber
28 */
29
30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
35using namespace std;
36
37#include <cppunit/CompilerOutputter.h>
38#include <cppunit/extensions/TestFactoryRegistry.h>
39#include <cppunit/ui/text/TestRunner.h>
40
41// include headers that implement a archive in simple text format
42#include <boost/archive/text_oarchive.hpp>
43#include <boost/archive/text_iarchive.hpp>
44
45#include "SphericalPointDistributionUnitTest.hpp"
46
47#include <boost/assign.hpp>
48#include <boost/math/quaternion.hpp>
49
50#include "CodePatterns/Assert.hpp"
51#include "CodePatterns/Log.hpp"
52
53#include "LinearAlgebra/Line.hpp"
54
55#include "Fragmentation/Exporters/SphericalPointDistribution.hpp"
56
57#ifdef HAVE_TESTRUNNER
58#include "UnitTestMain.hpp"
59#endif /*HAVE_TESTRUNNER*/
60
61using namespace boost::assign;
62
63/********************************************** Test classes **************************************/
64
65// Registers the fixture into the 'registry'
66CPPUNIT_TEST_SUITE_REGISTRATION( SphericalPointDistributionTest );
67
68
69void SphericalPointDistributionTest::setUp()
70{
71 // failing asserts should be thrown
72 ASSERT_DO(Assert::Throw);
73
74 setVerbosity(5);
75}
76
77
78void SphericalPointDistributionTest::tearDown()
79{
80}
81
82void SphericalPointDistributionTest::QuaternionTest()
83{
84 Vector oldCenter(0.,1.,0.);
85 Vector newCenter(1.,0.,0.);
86
87 {
88 // setup quaternion
89 Vector RotationAxis = newCenter;
90 RotationAxis.VectorProduct(oldCenter);
91 RotationAxis.Normalize();
92 const double RotationAngle = oldCenter.Angle(newCenter)/(M_PI/2.);
93 // RotationAxis.Angle(oldCenter) - RotationAxis.Angle(newCenter);
94 boost::math::quaternion<double> q
95 (RotationAngle, RotationAxis[0], RotationAxis[1], RotationAxis[2]);
96 LOG(5, "DEBUG: RotationAxis is " << RotationAxis
97 << ", RotationAngle is " << RotationAngle);
98 LOG(5, "DEBUG: Quaternion describing rotation is " << q);
99 boost::math::quaternion<double> q_inverse =
100 boost::math::conj(q)/(boost::math::norm(q));
101 LOG(5, "DEBUG: Quaternion inverse is " << q_inverse);
102 boost::math::quaternion<double> identity(1,0,0,0);
103 const boost::math::quaternion<double> unity = q*q_inverse;
104 LOG(5, "DEBUG: q * q^-1 is " << unity);
105 CPPUNIT_ASSERT( boost::math::norm(unity - identity) < std::numeric_limits<double>::epsilon()*1e4);
106
107 // check that rotation works
108 boost::math::quaternion<double> p(0., newCenter[0], newCenter[1], newCenter[2]);
109 LOG(5, "DEBUG: Original newCenter is " << p);
110 p = p * q_inverse;
111 p = q * p;
112 LOG(5, "DEBUG: Rotated newCenter is " << p);
113 boost::math::quaternion<double> comparison(0., -oldCenter[0], oldCenter[1], oldCenter[2]);
114 LOG(5, "DEBUG: Difference norm is " << boost::math::norm(p - comparison));
115 CPPUNIT_ASSERT( boost::math::norm(p - comparison) < std::numeric_limits<double>::epsilon()*1e4);
116 }
117
118 // rotating with angle = 0 flips the vector unwantedly
119 {
120 // setup quaternion
121 Vector RotationAxis = newCenter;
122 RotationAxis.VectorProduct(oldCenter);
123 RotationAxis.Normalize();
124 const double RotationAngle = 0.;
125 // RotationAxis.Angle(oldCenter) - RotationAxis.Angle(newCenter);
126 boost::math::quaternion<double> q
127 (RotationAngle, RotationAxis[0], RotationAxis[1], RotationAxis[2]);
128 LOG(5, "DEBUG: RotationAxis is " << RotationAxis
129 << ", RotationAngle is " << RotationAngle);
130 LOG(5, "DEBUG: Quaternion describing rotation is " << q);
131 boost::math::quaternion<double> q_inverse =
132 boost::math::conj(q)/(boost::math::norm(q));
133 LOG(5, "DEBUG: Quaternion inverse is " << q_inverse);
134 boost::math::quaternion<double> identity(1,0,0,0);
135 const boost::math::quaternion<double> unity = q*q_inverse;
136 LOG(5, "DEBUG: q * q^-1 is " << unity);
137 CPPUNIT_ASSERT( boost::math::norm(unity - identity) < std::numeric_limits<double>::epsilon()*1e4);
138
139 // check that rotation works
140 boost::math::quaternion<double> p(0., newCenter[0], newCenter[1], newCenter[2]);
141 boost::math::quaternion<double> comparison(0., -newCenter[0], newCenter[1], newCenter[2]);
142 LOG(5, "DEBUG: Original newCenter is " << p);
143 p = p * q_inverse;
144 p = q * p;
145 LOG(5, "DEBUG: Rotated newCenter is " << p);
146 LOG(5, "DEBUG: Difference norm is " << boost::math::norm(p - comparison));
147 CPPUNIT_ASSERT( boost::math::norm(p - comparison) < std::numeric_limits<double>::epsilon()*1e4);
148 }
149}
150
151/** UnitTest for matchSphericalPointDistributions() with two points
152 */
153void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_2()
154{
155 SphericalPointDistribution SPD(1.);
156 // test with one point, matching trivially
157 {
158 SphericalPointDistribution::Polygon_t polygon;
159 polygon += Vector(1.,0.,0.);
160 SphericalPointDistribution::Polygon_t newpolygon =
161 SPD.get<2>();
162 SphericalPointDistribution::Polygon_t expected;
163 expected += Vector(-1.,0.,0.);
164 SphericalPointDistribution::Polygon_t remaining =
165 SphericalPointDistribution::matchSphericalPointDistributions(
166 polygon,
167 newpolygon);
168 CPPUNIT_ASSERT_EQUAL( expected, remaining );
169 }
170
171 // test with one point, just a flip of axis
172 {
173 SphericalPointDistribution::Polygon_t polygon;
174 polygon += Vector(0.,1.,0.);
175 SphericalPointDistribution::Polygon_t newpolygon =
176 SPD.get<2>();
177 SphericalPointDistribution::Polygon_t expected;
178 expected += Vector(0.,-1.,0.);
179 SphericalPointDistribution::Polygon_t remaining =
180 SphericalPointDistribution::matchSphericalPointDistributions(
181 polygon,
182 newpolygon);
183 CPPUNIT_ASSERT_EQUAL( expected, remaining );
184 }
185
186 // test with one point, just a flip to another axis
187 {
188 SphericalPointDistribution::Polygon_t polygon;
189 polygon += Vector(0.,0.,-1.);
190 SphericalPointDistribution::Polygon_t newpolygon =
191 SPD.get<2>();
192 SphericalPointDistribution::Polygon_t expected;
193 expected += Vector(0.,0.,1.);
194 SphericalPointDistribution::Polygon_t remaining =
195 SphericalPointDistribution::matchSphericalPointDistributions(
196 polygon,
197 newpolygon);
198 CPPUNIT_ASSERT_EQUAL( expected, remaining );
199 }
200
201 // test with one point, full rotation
202 {
203 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
204 SphericalPointDistribution::Polygon_t polygon;
205 polygon += RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI);
206 SphericalPointDistribution::Polygon_t newpolygon =
207 SPD.get<2>();
208 SphericalPointDistribution::Polygon_t expected;
209 expected += RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180*M_PI);
210 SphericalPointDistribution::Polygon_t remaining =
211 SphericalPointDistribution::matchSphericalPointDistributions(
212 polygon,
213 newpolygon);
214 CPPUNIT_ASSERT_EQUAL( expected, remaining );
215 }
216}
217
218/** UnitTest for matchSphericalPointDistributions() with three points
219 */
220void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_3()
221{
222 SphericalPointDistribution SPD(1.);
223
224 // test with one point, matching trivially
225 {
226 SphericalPointDistribution::Polygon_t polygon;
227 polygon += Vector(1.,0.,0.);
228 SphericalPointDistribution::Polygon_t newpolygon =
229 SPD.get<3>();
230 SphericalPointDistribution::Polygon_t expected = newpolygon;
231 expected.pop_front(); // remove first point
232 SphericalPointDistribution::Polygon_t remaining =
233 SphericalPointDistribution::matchSphericalPointDistributions(
234 polygon,
235 newpolygon);
236 CPPUNIT_ASSERT_EQUAL( expected, remaining );
237 }
238
239 // test with one point, just a flip of x and y axis
240 {
241 SphericalPointDistribution::Polygon_t polygon;
242 polygon += Vector(0.,1.,0.);
243 SphericalPointDistribution::Polygon_t newpolygon =
244 SPD.get<3>();
245 SphericalPointDistribution::Polygon_t expected = newpolygon;
246 expected.pop_front(); // remove first point
247 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
248 iter != expected.end(); ++iter) {
249 std::swap((*iter)[0], (*iter)[1]);
250 (*iter)[0] *= -1.;
251 }
252 SphericalPointDistribution::Polygon_t remaining =
253 SphericalPointDistribution::matchSphericalPointDistributions(
254 polygon,
255 newpolygon);
256 CPPUNIT_ASSERT_EQUAL( expected, remaining );
257 }
258}
259
260/** UnitTest for matchSphericalPointDistributions() with four points
261 */
262void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_4()
263{
264 SphericalPointDistribution SPD(1.);
265
266 // test with one point, matching trivially
267 {
268 SphericalPointDistribution::Polygon_t polygon;
269 polygon += Vector(1.,0.,0.);
270 SphericalPointDistribution::Polygon_t newpolygon =
271 SPD.get<4>();
272 SphericalPointDistribution::Polygon_t expected = newpolygon;
273 expected.pop_front(); // remove first point
274 SphericalPointDistribution::Polygon_t remaining =
275 SphericalPointDistribution::matchSphericalPointDistributions(
276 polygon,
277 newpolygon);
278 CPPUNIT_ASSERT_EQUAL( expected, remaining );
279 }
280
281 // test with one point, just a flip of axis
282 {
283 SphericalPointDistribution::Polygon_t polygon;
284 polygon += Vector(0.,1.,0.);
285 SphericalPointDistribution::Polygon_t newpolygon =
286 SPD.get<4>();
287 SphericalPointDistribution::Polygon_t expected = newpolygon;
288 expected.pop_front(); // remove first point
289 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
290 iter != expected.end(); ++iter) {
291 std::swap((*iter)[0], (*iter)[1]);
292 (*iter)[0] *= -1.;
293 }
294 SphericalPointDistribution::Polygon_t remaining =
295 SphericalPointDistribution::matchSphericalPointDistributions(
296 polygon,
297 newpolygon);
298 CPPUNIT_ASSERT_EQUAL( expected, remaining );
299 }
300}
301
302/** UnitTest for matchSphericalPointDistributions() with five points
303 */
304void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_5()
305{
306 SphericalPointDistribution SPD(1.);
307
308 // test with one point, matching trivially
309 {
310 SphericalPointDistribution::Polygon_t polygon;
311 polygon += Vector(1.,0.,0.);
312 SphericalPointDistribution::Polygon_t newpolygon =
313 SPD.get<5>();
314 SphericalPointDistribution::Polygon_t expected = newpolygon;
315 expected.pop_front(); // remove first point
316 SphericalPointDistribution::Polygon_t remaining =
317 SphericalPointDistribution::matchSphericalPointDistributions(
318 polygon,
319 newpolygon);
320 CPPUNIT_ASSERT_EQUAL( expected, remaining );
321 }
322
323 // test with one point, just a flip of axis
324 {
325 SphericalPointDistribution::Polygon_t polygon;
326 polygon += Vector(0.,1.,0.);
327 SphericalPointDistribution::Polygon_t newpolygon =
328 SPD.get<5>();
329 SphericalPointDistribution::Polygon_t expected = newpolygon;
330 expected.pop_front(); // remove first point
331 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
332 iter != expected.end(); ++iter) {
333 std::swap((*iter)[0], (*iter)[1]);
334 (*iter)[0] *= -1.;
335 }
336 SphericalPointDistribution::Polygon_t remaining =
337 SphericalPointDistribution::matchSphericalPointDistributions(
338 polygon,
339 newpolygon);
340 CPPUNIT_ASSERT_EQUAL( expected, remaining );
341 }
342}
343
344/** UnitTest for matchSphericalPointDistributions() with six points
345 */
346void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_6()
347{
348 SphericalPointDistribution SPD(1.);
349
350 // test with one point, matching trivially
351 {
352 SphericalPointDistribution::Polygon_t polygon;
353 polygon += Vector(1.,0.,0.);
354 SphericalPointDistribution::Polygon_t newpolygon =
355 SPD.get<6>();
356 SphericalPointDistribution::Polygon_t expected = newpolygon;
357 expected.pop_front(); // remove first point
358 SphericalPointDistribution::Polygon_t remaining =
359 SphericalPointDistribution::matchSphericalPointDistributions(
360 polygon,
361 newpolygon);
362 CPPUNIT_ASSERT_EQUAL( expected, remaining );
363 }
364
365 // test with one point, just a flip of axis
366 {
367 SphericalPointDistribution::Polygon_t polygon;
368 polygon += Vector(0.,1.,0.);
369 SphericalPointDistribution::Polygon_t newpolygon =
370 SPD.get<6>();
371 SphericalPointDistribution::Polygon_t expected = newpolygon;
372 expected.pop_front(); // remove first point
373 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
374 iter != expected.end(); ++iter) {
375 std::swap((*iter)[0], (*iter)[1]);
376 (*iter)[0] *= -1.;
377 }
378 SphericalPointDistribution::Polygon_t remaining =
379 SphericalPointDistribution::matchSphericalPointDistributions(
380 polygon,
381 newpolygon);
382 CPPUNIT_ASSERT_EQUAL( expected, remaining );
383 }
384}
385
386/** UnitTest for matchSphericalPointDistributions() with seven points
387 */
388void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_7()
389{
390 SphericalPointDistribution SPD(1.);
391
392 // test with one point, matching trivially
393 {
394 SphericalPointDistribution::Polygon_t polygon;
395 polygon += Vector(1.,0.,0.);
396 SphericalPointDistribution::Polygon_t newpolygon =
397 SPD.get<7>();
398 SphericalPointDistribution::Polygon_t expected = newpolygon;
399 expected.pop_front(); // remove first point
400 SphericalPointDistribution::Polygon_t remaining =
401 SphericalPointDistribution::matchSphericalPointDistributions(
402 polygon,
403 newpolygon);
404 CPPUNIT_ASSERT_EQUAL( expected, remaining );
405 }
406
407 // test with one point, just a flip of axis
408 {
409 SphericalPointDistribution::Polygon_t polygon;
410 polygon += Vector(0.,1.,0.);
411 SphericalPointDistribution::Polygon_t newpolygon =
412 SPD.get<7>();
413 SphericalPointDistribution::Polygon_t expected = newpolygon;
414 expected.pop_front(); // remove first point
415 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
416 iter != expected.end(); ++iter) {
417 std::swap((*iter)[0], (*iter)[1]);
418 (*iter)[0] *= -1.;
419 }
420 SphericalPointDistribution::Polygon_t remaining =
421 SphericalPointDistribution::matchSphericalPointDistributions(
422 polygon,
423 newpolygon);
424 CPPUNIT_ASSERT_EQUAL( expected, remaining );
425 }
426}
427
428/** UnitTest for matchSphericalPointDistributions() with eight points
429 */
430void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_8()
431{
432 SphericalPointDistribution SPD(1.);
433
434 // test with one point, matching trivially
435 {
436 SphericalPointDistribution::Polygon_t polygon;
437 polygon += Vector(1.,0.,0.);
438 SphericalPointDistribution::Polygon_t newpolygon =
439 SPD.get<8>();
440 SphericalPointDistribution::Polygon_t expected = newpolygon;
441 expected.pop_front(); // remove first point
442 SphericalPointDistribution::Polygon_t remaining =
443 SphericalPointDistribution::matchSphericalPointDistributions(
444 polygon,
445 newpolygon);
446 CPPUNIT_ASSERT_EQUAL( expected, remaining );
447 }
448
449 // test with one point, just a flip of axis
450 {
451 SphericalPointDistribution::Polygon_t polygon;
452 polygon += Vector(0.,1.,0.);
453 SphericalPointDistribution::Polygon_t newpolygon =
454 SPD.get<8>();
455 SphericalPointDistribution::Polygon_t expected = newpolygon;
456 expected.pop_front(); // remove first point
457 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
458 iter != expected.end(); ++iter) {
459 std::swap((*iter)[0], (*iter)[1]);
460 (*iter)[0] *= -1.;
461 }
462 SphericalPointDistribution::Polygon_t remaining =
463 SphericalPointDistribution::matchSphericalPointDistributions(
464 polygon,
465 newpolygon);
466 CPPUNIT_ASSERT_EQUAL( expected, remaining );
467 }
468}
Note: See TracBrowser for help on using the repository browser.