-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmullermod.cpp
147 lines (117 loc) · 4.16 KB
/
mullermod.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
#include "mullermod.h"
Muller::Muller() {
this->setupSystem();
this->initializePositions();
this->initializeVelocities();
}
void Muller::setupSystem() {
this->numberOfParticles = numParticles;
this->systemDimensionality = 2;
for(int i = 0 ; i < this->numberOfParticles ; i++)
this->masses.push_back(1.0f);
// Initializing constants
A = {-200.0f, -100.0f, -170.0f, 15.0f};
xMean = {1.0f, 0.0f, -0.5f, -1.0f};
yMean = {0.0f, 0.5f, 1.5f, 1.0f};
a = {-1.0f, -1.0f, -6.5f, 0.7f};
b = {0.0f, 0.0f, 11.0f, 0.6f};
c = {-10.0f, -10.0f, -6.5f, 0.7f};
}
void Muller::initializePositions() {
for(int i = 0 ; i < this->numberOfParticles ; i++) {
this->positions.push_back(std::vector<float>(this->systemDimensionality, 0.0f));
this->positions[i][0] = generateUniformRandom(-0.525, -0.275);
this->positions[i][1] = generateUniformRandom(1.5, 1.8);
}
}
std::vector<std::vector<float>> Muller::force(std::vector<std::vector<float>>& pos) {
std::vector<std::vector<float>> returnValue;
for(int i = 0 ; i < this->numberOfParticles ; i++)
returnValue.push_back(F(pos[i]));
return returnValue;
}
std::vector<std::vector<float>> Muller::force() {
return this->force(this->positions);
}
float Muller::potentialEnergy(std::vector<std::vector<float>>& pos) {
float peValue = 0;
for(int i = 0 ; i < this->numberOfParticles ; i++)
peValue += U(pos[i]);
return peValue;
}
float Muller::potentialEnergy() {
return this->potentialEnergy(this->positions);
}
float Muller::U(std::vector<float> point) {
float x = point[0];
float y = point[1];
float peValue = 0;
float powValue;
for(int i = 0 ; i < 4 ; i++) {
powValue = a[i] * pow(x - xMean[i], 2) + b[i] * (x - xMean[i]) * (y - yMean[i]) + c[i] * pow(y - yMean[i], 2);
peValue += A[i] * exp(powValue);
}
return peValue;
}
std::vector<float> Muller::F(std::vector<float> point) {
float x = point[0];
float y = point[1];
float fX, fY;
fX = fY = 0;
float peValue = 0;
float powValue;
for(int i = 0 ; i < 4 ; i++) {
powValue = a[i] * pow(x - xMean[i], 2) + b[i] * (x - xMean[i]) * (y - yMean[i]) + c[i] * pow(y - yMean[i], 2);
fX += A[i] * exp(powValue) * (- 2 * a[i] * (x - xMean[i]) - b[i] * (y - yMean[i]));
fY += A[i] * exp(powValue) * (-b[i] * (x - xMean[i]) - 2 * c[i] * (y - yMean[i]));
}
return {fX, fY};
}
// Muller Mod
MullerMod::MullerMod() {
this->sigma = 0.8f;
this->sigma_2 = pow(sigma, 2);
this->height = 200.0f;
this->center = {-0.25f, 0.65f};
}
/* Need the following functions, but are duplicate of the ones in Muller
they don't call the protected function of MullerMod
*/
std::vector<std::vector<float>> MullerMod::force(std::vector<std::vector<float>>& pos) {
std::vector<std::vector<float>> returnValue;
for(int i = 0 ; i < this->numberOfParticles ; i++)
returnValue.push_back(F(pos[i]));
return returnValue;
}
std::vector<std::vector<float>> MullerMod::force() {
return this->force(this->positions);
}
float MullerMod::potentialEnergy(std::vector<std::vector<float>>& pos) {
float peValue = 0;
for(int i = 0 ; i < this->numberOfParticles ; i++)
peValue += U(pos[i]);
return peValue;
}
float MullerMod::potentialEnergy() {
return this->potentialEnergy(this->positions);
}
float MullerMod::U(std::vector<float> pos) {
float peValue = Muller::U(pos);
float x = pos[0];
float y = pos[1];
float powValue = pow(x - center[0], 2) + pow(y - center[1], 2);
powValue /= (2 * sigma_2);
float extraTerm = height * exp(-powValue);
return peValue + extraTerm;
}
std::vector<float> MullerMod::F(std::vector<float> pos) {
std::vector<float> fValue = Muller::F(pos);
float x = pos[0];
float y = pos[1];
float powValue = pow(x - center[0], 2) + pow(y - center[1], 2);
powValue /= (2 * sigma_2);
float amplitude = height * exp(-powValue);
fValue[0] += amplitude * (x - center[0]) / (sigma_2);
fValue[1] += amplitude * (y - center[1]) / (sigma_2);
return fValue;
}