Exemple #1
0
        Link GetRandomMetroLink()
        {
            double e = 0.1;

            double x0m = 0, x1m = 0, x2m = 0, x3m = 0; Link X = new Link(true);

            for (int i = 0; i < d; i++)
                for (int j = i + 1; j < d; j++)
                {

                    double r0 = GetRandom() - 0.5, r1 = GetRandom() - 0.5, r2 = GetRandom() - 0.5, r3 = GetRandom() - 0.5;
                    x0m = Math.Sqrt(1 - e * e);
                    // if (r0 < 0) x0m = -x0m;
                    double len = Math.Sqrt(r1 * r1 + r2 * r2 + r3 * r3);
                    x1m = e * r1 / len; x2m = e * r2 / len; x3m = e * r3 / len;

                    Complex A00 = new Complex(x0m, x3m);
                    Complex A01 = new Complex(x2m, x1m);
                    Complex A10 = new Complex(-x2m, x1m);
                    Complex A11 = new Complex(x0m, -x3m);

                    Link T = new Link(true);
                    T.A[i, i] = A00;
                    T.A[i, j] = A01;
                    T.A[j, i] = A10;
                    T.A[j, j] = A11;
                    X = Mul(T, X);
                }
            return X;
        }
Exemple #2
0
        Link GetSumOfStaples(int x, int y, int z, int t, int dir)
        {
            Link A = new Link(false);
            //calculating staples
            for (int i = 1; i <= 4; i++)
            {

                if (i != dir)
                {
                    //create staple
                    /*   r+i----<----r+dir+i
                     *     |         |
                     *  ^i \/        ^
                     *     |         |
                           r  ->dir r+dir
                     *
                     */
                    //up
                    Link A1 = new Link(false);
                    int x1 = x, y1 = y, z1 = z, t1 = t; int x2 = x, y2 = y, z2 = z, t2 = t;
                    GetNode(ref x1, ref y1, ref z1, ref t1, dir);
                    GetNode(ref x2, ref y2, ref z2, ref t2, i);
                    Link U1, U2, U3;
                    U1 = U[x1, y1, z1, t1, i];
                    U2 = U[x2, y2, z2, t2, dir];
                    U3 = U[x, y, z, t, i];
                    if (x1 == Ns) { if (i == 2) U1 = Mul(Temp, Mul(U[0, y1, z1, t1, i], Temp)); else U1 = U[0, y1, z1, t1, i]; }
                    if (x2 == Ns)
                    {
                        if (dir == 2) U2 = Mul(Temp, Mul(U[0, y2, z2, t2, dir], Temp)); else U2 = U[0, y2, z2, t2, dir];
                    }
                    //if (x == Ns) {
                    //     if (i == 2) U3 = Mul(Temp, Mul(U[0, y, z, t, i], Temp)); else U3 = U[0, y, z, t, i]; }
                    A1 = Mul(U1, U2.HermConj());//CONJ!
                    A1 = Mul(A1, U3.HermConj());//CONJ!

                    /*     r  ->dir r+dir
                     *     |         |
                     *  ^i ^         \/
                     *     |         |
                     *   r-i----<----r+dir-i
                     */
                    //down
                    Link A2 = new Link(false);
                    x1 = x; y1 = y; z1 = z; t1 = t;
                    GetNode(ref x1, ref y1, ref z1, ref t1, -i);
                    x2 = x1; y2 = y1; z2 = z1; t2 = t1;//2 - r-i
                    GetNode(ref x1, ref y1, ref z1, ref t1, dir);
                    U1 = U[x1, y1, z1, t1, i];
                    U2 = U[x2, y2, z2, t2, dir];
                    U3 = U[x2, y2, z2, t2, i];

                    if (x1 == Ns)
                    {
                        if (i == 2)
                            U1 = Mul(Temp, Mul(U[0, y1, z1, t1, i], Temp));
                        else U1 = U[0, y1, z1, t1, i];
                    }
                    //if (x2 == Ns) {
                    //    if (dir == 2) U2 = Mul(Temp, Mul(U[0, y2, z2, t2, dir], Temp)); else U2 =U[0, y2, z2, t2, dir];}
                    //if (x2 == Ns)
                    //{  if (i == 2) U3 = Mul(Temp, Mul(U[0, y2, z2, t2, i], Temp)); else U3 = U[0, y2, z2, t2, i];}

                    A2 = Mul(U1.HermConj(), U2.HermConj());//CONJ!
                    A2 = Mul(A2, U3);

                    for (int m = 0; m < SU3.d; m++)
                        for (int n = 0; n < SU3.d; n++)
                            A.A[m, n] += A1.A[m, n] + A2.A[m, n];
                }
            }
            return A;
        }
