int GetSiteNumber(Site t) { return t.t * Nxyz + t.z * Nxy + t.y * Nx + t.x; }
public void Update(int x, int y, int z, int t, int dir, bool withOR) { Link A = GetSumOfStaples(x, y, z, t, dir); //here A is the sum of staples! //heatbath //Link W = Mul(U[x, y, z, t, dir], A); double det; //Link X = new Link(true); ////for heat-bath //for (int i = 0; i < d; i++) // for (int j = i + 1; j < d; j++) // { // Complex a = W.A[i, i]; // Complex B = W.A[i, j]; // Complex C = W.A[j, i]; // Complex D = W.A[j, j]; // // det = (W.A[i, i] * W.A[j, j] - W.A[i, j] * W.A[j, i]).x; // double x0 = 1 / 2f * (a.x + D.x); // double x1 = 1 / 2f * (B.y + C.y); // double x2 = 1 / 2f * (B.x - C.x); // double x3 = 1 / 2f * (a.y - D.y); // // det = GetDet(A); // det = x0 * x0 + x1 * x1 + x2 * x2 + x3 * x3; // Link a_ = GetHeatBath(det, i, j); // Link r = new Link(true); // det = Math.Sqrt(det); // x0 /= det; // x1 /= det; // x2 /= det; // x3 /= det; // r.A[i, i] = new Complex(x0, x3); // r.A[i, j] = new Complex(x2, x1); // r.A[j, i] = new Complex(-x2, x1); // r.A[j, j] = new Complex(x0, -x3); // r = Mul(a_, r.HermConj()); // W = Mul(r, W); // X = Mul(r, X); // } //U[x, y, z, t, dir] = Mul(X, U[x, y, z, t, dir]); // //for overrelaxation //if (GetRandom() < 0.1) /* if (withOR) { //for (int or = 0; or < 0; or++) //{ //calculating determinant of SU(2) double det = Math.Pow(GetDet(A),1.0/3.0); for (int i = 0; i < SU3.d; i++) for (int j = 0; j < SU3.d; j++) { A.A[i, j].x /= det; A.A[i, j].y /= det; } A = Mul(A.HermConj(), Mul(U[x, y, z, t, dir].HermConj(), A.HermConj())); Orthogonalize(ref A); U[x, y, z, t, dir]=A; } else {*/ //for Metropolis //for (int hit = 0; hit <= 10; hit++) //{ // bool accepted = false; double dSG; Link X = new Link(true); // while (!accepted) // { // X = GetRandomMetroLink(); // //-I // for (int i = 0; i < d; i++) X.A[i, i].x--; // dSG = -beta / SU3.d * ReTr(Mul(X, Mul(U[x, y, z, t, dir], A))); // double r = GetRandom(); // if (r <= Math.Exp(-dSG)) accepted = true; // } // for (int i = 0; i < d; i++) X.A[i, i].x++; // U[x, y, z, t, dir] = Mul(X, U[x, y, z, t, dir]); //} //for poor dynamical fermions for (int hit = 0; hit <= 10; hit++) { bool accepted = false; double dSG; Link X = new Link(true); while (!accepted) { X = GetRandomMetroLink(); Xsite = new Site(x, y, z, t); Xdir = dir; Uprime = Mul(X, U[x, y, z, t, dir]); Dirac D = new Dirac(this); Vector chi = new Vector(Dirac.N); chi.FillGaussRandom(); D.phi = D.MulD(chi); double Fold = Dirac.V1hermV2(chi, chi).x; D.Prepare(); D.IterPrime(); //here - D.x = D^-1*phi double Fnew = Dirac.V1hermV2(D.x, D.x).x; double dSF = Fnew - Fold; //X-I for (int i = 0; i < d; i++) X.A[i, i].x--; dSG = -beta / SU3.d * ReTr(Mul(X, Mul(U[x, y, z, t, dir], A))); double r = GetRandom(); if (r <= Math.Exp(-(dSG + dSF))) accepted = true; } for (int i = 0; i < d; i++) X.A[i, i].x++; U[x, y, z, t, dir] = Mul(X, U[x, y, z, t, dir]); } }
Site GetSite(int n) { Site t = new Site(); int tempn; t.t = n / Nxyz; tempn = n - t.t * Nxyz; t.z = tempn / Nxy; tempn -= t.z * Nxy; t.y = tempn / Nx; t.x = tempn - t.y * Nx; return t; }
public Vector MulDprime(Vector V) { Vector res = new Vector(N); Site[] AdjacentSites = new Site[9]; Link[] AdjacentLinks = new Link[9]; Complex g; double flipsign = 1.0; int mu = 0; Complex c; for (int i = 0; i < N; i++) { AdjacentSites[0] = GetSite(i); AdjacentLinks[0] = AdjacentSites[0] == U.Xsite ? U.Uprime : new Link(true); for (int ai = 1; ai < 5; ai++) { mu = (ai - 1) % 4 + 1; AdjacentSites[ai] = AdjacentSites[0]; U.GetNode(ref AdjacentSites[ai].x, ref AdjacentSites[ai].y, ref AdjacentSites[ai].z, ref AdjacentSites[ai].t, ai); AdjacentLinks[ai] = AdjacentSites[ai] == U.Xsite ? U.Uprime : U.U[AdjacentSites[ai].x, AdjacentSites[ai].y, AdjacentSites[ai].z, AdjacentSites[ai].t, mu]; } for (int ai = 5; ai < 9; ai++) { mu = (ai - 1) % 4 + 1; AdjacentSites[ai] = AdjacentSites[0]; U.GetNode(ref AdjacentSites[ai].x, ref AdjacentSites[ai].y, ref AdjacentSites[ai].z, ref AdjacentSites[ai].t, -(ai - 4)); AdjacentLinks[ai] = AdjacentSites[ai] == U.Xsite ? U.Uprime : U.U[AdjacentSites[ai].x, AdjacentSites[ai].y, AdjacentSites[ai].z, AdjacentSites[ai].t, mu]; } for (int ai = 0; ai < 9; ai++) { flipsign = ai < 5 ? 1.0 : -1.0; mu = (ai - 1) % 4 + 1; int i1 = GetSiteNumber(AdjacentSites[ai]); for (byte j = 0; j < 4; j++) for (byte j1 = 0; j1 < 4; j1++) { if (ai == 0) g = Complex.One; else g = (flipsign == 1.0) ? OneMinusgamma[mu - 1][j, j1] : OnePlusgamma[mu - 1][j, j1]; if (g.x != 0 || g.y != 0) { c = ai == 0 ? Complex.One : new Complex(-kappa, 0) * g; for (byte k = 0; k < 3; k++) for (byte k1 = 0; k1 < 3; k1++) { if (ai == 0 && j == j1 && k == k1) res[i, j, k] += Complex.One * V[i1, j1, k1]; else { if (ai != 0) { if (flipsign == 1.0) res[i, j, k] += c * AdjacentLinks[ai].A[k, k1] * V[i1, j1, k1]; else res[i, j, k] += c * AdjacentLinks[ai].A[k1, k].Conj() * V[i1, j1, k1];//u.HermConj().A[k, k1] } } } } } } } return res; }
public Vector MulD(Vector V) { //Site s = new Site(1, 1, 1, 1); //GetNode(s, 1); //System.Windows.Forms.MessageBox.Show(s.x.ToString()); //Vector res = new Vector(N); //Site mainsite, adjacentsite; Complex g; //for (int i = 0; i < N; i++) //{ // mainsite = GetSite(i); // for (int ai = 1; ai < 5; ai++) // { // adjacentsite = mainsite; // U.GetNode(ref adjacentsite.x, ref adjacentsite.y, ref adjacentsite.z, ref adjacentsite.t, ai); // int i1 = GetSiteNumber(adjacentsite); // for (byte j = 0; j < 4; j++) // for (byte j1 = 0; j1 < 4; j1++) // { // //g = OneMinusgamma[ai - 1][j, j1]; // //if (g.x != 0 || g.y != 0) // //{ // for (byte k = 0; k < 3; k++) // for (byte k1 = 0; k1 < 3; k1++) // { // res[i, j, k] += D(mainsite, adjacentsite, j, j1, k, k1) * V[i1, j1, k1]; // } // // } // } // } // for (int ai = 1; ai < 5; ai++) // { // adjacentsite = mainsite; // U.GetNode(ref adjacentsite.x, ref adjacentsite.y, ref adjacentsite.z, ref adjacentsite.t, -ai); // int i1 = GetSiteNumber(adjacentsite); // for (byte j = 0; j < 4; j++) // for (byte j1 = 0; j1 < 4; j1++) // { // //g = OneMinusgamma[ai - 1][j, j1]; // //if (g.x != 0 || g.y != 0) // //{ // for (byte k = 0; k < 3; k++) // for (byte k1 = 0; k1 < 3; k1++) // res[i, j, k] += D(mainsite, adjacentsite, j, j1, k, k1) * V[i1, j1, k1]; // // } // } // } //} //Site[] AdjacentSites = new Site[9]; Complex g; int mu = 0; //for (int i = 0; i < N; i++) //{ // AdjacentSites[0] = GetSite(i); // for (int ai = 1; ai < 5; ai++) // { // AdjacentSites[ai] = AdjacentSites[0]; // U.GetNode(ref AdjacentSites[ai].x, ref AdjacentSites[ai].y, ref AdjacentSites[ai].z, ref AdjacentSites[ai].t, ai); // } // for (int ai = 5; ai < 9; ai++) // { // AdjacentSites[ai] = AdjacentSites[0]; // U.GetNode(ref AdjacentSites[ai].x, ref AdjacentSites[ai].y, ref AdjacentSites[ai].z, ref AdjacentSites[ai].t, -(ai - 4)); // } // for (int ai = 0; ai < 9; ai++) // { // mu = (ai - 1) % 4; // int i1 = GetSiteNumber(AdjacentSites[ai]); // for (byte j = 0; j < 4; j++) // for (byte j1 = 0; j1 < 4; j1++) // { // if (ai == 0) g = Complex.One; // else // g = OneMinusgamma[mu][j, j1]; // if (g.x != 0 || g.y != 0) // for (byte k = 0; k < 3; k++) // for (byte k1 = 0; k1 < 3; k1++) // { // res[i, j, k] += D(AdjacentSites[0], AdjacentSites[ai], j, j1, k, k1) * V[i1, j1, k1]; // } // } // } //} //return res; Vector res = new Vector(N); Site[] AdjacentSites = new Site[9]; Link[] AdjacentLinks = new Link[9]; Complex g; double flipsign = 1.0; int mu = 0; Complex c; for (int i = 0; i < N; i++) { AdjacentSites[0] = GetSite(i); AdjacentLinks[0] = new Link(true); for (int ai = 1; ai < 5; ai++) { mu = (ai - 1) % 4 + 1; AdjacentSites[ai] = AdjacentSites[0]; U.GetNode(ref AdjacentSites[ai].x, ref AdjacentSites[ai].y, ref AdjacentSites[ai].z, ref AdjacentSites[ai].t, ai); AdjacentLinks[ai] = U.U[AdjacentSites[ai].x, AdjacentSites[ai].y, AdjacentSites[ai].z, AdjacentSites[ai].t, mu]; } for (int ai = 5; ai < 9; ai++) { mu = (ai - 1) % 4 + 1; AdjacentSites[ai] = AdjacentSites[0]; U.GetNode(ref AdjacentSites[ai].x, ref AdjacentSites[ai].y, ref AdjacentSites[ai].z, ref AdjacentSites[ai].t, -(ai - 4)); AdjacentLinks[ai] = U.U[AdjacentSites[ai].x, AdjacentSites[ai].y, AdjacentSites[ai].z, AdjacentSites[ai].t, mu]; } for (int ai = 0; ai < 9; ai++) { flipsign = ai < 5 ? 1.0 : -1.0; mu = (ai - 1) % 4 + 1; int i1 = GetSiteNumber(AdjacentSites[ai]); for (byte j = 0; j < 4; j++) for (byte j1 = 0; j1 < 4; j1++) { if (ai == 0) g = Complex.One; else g = (flipsign == 1.0) ? OneMinusgamma[mu - 1][j, j1] : OnePlusgamma[mu - 1][j, j1]; if (g.x != 0 || g.y != 0) { c = ai == 0 ? Complex.One : new Complex(-kappa, 0) * g; for (byte k = 0; k < 3; k++) for (byte k1 = 0; k1 < 3; k1++) { if (ai == 0 && j == j1 && k == k1) res[i, j, k] += Complex.One * V[i1, j1, k1]; else { if (ai != 0) { if (flipsign == 1.0) res[i, j, k] += c * AdjacentLinks[ai].A[k, k1] * V[i1, j1, k1]; else res[i, j, k] += c * AdjacentLinks[ai].A[k1, k].Conj() * V[i1, j1, k1];//u.HermConj().A[k, k1] } } } } } } } return res; }
public void GetNode(Site s, int dir) { if (dir == 1) s.x++; if (dir == -1) s.x--; if (dir == 2) s.y++; if (dir == -2) s.y--; if (dir == 3) s.z++; if (dir == -3) s.z--; if (dir == 4) s.t++; if (dir == -4) s.t--; if (s.x == -1) s.x = Nx - 1; if (s.x == Nx) s.x = 0;//comment if (x == Ns) x = 0; to use flux!!! if (s.y == -1) s.y = Ny - 1; if (s.y == Ny) s.y = 0; if (s.z == -1) s.z = Nz - 1; if (s.z == Nz) s.z = 0; if (s.t == -1) s.t = Nt - 1; if (s.t == Nt) s.t = 0; }
public Complex D(Site n, Site m, byte alpha, byte beta, byte a, byte b) { Complex r = new Complex(); int c = 0; if (n == m && alpha == beta && a == b) { r += Complex.One; c++; } Site t; for (int i = 1; i <= 4; i++) { t = n; U.GetNode(ref t.x, ref t.y, ref t.z, ref t.t, i); if (t == m) { r += new Complex(-kappa, 0) * OneMinusgamma[i - 1][alpha, beta] * U.U[n.x, n.y, n.z, n.t, i].A[a, b]; c++; // if (c > 1) // System.Windows.Forms.MessageBox.Show("WTF?"); } } for (int i = 1; i <= 4; i++) { t = n; U.GetNode(ref t.x, ref t.y, ref t.z, ref t.t, -i); if (t == m) { r += new Complex(-kappa, 0) * OnePlusgamma[i - 1][alpha, beta] * U.U[t.x, t.y, t.z, t.t, i].A[b, a].Conj();//.HermConj().A[a, b]; - much more efficient! c++; // if (c > 1) // System.Windows.Forms.MessageBox.Show("WTF?"); } } return r; }