source: src/Fragmentation/Summation/SetValues/unittests/SamplingGridUnitTest.cpp@ d56e21

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion GeometryObjects Gui_displays_atomic_force_velocity IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks RotateToPrincipalAxisSystem_UndoRedo StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps Ubuntu_1604_changes stable
Last change on this file since d56e21 was d56e21, checked in by Frederik Heber <heber@…>, 8 years ago

Added padWithZerosForEvenNumberedSamples(), required by downsample().

  • added unit test function.
  • Property mode set to 100644
File size: 33.8 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2012 University of Bonn. All rights reserved.
5 * Copyright (C) 2013 Frederik Heber. All rights reserved.
6 *
7 *
8 * This file is part of MoleCuilder.
9 *
10 * MoleCuilder is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * MoleCuilder is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24/*
25 * SamplingGridUnitTest.cpp
26 *
27 * Created on: Jul 29, 2012
28 * Author: heber
29 */
30
31// include config.h
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36using namespace std;
37
38#include <cppunit/CompilerOutputter.h>
39#include <cppunit/extensions/TestFactoryRegistry.h>
40#include <cppunit/ui/text/TestRunner.h>
41
42// include headers that implement a archive in simple text format
43#include <boost/archive/text_oarchive.hpp>
44#include <boost/archive/text_iarchive.hpp>
45
46#include "SamplingGridUnitTest.hpp"
47
48#include "CodePatterns/Assert.hpp"
49#include "CodePatterns/Log.hpp"
50
51#include <boost/assign.hpp>
52
53#include <cmath>
54#include <numeric>
55
56#ifdef HAVE_TESTRUNNER
57#include "UnitTestMain.hpp"
58#endif /*HAVE_TESTRUNNER*/
59
60using namespace boost::assign;
61
62/********************************************** Test classes **************************************/
63
64const double grid_value=1.;
65
66#define NUMBEROFSAMPLES(n) (size_t)(pow(pow(2,n),(int)NDIM))
67#define DOMAINVOLUME(l) (size_t)pow(l,(int)NDIM)
68
69// Registers the fixture into the 'registry'
70CPPUNIT_TEST_SUITE_REGISTRATION( SamplingGridTest );
71
72
73void SamplingGridTest::setUp()
74{
75 // failing asserts should be thrown
76 ASSERT_DO(Assert::Throw);
77
78 // create the grid
79 const double begin[NDIM] = { 0., 0., 0. };
80 const double end[NDIM] = { 1., 1., 1. };
81 for (size_t i=0; i< DOMAINVOLUME(1)*NUMBEROFSAMPLES(2); ++i)
82 values += grid_value;
83 grid = new SamplingGrid(begin, end, 2, values);
84 CPPUNIT_ASSERT_EQUAL( grid_value, *(grid->sampled_grid.begin()) );
85}
86
87
88void SamplingGridTest::tearDown()
89{
90 delete grid;
91}
92
93/** UnitTest on equivalent combination of props and values
94 */
95void SamplingGridTest::equivalentGrids_Test()
96{
97 // check illegal grid
98 const double begin[NDIM] = { 0., 0., 0. };
99 const double end[NDIM] = { 1., 1., 1. };
100 SamplingGridProperties illegal_props(begin, end, 5);
101 SamplingGridProperties legal_props(begin, end, 2);
102 CPPUNIT_ASSERT( !grid->isEquivalent(illegal_props) );
103 CPPUNIT_ASSERT( grid->isEquivalent(legal_props) );
104 SamplingGrid::sampledvalues_t illegal_values;
105 for (size_t i=0; i< NUMBEROFSAMPLES(1); ++i)
106 illegal_values += 1.5;
107 SamplingGrid::sampledvalues_t legal_values;
108 for (size_t i=0; i< NUMBEROFSAMPLES(2); ++i)
109 legal_values += 1.5;
110#ifndef NDEBUG
111 // throws because props and size of illegal_values don't match
112 std::cout << "The following assertion is intended and does not indicate a failure of the test." << std::endl;
113 CPPUNIT_ASSERT_THROW( SamplingGrid illegal_grid(illegal_props, illegal_values), Assert::AssertionFailure );
114 std::cout << "The following assertion is intended and does not indicate a failure of the test." << std::endl;
115 CPPUNIT_ASSERT_THROW( SamplingGrid illegal_grid(legal_props, illegal_values), Assert::AssertionFailure );
116 std::cout << "The following assertion is intended and does not indicate a failure of the test." << std::endl;
117 CPPUNIT_ASSERT_THROW( SamplingGrid illegal_grid(illegal_props, legal_values), Assert::AssertionFailure );
118#endif
119 // check that grid is still the same
120 for (SamplingGrid::sampledvalues_t::const_iterator iter = grid->sampled_grid.begin();
121 iter != grid->sampled_grid.end(); ++iter)
122 CPPUNIT_ASSERT_EQUAL( grid_value, *iter );
123}
124
125/** UnitTest on compatible combination of props and values
126 */
127void SamplingGridTest::compatibleGrids_Test()
128{
129 // check illegal grid
130 const double begin[NDIM] = { 0., 0., 0. };
131 const double end[NDIM] = { 1., 1., 1. };
132 const double otherend[NDIM] = { 2.5, 2.5, 2.5 };
133 SamplingGridProperties illegal_props(begin, otherend, 5);
134 SamplingGridProperties legal_props(begin, end, 3);
135 CPPUNIT_ASSERT( !grid->isCompatible(illegal_props) );
136 CPPUNIT_ASSERT( grid->isCompatible(legal_props) );
137 SamplingGrid::sampledvalues_t illegal_values;
138 for (size_t i=0; i< NUMBEROFSAMPLES(1); ++i)
139 illegal_values += 1.5;
140 SamplingGrid::sampledvalues_t legal_values;
141 for (size_t i=0; i< NUMBEROFSAMPLES(2); ++i)
142 legal_values += 1.5;
143#ifndef NDEBUG
144 // throws because props and size of illegal_values don't match
145 std::cout << "The following assertion is intended and does not indicate a failure of the test." << std::endl;
146 CPPUNIT_ASSERT_THROW( SamplingGrid illegal_grid(illegal_props, illegal_values), Assert::AssertionFailure );
147 std::cout << "The following assertion is intended and does not indicate a failure of the test." << std::endl;
148 CPPUNIT_ASSERT_THROW( SamplingGrid illegal_grid(legal_props, illegal_values), Assert::AssertionFailure );
149 std::cout << "The following assertion is intended and does not indicate a failure of the test." << std::endl;
150 CPPUNIT_ASSERT_THROW( SamplingGrid illegal_grid(illegal_props, legal_values), Assert::AssertionFailure );
151#endif
152 // check that grid is still the same
153 for (SamplingGrid::sampledvalues_t::const_iterator iter = grid->sampled_grid.begin();
154 iter != grid->sampled_grid.end(); ++iter)
155 CPPUNIT_ASSERT_EQUAL( grid_value, *iter );
156}
157
158/** UnitTest for isCongruent()
159 */
160void SamplingGridTest::isCongruent_Test()
161{
162 const double begin[NDIM] = { 0., 0., 0. };
163 const double end[NDIM] = { 2., 2., 2. };
164 const double otherbegin[NDIM] = { 0.1, 0.1, 0.1 };
165 const double otherend[NDIM] = { 1., 1., 1. };
166 SamplingGridProperties illegal_begin_props(otherbegin, end, 5);
167 SamplingGridProperties illegal_end_props(begin, otherend, 5);
168 SamplingGridProperties illegal_level_props(begin, end, 5);
169 SamplingGridProperties legal_props(begin, end, 2);
170
171 // differing windows
172// const double begin_window[NDIM] = { 0.5, 0.5, 0.5 };
173// const double end_window[NDIM] = { 1., 1., 1. };
174 const double otherbegin_window[NDIM] = { 0.45, 0.45, 0.45 };
175 const double otherend_window[NDIM] = { 1.05, 1.05, 1.05 };
176
177 // check that incompatible grid are also incongruent
178 SamplingGrid default_grid(legal_props);
179 // note that we always construct a temporary SamplingGrid from given props
180 CPPUNIT_ASSERT( default_grid.isEquivalent(illegal_begin_props) == default_grid.isCongruent(illegal_begin_props));
181 CPPUNIT_ASSERT( default_grid.isEquivalent(illegal_end_props) == default_grid.isCongruent(illegal_end_props));
182 CPPUNIT_ASSERT( default_grid.isEquivalent(illegal_level_props) == default_grid.isCongruent(illegal_level_props));
183 CPPUNIT_ASSERT( default_grid.isEquivalent(legal_props) == default_grid.isCongruent(legal_props) );
184
185 default_grid.setWindowSize(begin, end);
186 // same window
187 {
188 SamplingGrid illegal_begin_grid(illegal_begin_props);
189 SamplingGrid illegal_end_grid(illegal_end_props);
190 SamplingGrid illegal_level_grid(illegal_level_props);
191 SamplingGrid legal_grid(legal_props);
192 illegal_begin_grid.setWindowSize(begin, end);
193 illegal_end_grid.setWindowSize(begin, end);
194 illegal_level_grid.setWindowSize(begin, end);
195 legal_grid.setWindowSize(begin, end);
196 CPPUNIT_ASSERT( !illegal_begin_grid.isCongruent(default_grid) );
197 CPPUNIT_ASSERT( !illegal_end_grid.isCongruent(default_grid) );
198 CPPUNIT_ASSERT( !illegal_level_grid.isCongruent(default_grid) );
199 CPPUNIT_ASSERT( legal_grid.isCongruent(default_grid) );
200 }
201
202 // different begin
203 {
204 SamplingGrid illegal_begin_grid(illegal_begin_props);
205 SamplingGrid illegal_end_grid(illegal_end_props);
206 SamplingGrid illegal_level_grid(illegal_level_props);
207 SamplingGrid legal_grid(legal_props);
208 illegal_begin_grid.setWindowSize(otherbegin_window, end);
209 illegal_end_grid.setWindowSize(otherbegin_window, end);
210 illegal_level_grid.setWindowSize(otherbegin_window, end);
211 legal_grid.setWindowSize(begin, end);
212 CPPUNIT_ASSERT( !illegal_begin_grid.isCongruent(legal_grid) );
213 CPPUNIT_ASSERT( !illegal_end_grid.isCongruent(legal_grid) );
214 CPPUNIT_ASSERT( !illegal_level_grid.isCongruent(legal_grid) );
215 CPPUNIT_ASSERT( legal_grid.isCongruent(default_grid) );
216 }
217
218 // different end
219 {
220 SamplingGrid illegal_begin_grid(illegal_begin_props);
221 SamplingGrid illegal_end_grid(illegal_end_props);
222 SamplingGrid illegal_level_grid(illegal_level_props);
223 SamplingGrid legal_grid(legal_props);
224 illegal_begin_grid.setWindowSize(begin, otherend_window);
225 illegal_end_grid.setWindowSize(begin, otherend_window);
226 illegal_level_grid.setWindowSize(begin, otherend_window);
227 legal_grid.setWindowSize(begin, end);
228 CPPUNIT_ASSERT( !illegal_begin_grid.isCongruent(legal_grid) );
229 CPPUNIT_ASSERT( !illegal_end_grid.isCongruent(legal_grid) );
230 CPPUNIT_ASSERT( !illegal_level_grid.isCongruent(legal_grid) );
231 CPPUNIT_ASSERT( legal_grid.isCongruent(default_grid) );
232 }
233
234 // different begin and end
235 {
236 SamplingGrid illegal_begin_grid(illegal_begin_props);
237 SamplingGrid illegal_end_grid(illegal_end_props);
238 SamplingGrid illegal_level_grid(illegal_level_props);
239 SamplingGrid legal_grid(legal_props);
240 illegal_begin_grid.setWindowSize(otherbegin_window, otherend_window);
241 illegal_end_grid.setWindowSize(otherbegin_window, otherend_window);
242 illegal_level_grid.setWindowSize(otherbegin_window, otherend_window);
243 legal_grid.setWindowSize(begin, end);
244 CPPUNIT_ASSERT( !illegal_begin_grid.isCongruent(legal_grid) );
245 CPPUNIT_ASSERT( !illegal_end_grid.isCongruent(legal_grid) );
246 CPPUNIT_ASSERT( !illegal_level_grid.isCongruent(legal_grid) );
247 CPPUNIT_ASSERT( legal_grid.isCongruent(default_grid) );
248 }
249}
250
251/** UnitTest for integral()
252 */
253void SamplingGridTest::integral_Test()
254{
255 double sum = 0.;
256 sum = std::accumulate( grid->sampled_grid.begin(), grid->sampled_grid.end(), sum );
257 CPPUNIT_ASSERT_EQUAL( sum*grid->getVolume()/grid->getWindowGridPoints(), grid->integral() );
258}
259
260/** UnitTest for getVolume()
261 */
262void SamplingGridTest::getVolume_Test()
263{
264 CPPUNIT_ASSERT_EQUAL( 1., grid->getVolume() );
265}
266
267/** UnitTest for getWindowSize()
268 */
269void SamplingGridTest::getWindowSize_Test()
270{
271 // check size of default grid
272 CPPUNIT_ASSERT_EQUAL( (size_t)(NUMBEROFSAMPLES(grid->level)), grid->getWindowGridPoints() );
273
274 // create another one and check its size, too
275 const double begin[NDIM] = { 0., 0., 0. };
276 const double end[NDIM] = { 1., 1., 1. };
277 for (size_t level = 3; level<=6; ++level) {
278 values.clear();
279 for (size_t i=0; i< NUMBEROFSAMPLES(level); ++i)
280 values += grid_value;
281 delete grid;
282 // use other pointer in case something fails
283 SamplingGrid *tmpgrid = new SamplingGrid(begin, end, level, values);
284 grid = tmpgrid;
285 CPPUNIT_ASSERT_EQUAL( (size_t)NUMBEROFSAMPLES(level), grid->getWindowGridPoints() );
286 }
287}
288
289/** UnitTest for extendWindow()
290 */
291void SamplingGridTest::extendWindow_Test()
292{
293 // we have a grid with size of one, extend to twice the size and check
294 const double begin[NDIM] = { 0., 0., 0. };
295 const double size = 2.;
296 const double end[NDIM] = { size, size, size };
297 double offset[NDIM];
298 for (offset[0] = 0.; offset[0] <= 1.; offset[0] += .5)
299 for (offset[1] = 0.; offset[1] <= 1.; offset[1] += .5)
300 for (offset[2] = 0.; offset[2] <= 1.; offset[2] += .5) {
301 const double window_begin[NDIM] = { 0.+offset[0], 0.+offset[1], 0.+offset[2]};
302 const double window_end[NDIM] = { 1.+offset[0], 1.+offset[1], 1.+offset[2]};
303 SamplingGrid newgrid(begin, end, 2);
304 newgrid.setWindowSize(window_begin, window_end);
305 // resize values by hand to new window size. Otherwise they get zero'd.
306 newgrid.sampled_grid = values;
307 newgrid.sampled_grid.resize(NUMBEROFSAMPLES(1));
308 newgrid.extendWindow(begin, end);
309
310 // check integral
311 CPPUNIT_ASSERT_EQUAL(
312 grid_value/(NUMBEROFSAMPLES(grid->level)/NUMBEROFSAMPLES(grid->level)),
313 grid->integral()
314 );
315
316 // check number of points
317 CPPUNIT_ASSERT_EQUAL(
318 (size_t)NUMBEROFSAMPLES(grid->level),
319 grid->getWindowGridPoints()
320 );
321 }
322}
323
324/** UnitTest for extendWindow() with asymmetric values
325 */
326void SamplingGridTest::extendWindow_asymmetric_Test()
327{
328 std::cout << "SamplingGridTest::extendWindow_asymmetric_Test()" << std::endl;
329 const double begin[NDIM] = { 0., 0., 0. };
330 const double end[NDIM] = { 2., 2., 2. };
331 double offset[NDIM];
332 for (offset[0] = 0.; offset[0] <= 1.; offset[0] += .5)
333 for (offset[1] = 0.; offset[1] <= 1.; offset[1] += .5)
334 for (offset[2] = 0.; offset[2] <= 1.; offset[2] += .5) {
335 const double window_begin[NDIM] = { 0.+offset[0], 0.+offset[1], 0.+offset[2]};
336 const double window_end[NDIM] = { 1.+offset[0], 1.+offset[1], 1.+offset[2]};
337 SamplingGrid newgrid(begin, end, 2);
338 CPPUNIT_ASSERT_EQUAL( (size_t)0, newgrid.getWindowGridPoints() );
339 newgrid.setWindowSize(window_begin, window_end);
340 // window size is only half of domain size
341 const size_t max_samples = NUMBEROFSAMPLES(newgrid.level)*pow(0.5,(int)NDIM);
342 for (size_t i=0; i< max_samples; ++i)
343 newgrid.sampled_grid += grid_value*i;
344 const size_t sum_weight = (max_samples)*(max_samples-1)/2;
345 const double integral = newgrid.integral();
346 newgrid.extendWindow(begin, end);
347
348 // check that integral has remained the same
349 CPPUNIT_ASSERT_EQUAL( integral, newgrid.integral() );
350 CPPUNIT_ASSERT_EQUAL( grid_value*sum_weight/DOMAINVOLUME(2), newgrid.integral() );
351 }
352}
353
354/** UnitTest for addOntoWindow()
355 */
356void SamplingGridTest::addOntoWindow_Test()
357{
358 // first window is from (0,0,0) to (1,1,1)
359 CPPUNIT_ASSERT_EQUAL( 1.*grid_value, grid->integral() );
360
361 // create values for half-sized window
362 values.clear();
363 for (size_t i=0; i< (size_t)pow(.5*pow(2,2),(int)NDIM); ++i)
364 values += grid_value;
365
366 // check that too large a window throws
367#ifndef NDEBUG
368 const double begin[NDIM] = { .5, .5, .5 };
369 const double wrongend[NDIM] = { 1.5, 1.5, 1.5 };
370 std::cout << "The following assertion is intended and does not indicate a failure of the test." << std::endl;
371 CPPUNIT_ASSERT_THROW( grid->addOntoWindow(begin, wrongend, values, +1.), Assert::AssertionFailure );
372#endif
373
374 // create another window from (.5,.5,.5) to (1., 1., 1.)
375 double offset[NDIM];
376 for (offset[0] = 0.; offset[0] <= .5; offset[0] += .5)
377 for (offset[1] = 0.; offset[1] <= .5; offset[1] += .5)
378 for (offset[2] = 0.; offset[2] <= .5; offset[2] += .5) {
379 const double window_begin[NDIM] = { 0.+offset[0], 0.+offset[1], 0.+offset[2]};
380 const double window_end[NDIM] = { .5+offset[0], .5+offset[1], .5+offset[2]};
381
382 SamplingGrid newgrid(*grid);
383 // now perform working operation
384 newgrid.addOntoWindow(window_begin, window_end, values, +1.);
385
386 // check integral to be one and one eighth times the old value
387 CPPUNIT_ASSERT_EQUAL( (1.+pow(.5,(int)NDIM))*grid_value, newgrid.integral() );
388 }
389}
390
391/** UnitTest for addOntoWindow() with asymmetric values
392 */
393void SamplingGridTest::addOntoWindow_asymmetric_Test()
394{
395 const size_t size = grid->end[0]-grid->begin[0];
396 // check with asymmetric values
397 grid->sampled_grid.clear();
398 grid->sampled_grid.resize(DOMAINVOLUME(size)*NUMBEROFSAMPLES(grid->level), 0.);
399
400 for (size_t i=0;i<grid->level*(grid->end[0]-grid->begin[0]);++i)
401 grid->sampled_grid[(i*2+0)*2+0] += .5*grid_value;
402 for (size_t i=0;i<grid->level*(grid->end[1]-grid->begin[1]);++i)
403 grid->sampled_grid[(0*2+i)*2+0] += 1.*grid_value;
404 for (size_t i=0;i<grid->level*(grid->end[2]-grid->begin[2]);++i)
405 grid->sampled_grid[(0*2+0)*2+i] += 1.5*grid_value;
406
407 const double integral = grid->integral();
408
409 // now perform working operation
410 grid->addOntoWindow(grid->begin, grid->end, values, +1.);
411 // values is equal to integral of 1.
412 CPPUNIT_ASSERT_EQUAL( 1.+integral, grid->integral() );
413}
414
415/** UnitTest for operator+=()
416 */
417void SamplingGridTest::operatorPlusEqual_Test()
418{
419 // create other grid
420 const double begin[NDIM] = { 0., 0., 0. };
421 const double end[NDIM] = { 1., 1., 1. };
422 SamplingGrid::sampledvalues_t othervalues;
423 const double othergrid_value = 1.5;
424 for (size_t i=0; i< NUMBEROFSAMPLES(2); ++i)
425 othervalues += othergrid_value;
426 SamplingGrid othergrid(begin, end, 2, othervalues);
427 CPPUNIT_ASSERT_EQUAL( othergrid_value, *(othergrid.sampled_grid.begin()) );
428
429 // perform operation
430 CPPUNIT_ASSERT_NO_THROW( *grid += othergrid );
431
432 // check the contents of the grid
433 const double sum = grid_value+othergrid_value;
434 for (SamplingGrid::sampledvalues_t::const_iterator iter = grid->sampled_grid.begin();
435 iter != grid->sampled_grid.end(); ++iter)
436 CPPUNIT_ASSERT_EQUAL( sum, *iter );
437}
438
439/** UnitTest for operator-=()
440 */
441void SamplingGridTest::operatorMinusEqual_Test()
442{
443 // create other grid
444 const double begin[NDIM] = { 0., 0., 0. };
445 const double end[NDIM] = { 1., 1., 1. };
446 SamplingGrid::sampledvalues_t othervalues;
447 const double othergrid_value = 1.5;
448 for (size_t i=0; i< NUMBEROFSAMPLES(2); ++i)
449 othervalues += othergrid_value;
450 SamplingGrid othergrid(begin, end, 2, othervalues);
451 CPPUNIT_ASSERT_EQUAL( othergrid_value, *(othergrid.sampled_grid.begin()) );
452
453 // perform operation
454 CPPUNIT_ASSERT_NO_THROW( *grid -= othergrid );
455
456 // check the contents of the grid
457 const double difference = grid_value-othergrid_value;
458 for (SamplingGrid::sampledvalues_t::const_iterator iter = grid->sampled_grid.begin();
459 iter != grid->sampled_grid.end(); ++iter)
460 CPPUNIT_ASSERT_EQUAL( difference, *iter );
461}
462
463
464/** UnitTest for operator==()
465 */
466void SamplingGridTest::equality_Test()
467{
468 const double begin[NDIM] = { 0., 0., 0. };
469 const double otherbegin[NDIM] = { .5, 0.1, -0.5 };
470 const double end[NDIM] = { 1., 1., 1. };
471 const double otherend[NDIM] = { 2., 2., 2. };
472 const double begin_window[NDIM] = { 0., 0., 0. };
473 const double otherbegin_window[NDIM] = { .75, 0.1, 0. };
474 const double end_window[NDIM] = { 1., 1., 1. };
475 const double otherend_window[NDIM] = { .9, .9, .9 };
476
477 // create other grid
478 SamplingGrid samegrid(begin, end, 2, values);
479 SamplingGrid differentbegin(otherbegin, end, 2, values);
480 SamplingGrid differentend(begin, otherend, 2, values);
481 SamplingGrid::sampledvalues_t morevalues;
482 {
483 const double othergrid_value = 1.5;
484 for (size_t i=0; i< NUMBEROFSAMPLES(4); ++i)
485 morevalues += othergrid_value;
486 }
487 SamplingGrid differentlevel(begin, end, 4, morevalues);
488 SamplingGrid::sampledvalues_t othervalues;
489 {
490 const double othergrid_value = 1.5;
491 for (size_t i=0; i< NUMBEROFSAMPLES(2); ++i)
492 othervalues += othergrid_value;
493 }
494 SamplingGrid differentvalues(begin, end, 2, othervalues);
495
496 // check for same level, begin, and end
497 CPPUNIT_ASSERT( *grid == *grid );
498 CPPUNIT_ASSERT( *grid == samegrid );
499 CPPUNIT_ASSERT( samegrid == *grid);
500 CPPUNIT_ASSERT( *grid != differentbegin);
501 CPPUNIT_ASSERT( differentbegin != *grid);
502 CPPUNIT_ASSERT( *grid != differentend );
503 CPPUNIT_ASSERT( differentend != *grid );
504 CPPUNIT_ASSERT( *grid != differentlevel );
505 CPPUNIT_ASSERT( differentlevel != *grid );
506
507 // check for all but differing values
508 CPPUNIT_ASSERT( *grid != differentvalues );
509 CPPUNIT_ASSERT( differentvalues != *grid );
510
511 // check for different windows
512 SamplingGrid differentwindowbegin(begin, end, 2);
513 differentwindowbegin.setWindow(otherbegin_window, end_window);
514 SamplingGrid differentwindowend(begin, end, 2);
515 differentwindowend.setWindow(begin_window, otherend_window);
516 CPPUNIT_ASSERT( *grid != differentwindowbegin );
517 CPPUNIT_ASSERT( differentwindowbegin != *grid );
518 CPPUNIT_ASSERT( *grid != differentwindowend );
519 CPPUNIT_ASSERT( differentwindowend != *grid );
520
521 // check against ZeroInstance
522 CPPUNIT_ASSERT( *grid != ZeroInstance<SamplingGrid>() );
523 CPPUNIT_ASSERT( samegrid != ZeroInstance<SamplingGrid>() );
524 CPPUNIT_ASSERT( differentbegin != ZeroInstance<SamplingGrid>() );
525 CPPUNIT_ASSERT( differentend != ZeroInstance<SamplingGrid>() );
526 CPPUNIT_ASSERT( differentlevel != ZeroInstance<SamplingGrid>() );
527 CPPUNIT_ASSERT( differentvalues != ZeroInstance<SamplingGrid>() );
528 CPPUNIT_ASSERT( differentwindowbegin != ZeroInstance<SamplingGrid>() );
529 CPPUNIT_ASSERT( differentwindowend != ZeroInstance<SamplingGrid>() );
530}
531
532/** UnitTest for serialization
533 */
534void SamplingGridTest::serializeTest()
535{
536 // serialize
537 std::stringstream outputstream;
538 boost::archive::text_oarchive oa(outputstream);
539 oa << grid;
540
541 // deserialize
542 SamplingGrid *samegrid = NULL;
543 std::stringstream returnstream(outputstream.str());
544 boost::archive::text_iarchive ia(returnstream);
545 ia >> samegrid;
546
547 CPPUNIT_ASSERT( samegrid != NULL );
548 CPPUNIT_ASSERT( *grid == *samegrid );
549
550 delete samegrid;
551}
552
553#ifdef HAVE_INLINE
554inline
555#endif
556static int calculateIndex(const int N[NDIM], const int &_length)
557{
558 return N[2] + N[1]*_length + N[0]*_length*_length;
559}
560
561#ifdef HAVE_INLINE
562inline
563#endif
564static double calculateDistanceSquared(const int N[NDIM], const int &_length)
565{
566 return
567 ::pow(N[0]/(double)_length-.5,2)
568 + ::pow(N[1]/(double)_length-.5,2)
569 + ::pow(N[2]/(double)_length-.5,2);
570}
571
572#ifdef HAVE_INLINE
573inline
574#endif
575static double getBoundaryCaseFactor(const int N[NDIM], const int &_length)
576{
577 static double third_two=::pow(4., 1./3.);
578 double returnthreshold = 1.;
579 for (size_t i=0;i<NDIM;++i)
580 if ((N[i] == 0) || (N[i] == _length-1))
581 returnthreshold *= third_two;
582 return returnthreshold;
583}
584
585/** UnitTest for padWithZerosForEvenNumberedSamples()
586 *
587 */
588void SamplingGridTest::padWithZerosForEvenNumberedSamplesTest()
589{
590 const double begin[NDIM] = { 0., 0., 0. };
591 const double end[NDIM] = { 2., 2., 2. };
592
593 // we check for window of odd numbers
594 {
595 // LOG(2, "Checking with difference " << grid_difference);
596 const int gridpoints = 1*2*2;
597 const int extended_gridpoints = 2*4*4;
598 SamplingGrid::sampledvalues_t values(gridpoints, 1.); // length in one axis is odd
599 SamplingGrid::sampledvalues_t checkvalues(extended_gridpoints, 0.);
600 {
601 int N[NDIM];
602 int index = 0;
603 for (N[0]=2;N[0]<3;++N[0]) {
604 for (N[1]=0;N[1]<1;++N[1]) {
605 for (N[2]=0;N[2]<4;++N[2]) {
606 checkvalues[index++] = 0.;
607 }
608 }
609 for (N[1]=1;N[1]<3;++N[1]) {
610 checkvalues[index++] = 0.;
611 for (N[2]=1;N[2]<3;++N[2]) {
612 checkvalues[index++] = 1.;
613 }
614 checkvalues[index++] = 0.;
615 }
616 for (N[1]=3;N[1]<4;++N[1]) {
617 for (N[2]=0;N[2]<4;++N[2]) {
618 checkvalues[index++] = 0.;
619 }
620 }
621 }
622 for (N[0]=3;N[0]<4;++N[0]) {
623 for (N[1]=0;N[1]<4;++N[1]) {
624 for (N[2]=0;N[2]<4;++N[2]) {
625 checkvalues[index++] = 0.;
626 }
627 }
628 }
629 }
630
631 /** Here, we must initialize the larger grid with zero window first and
632 * then add the values into the smaller window.
633 */
634 SamplingGrid grid(begin, end, 2);
635 const double window_begin[NDIM] = {
636 grid.getNearestHigherGridPoint(1.0, 0), // index 2
637 grid.getNearestHigherGridPoint(0.5, 1), // index 1 -> 0
638 grid.getNearestHigherGridPoint(0.5, 2) }; // index 1 -> 0
639 const double window_end[NDIM] = {
640 grid.getNearestLowerGridPoint(1.5, 0), // index 3 -> 4
641 grid.getNearestLowerGridPoint(1.5, 1), // index 3 -> 4
642 grid.getNearestLowerGridPoint(1.5, 2) }; // index 3 -> 4
643 grid.setWindow(window_begin, window_end);
644 grid.addOntoWindow(window_begin, window_end, values, +1.);
645 grid.padWithZerosForEvenNumberedSamples();
646
647 SamplingGrid checkgrid(begin, end, 2);
648 const double check_window_begin[NDIM] = {
649 checkgrid.getNearestHigherGridPoint(1., 0),
650 checkgrid.getNearestHigherGridPoint(0., 1),
651 checkgrid.getNearestHigherGridPoint(0., 2) };
652 const double check_window_end[NDIM] = {
653 checkgrid.getNearestHigherGridPoint(2., 0),
654 checkgrid.getNearestHigherGridPoint(2., 1),
655 checkgrid.getNearestHigherGridPoint(2., 2) };
656 checkgrid.setWindow(check_window_begin, check_window_end);
657 checkgrid.addOntoWindow(check_window_begin, check_window_end, checkvalues, +1.);
658
659 std::cout << " grid value " << grid.sampled_grid << std::endl;
660 std::cout << " checkgrid value " << checkgrid.sampled_grid << std::endl;
661 CPPUNIT_ASSERT_EQUAL( checkgrid.sampled_grid.size(), grid.sampled_grid.size());
662 CPPUNIT_ASSERT_EQUAL( checkgrid, grid );
663 }
664}
665
666/** UnitTest for downsample()
667 */
668void SamplingGridTest::downsample_gridTest()
669{
670 const double begin[NDIM] = { 0., 0., 0. };
671 const double end[NDIM] = { 1., 1., 1. };
672
673 // simple test, one level difference, same value everywhere
674 {
675 SamplingGrid::sampledvalues_t checkvalues;
676 SamplingGrid::sampledvalues_t othervalues;
677 const double othergrid_value = 1.5;
678 for (size_t i=0; i< NUMBEROFSAMPLES(2); ++i)
679 checkvalues += othergrid_value;
680 for (size_t i=0; i< NUMBEROFSAMPLES(3); ++i)
681 othervalues += othergrid_value;
682
683 SamplingGrid largegrid(begin, end, 3, othervalues);
684// std::cout << " largegrid value " << largegrid.sampled_grid << std::endl;
685 SamplingGrid smallgrid(begin, end, 2);
686 SamplingGrid::downsample(smallgrid, largegrid, 2);
687 SamplingGrid checkgrid(begin, end, 2, checkvalues);
688// std::cout << " smallgrid value " << smallgrid.sampled_grid << std::endl;
689// std::cout << " checkgrid value " << checkgrid.sampled_grid << std::endl;
690 CPPUNIT_ASSERT_EQUAL( smallgrid, checkgrid );
691 }
692
693 // simple test, two level difference, same value everywhere
694 {
695 SamplingGrid::sampledvalues_t checkvalues;
696 SamplingGrid::sampledvalues_t othervalues;
697 const double othergrid_value = 1.5;
698 for (size_t i=0; i< NUMBEROFSAMPLES(2); ++i)
699 checkvalues += othergrid_value;
700 for (size_t i=0; i< NUMBEROFSAMPLES(4); ++i)
701 othervalues += othergrid_value;
702
703 SamplingGrid largegrid(begin, end, 4, othervalues);
704// std::cout << " largegrid value " << largegrid.sampled_grid << std::endl;
705 SamplingGrid smallgrid(begin, end, 2);
706 SamplingGrid::downsample(smallgrid, largegrid, 2);
707 SamplingGrid checkgrid(begin, end, 2, checkvalues);
708// std::cout << " smallgrid value " << smallgrid.sampled_grid << std::endl;
709// std::cout << " checkgrid value " << checkgrid.sampled_grid << std::endl;
710 CPPUNIT_ASSERT_EQUAL( smallgrid, checkgrid );
711 }
712
713 // same grid, window equals grids, ever larger largegrids
714 const int base_level = 2;
715 for (int grid_difference = 1; grid_difference <= 3; ++grid_difference) {
716// LOG(2, "Checking with difference " << grid_difference);
717 const int length_c = ::pow(2, base_level);
718 const int length_f = ::pow(2, base_level+grid_difference);
719 SamplingGrid::sampledvalues_t checkvalues((int)::pow(length_c, (int)NDIM), 0.);
720 SamplingGrid::sampledvalues_t othervalues((int)::pow(length_f, (int)NDIM), 0.);
721 int N[NDIM];
722 for (N[0]=0; N[0]< length_f; ++N[0]) {
723 for (N[1]=0; N[1]< length_f; ++N[1]) {
724 for (N[2]=0; N[2]< length_f; ++N[2]) {
725 const int index = calculateIndex(N, length_f);
726 const double dist = calculateDistanceSquared(N, length_f);
727 othervalues[index] = cos(M_PI*dist/1.5);
728 }
729 }
730 }
731 for (N[0]=0; N[0]< length_c; ++N[0]) {
732 for (N[1]=0; N[1]< length_c; ++N[1]) {
733 for (N[2]=0; N[2]< length_c; ++N[2]) {
734 const int index = calculateIndex(N, length_c);
735 const double dist = calculateDistanceSquared(N, length_c);
736 checkvalues[index] = cos(M_PI*dist/1.5);
737 }
738 }
739 }
740
741 SamplingGrid largegrid(begin, end, base_level+grid_difference, othervalues);
742// std::cout << " largegrid value " << largegrid.sampled_grid << std::endl;
743 SamplingGrid smallgrid(begin, end, base_level);
744 SamplingGrid::downsample(smallgrid, largegrid, base_level);
745 SamplingGrid checkgrid(begin, end, base_level, checkvalues);
746// std::cout << " smallgrid value " << smallgrid.sampled_grid << std::endl;
747// std::cout << " checkgrid value " << checkgrid.sampled_grid << std::endl;
748 const double threshold = 3.2e-2;
749 // we skip the first value as checkvalues[0] is always zero, hard to get from downsampling
750 for (N[0]=1; N[0]< length_c; ++N[0])
751 for (N[1]=0; N[1]< length_c; ++N[1])
752 for (N[2]=0; N[2]< length_c; ++N[2]) {
753 const double check_threshold =
754 threshold*(1.+grid_difference/4.)*getBoundaryCaseFactor(N, length_c);
755 const int index = calculateIndex(N, length_c);
756// std::cout << "Comparing "
757// << fabs((smallgrid.sampled_grid[index] - checkgrid.sampled_grid[index]))
758// << " < " << check_threshold << std::endl;
759 CPPUNIT_ASSERT(
760 fabs((smallgrid.sampled_grid[index] - checkgrid.sampled_grid[index])) < check_threshold);
761// if (fabs(checkgrid.sampled_grid[index]) > 1e-10) {
762// std::cout << "Comparing "
763// << fabs((smallgrid.sampled_grid[index] - checkgrid.sampled_grid[index])/checkgrid.sampled_grid[index])
764// << " < " << check_threshold << std::endl;
765// CPPUNIT_ASSERT(
766// fabs((smallgrid.sampled_grid[index] - checkgrid.sampled_grid[index])/checkgrid.sampled_grid[index]) < check_threshold);
767// }
768 }
769 }
770}
771
772/** UnitTest for downsample()
773 */
774void SamplingGridTest::downsample_smallerwindowTest()
775{
776 const double begin[NDIM] = { 0., 0., 0. };
777 const double end[NDIM] = { 2., 2., 2. };
778
779 // same grid, window is half of grid, different level by one
780 const int base_level = 3;
781 for (int grid_difference = 1; grid_difference <= 3; ++grid_difference) {
782// LOG(2, "Checking with difference " << grid_difference);
783 const int window_length_c = ::pow(2, base_level-1);
784 const int window_length_f = ::pow(2, base_level+grid_difference-1);
785 SamplingGrid::sampledvalues_t checkvalues((int)::pow(window_length_c, (int)NDIM), 0.);
786 SamplingGrid::sampledvalues_t othervalues((int)::pow(window_length_f, (int)NDIM), 0.);
787 int N[NDIM];
788 for (N[0]=0; N[0]< window_length_f; ++N[0]) {
789 for (N[1]=0; N[1]< window_length_f; ++N[1]) {
790 for (N[2]=0; N[2]< window_length_f; ++N[2]) {
791 const int index = calculateIndex(N, window_length_f);
792 const double dist = calculateDistanceSquared(N, window_length_f);
793 othervalues[index] = cos(M_PI*dist/1.5);
794 }
795 }
796 }
797 for (N[0]=0; N[0]< window_length_c; ++N[0]) {
798 for (N[1]=0; N[1]< window_length_c; ++N[1]) {
799 for (N[2]=0; N[2]< window_length_c; ++N[2]) {
800 const int index = calculateIndex(N, window_length_c);
801 const double dist = calculateDistanceSquared(N, window_length_c);
802 checkvalues[index] = cos(M_PI*dist/1.5);
803 }
804 }
805 }
806
807 /** Here, we must initialize the larger grid with zero window first and
808 * then add the values into the smaller window.
809 */
810 SamplingGrid largegrid(begin, end, base_level+grid_difference);
811 const double window_begin[NDIM] = {
812 largegrid.getNearestHigherGridPoint(0.5, 0),
813 largegrid.getNearestHigherGridPoint(0.5, 1),
814 largegrid.getNearestHigherGridPoint(0.5, 2) };
815 const double window_end[NDIM] = {
816 largegrid.getNearestLowerGridPoint(1.5, 0),
817 largegrid.getNearestLowerGridPoint(1.5, 1),
818 largegrid.getNearestLowerGridPoint(1.5, 2) };
819 largegrid.setWindow(window_begin, window_end);
820 largegrid.addOntoWindow(window_begin, window_end, othervalues, +1.);
821// std::cout << " largegrid value " << largegrid.sampled_grid << std::endl;
822
823 // smallgrid is downsample from full large grid
824 SamplingGrid smallgrid(begin, end, base_level);
825 SamplingGrid::downsample(smallgrid, largegrid, base_level);
826// std::cout << " smallgrid value " << smallgrid.sampled_grid << std::endl;
827
828 // checkgrid is created in the same way as the large grid (only with smaller level)
829 SamplingGrid checkgrid(begin, end, base_level);
830 checkgrid.setWindow(window_begin, window_end);
831 checkgrid.addOntoWindow(window_begin, window_end, checkvalues, +1.);
832// std::cout << " checkgrid value " << checkgrid.sampled_grid << std::endl;
833
834 // then we compare over the full length
835 /** Note that the threshold does not get better with increasing grid_difference,
836 * on the contrary! For a grid_difference of 1, the finer grid is exact as it
837 * directly sampled from the function. For a larger grid_difference, the finer
838 * grid (being one level away from the desired coarse grid) is just an
839 * approximation although obtained from a finer sampling. Hence, the larger the
840 * grid_difference, the worse is the smallgrid with respect to checkgrid.
841 */
842 const double threshold = 3.2e-2;
843 // we skip the first value as checkvalues[0] is always zero, hard to get from downsampling
844 for (N[0]=1; N[0]< window_length_c; ++N[0])
845 for (N[1]=0; N[1]< window_length_c; ++N[1])
846 for (N[2]=0; N[2]< window_length_c; ++N[2]) {
847 const double check_threshold =
848 threshold*(1.+grid_difference/4.)*getBoundaryCaseFactor(N, window_length_c);
849 const int index = calculateIndex(N, window_length_c);
850 const double difference = fabs((smallgrid.sampled_grid[index] - checkgrid.sampled_grid[index]));
851// std::cout << "Comparing |"
852// << scientific
853// << smallgrid.sampled_grid[index] << " - "
854// << checkgrid.sampled_grid[index] << "| = "
855// << fabs((smallgrid.sampled_grid[index] - checkgrid.sampled_grid[index]))
856// << " < " << check_threshold << " => "
857// << fixed << setprecision(2)
858// << 100*difference/threshold
859// << " %, compare to " << 100*(1.+grid_difference/4.)*getBoundaryCaseFactor(N, window_length_c)
860// << " %" << std::endl;
861 CPPUNIT_ASSERT( difference < check_threshold );
862 }
863 }
864}
Note: See TracBrowser for help on using the repository browser.