Exemple #3
0
        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]);
            }
        }
Exemple #4
0
 double GetDet(Link W)
 {
     return (W.A[0, 0] * W.A[1, 1] * W.A[2, 2] + W.A[0, 1] * W.A[1, 2] * W.A[2, 0] + W.A[0, 2] * W.A[1, 0] * W.A[2, 1] - W.A[0, 2] * W.A[1, 1] * W.A[2, 0] - W.A[0, 1] * W.A[1, 0] * W.A[2, 2] - W.A[1, 2] * W.A[2, 1] * W.A[0, 0]).Module();
        // return (W.A[0,0]*W.A[1,1]-W.A[0,1]*W.A[1,0]).x;
 }
Exemple #5
0
        public void Orthogonalize(ref Link U)
        {
            // double x0 = U.a0, x1 = U.a1, x2 = U.a2, x3 = U.a3;
            //double len = Math.Sqrt(x1 * x1 + x2 * x2 + x3 * x3);
            //x1 /= len; x2 /= len; x3 /= len;
              //  x0 = Math.Sqrt(1 - x1 * x1 - x2 * x2 - x3 * x3);
              //  if (x0<=1) U.a0 = x0;
            double module = Math.Sqrt(U.A[0, 0].Module() * U.A[0, 0].Module() +
                                        U.A[0, 1].Module() * U.A[0, 1].Module() +
                                            U.A[0, 2].Module() * U.A[0, 2].Module());

            //U'=U/|U|
            U.A[0,0].x /= module; U.A[0,0].y /= module;
            U.A[0,1].x /= module; U.A[0,1].y /= module;
            U.A[0,2].x /= module; U.A[0,2].y /= module;

            //V'=V-(V U'*)U'
            Complex VU = U.A[1,0] * U.A[0,0].Conj() + U.A[1,1] * U.A[0,1].Conj() +U.A[1,2] * U.A[0,2].Conj();

            U.A[1,0]=U.A[1,0]-VU*U.A[0,0];
            U.A[1,1]=U.A[1,1]-VU*U.A[0,1];
            U.A[1,2]=U.A[1,2]-VU*U.A[0,2];

            //V'=V/|V|
            module = Math.Sqrt(U.A[1, 0].Module() * U.A[1, 0].Module() +
                                    U.A[1, 1].Module() * U.A[1, 1].Module() +
                                        U.A[1, 2].Module()*U.A[1, 2].Module());

            U.A[1,0].x /= module; U.A[1,0].y /= module;
            U.A[1,1].x /= module; U.A[1,1].y /= module;
            U.A[1,2].x /= module; U.A[1,2].y /= module;

            U.A[2,0]=(U.A[0,1] * U.A[1,2] - U.A[0,2] * U.A[1,1]).Conj();
            U.A[2,1]=(U.A[0,2] * U.A[1,0] - U.A[0,0] * U.A[1,2]).Conj();
            U.A[2,2]=(U.A[0,0] * U.A[1,1] - U.A[0,1] * U.A[1,0]).Conj();
        }
Exemple #6
0
 public double ReTr(Link L)
 {
     Complex C= new Complex();
     for (int i = 0; i < SU3.d; i++)
         C += L.A[i, i];
     return C.x;
 }
