LandauGinzburg
Loading...
Searching...
No Matches
field_class.cpp
Go to the documentation of this file.
1
7#include "field_class.hpp"
8
9
10void Field::setgauss (const int num_col,
11 const double mean, const double dev) {
12 int N = (Li+1) * (Li+1);
13 field = MatrixXcd::Zero(N, num_col);
14 std::random_device rnd;
15 std::normal_distribution<> gauss(mean, dev);
16 for (int i = 0; i < N; ++i) {
17 for (int j = 0; j < num_col; ++j) {
18 field(i, j) = std::complex<double>(gauss(rnd), gauss(rnd));
19 }
20 }
21 return;
22}
23void Field::setgaussl (const int num_col,
24 const double mean) {
25 setgauss(num_col, mean, Li / M_SQRT2);
26}
27void Field::setgaussmt (const int num_col,
28 const double mean, const double dev) {
29 int N = (Li+1) * (Li+1);
30 field = MatrixXcd::Zero(N, num_col);
31 std::random_device rnd;
32 std::mt19937_64 mt(rnd());
33 std::normal_distribution<> gauss(mean, dev);
34 for (int i = 0; i < N; ++i) {
35 for (int j = 0; j < num_col; ++j) {
36 field(i, j) = std::complex<double>(gauss(mt), gauss(mt));
37 }
38 }
39 return;
40}
41void Field::setgaussmtl (const int num_col,
42 const double mean) {
43 setgaussmt(num_col, mean, Li / M_SQRT2);
44}
45
46void Field::setconf (const int num_col, const Distribution n,
47 const double mean, const double dev) {
48 try {
49 if (Li < 1 || num_f < 1 || num_col < 1)
50 throw "ERROR<Field::setconf> Some parameters are not positive.";
51 switch (n) {
53 setgauss(num_col, mean, dev); break;
55 setgaussl(num_col, mean); break;
57 setgaussmt(num_col, mean, dev); break;
59 setgaussmtl(num_col, mean); break;
61 field = MatrixXcd::Zero( (Li+1)*(Li+1), num_col );
62 }
63 } catch (const char *str) {cerr << str << endl;
64 Li = 1; num_f = 1;
65 field = MatrixXcd::Zero( (Li+1)*(Li+1), 1);}
66}
67
68void Field::setconf (const VectorXcd &v, const int num_field) {
69 num_f = num_field;
70 int N = v.size();
71 Li = (int)sqrt(N) - 1;
72 try {
73 if (N != (Li+1)*(Li+1))
74 throw "ERROR<Field::setconf> Mismatched size of VectorXcd.";
75 field = MatrixXcd::Zero(N, num_f);
76 for (int i = 0; i < N; ++i) {field(i, 0) = v(i);}
77 } catch (const char *str) {
78 cerr << str << endl;
79 ++Li; int Nnew = (Li+1)*(Li+1);
80 field = MatrixXcd::Zero(Nnew, 1);
81 for (int i = 0; i < N; ++i) {field(i, 0) = v(i);}
82 }
83}
84void Field::setconf (const VectorXd &v, const int num_field) {
85 num_f = num_field;
86 int Ntotal = v.size();
87 int Nunit = int(Ntotal / num_f);
88 int N = int(Nunit / 2);
89 Li = (int)sqrt(N) - 1;
90 MatrixXcd m(N, num_f);
91 for (int j = 0; j < num_f; ++j) {
92 int tmp = 2*N * j;
93 for (int i = 0; i < N; ++i) {
94 m(i, j) = v(tmp + i) + IM * v(tmp + i + N);
95 }
96 }
97 try {
98 if (N != (Li+1)*(Li+1))
99 throw "ERROR<Field::setconf> Mismatched size of VectorXd.";
100 field = m;
101 } catch (const char *str) {
102 cerr << str << endl;
103 ++Li; int Nnew = (Li+1)*(Li+1);
104 field = MatrixXcd::Zero(Nnew, num_f);
105 field.block(0,0, N,num_f) = m;
106 }
107}
108void Field::setconf (const MatrixXcd &m) {
109 num_f = m.cols();
110 int N = m.rows();
111 Li = (int)sqrt(N) - 1;
112 try {
113 if (N != (Li+1)*(Li+1))
114 throw "ERROR<Field::Field> Mismatched size of MatrixXcd.";
115 field = m;
116 } catch (const char *str) {
117 cerr << str << endl;
118 ++Li; int Nnew = (Li+1)*(Li+1);
119 field = MatrixXcd::Zero(Nnew, num_f);
120 field.block(0,0, N,num_f) = m;
121 }
122}
123void Field::setconf (const MatrixXcd &m, const int num_field) {
124 num_f = num_field;
125 int num_col = m.cols();
126 int N = m.rows();
127 Li = (int)sqrt(N) - 1;
128 try {
129 if (N != (Li+1)*(Li+1))
130 throw "ERROR<Field::Field> Mismatched size of MatrixXcd.";
131 field = m;
132 } catch (const char *str) {
133 cerr << str << endl;
134 ++Li; int Nnew = (Li+1)*(Li+1);
135 field = MatrixXcd::Zero(Nnew, num_col);
136 field.block(0,0, N,num_col) = m;
137 }
138}
139
140MatrixXcd Field::vector2matrix (const int n) const {
141 int L = (Li + 1);
142 try {
143 if (n < 0 || n >= num_f)
144 throw "ERROR<Field::vector2matrix> Column number is not in [0, num_f).";
145 MatrixXcd M(L, L);
146 for (int i = 0; i < L; ++i) {
147 for (int j = 0; j < L; ++j) {
148 M(i, j) = field(L * i + j, n);
149 }
150 }
151 return M;
152 } catch (const char *str) {cerr << str << endl; return MatrixXcd::Zero(L, L);}
153}
154MatrixXcd Field::field2matrix (const int n) const {
155 int N = (Li+1) * (Li+1);
156 try {
157 if (n < 0 || n >= field.cols())
158 throw "ERROR<Field::field2matrix> Column number is out of range.";
159 if (N % 2 == 0)
160 throw "ERROR<Field::field2matrix> Size of VectorXcd is not ODD.";
161 int L = (Li + 1);
162 MatrixXcd M = MatrixXcd::Zero(N, N);
163 for (int i = 0; i < N; ++i) {
164 for (int j = 0; j < N; ++j) {
165 int ind_0 = L/2 + i/L - j/L;
166 int ind_1 = L/2 + i%L - j%L;
167 if (0 <= ind_0 && ind_0 < L && 0 <= ind_1 && ind_1 < L) {
168 M(i, j) = field(L*ind_0 + ind_1, n);
169 }
170 }
171 }
172 return M;
173 } catch (const char *str) {cerr << str << endl; return MatrixXcd::Zero(N, N);}
174}
175MatrixXcd Field::dfield2matrix (const int n) const {
176 int N = (Li+1) * (Li+1);
177 try {
178 if (n < 0 || n >= field.cols())
179 throw "ERROR<Field::dfield2matrix> Column number is out of range.";
180 if (N % 2 == 0)
181 throw "ERROR<Field::dfield2matrix> Size of VectorXcd is not ODD.";
182 VectorXcd v = conf(n);
183 return v * v.transpose().reverse() / v(N/2);
184 } catch (const char *str) {cerr << str << endl; return MatrixXcd::Zero(N, N);}
185}
186
187Field Field::conv (const int n1, const int n2) const {
188 try {
189 int num_col = field.cols();
190 if (n1 < 0 || n1 >= num_col || n2 < 0 || n2 >= num_col)
191 throw "ERROR<Field::conv> Column numbers are out of range.";
192 int N = (Li+1) * (Li+1);
193 if (N % 2 == 0)
194 throw "ERROR<Field::conv> Size of VectorXcd is not ODD.";
195 MatrixXcd mat = field2matrix(n1);
196 VectorXcd cnv;
197 cnv = mat * field.col(n2) / double(Li * Li);
198 return Field {cnv};
199 } catch (const char *str) {cerr << str << endl; return Field::Zero(Li, 1);}
200}
201Field Field::conjconv (const int n) const {
202 try {
203 int num_col = field.cols();
204 if (n < 0 || n >= num_col)
205 throw "ERROR<Field::conjconv> Column number is out of range.";
206 int N = (Li+1) * (Li+1);
207 if (N % 2 == 0)
208 throw "ERROR<Field::conjconv> Size of VectorXcd is not ODD.";
209 MatrixXcd m(N, 2);
210 VectorXcd frev = conf(n).conjugate().reverse();
211 for (int i = 0; i < N; ++i) {
212 m(i, 0) = field(i, n);
213 m(i, 1) = frev(i);
214 }
215 Field f(m);
216 return f.conv(0, 1);
217 } catch (const char *str) {cerr << str << endl; return Field::Zero(Li, 1);}
218}
219Field Field::conv_pw (const int pw, const int n) const {
220 try {
221 int num_col = field.cols();
222
223 if (n < 0 || n >= num_col)
224 throw "ERROR<Field::conv_pw> Column number is out of range.";
225 int N = (Li+1) * (Li+1);
226 if (N % 2 == 0)
227 throw "ERROR<Field::conv_pw> Size of VectorXcd is not ODD.";
228 if (pw < 0)
229 throw "ERROR<Field::conv_pw> Number of convolutions is negative.";
230
231 if (pw == 0) {
232 int N = (Li+1) * (Li+1);
233 VectorXcd v = VectorXcd::Zero(N); v(N/2) = Li * Li;
234 return Field {v};
235 } else if (pw == 1) {
236 VectorXcd v = conf(n); return Field {v};
237 } else if (pw == 2) { return conv(n, n); }
238
239 int L = (Li + 1);
240 MatrixXcd M, Mp;
241 M = field2matrix(n);
242 Mp = MatrixXcd::Identity(N, N);
243 for (int i = 0; i < pw-2; ++i) { Mp = M * Mp; }
244 int Ln = 1;
245 for (int i = 0; i < pw-1; ++i) { Ln *= Li * Li; }
246 VectorXcd cnv;
247 cnv = M * Mp * field.col(n) / Ln;
248 return Field {cnv};
249 } catch (const char *str) {cerr << str << endl; return Field::Zero(Li, 1);}
250}
251
253 try {
254 if (field.rows()==0) {*this = f; return *this;}
255 if (*this != f)
256 throw "ERROR<Field::combine_with> Sizes of Fields are not same .";
257 int num_col1 = field.cols();
258 int num_col2 = f.field.cols();
259 int num_col_total = num_col1 + num_col2;
260 int N = field.rows();
261 MatrixXcd m(N, num_col_total);
262 m.block(0,0, N, num_col1) = field;
263 m.block(0,num_col1, N, num_col2) = f.field;
264 *this = Field {m, num_f}; return *this;
265 }
266 catch (const char *str) {cerr << str << endl; return *this;}
267}
268
269void Field::show () const {
270 cout << "# class Field" << endl
271 << "Li = " << Li << endl
272 << "field = " << endl
273 << field << endl;
274 return;
275}
276
Generate normal distributions; Compute convolutions.
Field conjconv(const int n) const
Convolution field(:,n)*conf(field(:,n))
MatrixXcd field
Superfields.
void setgaussl(const int num_col, const double mean=0.0)
MatrixXcd conf() const
MatrixXcd field2matrix(const int n) const
void setgauss(const int num_col, const double mean=0.0, const double dev=1.0)
void setgaussmtl(const int num_col, const double mean=0.0)
Field combine_with(const Field &f)
Combine with another Field object; Mutate field (Li and num_f are unchaged) except for the case that ...
void setconf(const int num_col, const Distribution n, const double mean=0.0, const double dev=1.0)
int Li
Physical box size, N_0=N_1.
MatrixXcd dfield2matrix(const int n) const
Field conv(const int n1, const int n2) const
Convolution field(:,n1)*field(:,n2)
Field conv_pw(const int pw, const int n=0) const
Convolution field(:,n)*field(:,n)*...*field(:,n)
int num_f
Number of superfields.
virtual void show() const
Output Li, field.
void setgaussmt(const int num_col, const double mean=0.0, const double dev=1.0)
static Field Zero(const int n1, const int n2)
MatrixXcd vector2matrix(const int n) const
Definition of the class Field.
const std::complex< double > IM(0, 1.0)
Imaginary unit.
Distribution
Types of normal distributions.