-
Notifications
You must be signed in to change notification settings - Fork 3
/
mrpt-find-intersect.cpp
178 lines (143 loc) · 6 KB
/
mrpt-find-intersect.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. See the enclosed file LICENSE for a copy or if
* that was not distributed with this file, You can obtain one at
* http://mozilla.org/MPL/2.0/.
*
* Copyright 2017 Max H. Gerlach
*
* */
#include <vector>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
#include "boost/math/tools/roots.hpp"
#pragma GCC diagnostic pop
#include "mrpt-binderratio-intersect.h"
#include "statistics.h"
// Callables that we are going to minimize
// <|m|^4> / <|m|^2>^2
class BinderRatioDifference {
MRPT_Pointer mr1, mr2;
public:
BinderRatioDifference(MRPT_Pointer mr1_, MRPT_Pointer mr2_) :
mr1(mr1_), mr2(mr2_) { }
double operator()(double controlParameter) {
double br1 = mr1->reweightObservableBinderRatio(controlParameter);
double br2 = mr2->reweightObservableBinderRatio(controlParameter);
double diff = br1 - br2;
std::cout << diff << std::endl;
return diff;
}
};
class BinderRatioDifferenceJK {
MRPTJK_Pointer mr1, mr2;
unsigned jkBlock;
public:
BinderRatioDifferenceJK(MRPTJK_Pointer mr1_, MRPTJK_Pointer mr2_, unsigned jkBlock_) :
mr1(mr1_), mr2(mr2_), jkBlock(jkBlock_) { }
double operator()(double controlParameter) {
double br1 = mr1->reweightObservableBinderRatioJK(controlParameter, jkBlock);
double br2 = mr2->reweightObservableBinderRatioJK(controlParameter, jkBlock);
double diff = br1 - br2;
return diff;
}
};
// systemSize * <|m|^2> / L^(2-eta) with eta = 0.25
class ScaledKTSusceptibilityDifference {
MRPT_Pointer mr1, mr2;
unsigned systemL1, systemL2;
double divisor1, divisor2;
public:
ScaledKTSusceptibilityDifference(MRPT_Pointer mr1_, MRPT_Pointer mr2_) :
mr1(mr1_), mr2(mr2_),
systemL1(mr1->getSystemL()), systemL2(mr2->getSystemL()),
divisor1(std::pow(double(systemL1), 2.0 - 0.25)),
divisor2(std::pow(double(systemL2), 2.0 - 0.25)) { }
double operator()(double controlParameter) {
double s1 = mr1->reweightObservableSusceptibilityPart(controlParameter) / divisor1;
double s2 = mr2->reweightObservableSusceptibilityPart(controlParameter) / divisor2;
double diff = s1 - s2;
std::cout << diff << std::endl;
return diff;
}
};
class ScaledKTSusceptibilityDifferenceJK {
MRPTJK_Pointer mr1, mr2;
unsigned jkBlock;
unsigned systemL1, systemL2;
double divisor1, divisor2;
public:
ScaledKTSusceptibilityDifferenceJK(MRPTJK_Pointer mr1_, MRPTJK_Pointer mr2_, unsigned jkBlock_) :
mr1(mr1_), mr2(mr2_), jkBlock(jkBlock_),
systemL1(mr1->getSystemL()), systemL2(mr2->getSystemL()),
divisor1(std::pow(double(systemL1), 2.0 - 0.25)),
divisor2(std::pow(double(systemL2), 2.0 - 0.25)) { }
double operator()(double controlParameter) {
double s1 = mr1->reweightObservableSusceptibilityPartJK(controlParameter, jkBlock) / divisor1;
double s2 = mr2->reweightObservableSusceptibilityPartJK(controlParameter, jkBlock) / divisor2;
double diff = s1 - s2;
return diff;
}
};
// find root between a and b
template<class Callable>
double findRoot(Callable f, double a, double b, bool& ok) {
using namespace boost::math::tools;
const boost::uintmax_t max_iter_target=500;
boost::uintmax_t max_iter=max_iter_target;
try {
auto r1 = toms748_solve( f , a, b,
eps_tolerance<double>(7), max_iter );
ok = (max_iter <= max_iter_target);
return (r1.second + r1.first) / 2.0;
} catch (const std::exception& e) {
std::cerr << "findRoot failed. what(): " << e.what() << std::endl;
ok = false;
return 0;
}
}
template<class DifferenceCallable>
void findIntersectImplementation(double& cpOut, bool& ok,
MRPT_Pointer mr1, MRPT_Pointer mr2,
double cpMin, double cpMax) {
DifferenceCallable f(mr1, mr2);
cpOut = findRoot(f, cpMin, cpMax, ok);
}
template<class DifferenceJKCallable>
void findIntersectErrorImplementation(double& cpOut, double& cpErrOut, bool& ok,
MRPTJK_Pointer mr1, MRPTJK_Pointer mr2,
double cpMin, double cpMax, unsigned jkBlockCount) {
//jackknife blocking
std::vector<double> jkCp_b(jkBlockCount);
ok = true;
for (signed b = 0; b < (signed)jkBlockCount; ++b) {
DifferenceJKCallable f(mr1, mr2, b);
bool ok_b = true;
jkCp_b[b] = findRoot(f, cpMin, cpMax, ok_b);
ok = ok && ok_b;
}
jackknife(cpOut, cpErrOut, jkCp_b);
}
void findBinderRatioIntersect(double& cpOut, bool& ok,
MRPT_Pointer mr1, MRPT_Pointer mr2,
double cpMin, double cpMax) {
findIntersectImplementation<BinderRatioDifference>(
cpOut, ok, mr1, mr2, cpMin, cpMax);
}
void findBinderRatioIntersectError(double& cpOut, double& cpErrOut, bool& ok,
MRPTJK_Pointer mr1, MRPTJK_Pointer mr2,
double cpMin, double cpMax, unsigned jkBlockCount) {
findIntersectErrorImplementation<BinderRatioDifferenceJK>(
cpOut, cpErrOut, ok, mr1, mr2, cpMin, cpMax, jkBlockCount);
}
void findScaledKTSusceptibilityIntersect(double& cpOut, bool& ok,
MRPT_Pointer mr1, MRPT_Pointer mr2,
double cpMin, double cpMax) {
findIntersectImplementation<ScaledKTSusceptibilityDifference>(
cpOut, ok, mr1, mr2, cpMin, cpMax);
}
void findScaledKTSusceptibilityIntersectError(double& cpOut, double& cpErrOut, bool& ok,
MRPTJK_Pointer mr1, MRPTJK_Pointer mr2,
double cpMin, double cpMax, unsigned jkBlockCount) {
findIntersectErrorImplementation<ScaledKTSusceptibilityDifferenceJK>(
cpOut, cpErrOut, ok, mr1, mr2, cpMin, cpMax, jkBlockCount);
}