Exemple #7
0
        public double MeasureS()
        {
            int n = 0; double S = 0;
            for (int Mu = 1; Mu <= 3; Mu++)
            {
                for (int Nu = Mu + 1; Nu <= 4; Nu++)
                {

                    for (int i = 0; i < Ns; i++)
                        for (int j = 0; j < Ns; j++)
                            for (int k = 0; k < Ns; k++)
                                for (int t = 0; t < Nt; t++)
                                {
                                    Link A1 = new Link(false);
                                    int i1 = i, j1 = j, k1 = k, t1 = t; int i2 = i, j2 = j, k2 = k, t2 = t;

                                    GetNode(ref i1, ref j1, ref k1, ref t1, Mu);
                                    GetNode(ref i2, ref j2, ref k2, ref t2, Nu);

                                    if (i == Ns) i = 0; if (i1 == Ns) i1 = 0; if (i2 == Ns) i2 = 0;
                                    A1 = Mul(U[i, j, k, t, Mu], U[i1, j1, k1, t1, Nu]);//U_mu(x)*U_nu(x+mu)
                                    A1 = Mul(A1, U[i2, j2, k2, t2, Mu].HermConj());//*U_mu+(x+Nu)
                                    A1 = Mul(A1, U[i, j, k, t, Nu].HermConj());//*U_nu+(x)
                                    //here A1 is U_mu_nu

                                    n++;
                                  //  S += A1.a0; //1/2 Re(Tr(U_mu_nu)
                                    S += ReTr(A1)/3;
                                }
                }
            }

               // S = /*beta / 3 **/ (1 - S/(3*n));//S=beta/3*Sum(x,Sum(mu<nu,{Re(Tr(1-U_mu_nu))}))
            return Math.Abs(1 - S /(n));
        }
Exemple #8
0
        public Link Mul(Link U, Link V)
        {
            Link R = new Link(false);

            for (int i = 0; i < SU3.d; i++)
                for (int j = 0; j < SU3.d; j++)
                    for (int k = 0; k < SU3.d; k++)
                        R.A[i, j] += U.A[i, k] * V.A[k, j];

               /* R.a0 = U.a0 * V.a0 - U.a1 * V.a1 - U.a2 * V.a2 - U.a3 * V.a3;
            R.a1 = U.a0 * V.a1 + U.a1 * V.a0 - U.a2 * V.a3 + U.a3 * V.a2;
            R.a2 = U.a0 * V.a2 + U.a2 * V.a0 - U.a3 * V.a1 + U.a1 * V.a3;
            R.a3 = U.a0 * V.a3 + U.a3 * V.a0 - U.a1 * V.a2 + U.a2 * V.a1;
            */

            /*

            //multiplying the matrices
            U.U1 = Link1.U1 * Link2.U1 + Link1.U2 * Link2.V1 + Link1.U3 * Link2.W1();
            U.U2 = Link1.U1 * Link2.U2 + Link1.U2 * Link2.V2 + Link1.U3 * Link2.W2();
            U.U3 = Link1.U1 * Link2.U3 + Link1.U3 * Link2.V1 + Link1.U3 * Link2.W3();

            U.V1 = Link1.V1 * Link2.U1 + Link1.V2 * Link2.V1 + Link1.V3 * Link2.W1();
            U.V2 = Link1.V1 * Link2.U2 + Link1.V2 * Link2.V2 + Link1.V3 * Link2.W2();
            U.V3 = Link1.V1 * Link2.U3 + Link1.V3 * Link2.V1 + Link1.V3 * Link2.W3();
            */
            return R;
        }
Exemple #9
0
        //return 2x2 SU(2) matrix by given determinant of staples near link.
        public Link GetHeatBath(double det, int I, int J)
        {
            Complex[,] SU2 = new Complex[2, 2];
            //calculating elements of SU(2) matrix according to distribution dP~exp(-S(u))du

            double a = Math.Sqrt(Math.Abs(det));
            double x0=0, x1=0, x2=0, x3=0;
             /*
            //dP(x0)~exp(beta*a*x0) dx0
            //make t from [exp(-b*a),1]
            double pow = Math.Exp(-beta*a);
            bool accepted = false;
            while (!accepted)
            {

                double t = GetRandom() * (pow-1/pow)+1/pow;
                x0 =  1 / (beta * a) * Math.Log(t);
                //and accept it with probability Math.Sqrt(1-x0^2)
                t = GetRandom();
                if (t * t < 1 - x0 * x0) accepted = true;
            }
            */

              bool accepted = false;
            double r1 = 0; double r2 = 0; double r3 = 0; double r = 0; double lambda2 = 0;
            while (!accepted)
            {
                r1=GetRandom();r2=GetRandom();r3=GetRandom();
                r=GetRandom();
                lambda2 = -d / (4 * a * beta) * (Math.Log(r1) + Math.Pow(Math.Cos((2 * Math.PI * r2)), 2) * Math.Log(r3));
                //and accept it with probability Math.Sqrt(1-lambda2)
                if (r * r < 1 - lambda2) accepted = true;
            }
            x0 = 1 - 2 * lambda2;

            //x1,x2,x3 with probability dOmega = d(cos(teta))d(fi), but on practice, may be (!check it!!!)
            double len = Math.Sqrt(1 - x0 * x0);
            accepted = false;
            double templen=1;
            while (!accepted)
            {
                x1 = GetRandom() * 2 - 1; x2 = GetRandom() * 2 - 1; x3 = GetRandom() * 2 - 1;
                templen = x1 * x1 + x2 * x2 + x3 * x3;
                if (templen < 1) accepted = true;
            }
            //normalizing to length len
            templen = Math.Sqrt(templen);
            x1 *= len/templen; x2 *= len/templen; x3 *= len/templen;

            Link Res = new Link(true);
              //  Res.a0 = x0; Res.a1 = x1; Res.a2= x2; Res.a3 = x3;

            Res.A[I, I] = new Complex(x0, x3);
            Res.A[I, J] = new Complex(x2, x1);
            Res.A[J, I] = new Complex(-x2, x1);
            Res.A[J, J] = new Complex(x0, -x3);

            return Res;
        }
