source: src/Jobs/Grid/SamplingGrid.cpp@ 313f83

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing 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_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 313f83 was 313f83, checked in by Frederik Heber <heber@…>, 12 years ago

SamplingGrid::operator*=() can now deal with incongruent windows.

  • new functions shrinkWindow() and AddIntoWindow() help to allow for shrinking the window to the minimum size of either window, copying the old values onto and multiplying with the other ones from a possibly larger window.
  • Property mode set to 100644
File size: 21.5 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2012 University of Bonn. 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 * SamplingGrid.cpp
25 *
26 * Created on: 25.07.2012
27 * Author: heber
28 */
29
30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
35// include headers that implement a archive in simple text format
36// otherwise BOOST_CLASS_EXPORT_IMPLEMENT has no effect
37#include <boost/archive/text_oarchive.hpp>
38#include <boost/archive/text_iarchive.hpp>
39
40#include "CodePatterns/MemDebug.hpp"
41
42#include "Jobs/Grid/SamplingGrid.hpp"
43
44#include <boost/bind.hpp>
45#include <limits>
46
47#include "CodePatterns/Assert.hpp"
48#include "CodePatterns/Log.hpp"
49
50// static instances
51const double SamplingGrid::zeroOffset[3] = { 0., 0., 0. };
52
53SamplingGrid::SamplingGrid() :
54 SamplingGridProperties()
55{
56 setWindowSize(zeroOffset, zeroOffset);
57 ASSERT( getWindowGridPoints() == (size_t)0,
58 "SamplingGrid::SamplingGrid() - incorrect number of samples given for the window.");
59}
60
61SamplingGrid::SamplingGrid(const double _begin[3],
62 const double _end[3],
63 const int _level) :
64 SamplingGridProperties(_begin, _end, _level)
65{
66 setWindowSize(zeroOffset, zeroOffset);
67 ASSERT( getWindowGridPoints() == (size_t)0,
68 "SamplingGrid::SamplingGrid() - incorrect number of samples given for the window.");
69}
70
71SamplingGrid::SamplingGrid(const double _begin[3],
72 const double _end[3],
73 const int _level,
74 const sampledvalues_t &_sampled_grid) :
75 SamplingGridProperties(_begin, _end, _level),
76 sampled_grid(_sampled_grid)
77{
78 setWindowSize(_begin, _end);
79 ASSERT( getWindowGridPoints() == (size_t)_sampled_grid.size(),
80 "SamplingGrid::SamplingGrid() - incorrect number of samples given for the window.");
81}
82
83SamplingGrid::SamplingGrid(const SamplingGrid &_grid) :
84 SamplingGridProperties(_grid),
85 sampled_grid(_grid.sampled_grid)
86{
87 setWindowSize(_grid.begin_window, _grid.end_window);
88 ASSERT( getWindowGridPoints() == _grid.getWindowGridPoints(),
89 "SamplingGrid::SamplingGrid() - incorrect number of samples given for the window.");
90}
91
92SamplingGrid::SamplingGrid(const SamplingGridProperties &_props) :
93 SamplingGridProperties(_props)
94{
95 setWindowSize(zeroOffset, zeroOffset);
96 ASSERT( getWindowGridPoints() == (size_t)0,
97 "SamplingGrid::SamplingGrid() - incorrect number of samples given for the window.");
98}
99
100SamplingGrid::SamplingGrid(
101 const SamplingGridProperties &_props,
102 const sampledvalues_t &_sampled_grid) :
103 SamplingGridProperties(_props),
104 sampled_grid(_sampled_grid)
105{
106 setWindowSize(_props.begin, _props.end);
107 ASSERT( getWindowGridPoints() == (size_t)_sampled_grid.size(),
108 "SamplingGrid::SamplingGrid() - incorrect number of samples given for the window.");
109}
110
111SamplingGrid::~SamplingGrid()
112{}
113
114bool SamplingGrid::isCongruent(const SamplingGrid &_props) const
115{
116 bool status = true;
117 status &= (static_cast<const SamplingGridProperties &>(*this) ==
118 static_cast<const SamplingGridProperties &>(_props));
119 for(size_t i = 0; i<3; ++i) {
120 status &= begin_window[i] == _props.begin_window[i];
121 status &= end_window[i] == _props.end_window[i];
122 }
123 return status;
124}
125
126SamplingGrid& SamplingGrid::operator=(const SamplingGrid& other)
127{
128 // check for self-assignment
129 if (this != &other) {
130 static_cast<SamplingGridProperties &>(*this) = other;
131 setWindowSize(other.begin_window, other.end_window);
132 sampled_grid = other.sampled_grid;
133 }
134 return *this;
135}
136
137static void multiplyElements(
138 double &dest,
139 const double &source,
140 const double prefactor)
141{
142 dest *= prefactor*(source);
143}
144
145
146SamplingGrid& SamplingGrid::operator*=(const SamplingGrid& other)
147{
148 // check that grids are compatible
149 if (isCompatible(other)) {
150 /// get minimum of window
151 double min_begin_window[3];
152 double min_end_window[3];
153 bool doShrink = false;
154 for (size_t index=0; index<3;++index) {
155 if (begin_window[index] <= other.begin_window[index]) {
156 min_begin_window[index] = other.begin_window[index];
157 doShrink = true;
158 } else {
159 min_begin_window[index] = begin_window[index];
160 }
161 if (end_window[index] <= other.end_window[index]) {
162 min_end_window[index] = end_window[index];
163 } else {
164 min_end_window[index] = other.end_window[index];
165 doShrink = true;
166 }
167 }
168 LOG(2, "DEBUG: min begin is " << min_begin_window[0] << "," << min_begin_window[1] << "," << min_begin_window[2] << ".");
169 LOG(2, "DEBUG: min end is " << min_end_window[0] << "," << min_end_window[1] << "," << min_end_window[2] << ".");
170 if (doShrink)
171 shrinkWindow(min_begin_window, min_end_window);
172 addWindowOntoWindow(
173 other.begin_window,
174 other.end_window,
175 begin_window,
176 end_window,
177 sampled_grid,
178 other.sampled_grid,
179 boost::bind(multiplyElements, _1, _2, 1.),
180 sourcewindow);
181 } else {
182 ASSERT(0, "SamplingGrid::operator*=() - multiplying incongruent grids is so far not in the cards.");
183 }
184 return *this;
185}
186
187void SamplingGrid::superposeOtherGrids(const SamplingGrid &other, const double prefactor)
188{
189 /// check that grids are compatible
190 if (isCompatible(other)) {
191 /// get maximum of window
192 double max_begin_window[3];
193 double max_end_window[3];
194 bool doExtend = false;
195 for (size_t index=0; index<3;++index) {
196 if (begin_window[index] >= other.begin_window[index]) {
197 max_begin_window[index] = other.begin_window[index];
198 doExtend = true;
199 } else {
200 max_begin_window[index] = begin_window[index];
201 }
202 if (end_window[index] >= other.end_window[index]) {
203 max_end_window[index] = end_window[index];
204 } else {
205 max_end_window[index] = other.end_window[index];
206 doExtend = true;
207 }
208 }
209 LOG(2, "DEBUG: max begin is " << max_begin_window[0] << "," << max_begin_window[1] << "," << max_begin_window[2] << ".");
210 LOG(2, "DEBUG: max end is " << max_end_window[0] << "," << max_end_window[1] << "," << max_end_window[2] << ".");
211 if (doExtend)
212 extendWindow(max_begin_window, max_end_window);
213 /// and copy other into larger window, too
214 addOntoWindow(other.begin_window, other.end_window, other.sampled_grid, prefactor);
215 } else {
216 ASSERT(0, "SamplingGrid::superposeOtherGrids() - superposing incompatible grids is so far not in the cards.");
217 }
218}
219
220const size_t SamplingGrid::getWindowGridPointsPerAxis(const size_t axis) const
221{
222 static const double round_offset(
223 (std::numeric_limits<size_t>::round_style == std::round_toward_zero) ?
224 0.5 : 0.); // need offset to get to round_toward_nearest behavior
225// const double total = getTotalLengthPerAxis(axis);
226 const double delta = getDeltaPerAxis(axis);
227 if (delta == 0)
228 return 0;
229 const double length = getWindowLengthPerAxis(axis);
230 if (length == 0)
231 return 0;
232 return (size_t)(length/delta+round_offset);
233}
234
235double SamplingGrid::integral() const
236{
237 const double volume_element = getVolume()/(double)getTotalGridPoints();
238 double int_value = 0.;
239 for (sampledvalues_t::const_iterator iter = sampled_grid.begin();
240 iter != sampled_grid.end();
241 ++iter)
242 int_value += *iter;
243 int_value *= volume_element;
244 LOG(2, "DEBUG: SamplingGrid::integral() is " << scientific << setprecision(13) << int_value << ".");
245 return int_value;
246}
247
248double SamplingGrid::integral(const SamplingGrid &weight) const
249{
250 if (isCompatible(weight)) {
251 const double volume_element = getVolume()/(double)getTotalGridPoints();
252 double int_value = 0.;
253 sampledvalues_t::const_iterator iter = sampled_grid.begin();
254 sampledvalues_t::const_iterator weightiter = weight.sampled_grid.begin();
255 for (;iter != sampled_grid.end();++iter,++weightiter)
256 int_value += (*weightiter) * (*iter);
257 int_value *= volume_element;
258 //LOG(2, "DEBUG: SamplingGrid::integral() is " << scientific << setprecision(13) << int_value << ".");
259 return int_value;
260 } else
261 return 0.;
262}
263
264double SamplingGrid::getNearestLowerGridPoint(
265 const double value, const size_t axis) const
266{
267 const double length = end[axis] - begin[axis];
268 if ((fabs(length) < std::numeric_limits<double>::epsilon()) || (getGridPointsPerAxis() == 0)) {
269 return 0.;
270 } else {
271 const double offset = value - begin[axis];
272 // modify value a little if value actually has been on a grid point but
273 // perturbed by numerical rounding: here up, as we always go lower
274 const double factor =
275 floor((double)getGridPointsPerAxis()*(offset/length)
276 +std::numeric_limits<double>::epsilon()*1.e4);
277 return factor*(length/(double)getGridPointsPerAxis());
278 }
279}
280
281double SamplingGrid::getNearestHigherGridPoint(
282 const double value, const size_t axis) const
283{
284 const double length = end[axis] - begin[axis];
285 if ((fabs(length) < std::numeric_limits<double>::epsilon()) || (getGridPointsPerAxis() == 0)) {
286 return 0.;
287 } else {
288 const double offset = value - begin[axis];
289 // modify value a little if value actually has been on a grid point but
290 // perturbed by numerical rounding: here down, as we always go higher
291 const double factor =
292 ceil((double)getGridPointsPerAxis()*(offset/length)
293 -std::numeric_limits<double>::epsilon()*1.e4);
294 return factor*(length/(double)getGridPointsPerAxis());
295 }
296}
297
298void SamplingGrid::setWindowSize(
299 const double _begin_window[3],
300 const double _end_window[3])
301{
302 for (size_t index=0;index<3;++index) {
303 begin_window[index] = getNearestLowerGridPoint(_begin_window[index], index);
304 ASSERT( begin_window[index] >= begin[index],
305 "SamplingGrid::setWindowSize() - window starts earlier than domain on "
306 +toString(index)+"th component.");
307 end_window[index] = getNearestHigherGridPoint(_end_window[index], index);
308 ASSERT( end_window[index] <= end[index],
309 "SamplingGrid::setWindowSize() - window ends later than domain on "
310 +toString(index)+"th component.");
311 }
312}
313
314void SamplingGrid::setWindow(
315 const double _begin_window[3],
316 const double _end_window[3])
317{
318 setWindowSize(_begin_window, _end_window);
319 const size_t gridpoints_window = getWindowGridPoints();
320 sampled_grid.clear();
321 sampled_grid.resize(gridpoints_window, 0.);
322}
323
324void SamplingGrid::setDomain(
325 const double _begin[3],
326 const double _end[3])
327{
328 setDomainSize(_begin, _end);
329 setWindowSize(_begin, _end);
330 const size_t gridpoints = getTotalGridPoints();
331 sampled_grid.resize(gridpoints, 0.);
332}
333
334void SamplingGrid::extendWindow(
335 const double _begin_window[3],
336 const double _end_window[3])
337{
338#ifndef NDEBUG
339 for(size_t index=0;index < 3; ++index) {
340 // check that we truly have to extend the window
341 ASSERT ( begin_window[index] >= _begin_window[index],
342 "SamplingGrid::extendWindow() - component "+toString(index)+
343 " of window start is greater than old value.");
344 ASSERT ( end_window[index] <= _end_window[index],
345 "SamplingGrid::extendWindow() - component "+toString(index)+
346 " of window end is less than old value.");
347
348 // check that we are still less than domain
349 ASSERT ( _begin_window[index] >= begin[index],
350 "SamplingGrid::extendWindow() - component "+toString(index)+
351 " of window start is less than domain start.");
352 ASSERT ( _end_window[index] <= end[index],
353 "SamplingGrid::extendWindow() - component "+toString(index)+
354 " of window end is greater than domain end.");
355 }
356#endif
357 // copy old window size and values
358 double old_begin_window[3];
359 double old_end_window[3];
360 for(size_t index=0;index<3;++index) {
361 old_begin_window[index] = begin_window[index];
362 old_end_window[index] = end_window[index];
363 }
364 sampledvalues_t old_values(sampled_grid);
365 // set new window
366 setWindow(_begin_window,_end_window);
367 // now extend it ...
368 addOntoWindow(old_begin_window, old_end_window, old_values, +1.);
369 LOG(2, "DEBUG: Grid after extension is " << sampled_grid << ".");
370}
371
372void SamplingGrid::shrinkWindow(
373 const double _begin_window[3],
374 const double _end_window[3])
375{
376#ifndef NDEBUG
377 for(size_t index=0;index < 3; ++index) {
378 // check that we truly have to shrink the window
379 ASSERT ( begin_window[index] <= _begin_window[index],
380 "SamplingGrid::shrinkWindow() - component "+toString(index)+
381 " of window start is less than old value.");
382 ASSERT ( end_window[index] >= _end_window[index],
383 "SamplingGrid::shrinkWindow() - component "+toString(index)+
384 " of window end is greater than old value.");
385
386 // check that we are still less than domain
387 ASSERT ( _begin_window[index] >= begin[index],
388 "SamplingGrid::shrinkWindow() - component "+toString(index)+
389 " of window start is less than domain start.");
390 ASSERT ( _end_window[index] <= end[index],
391 "SamplingGrid::shrinkWindow() - component "+toString(index)+
392 " of window end is greater than domain end.");
393 }
394#endif
395 // copy old window size and values
396 double old_begin_window[3];
397 double old_end_window[3];
398 for(size_t index=0;index<3;++index) {
399 old_begin_window[index] = begin_window[index];
400 old_end_window[index] = end_window[index];
401 }
402 sampledvalues_t old_values(sampled_grid);
403 // set new window
404 setWindow(_begin_window,_end_window);
405 // now extend it ...
406 addIntoWindow(old_begin_window, old_end_window, old_values, +1.);
407 LOG(2, "DEBUG: Grid after extension is " << sampled_grid << ".");
408}
409
410static void addElements(
411 double &dest,
412 const double &source,
413 const double prefactor)
414{
415 dest += prefactor*(source);
416}
417
418void SamplingGrid::addOntoWindow(
419 const double _begin_window[3],
420 const double _end_window[3],
421 const sampledvalues_t &_sampled_grid,
422 const double prefactor)
423{
424 addWindowOntoWindow(
425 begin_window,
426 end_window,
427 _begin_window,
428 _end_window,
429 sampled_grid,
430 _sampled_grid,
431 boost::bind(addElements, _1, _2, boost::cref(prefactor)),
432 destwindow);
433}
434
435void SamplingGrid::addIntoWindow(
436 const double _begin_window[3],
437 const double _end_window[3],
438 const sampledvalues_t &_sampled_grid,
439 const double prefactor)
440{
441 addWindowOntoWindow(
442 _begin_window,
443 _end_window,
444 begin_window,
445 end_window,
446 sampled_grid,
447 _sampled_grid,
448 boost::bind(addElements, _1, _2, boost::cref(prefactor)),
449 sourcewindow);
450}
451
452void SamplingGrid::addWindowOntoWindow(
453 const double larger_wbegin[3],
454 const double larger_wend[3],
455 const double smaller_wbegin[3],
456 const double smaller_wend[3],
457 sampledvalues_t &dest_sampled_grid,
458 const sampledvalues_t &source_sampled_grid,
459 boost::function<void (double &, const double &)> op,
460 enum eLargerWindow larger_window)
461{
462#ifndef NDEBUG
463 for(size_t index=0;index<3;++index) {
464 ASSERT( smaller_wbegin[index] >= larger_wbegin[index],
465 "SamplingGrid::addWindowOntoWindow() - given smaller window starts earlier than larger window in component "
466 +toString(index)+".");
467 ASSERT( smaller_wend[index] <= larger_wend[index],
468 "SamplingGrid::addWindowOntoWindow() - given smaller window ends later than larger window in component "
469 +toString(index)+".");
470 }
471#endif
472 // the only issue are indices
473 const size_t gridpoints_axis = getGridPointsPerAxis();
474 size_t pre_offset[3];
475 size_t post_offset[3];
476 size_t length[3];
477 size_t total[3];
478 const double round_offset =
479 (std::numeric_limits<size_t>::round_style == std::round_toward_zero) ?
480 0.5 : 0.; // need offset to get to round_toward_nearest behavior
481 for(size_t index=0;index<3;++index) {
482 // we refrain from using floor/ceil as the window's starts and ends,
483 // the grids have to be compatible (equal level), should always be on
484 // discrete grid point locations.
485 const double delta = (double)gridpoints_axis/(end[index] - begin[index]);
486 // delta is conversion factor from box length to discrete length, i.e. number of points
487 pre_offset[index] = delta*(smaller_wbegin[index] - larger_wbegin[index])+round_offset;
488 length[index] = delta*(smaller_wend[index] - smaller_wbegin[index])+round_offset;
489 post_offset[index] = delta*(larger_wend[index] - smaller_wend[index])+round_offset;
490 total[index] = delta*(larger_wend[index] - larger_wbegin[index])+round_offset;
491 // total is used as safe-guard against loss due to discrete conversion
492 ASSERT( pre_offset[index]+post_offset[index]+length[index] == total[index],
493 "SamplingGrid::addWindowOntoWindow() - pre, post, and length don't sum up to total for "
494 +toString(index)+"th component.");
495 }
496 // assert that calculated lengths match with given vector sizes
497#ifndef NDEBUG
498 const size_t calculated_size = length[0]*length[1]*length[2];
499 if (larger_window == destwindow) {
500 ASSERT( calculated_size == source_sampled_grid.size(),
501 "SamplingGrid::addWindowOntoWindow() - not enough source sampled values given: "
502 +toString(calculated_size)+" != "+toString(source_sampled_grid.size())+".");
503 ASSERT( calculated_size <= dest_sampled_grid.size(),
504 "SamplingGrid::addWindowOntoWindow() - not enough sampled values available: "
505 +toString(calculated_size)+" <= "+toString(dest_sampled_grid.size())+".");
506 } else {
507 ASSERT( calculated_size == dest_sampled_grid.size(),
508 "SamplingGrid::addWindowOntoWindow() - not enough dest sampled values given: "
509 +toString(calculated_size)+" != "+toString(dest_sampled_grid.size())+".");
510 ASSERT( calculated_size <= source_sampled_grid.size(),
511 "SamplingGrid::addWindowOntoWindow() - not enough source sampled values available: "
512 +toString(calculated_size)+" <= "+toString(source_sampled_grid.size())+".");
513 }
514 const size_t total_size = total[0]*total[1]*total[2];
515 if (larger_window == destwindow) {
516 ASSERT( total_size == dest_sampled_grid.size(),
517 "SamplingGrid::addWindowOntoWindow() - total size is not equal to number of present dest points: "
518 +toString(total_size)+" != "+toString(dest_sampled_grid.size())+".");
519 } else {
520 ASSERT( total_size == source_sampled_grid.size(),
521 "SamplingGrid::addWindowOntoWindow() - total size is not equal to number of present source points: "
522 +toString(total_size)+" != "+toString(source_sampled_grid.size())+".");
523 }
524#endif
525 size_t N[3];
526// size_t counter = 0;
527 sampledvalues_t::iterator destiter = dest_sampled_grid.begin();
528 sampledvalues_t::const_iterator sourceiter = source_sampled_grid.begin();
529 if (larger_window == destwindow)
530 std::advance(destiter, pre_offset[0]*total[1]*total[2]);
531 else
532 std::advance(sourceiter, pre_offset[0]*total[1]*total[2]);
533 for(N[0]=0; N[0] < length[0]; ++N[0]) {
534 if (larger_window == destwindow)
535 std::advance(destiter, pre_offset[1]*total[2]);
536 else
537 std::advance(sourceiter, pre_offset[1]*total[2]);
538 for(N[1]=0; N[1] < length[1]; ++N[1]) {
539 if (larger_window == destwindow)
540 std::advance(destiter, pre_offset[2]);
541 else
542 std::advance(sourceiter, pre_offset[2]);
543 for(N[2]=0; N[2] < length[2]; ++N[2]) {
544 ASSERT( destiter != dest_sampled_grid.end(),
545 "SamplingGrid::addWindowOntoWindow() - destiter is already at end of window.");
546 ASSERT( sourceiter != source_sampled_grid.end(),
547 "SamplingGrid::addWindowOntoWindow() - destiter is already at end of window.");
548 op(*destiter, *sourceiter);
549 ++destiter;
550 ++sourceiter;
551 }
552 if (larger_window == destwindow)
553 std::advance(destiter, post_offset[2]);
554 else
555 std::advance(sourceiter, post_offset[2]);
556 }
557 if (larger_window == destwindow)
558 std::advance(destiter, post_offset[1]*total[2]);
559 else
560 std::advance(sourceiter, post_offset[1]*total[2]);
561 }
562#ifndef NDEBUG
563 if (larger_window == destwindow)
564 std::advance(destiter, post_offset[0]*total[1]*total[2]);
565 else
566 std::advance(sourceiter, post_offset[0]*total[1]*total[2]);
567 ASSERT( destiter == dest_sampled_grid.end(),
568 "SamplingGrid::addWindowOntoWindow() - destiter is not at end of window.");
569 ASSERT( sourceiter == source_sampled_grid.end(),
570 "SamplingGrid::addWindowOntoWindow() - sourceiter is not at end of window.");
571#endif
572 LOG(2, "DEBUG: Grid after adding other is " << dest_sampled_grid << ".");
573}
574
575std::ostream & operator<<(std::ostream &ost, const SamplingGrid& other)
576{
577 ost << "SamplingGrid";
578 ost << " starting at " << other.begin[0] << "," << other.begin[1] << "," << other.begin[2];
579 ost << " ending at " << other.end[0] << "," << other.end[1] << "," << other.end[2];
580 ost << ", window starting at " << other.begin_window[0] << "," << other.begin_window[1] << "," << other.begin_window[2];
581 ost << ", window ending at " << other.end_window[0] << "," << other.end_window[1] << "," << other.end_window[2];
582 ost << ", level of " << other.level;
583 ost << " and integrated value of " << other.integral();
584 return ost;
585}
586
587template<> SamplingGrid ZeroInstance<SamplingGrid>()
588{
589 SamplingGrid returnvalue;
590 return returnvalue;
591}
592
593// we need to explicitly instantiate the serialization functions as
594// its is only serialized through its base class FragmentJob
595BOOST_CLASS_EXPORT_IMPLEMENT(SamplingGrid)
Note: See TracBrowser for help on using the repository browser.