11 const int rw,
const int cl) {
12 MatrixXcd res = MatrixXcd::Zero(rw, cl);
13 int r2 = m.rows();
int c2 = m.cols();
16 res = m.block(0,0,rw,cl);
18 res.block(0,0,rw,c2) = m.block(0,0,rw,c2);
21 res.block(0,0,r2,cl) = m.block(0,0,r2,cl);
23 res.block(0,0,r2,c2) = m;
32 if (r % 2 == 0 || c % 2 == 0)
33 throw "ERROR<DeleteZeroLine> Size of rows() or cols() is not ODD.";
36 MatrixXcd T(r - 1, c - 1);
37 T.block(0, 0, Qr, Qc) = m.block(0, 0, Qr, Qc);
38 T.block(0, Qc, Qr, Qc) = m.block(0, Qc+1, Qr, Qc);
39 T.block(Qr, 0, Qr, Qc) = m.block(Qr+1, 0, Qr, Qc);
40 T.block(Qr, Qc, Qr, Qc) = m.block(Qr+1, Qc+1, Qr, Qc);
42 }
catch (
const char *str) {cerr << str << endl;
return MatrixXcd::Zero(r-1, c-1);}
45 const PartialPivLU<MatrixXcd> &lu) {
49 throw "ERROR<DiffLU> Not a square matrix.";
51 P = lu.permutationP();
52 L = lu.matrixLU().triangularView<StrictlyLower>();
53 L += MatrixXcd::Identity(N, N);
54 U = lu.matrixLU().triangularView<Upper>();
55 MatrixXcd Prod; Prod = P.inverse() * L * U;
56 MatrixXcd Diff; Diff = m - Prod;
58 }
catch (
const char *str) {cerr << str << endl;
return -1.0;}
62 if (m.rows() != m.cols())
63 throw "ERROR<SignDet> Not a square matrix.";
64 PartialPivLU<MatrixXcd> lu(m);
65 VectorXcd diag; diag = lu.matrixLU().diagonal();
66 std::complex<double> phase = 1;
67 for (
int i = 0; i < diag.size(); ++i) {
68 phase *= diag(i) / std::abs(diag(i));
70 if ( lu.permutationP().determinant() < 0 ) phase *= -1;
72 if (phase.real() < 0) sign *= -1;
75 VectorXd im = lu.matrixLU().diagonal().imag();
76 double im_norm = im.norm();
78 for (
int i = 0; i < im.size(); ++i) {
79 if (im_max < std::abs(im(i))) im_max = std::abs(im(i));
81 cerr <<
"PartialPiv: " <<
"Difference " << diff << endl
82 <<
" " <<
"Imag Norm " << im_norm << endl
83 <<
" " <<
" Max " << im_max << endl
84 <<
" " <<
"Phase of Det " << phase << endl;
87 }
catch (
const char *str) {cerr << str << endl;
return 0;}
92void Potential::setpotential(
const MatrixXcd &m) {
93 int N = m.rows();
int mcol = m.cols();
94 int num_field;
int num_col;
95 for (
int i = 1; i <= mcol; ++i) {
96 int tmp = int(i * (i + 1) / 2);
97 if (tmp >= mcol) {num_field = i; num_col = tmp;
break;}
99 if (num_col == mcol)
setconf(m, num_field);
101 MatrixXcd mbig = MatrixXcd::Zero(N, num_col);
102 mbig.block(0,0, N, mcol) = m;
107void Potential::setpotential(
const MatrixXcd &m,
const int num_field) {
108 if (num_field < 1) {setpotential(m);
return;}
109 int num_col = int(num_field*(num_field+1)/2);
112 if (num_col > mcol)
throw 1;
113 else if (num_col < mcol)
throw 2;
116 }
catch (
const int i) {
118 int num_field2;
int num_col2;
121 num_field2 = num_field; num_col2 = num_col;
124 for (
int j = num_field; j <= mcol; ++j) {
125 int tmp = int(j * (j+1) / 2);
126 if (tmp >= mcol) {num_field2 = j; num_col2 = tmp;
break;}
130 MatrixXcd mbig = MatrixXcd::Zero(N, num_col2);
131 mbig.block(0,0, N, mcol) = m;
137MatrixXcd Potential::unifield_tilde_type ()
const {
138 int N = (
Li+1) * (
Li+1);
141 throw "ERROR<unifield_tilde_type> Size of Vector is not ODD.";
143 throw "ERROR<unifield_tilde_type> Number of superfields is not unity.";
146 }
catch (
const char *str) {cerr << str << endl;
return MatrixXcd::Zero(N-1, N-1);}
149MatrixXcd Potential::unifield_jacobian ()
const {
150 int N = (
Li+1) * (
Li+1);
153 throw "ERROR<unifield_jacobian> Size of Vector is not ODD.";
155 throw "ERROR<unifield_jacobian> Number of superfields is not unity.";
157 MatrixXcd wt = unifield_tilde_type();
159 p = MatrixXcd::Zero(N-1, N-1);
160 pi = MatrixXcd::Zero(N-1, N-1);
161 for (
int i = 0; i < N/2; ++i) {
162 p(i, i) = 2.0 * M_PI * double(L-1)
163 * (double(L/2 - i/L) +
IM * double(L/2 - i%L));
164 p(N-2 - i, N-2 - i) = - p(i, i);
165 pi(i, i) = p(i, i) / std::norm(p(i,i));
166 pi(N-2 - i, N-2 - i) = - pi(i,i);
168 return p + wt * pi * wt.adjoint();
169 }
catch (
const char *str) {cerr << str << endl;
return MatrixXcd::Zero(N-1, N-1);}
171MatrixXcd Potential::dualfield_jacobian ()
const {
172 int N = (
Li+1) * (
Li+1);
175 throw "ERROR<dualfield_jacobian> Size of Vector is not ODD.";
177 throw "ERROR<dualfield_jacobian> Number of superfields is not 2.";
180 MatrixXcd m1 = MatrixXcd::Zero(2*N, 2*N);
181 m1.block(0,0, N,N) = w12; m1.block(N,N, N,N) = w12.adjoint();
182 MatrixXcd m2 = MatrixXcd::Zero(2*N, 2*N);
184 MatrixXcd p = MatrixXcd::Zero(N, N);
185 for (
int i = 0; i < N; ++i) {
186 p(i, i) = 2.0 * M_PI * double(
Li) * (
IM * double(L/2 - i/L) + double(L/2 - i%L));
188 MatrixXcd m21 = MatrixXcd::Zero(2*N, 2*N);
191 m21.block(0,0, N,N) = w22; m21.block(N,N, N,N) = w22.adjoint();
192 m21.block(N,0, N,N) = p; m21.block(0,N, N,N) = - p.adjoint();
194 MatrixXcd m22 = MatrixXcd::Zero(2*N, 2*N);
196 PartialPivLU<MatrixXcd> lu(w12);
197 MatrixXcd m_inv; m_inv = lu.inverse();
198 m22.block(0,0, N,N) = m_inv; m22.block(N,N, N,N) = m_inv.adjoint();
200 MatrixXcd m23 = MatrixXcd::Zero(2*N, 2*N);
203 m23.block(0,0, N,N) = w11; m23.block(N,N, N,N) = w11.adjoint();
204 m23.block(N,0, N,N) = p; m23.block(0,N, N,N) = - p.adjoint();
206 m2 = m21 * m22 * m23;
209 }
catch (
const char *str) {cerr << str << endl;
return MatrixXcd::Zero(2*N,2*N);}
211MatrixXcd Potential::triplefield_jacobian1 ()
const {
212 int N = (
Li+1) * (
Li+1);
215 throw "ERROR<triplefield_jacobian> Size of Vector is not ODD.";
217 throw "ERROR<triplefield_jacobian> Number of superfields is not 3.";
219 MatrixXcd w11 = MatrixXcd::Zero(2*N, 2*N);
221 w11.block(0,0, N,N) = w; w11.block(N,N, N,N) = w.adjoint();}
222 MatrixXcd w12 = MatrixXcd::Zero(2*N, 2*N);
224 w12.block(0,0, N,N) = w; w12.block(N,N, N,N) = w.adjoint();}
225 MatrixXcd w13 = MatrixXcd::Zero(2*N, 2*N);
227 w13.block(0,0, N,N) = w; w13.block(N,N, N,N) = w.adjoint();}
228 MatrixXcd w22 = MatrixXcd::Zero(2*N, 2*N);
230 w22.block(0,0, N,N) = w; w22.block(N,N, N,N) = w.adjoint();}
231 MatrixXcd w23 = MatrixXcd::Zero(2*N, 2*N);
232 MatrixXcd w23_inv = MatrixXcd::Zero(2*N, 2*N);
234 PartialPivLU<MatrixXcd> lu(w);
235 MatrixXcd w_inv; w_inv = lu.inverse();
236 w23.block(0,0, N,N) = w; w23.block(N,N, N,N) = w.adjoint();
237 w23_inv.block(0,0, N,N) = w_inv; w23_inv.block(N,N, N,N) = w_inv.adjoint();}
238 MatrixXcd w33 = MatrixXcd::Zero(2*N, 2*N);
240 w33.block(0,0, N,N) = w; w33.block(N,N, N,N) = w.adjoint();}
243 MatrixXcd p = MatrixXcd::Zero(N, N);
244 for (
int i = 0; i < N; ++i) {
245 p(i, i) = 2.0 * M_PI * double(
Li) * (
IM * double(L/2 - i/L) + double(L/2 - i%L));
247 w11.block(N,0, N,N) = p; w11.block(0,N, N,N) = - p.adjoint();
248 w22.block(N,0, N,N) = p; w22.block(0,N, N,N) = - p.adjoint();
249 w33.block(N,0, N,N) = p; w33.block(0,N, N,N) = - p.adjoint();
253 m1 = w23 - w33 * w23_inv * w22;
255 MatrixXcd m2_1, m2_2, m2_3, m2_4;
256 m2_1 = w11 - w13 * w23_inv * w12;
257 m2_2 = w12 - w13 * w23_inv * w22;
258 {PartialPivLU<MatrixXcd> lu(m1); m2_3 = lu.inverse();}
259 m2_4 = w13 - w33 * w23_inv * w12;
260 m2 = m2_1 - m2_2 * m2_3 * m2_4;
263 }
catch (
const char *str) {cerr << str << endl;
return MatrixXcd::Zero(4*N,4*N);}
265MatrixXcd Potential::triplefield_jacobian2 ()
const {
266 int N = (
Li+1) * (
Li+1);
269 throw "ERROR<triplefield_jacobian> Size of Vector is not ODD.";
271 throw "ERROR<triplefield_jacobian> Number of superfields is not 3.";
273 MatrixXcd w11 = MatrixXcd::Zero(2*N, 2*N);
275 w11.block(0,0, N,N) = w; w11.block(N,N, N,N) = w.adjoint();}
276 MatrixXcd w12 = MatrixXcd::Zero(2*N, 2*N);
277 MatrixXcd w12_inv = MatrixXcd::Zero(2*N, 2*N);
279 PartialPivLU<MatrixXcd> lu(w);
280 MatrixXcd w_inv; w_inv = lu.inverse();
281 w12.block(0,0, N,N) = w; w12.block(N,N, N,N) = w.adjoint();
282 w12_inv.block(0,0, N,N) = w_inv; w12_inv.block(N,N, N,N) = w_inv.adjoint();}
283 MatrixXcd w13 = MatrixXcd::Zero(2*N, 2*N);
285 w13.block(0,0, N,N) = w; w13.block(N,N, N,N) = w.adjoint();}
286 MatrixXcd w22 = MatrixXcd::Zero(2*N, 2*N);
288 w22.block(0,0, N,N) = w; w22.block(N,N, N,N) = w.adjoint();}
289 MatrixXcd w23 = MatrixXcd::Zero(2*N, 2*N);
291 w23.block(0,0, N,N) = w; w23.block(N,N, N,N) = w.adjoint();}
292 MatrixXcd w33 = MatrixXcd::Zero(2*N, 2*N);
294 w33.block(0,0, N,N) = w; w33.block(N,N, N,N) = w.adjoint();}
297 MatrixXcd p = MatrixXcd::Zero(N, N);
298 for (
int i = 0; i < N; ++i) {
299 p(i, i) = 2.0 * M_PI * double(
Li) * (
IM * double(L/2 - i/L) + double(L/2 - i%L));
301 w11.block(N,0, N,N) = p; w11.block(0,N, N,N) = - p.adjoint();
302 w22.block(N,0, N,N) = p; w22.block(0,N, N,N) = - p.adjoint();
303 w33.block(N,0, N,N) = p; w33.block(0,N, N,N) = - p.adjoint();
306 MatrixXcd m1 = MatrixXcd::Zero(4*N, 4*N);
307 MatrixXcd m2 = MatrixXcd::Zero(4*N, 4*N);
309 m1.block(0, 0, 2*N,2*N) = w12; m1.block( 0,2*N, 2*N,2*N) = w13;
310 m1.block(2*N,0, 2*N,2*N) = w23; m1.block(2*N,2*N, 2*N,2*N) = w33;
313 MatrixXcd m2_1 = MatrixXcd::Zero(4*N, 2*N);
314 MatrixXcd m2_2 = MatrixXcd::Zero(2*N, 4*N);
315 m2_1.block(0,0, 2*N,2*N) = w11; m2_1.block(2*N,0, 2*N,2*N) = w13;
316 m2_2.block(0,0, 2*N,2*N) = w22; m2_2.block(0,2*N, 2*N,2*N) = w23;
317 m2 = m2_1 * w12_inv * m2_2;
320 }
catch (
const char *str) {cerr << str << endl;
return MatrixXcd::Zero(4*N,4*N);}
322MatrixXcd Potential::multifield_jacobian ()
const {
323 int N = (
Li+1) * (
Li+1);
324 int Ns = 2 * N *
num_f;
327 throw "ERROR<multifield_jacobian> Size of Vector is not ODD.";
329 throw "ERROR<multifield_jacobian> Number of superfields is not positive.";
331 MatrixXcd jac = MatrixXcd::Zero(Ns, Ns);
333 MatrixXcd iP = MatrixXcd::Zero(2*N, 2*N);
335 MatrixXcd p = MatrixXcd::Zero(N, N);
336 for (
int i = 0; i < N/2; ++i) {
337 p(i, i) = 2.0 * M_PI * double(
Li) * (
IM * double(L/2 - i/L) + double(L/2 - i%L));
338 p(N-1 - i, N-1 - i) = - p(i,i);
340 iP.block(0,0, N,N) = p; iP.block(N,N, N,N) = - p.conjugate();
342 for (
int i = 0; i <
num_f; ++i) {
344 jac.block(tmp, tmp, 2*N, 2*N) = iP;
349 for (
int i = 0; i <
num_f; ++i) {
351 for (
int j = i; j <
num_f; ++j) {
354 jac.block(tmp1+N, tmp2, N,N) = w;
355 jac.block(tmp1, tmp2+N, N,N) = w.adjoint();
357 jac.block(tmp2+N, tmp1, N,N) = w;
358 jac.block(tmp2, tmp1+N, N,N) = w.adjoint();
364 }
catch (
const char *str) {cerr << str << endl;
return MatrixXcd::Zero(Ns,Ns);}
367MatrixXcd Potential::jacobian ()
const {
368 if (
num_f == 1) {
return unifield_jacobian();}
369 else if (
num_f == 2) {
return dualfield_jacobian();}
370 else if (
num_f == 3) {
return triplefield_jacobian2();}
371 return MatrixXcd::Zero( (
Li+1)*(
Li+1), (
Li+1)*(
Li+1) );
382 else if (
num_f >=4) {
389 int ph = (
num_f % 2 == 0)?1:(-1);
394 cout <<
"# class Potential" << endl
395 <<
"Li = " <<
Li << endl
396 <<
"num_f = " <<
num_f << endl
397 <<
"field(i, j) = " << endl
410 for (
int i = 0;
i <
N; ++
i) {
455 int N = (
Li+1) * (
Li+1);
461 for (
int i = 0;
i <
N; ++
i) {
472 int N = (
Li+1) * (
Li+1);
477 for (
int i = 0;
i <
N; ++
i) {
NR(
tmp +
i) = field2(
N-1 -
i,
j);}
483 cout <<
"# class PotentialNR" << endl
484 <<
"Li = " <<
Li << endl
485 <<
"num_f = " <<
num_f << endl
486 <<
"field(i, j)|_{i <= j} = " << endl
488 <<
"field2(i) = " << endl
490 <<
"field3(i) = " << endl
MatrixXcd field
Superfields.
MatrixXcd field2matrix(const int n) const
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
int num_f
Number of superfields.
virtual void show() const
Output Li, field.
int sign_det(const int debug=0) const
Sign determinant with a fast algorithm (num_f < 4)
int sign_det4multifield(const int debug=0) const
Sign determinant for mutli-superfield.
VectorXd nr_pvec() const
Compute Vector for NR method (Real type)
MatrixXd nr_mat() const
Compute Matrix for NR method (Real type)
void show() const
Output Li, field, field2, field3.
VectorXcd nrerr_pvec() const
Compute Vector for NR error estimate (complex type)
const std::complex< double > IM(0, 1.0)
Imaginary unit.
Definition of the class Potential.
MatrixXcd DeleteZeroLine(const MatrixXcd &m)
Delete a row and a column with p=0, q=0.
double DiffLU(const MatrixXcd &m, const PartialPivLU< MatrixXcd > &lu)
Difference between a matrix and its LU decomposition.
int SignDet(const MatrixXcd &m, const int debug=0)
Sign of determinant with LU Decomposition.
MatrixXcd ResizeMatrix(const MatrixXcd &m, const int rw, const int cl)
Output m as MatrixXcd(rw, cl) with zeros.