Exemple #10
0
        public SU3(int Nspace, int Ntemp, double b, double flux, bool ColdStart)
        {
            Ns = Nspace; Nt = Ntemp; beta = b;
            U = new Link[Ns+1, Ns, Ns, Nt, 5];//x1,x2,x3,x4 (x0 omitted)
            InitializeRandom(DateTime.Now.Millisecond);

            if (ColdStart)
            {
                for (int d = 1; d <= 4; d++)
                    for (int i = 0; i < Ns; i++)
                        for (int j = 0; j < Ns; j++)
                            for (int k = 0; k < Ns; k++)
                                for (int t = 0; t < Nt; t++)
                                {
                                  /*  U[i, j, k, t, d].a0 = 1;
                                    U[i, j, k, t, d].a1 = 0;
                                    U[i, j, k, t, d].a2 = 0;
                                    U[i, j, k, t, d].a3 = 0;
                                    */
                                    U[i, j, k, t, d] = new Link(true);
                                }
            }
            else
            {
                for (int d = 1; d <= 4; d++)
                    for (int i = 0; i < Ns; i++)
                        for (int j = 0; j < Ns; j++)
                            for (int k = 0; k < Ns; k++)
                                for (int t = 0; t < Nt; t++)
                                {

                                    //for SU(2)

                                    double x0 = GetRandom() * 2 - 1;
                                    double x1 = GetRandom() - 0.5, x2 = GetRandom() - 0.5, x3 = GetRandom() - 0.5;
                                    double tlen = Math.Sqrt(x1 * x1 + x2 * x2 + x3 * x3);
                                    double len = Math.Sqrt(1-x0 * x0);

                                    x1 *= len/tlen; x2 *= len/tlen; x3 *= len/tlen;
                                   /* U[i, j, k, t, d].a0 = x0;
                                    U[i, j, k, t, d].a1 = x1;
                                    U[i, j, k, t, d].a2 = x2;
                                    U[i, j, k, t, d].a3 = x3;
                                    */

                                    //Orthogonalize2(ref U[i, j, k, t, d]);
                                   // double det = GetDet(U[i, j, k, t, d].GetMatrix());
                                }
            }
            //exppos2xi = new Complex(Math.Cos(flux), Math.Sin(flux));
            expposxi = new Complex(Math.Cos(flux/2), Math.Sin(flux/2));
            //expneg2xi = new Complex(Math.Cos(flux), -Math.Sin(flux));
            expnegxi = new Complex(Math.Cos(flux / 2),- Math.Sin(flux / 2));

            Temp.A[0, 0] = expposxi;
            Temp.A[1, 1] = expnegxi;
        }
Exemple #11
0
        public Link HermConj()
        {
            Link L = new Link(false);
            for (int i = 0; i < SU3.d; i++)
                for (int j = 0; j < SU3.d; j++)
                    L.A[i, j] = A[j, i].Conj();

            return L;
        }
Exemple #12
0
        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;
        }
Exemple #13
0
        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;
        }