source: src/Analysis/analysis_correlation.hpp@ 97dff0

Last change on this file since 97dff0 was e9bdef, checked in by Frederik Heber <heber@…>, 12 years ago

TESTFIX: Analysis' DipoleAngularCorrelation() and BinData() suffered numerical instabilities.

  • cut precision down to 6 digits which also matches with output precision.
  • TESTFIX: As we use floor() to round, the least digit changed in some cases, i.e. a change within 1e-6. Corrected in regression tests Analysis/ DipoleAngularCorrelation.
  • TESTFIX: same with AnalysisPairCorrelationUnitTest.
  • Property mode set to 100644
File size: 8.1 KB
RevLine 
[c4d4df]1/*
2 * analysis.hpp
3 *
4 * Created on: Oct 13, 2009
5 * Author: heber
6 */
7
8#ifndef ANALYSIS_HPP_
9#define ANALYSIS_HPP_
10
11using namespace std;
12
13/*********************************************** includes ***********************************/
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
[146cff2]20#include <cmath>
[92e5cb]21#include <iomanip>
[c4d4df]22#include <fstream>
23
24// STL headers
25#include <map>
[e65de8]26#include <vector>
[c4d4df]27
[e4fe8d]28#include "Helpers/defs.hpp"
[c4d4df]29
[6f0841]30#include "Atom/atom.hpp"
[92e5cb]31#include "CodePatterns/Info.hpp"
32#include "CodePatterns/Log.hpp"
[1cc661]33#include "CodePatterns/Range.hpp"
[ad011c]34#include "CodePatterns/Verbose.hpp"
[255829]35#include "Helpers/helpers.hpp"
[c1a9d6]36#include "World.hpp"
[c4d4df]37
38/****************************************** forward declarations *****************************/
39
40class BoundaryTriangleSet;
[ea430a]41class Formula;
[c4d4df]42class element;
[6bd7e0]43class LinkedCell_deprecated;
[c4d4df]44class Tesselation;
45class Vector;
46
47/********************************************** definitions *********************************/
48
[c1a9d6]49typedef multimap<double, pair<const TesselPoint *, const TesselPoint *> > PairCorrelationMap;
[59fff1]50typedef multimap<double, const atom * > DipoleAngularCorrelationMap;
51typedef multimap<double, pair<const molecule *, const molecule *> > DipoleCorrelationMap;
52typedef multimap<double, pair<const atom *, const Vector *> > CorrelationToPointMap;
53typedef multimap<double, pair<const atom *, BoundaryTriangleSet *> > CorrelationToSurfaceMap;
[c4d4df]54typedef map<double, int> BinPairMap;
55
[99b87a]56enum ResetWorldTime {
57 DontResetTime,
58 DoResetTime
59};
60
[c4d4df]61/********************************************** declarations *******************************/
62
[e65878]63range<size_t> getMaximumTrajectoryBounds(const std::vector<atom *> &atoms);
64std::map<atomId_t, Vector> CalculateZeroAngularDipole(const std::vector<molecule *> &molecules);
[1cc661]65
[e65878]66DipoleAngularCorrelationMap *DipoleAngularCorrelation(const Formula &DipoleFormula, const size_t timestep, const std::map<atomId_t, Vector> &ZeroVector, const enum ResetWorldTime DoTimeReset = DontResetTime);
[208237b]67DipoleCorrelationMap *DipoleCorrelation(std::vector<molecule *> &molecules);
[c1a9d6]68PairCorrelationMap *PairCorrelation(
69 const World::AtomComposite &atoms_first,
70 const World::AtomComposite &atoms_second,
71 const double max_distance);
[e5c0a1]72CorrelationToPointMap *CorrelationToPoint(std::vector<molecule *> &molecules, const std::vector<const element *> &elements, const Vector *point );
[6bd7e0]73CorrelationToSurfaceMap *CorrelationToSurface(std::vector<molecule *> &molecules, const std::vector<const element *> &elements, const Tesselation * const Surface, const LinkedCell_deprecated *LC );
[e5c0a1]74CorrelationToPointMap *PeriodicCorrelationToPoint(std::vector<molecule *> &molecules, const std::vector<const element *> &elements, const Vector *point, const int ranges[NDIM] );
[6bd7e0]75CorrelationToSurfaceMap *PeriodicCorrelationToSurface(std::vector<molecule *> &molecules, const std::vector<const element *> &elements, const Tesselation * const Surface, const LinkedCell_deprecated *LC, const int ranges[NDIM] );
[bd61b41]76int GetBin ( const double value, const double BinWidth, const double BinStart );
[92e5cb]77void OutputCorrelation_Header( ofstream * const file );
78void OutputCorrelation_Value( ofstream * const file, BinPairMap::const_iterator &runner );
79void OutputDipoleAngularCorrelation_Header( ofstream * const file );
80void OutputDipoleAngularCorrelation_Value( ofstream * const file, DipoleAngularCorrelationMap::const_iterator &runner );
[208237b]81void OutputDipoleCorrelation_Header( ofstream * const file );
82void OutputDipoleCorrelation_Value( ofstream * const file, DipoleCorrelationMap::const_iterator &runner );
[92e5cb]83void OutputPairCorrelation_Header( ofstream * const file );
84void OutputPairCorrelation_Value( ofstream * const file, PairCorrelationMap::const_iterator &runner );
85void OutputCorrelationToPoint_Header( ofstream * const file );
86void OutputCorrelationToPoint_Value( ofstream * const file, CorrelationToPointMap::const_iterator &runner );
87void OutputCorrelationToSurface_Header( ofstream * const file );
88void OutputCorrelationToSurface_Value( ofstream * const file, CorrelationToSurfaceMap::const_iterator &runner );
[c4d4df]89
90/** Searches for lowest and highest value in a given map of doubles.
91 * \param *map map of doubles to scan
92 * \param &min minimum on return
93 * \param &max maximum on return
94 */
95template <typename T> void GetMinMax ( T *map, double &min, double &max)
96{
97 min = 0.;
98 max = 0.;
99 bool FirstMinFound = false;
100 bool FirstMaxFound = false;
101
[f74d08]102 if (map == NULL) {
[47d041]103 ELOG(0, "Nothing to min/max, map is NULL!");
[e359a8]104 performCriticalExit();
[f74d08]105 return;
106 }
107
[c4d4df]108 for (typename T::iterator runner = map->begin(); runner != map->end(); ++runner) {
109 if ((min > runner->first) || (!FirstMinFound)) {
110 min = runner->first;
111 FirstMinFound = true;
112 }
113 if ((max < runner->first) || (!FirstMaxFound)) {
114 max = runner->first;
115 FirstMaxFound = true;
116 }
117 }
118};
119
120/** Puts given correlation data into bins of given size (histogramming).
121 * Note that BinStart and BinEnd are desired to fill the complete range, even where Bins are zero. If this is
[790807]122 * not desired, give equal BinStart and BinEnd and the map will contain only Bins where the count is one or greater. If a
123 * certain start value is desired, give BinStart and a BinEnd that is smaller than BinStart, then only BinEnd will be
124 * calculated automatically, i.e. BinStart = 0. and BinEnd = -1. .
[c4d4df]125 * Also note that the range is given inclusive, i.e. [ BinStart, BinEnd ].
126 * \param *map map of doubles to count
127 * \param BinWidth desired width of the binds
128 * \param BinStart first bin
129 * \param BinEnd last bin
130 * \return Map of doubles (the bins) with counts as values
131 */
[e138de]132template <typename T> BinPairMap *BinData ( T *map, const double BinWidth, const double BinStart, const double BinEnd )
[c4d4df]133{
134 BinPairMap *outmap = new BinPairMap;
[bd61b41]135 int bin = 0;
[c4d4df]136 double start = 0.;
137 double end = 0.;
138 pair <BinPairMap::iterator, bool > BinPairMapInserter;
139
[f74d08]140 if (map == NULL) {
[47d041]141 ELOG(0, "Nothing to bin, is NULL!");
[e359a8]142 performCriticalExit();
[f74d08]143 return outmap;
144 }
145
[c4d4df]146 if (BinStart == BinEnd) { // if same, find range ourselves
147 GetMinMax( map, start, end);
[790807]148 } else if (BinEnd < BinStart) { // if BinEnd smaller, just look for new max
149 GetMinMax( map, start, end);
150 start = BinStart;
151 } else { // else take both values
[c4d4df]152 start = BinStart;
153 end = BinEnd;
154 }
[e9bdef]155 // limit precision of start and end bin to 6 digits
156 const double precision = 1e-6/BinWidth;
157 end = precision*floor(end/precision);
158 start = precision*floor(start/precision);
[85da4e]159 for (int runner = 0; runner <= ceil((end-start)/BinWidth); runner++)
160 outmap->insert( pair<double, int> ((double)runner*BinWidth+start, 0) );
[c4d4df]161
162 for (typename T::iterator runner = map->begin(); runner != map->end(); ++runner) {
163 bin = GetBin (runner->first, BinWidth, start);
[bd61b41]164 BinPairMapInserter = outmap->insert ( pair<double, int> ((double)bin*BinWidth+start, 1) );
[c4d4df]165 if (!BinPairMapInserter.second) { // bin already present, increase
166 BinPairMapInserter.first->second += 1;
[c1a9d6]167 } else { // bin not present, then remove again
168 outmap->erase(BinPairMapInserter.first);
[c4d4df]169 }
170 }
171
172 return outmap;
173};
174
[92e5cb]175/** Prints correlation map of template type to file.
176 * \param *file file to write to
177 * \param *map map to write
178 * \param (*header) pointer to function that adds specific part to header
179 * \param (*value) pointer to function that prints value from given iterator
180 */
181template <typename T>
182void OutputCorrelationMap(
183 ofstream * const file,
184 const T * const map,
185 void (*header)( ofstream * const file),
186 void (*value)( ofstream * const file, typename T::const_iterator &runner)
187 )
188{
189 Info FunctionInfo(__func__);
190 *file << "BinStart\tBinCenter\tBinEnd";
191 header(file);
192 *file << endl;
193 typename T::const_iterator advancer = map->begin();
194 typename T::const_iterator runner = map->begin();
195 if (advancer != map->end())
196 advancer++;
197 for ( ;(advancer != map->end()) && (runner != map->end()); ++advancer, ++runner) {
198 *file << setprecision(8)
199 << runner->first << "\t"
200 << (advancer->first + runner->first)/2. << "\t"
201 << advancer->first << "\t";
202 value(file, runner);
203 *file << endl;
204 }
205 if(runner != map->end()) {
206 *file << setprecision(8) << runner->first << "\t0\t0\t";
207 value(file, runner);
208 *file << endl;
209 }
210};
211
212
[c4d4df]213#endif /* ANALYSIS_HPP_ */
Note: See TracBrowser for help on using the repository browser.