private static void FourthTerm(IList <Vector> caArray, double Epsilon, HessMatrix hessian, int i, int j) { int[] idx = new int[] { i, j }; Vector[] lcaArray = new Vector[] { caArray[idx[0]], caArray[idx[1]] }; Matrix lhess = FourthTerm(lcaArray, Epsilon); for (int c = 0; c < 2; c++) { for (int dc = 0; dc < 3; dc++) { for (int r = 0; r < 2; r++) { for (int dr = 0; dr < 3; dr++) { hessian[idx[c] * 3 + dc, idx[r] * 3 + dr] += lhess[c * 3 + dc, r *3 + dr]; } } } } if (HDebug.IsDebuggerAttachedWithProb(0.1)) { if (caArray.Count == 2) { // avoid stack overflow return; } HessMatrix lhess0 = new double[6, 6]; FourthTerm(lcaArray, Epsilon, lhess0, 0, 1); FourthTerm(lcaArray, Epsilon, lhess0, 1, 0); double r2 = (lcaArray[0] - lcaArray[1]).Dist2; Matrix dhess0 = (120 * Epsilon / r2) * Hess.GetHessAnm(lcaArray, double.PositiveInfinity); HDebug.AssertToleranceMatrix(0.00000001, lhess0 - dhess0); } }
public static void FirstTerm(IList <Vector> caArray, double K_r, HessMatrix hessian, int i, int j) { int[] idx = new int[] { i, j }; Vector[] lcaArray = new Vector[] { caArray[idx[0]], caArray[idx[1]] }; Matrix lhess = FirstTerm(lcaArray, K_r); double maxabs_lhess = lhess.ToArray().HAbs().HMax(); HDebug.Assert(maxabs_lhess < 10000); for (int c = 0; c < 2; c++) { for (int dc = 0; dc < 3; dc++) { for (int r = 0; r < 2; r++) { for (int dr = 0; dr < 3; dr++) { hessian[idx[c] * 3 + dc, idx[r] * 3 + dr] += lhess[c * 3 + dc, r *3 + dr]; } } } } if (HDebug.IsDebuggerAttached) { Matrix anm = (2 * K_r) * Hess.GetHessAnm(lcaArray, double.PositiveInfinity); HDebug.AssertToleranceMatrix(0.00000001, lhess - anm); } }
public HessMatrix SubMatrixByAtomsImpl0(IList <int> idxColAtoms, IList <int> idxRowAtoms) { if (SubMatrixByAtomsImpl0_selftest2) { SubMatrixByAtomsImpl0_selftest2 = false; Matrix thess1 = new double[, ] { { 0, 1, 2, 3, 4, 5 } , { 1, 2, 3, 4, 5, 6 } , { 2, 3, 4, 5, 6, 7 } , { 3, 4, 5, 6, 7, 8 } , { 4, 5, 6, 7, 8, 9 } , { 5, 6, 7, 8, 9, 0 } }; HessMatrix thess2 = HessMatrixDense.FromMatrix(thess1); HessMatrix thess3 = thess2.SubMatrixByAtomsImpl0(new int[] { 0 }, new int[] { 1 }); Matrix thess4 = new double[, ] { { 3, 4, 5 } , { 4, 5, 6 } , { 5, 6, 7 } }; HDebug.AssertToleranceMatrix(0, thess3 - thess4); } HessMatrix nhess = Zeros(idxColAtoms.Count * 3, idxRowAtoms.Count * 3); for (int nbc = 0; nbc < idxColAtoms.Count; nbc++) { for (int nbr = 0; nbr < idxRowAtoms.Count; nbr++) { int bc = idxColAtoms[nbc]; if (bc < 0) { continue; } int br = idxRowAtoms[nbr]; if (br < 0) { continue; } if (HasBlock(bc, br) == false) { continue; } MatrixByArr block = GetBlock(bc, br).CloneT(); // hessian matrix for interaction between atom i and j HDebug.Assert(block.IsZero() == false); nhess.SetBlock(nbc, nbr, block); } } return(nhess); }
public Matrix GetMassMatrix(int dim = 1) { Matrix masses = atoms.ToArray().GetMassMatrix(dim); if (HDebug.IsDebuggerAttached) { Matrix tmasses = new double[size * dim, size *dim]; for (int i = 0; i < size; i++) { for (int j = 0; j < dim; j++) { tmasses[i * dim + j, i *dim + j] = atoms[i].Mass; } } HDebug.AssertToleranceMatrix(0, masses - tmasses); } return(masses); }
public static Matrix GetInvSprTensorSymm(Matrix H, Matrix S, ILinAlg ila) { // check H be symmetric HDebug.AssertToleranceMatrix(0.00000001, H - H.Tr()); Matrix invK = GetInvSprTensor(H, S, ila); if (HDebug.IsDebuggerAttached && ila != null) { HDebug.AssertToleranceMatrix(0.00000001, invK - invK.Tr()); // check symmetric var invKK = ila.ToILMat(invK); var VVDD = ila.EigSymm(invKK); foreach (double d in VVDD.Item2) { HDebug.Assert(d > -0.00000001); } } return(invK); }
public static Matrix ThirdTerm(IList <Vector> caArray_, double K_phi , bool useArnaud96 = false , bool checkComputable = true) { //HDebug.Assert(useArnaud96 == true); // convert to use Arnaud96 if (useArnaud96) { HessMatrix hess3 = Paper.Arnaud96.HessSpring(caArray_, 2 * K_phi).ToArray(); //if(HDebug.IsDebuggerAttached) if (ThirdTerm_selftest) { ThirdTerm_selftest = false; Matrix hess3_ = ThirdTerm(caArray_, K_phi, useArnaud96: false, checkComputable: false); Matrix dhess3 = hess3 - hess3_; if (hess3_.IsComputable()) { Vector v0 = caArray_[0]; Vector v1 = caArray_[1]; Vector v2 = caArray_[2]; Vector v3 = caArray_[3]; Vector A012 = LinAlg.CrossProd(v0 - v1, v1 - v2).UnitVector(); Vector B123 = LinAlg.CrossProd(v1 - v2, v2 - v3).UnitVector(); double AB = LinAlg.VtV(A012, B123); double acosAB = Math.Acos(AB); double hess3max = hess3_.ToArray().HAbs().HMax(); if (Math.Abs(AB) < 0.999999) { HDebug.AssertToleranceMatrix(hess3max * 0.0001, dhess3); } } } return(hess3); } VECTORS caArray = new VECTORS(caArray_); MATRIX hessian = new MATRIX(new double[12, 12]); { int i = 1; int j = 2; int k = 3; int l = 4; double Xi = caArray[i, 1]; double Yi = caArray[i, 2]; double Zi = caArray[i, 3]; double Xj = caArray[j, 1]; double Yj = caArray[j, 2]; double Zj = caArray[j, 3]; double Xk = caArray[k, 1]; double Yk = caArray[k, 2]; double Zk = caArray[k, 3]; double Xl = caArray[l, 1]; double Yl = caArray[l, 2]; double Zl = caArray[l, 3]; Vector a = caArray.GetRow(j) - caArray.GetRow(i); Vector b = caArray.GetRow(k) - caArray.GetRow(j); Vector c = caArray.GetRow(l) - caArray.GetRow(k); Vector v1 = cross(a, b); Vector v2 = cross(b, c); double lv1l = glength(v1); double lv2l = glength(v2); double G = dot(v1, v2) / (lv1l * lv2l); /* dv1/dXi */ Vector dv1dXi = new double[] { 0, Zk - Zj, Yj - Yk }; /* dv1/dYi */ Vector dv1dYi = new double[] { Zj - Zk, 0, Xk - Xj }; /* dv1/dZi */ Vector dv1dZi = new double[] { Yk - Yj, Xj - Xk, 0 }; /* dv1/dXj */ Vector dv1dXj = new double[] { 0, Zi - Zk, Yk - Yi }; /* dv1/dYj */ Vector dv1dYj = new double[] { Zk - Zi, 0, Xi - Xk }; /* dv1/dZj */ Vector dv1dZj = new double[] { Yi - Yk, Xk - Xi, 0 }; /* dv1/dXk */ Vector dv1dXk = new double[] { 0, Zj - Zi, Yi - Yj }; /* dv2/dYk */ Vector dv1dYk = new double[] { Zi - Zj, 0, Xj - Xi }; /* dv2/dZk */ Vector dv1dZk = new double[] { Yj - Yi, Xi - Xj, 0 }; /* dv1/dXl */ Vector dv1dXl = new double[] { 0, 0, 0 }; /* dv1/dYl */ Vector dv1dYl = new double[] { 0, 0, 0 }; /* dv1/dZl */ Vector dv1dZl = new double[] { 0, 0, 0 }; /* dv2/dXi */ Vector dv2dXi = new double[] { 0, 0, 0 }; /* dv2/dYi */ Vector dv2dYi = new double[] { 0, 0, 0 }; /* dv2/dZi */ Vector dv2dZi = new double[] { 0, 0, 0 }; /* dv2/dXj */ Vector dv2dXj = new double[] { 0, Zl - Zk, Yk - Yl }; /* dv2/dYj */ Vector dv2dYj = new double[] { Zk - Zl, 0, Xl - Xk }; /* dv2/dZj */ Vector dv2dZj = new double[] { Yl - Yk, Xk - Xl, 0 }; /* dv2/dXk */ Vector dv2dXk = new double[] { 0, Zj - Zl, Yl - Yj }; /* dv2/dYk */ Vector dv2dYk = new double[] { Zl - Zj, 0, Xj - Xl }; /* dv2/dZk */ Vector dv2dZk = new double[] { Yj - Yl, Xl - Xj, 0 }; /* dv2/dXl */ Vector dv2dXl = new double[] { 0, Zk - Zj, Yj - Yk }; /* dv2/dYl */ Vector dv2dYl = new double[] { Zj - Zk, 0, Xk - Xj }; /* dv2/dZl */ Vector dv2dZl = new double[] { Yk - Yj, Xj - Xk, 0 }; double K1 = (Yj - Yi) * (Zk - Zj) - (Yk - Yj) * (Zj - Zi); double K1_2 = K1 * K1; double K2 = (Xk - Xj) * (Zj - Zi) - (Xj - Xi) * (Zk - Zj); double K2_2 = K2 * K2; double K3 = (Xj - Xi) * (Yk - Yj) - (Xk - Xj) * (Yj - Yi); double K3_2 = K3 * K3; /* dlv1l/dXi */ double dlv1ldXi = (2 * K2 * (Zk - Zj) + 2 * K3 * (Yj - Yk)) / (2 * sqrt(K1_2 + K2_2 + K3_2)); /* dlv1l/dYi */ double dlv1ldYi = (2 * K1 * (Zj - Zk) + 2 * K3 * (Xk - Xj)) / (2 * sqrt(K1_2 + K2_2 + K3_2)); /* dlv1l/dZi */ double dlv1ldZi = (2 * K1 * (Yk - Yj) + 2 * K2 * (Xj - Xk)) / (2 * sqrt(K1_2 + K2_2 + K3_2)); /* dlv1ldXj */ double dlv1ldXj = (2 * K2 * (Zi - Zk) + 2 * K3 * (Yk - Yi)) / (2 * sqrt(K1_2 + K2_2 + K3_2)); /* dlv1ldYj */ double dlv1ldYj = (2 * K1 * (Zk - Zi) + 2 * K3 * (Xi - Xk)) / (2 * sqrt(K1_2 + K2_2 + K3_2)); /* dlv1ldZj */ double dlv1ldZj = (2 * K1 * (Yi - Yk) + 2 * K2 * (Xk - Xi)) / (2 * sqrt(K1_2 + K2_2 + K3_2)); /* dlv1ldXk */ double dlv1ldXk = (2 * K2 * (Zj - Zi) + 2 * K3 * (Yi - Yj)) / (2 * sqrt(K1_2 + K2_2 + K3_2)); /* dlv1ldYk */ double dlv1ldYk = (2 * K1 * (Zi - Zj) + 2 * K3 * (Xj - Xi)) / (2 * sqrt(K1_2 + K2_2 + K3_2)); /* dlv1ldZk */ double dlv1ldZk = (2 * K1 * (Yj - Yi) + 2 * K2 * (Xi - Xj)) / (2 * sqrt(K1_2 + K2_2 + K3_2)); /* dlv1ldXl */ double dlv1ldXl = 0; /* dlv1ldYl */ double dlv1ldYl = 0; /* dlv1ldZl */ double dlv1ldZl = 0; double L1 = (Yk - Yj) * (Zl - Zk) - (Yl - Yk) * (Zk - Zj); double L1_2 = L1 * L1; double L2 = (Xl - Xk) * (Zk - Zj) - (Xk - Xj) * (Zl - Zk); double L2_2 = L2 * L2; double L3 = (Xk - Xj) * (Yl - Yk) - (Xl - Xk) * (Yk - Yj); double L3_2 = L3 * L3; /* dlv2l/dXi */ double dlv2ldXi = 0; /* dlv2l/dYi */ double dlv2ldYi = 0; /* dlv2l/dZi */ double dlv2ldZi = 0; /* dlv2l/dXj */ double dlv2ldXj = (2 * L2 * (Zl - Zk) + 2 * L3 * (Yk - Yl)) / (2 * sqrt(L1_2 + L2_2 + L3_2)); /* dlv2l/dYj */ double dlv2ldYj = (2 * L1 * (Zk - Zl) + 2 * L3 * (Xl - Xk)) / (2 * sqrt(L1_2 + L2_2 + L3_2)); /* dlv2l/dZj */ double dlv2ldZj = (2 * L1 * (Yl - Yk) + 2 * L2 * (Xk - Xl)) / (2 * sqrt(L1_2 + L2_2 + L3_2)); /* dlv2l/dXk */ double dlv2ldXk = (2 * L2 * (Zj - Zl) + 2 * L3 * (Yl - Yj)) / (2 * sqrt(L1_2 + L2_2 + L3_2)); /* dlv2l/dYk */ double dlv2ldYk = (2 * L1 * (Zl - Zj) + 2 * L3 * (Xj - Xl)) / (2 * sqrt(L1_2 + L2_2 + L3_2)); /* dlv2l/dZk */ double dlv2ldZk = (2 * L1 * (Yj - Yl) + 2 * L2 * (Xl - Xj)) / (2 * sqrt(L1_2 + L2_2 + L3_2)); /* dlv2l/dXl */ double dlv2ldXl = (2 * L2 * (Zk - Zj) + 2 * L3 * (Yj - Yk)) / (2 * sqrt(L1_2 + L2_2 + L3_2)); /* dlv2l/dYl */ double dlv2ldYl = (2 * L1 * (Zj - Zk) + 2 * L3 * (Xk - Xj)) / (2 * sqrt(L1_2 + L2_2 + L3_2)); /* dlv2l/dZl */ double dlv2ldZl = (2 * L1 * (Yk - Yj) + 2 * L2 * (Xj - Xk)) / (2 * sqrt(L1_2 + L2_2 + L3_2)); /* dG/dXi */ double dGdXi = ((dot(dv1dXi, v2) + dot(dv2dXi, v1)) * lv1l * lv2l - dot(v1, v2) * (dlv1ldXi * lv2l + dlv2ldXi * lv1l)) / pow(lv1l * lv2l); /* dG/dYi */ double dGdYi = ((dot(dv1dYi, v2) + dot(dv2dYi, v1)) * lv1l * lv2l - dot(v1, v2) * (dlv1ldYi * lv2l + dlv2ldYi * lv1l)) / pow(lv1l * lv2l); /* dG/dZi */ double dGdZi = ((dot(dv1dZi, v2) + dot(dv2dZi, v1)) * lv1l * lv2l - dot(v1, v2) * (dlv1ldZi * lv2l + dlv2ldZi * lv1l)) / pow(lv1l * lv2l); /* dG/dXj */ double dGdXj = ((dot(dv1dXj, v2) + dot(dv2dXj, v1)) * lv1l * lv2l - dot(v1, v2) * (dlv1ldXj * lv2l + dlv2ldXj * lv1l)) / pow(lv1l * lv2l); /* dG/dYj */ double dGdYj = ((dot(dv1dYj, v2) + dot(dv2dYj, v1)) * lv1l * lv2l - dot(v1, v2) * (dlv1ldYj * lv2l + dlv2ldYj * lv1l)) / pow(lv1l * lv2l); /* dG/dZj */ double dGdZj = ((dot(dv1dZj, v2) + dot(dv2dZj, v1)) * lv1l * lv2l - dot(v1, v2) * (dlv1ldZj * lv2l + dlv2ldZj * lv1l)) / pow(lv1l * lv2l); /* dG/dXk */ double dGdXk = ((dot(dv1dXk, v2) + dot(dv2dXk, v1)) * lv1l * lv2l - dot(v1, v2) * (dlv1ldXk * lv2l + dlv2ldXk * lv1l)) / pow(lv1l * lv2l); /* dG/dYk */ double dGdYk = ((dot(dv1dYk, v2) + dot(dv2dYk, v1)) * lv1l * lv2l - dot(v1, v2) * (dlv1ldYk * lv2l + dlv2ldYk * lv1l)) / pow(lv1l * lv2l); /* dG/dZk */ double dGdZk = ((dot(dv1dZk, v2) + dot(dv2dZk, v1)) * lv1l * lv2l - dot(v1, v2) * (dlv1ldZk * lv2l + dlv2ldZk * lv1l)) / pow(lv1l * lv2l); /* dG/dXl */ double dGdXl = ((dot(dv1dXl, v2) + dot(dv2dXl, v1)) * lv1l * lv2l - dot(v1, v2) * (dlv1ldXl * lv2l + dlv2ldXl * lv1l)) / pow(lv1l * lv2l); /* dG/dYl */ double dGdYl = ((dot(dv1dYl, v2) + dot(dv2dYl, v1)) * lv1l * lv2l - dot(v1, v2) * (dlv1ldYl * lv2l + dlv2ldYl * lv1l)) / pow(lv1l * lv2l); /* dG/dZl */ double dGdZl = ((dot(dv1dZl, v2) + dot(dv2dZl, v1)) * lv1l * lv2l - dot(v1, v2) * (dlv1ldZl * lv2l + dlv2ldZl * lv1l)) / pow(lv1l * lv2l); //Hij //d^2V/dXidXj d^2V/dXidYj d^2V/dXidZj //d^2V/dYidXj d^2V/dYidYj d^2V/dYidZj //d^2V/dZidXj d^2V/dZidYj d^2V/dZidZj // diagonals of off-diagonal super elements hessian[3 * i - 2, 3 * j - 2] += +(2 * K_phi) / (1 - G * G) * dGdXi * dGdXj; hessian[3 * i - 1, 3 * j - 1] += +(2 * K_phi) / (1 - G * G) * dGdYi * dGdYj; hessian[3 * i, 3 * j] += +(2 * K_phi) / (1 - G * G) * dGdZi * dGdZj; // off-diagonals of off-diagonal super elements hessian[3 * i - 2, 3 * j - 1] += +(2 * K_phi) / (1 - G * G) * dGdXi * dGdYj; hessian[3 * i - 2, 3 * j] += +(2 * K_phi) / (1 - G * G) * dGdXi * dGdZj; hessian[3 * i - 1, 3 * j - 2] += +(2 * K_phi) / (1 - G * G) * dGdYi * dGdXj; hessian[3 * i - 1, 3 * j] += +(2 * K_phi) / (1 - G * G) * dGdYi * dGdZj; hessian[3 * i, 3 * j - 2] += +(2 * K_phi) / (1 - G * G) * dGdZi * dGdXj; hessian[3 * i, 3 * j - 1] += +(2 * K_phi) / (1 - G * G) * dGdZi * dGdYj; //Hji // diagonals of off-diagonal super elements hessian[3 * j - 2, 3 * i - 2] += +(2 * K_phi) / (1 - G * G) * dGdXj * dGdXi; hessian[3 * j - 1, 3 * i - 1] += +(2 * K_phi) / (1 - G * G) * dGdYj * dGdYi; hessian[3 * j, 3 * i] += +(2 * K_phi) / (1 - G * G) * dGdZj * dGdZi; // off-diagonals of off-diagonal super elements hessian[3 * j - 2, 3 * i - 1] += +(2 * K_phi) / (1 - G * G) * dGdXj * dGdYi; hessian[3 * j - 2, 3 * i] += +(2 * K_phi) / (1 - G * G) * dGdXj * dGdZi; hessian[3 * j - 1, 3 * i - 2] += +(2 * K_phi) / (1 - G * G) * dGdYj * dGdXi; hessian[3 * j - 1, 3 * i] += +(2 * K_phi) / (1 - G * G) * dGdYj * dGdZi; hessian[3 * j, 3 * i - 2] += +(2 * K_phi) / (1 - G * G) * dGdZj * dGdXi; hessian[3 * j, 3 * i - 1] += +(2 * K_phi) / (1 - G * G) * dGdZj * dGdYi; //Hil // diagonals of off-diagonal super elements hessian[3 * i - 2, 3 * l - 2] += +(2 * K_phi) / (1 - G * G) * dGdXi * dGdXl; hessian[3 * i - 1, 3 * l - 1] += +(2 * K_phi) / (1 - G * G) * dGdYi * dGdYl; hessian[3 * i, 3 * l] += +(2 * K_phi) / (1 - G * G) * dGdZi * dGdZl; // off-diagonals of off-diagonal super elements hessian[3 * i - 2, 3 * l - 1] += +(2 * K_phi) / (1 - G * G) * dGdXi * dGdYl; hessian[3 * i - 2, 3 * l] += +(2 * K_phi) / (1 - G * G) * dGdXi * dGdZl; hessian[3 * i - 1, 3 * l - 2] += +(2 * K_phi) / (1 - G * G) * dGdYi * dGdXl; hessian[3 * i - 1, 3 * l] += +(2 * K_phi) / (1 - G * G) * dGdYi * dGdZl; hessian[3 * i, 3 * l - 2] += +(2 * K_phi) / (1 - G * G) * dGdZi * dGdXl; hessian[3 * i, 3 * l - 1] += +(2 * K_phi) / (1 - G * G) * dGdZi * dGdYl; //Hli // diagonals of off-diagonal super elements hessian[3 * l - 2, 3 * i - 2] += +(2 * K_phi) / (1 - G * G) * dGdXl * dGdXi; hessian[3 * l - 1, 3 * i - 1] += +(2 * K_phi) / (1 - G * G) * dGdYl * dGdYi; hessian[3 * l, 3 * i] += +(2 * K_phi) / (1 - G * G) * dGdZl * dGdZi; // off-diagonals of off-diagonal super elements hessian[3 * l - 2, 3 * i - 1] += +(2 * K_phi) / (1 - G * G) * dGdXl * dGdYi; hessian[3 * l - 2, 3 * i] += +(2 * K_phi) / (1 - G * G) * dGdXl * dGdZi; hessian[3 * l - 1, 3 * i - 2] += +(2 * K_phi) / (1 - G * G) * dGdYl * dGdXi; hessian[3 * l - 1, 3 * i] += +(2 * K_phi) / (1 - G * G) * dGdYl * dGdZi; hessian[3 * l, 3 * i - 2] += +(2 * K_phi) / (1 - G * G) * dGdZl * dGdXi; hessian[3 * l, 3 * i - 1] += +(2 * K_phi) / (1 - G * G) * dGdZl * dGdYi; //Hkj // diagonals of off-diagonal super elements hessian[3 * k - 2, 3 * j - 2] += +(2 * K_phi) / (1 - G * G) * dGdXk * dGdXj; hessian[3 * k - 1, 3 * j - 1] += +(2 * K_phi) / (1 - G * G) * dGdYk * dGdYj; hessian[3 * k, 3 * j] += +(2 * K_phi) / (1 - G * G) * dGdZk * dGdZj; // off-diagonals of off-diagonal super elements hessian[3 * k - 2, 3 * j - 1] += +(2 * K_phi) / (1 - G * G) * dGdXk * dGdYj; hessian[3 * k - 2, 3 * j] += +(2 * K_phi) / (1 - G * G) * dGdXk * dGdZj; hessian[3 * k - 1, 3 * j - 2] += +(2 * K_phi) / (1 - G * G) * dGdYk * dGdXj; hessian[3 * k - 1, 3 * j] += +(2 * K_phi) / (1 - G * G) * dGdYk * dGdZj; hessian[3 * k, 3 * j - 2] += +(2 * K_phi) / (1 - G * G) * dGdZk * dGdXj; hessian[3 * k, 3 * j - 1] += +(2 * K_phi) / (1 - G * G) * dGdZk * dGdYj; //Hjk // diagonals of off-diagonal super elements hessian[3 * j - 2, 3 * k - 2] += +(2 * K_phi) / (1 - G * G) * dGdXj * dGdXk; hessian[3 * j - 1, 3 * k - 1] += +(2 * K_phi) / (1 - G * G) * dGdYj * dGdYk; hessian[3 * j, 3 * k] += +(2 * K_phi) / (1 - G * G) * dGdZj * dGdZk; // off-diagonals of off-diagonal super elements hessian[3 * j - 2, 3 * k - 1] += +(2 * K_phi) / (1 - G * G) * dGdXj * dGdYk; hessian[3 * j - 2, 3 * k] += +(2 * K_phi) / (1 - G * G) * dGdXj * dGdZk; hessian[3 * j - 1, 3 * k - 2] += +(2 * K_phi) / (1 - G * G) * dGdYj * dGdXk; hessian[3 * j - 1, 3 * k] += +(2 * K_phi) / (1 - G * G) * dGdYj * dGdZk; hessian[3 * j, 3 * k - 2] += +(2 * K_phi) / (1 - G * G) * dGdZj * dGdXk; hessian[3 * j, 3 * k - 1] += +(2 * K_phi) / (1 - G * G) * dGdZj * dGdYk; //Hik // diagonals of off-diagonal super elements hessian[3 * i - 2, 3 * k - 2] += +(2 * K_phi) / (1 - G * G) * dGdXi * dGdXk; hessian[3 * i - 1, 3 * k - 1] += +(2 * K_phi) / (1 - G * G) * dGdYi * dGdYk; hessian[3 * i, 3 * k] += +(2 * K_phi) / (1 - G * G) * dGdZi * dGdZk; // off-diagonals of off-diagonal super elements hessian[3 * i - 2, 3 * k - 1] += +(2 * K_phi) / (1 - G * G) * dGdXi * dGdYk; hessian[3 * i - 2, 3 * k] += +(2 * K_phi) / (1 - G * G) * dGdXi * dGdZk; hessian[3 * i - 1, 3 * k - 2] += +(2 * K_phi) / (1 - G * G) * dGdYi * dGdXk; hessian[3 * i - 1, 3 * k] += +(2 * K_phi) / (1 - G * G) * dGdYi * dGdZk; hessian[3 * i, 3 * k - 2] += +(2 * K_phi) / (1 - G * G) * dGdZi * dGdXk; hessian[3 * i, 3 * k - 1] += +(2 * K_phi) / (1 - G * G) * dGdZi * dGdYk; //Hki // diagonals of off-diagonal super elements hessian[3 * k - 2, 3 * i - 2] += +(2 * K_phi) / (1 - G * G) * dGdXk * dGdXi; hessian[3 * k - 1, 3 * i - 1] += +(2 * K_phi) / (1 - G * G) * dGdYk * dGdYi; hessian[3 * k, 3 * i] += +(2 * K_phi) / (1 - G * G) * dGdZk * dGdZi; // off-diagonals of off-diagonal super elements hessian[3 * k - 2, 3 * i - 1] += +(2 * K_phi) / (1 - G * G) * dGdXk * dGdYi; hessian[3 * k - 2, 3 * i] += +(2 * K_phi) / (1 - G * G) * dGdXk * dGdZi; hessian[3 * k - 1, 3 * i - 2] += +(2 * K_phi) / (1 - G * G) * dGdYk * dGdXi; hessian[3 * k - 1, 3 * i] += +(2 * K_phi) / (1 - G * G) * dGdYk * dGdZi; hessian[3 * k, 3 * i - 2] += +(2 * K_phi) / (1 - G * G) * dGdZk * dGdXi; hessian[3 * k, 3 * i - 1] += +(2 * K_phi) / (1 - G * G) * dGdZk * dGdYi; //Hlj // diagonals of off-diagonal super elements hessian[3 * l - 2, 3 * j - 2] += +(2 * K_phi) / (1 - G * G) * dGdXl * dGdXj; hessian[3 * l - 1, 3 * j - 1] += +(2 * K_phi) / (1 - G * G) * dGdYl * dGdYj; hessian[3 * l, 3 * j] += +(2 * K_phi) / (1 - G * G) * dGdZl * dGdZj; // off-diagonals of off-diagonal super elements hessian[3 * l - 2, 3 * j - 1] += +(2 * K_phi) / (1 - G * G) * dGdXl * dGdYj; hessian[3 * l - 2, 3 * j] += +(2 * K_phi) / (1 - G * G) * dGdXl * dGdZj; hessian[3 * l - 1, 3 * j - 2] += +(2 * K_phi) / (1 - G * G) * dGdYl * dGdXj; hessian[3 * l - 1, 3 * j] += +(2 * K_phi) / (1 - G * G) * dGdYl * dGdZj; hessian[3 * l, 3 * j - 2] += +(2 * K_phi) / (1 - G * G) * dGdZl * dGdXj; hessian[3 * l, 3 * j - 1] += +(2 * K_phi) / (1 - G * G) * dGdZl * dGdYj; //Hjl // diagonals of off-diagonal super elements hessian[3 * j - 2, 3 * l - 2] += +(2 * K_phi) / (1 - G * G) * dGdXj * dGdXl; hessian[3 * j - 1, 3 * l - 1] += +(2 * K_phi) / (1 - G * G) * dGdYj * dGdYl; hessian[3 * j, 3 * l] += +(2 * K_phi) / (1 - G * G) * dGdZj * dGdZl; // off-diagonals of off-diagonal super elements hessian[3 * j - 2, 3 * l - 1] += +(2 * K_phi) / (1 - G * G) * dGdXj * dGdYl; hessian[3 * j - 2, 3 * l] += +(2 * K_phi) / (1 - G * G) * dGdXj * dGdZl; hessian[3 * j - 1, 3 * l - 2] += +(2 * K_phi) / (1 - G * G) * dGdYj * dGdXl; hessian[3 * j - 1, 3 * l] += +(2 * K_phi) / (1 - G * G) * dGdYj * dGdZl; hessian[3 * j, 3 * l - 2] += +(2 * K_phi) / (1 - G * G) * dGdZj * dGdXl; hessian[3 * j, 3 * l - 1] += +(2 * K_phi) / (1 - G * G) * dGdZj * dGdYl; //Hlk // diagonals of off-diagonal super elements hessian[3 * l - 2, 3 * k - 2] += +(2 * K_phi) / (1 - G * G) * dGdXl * dGdXk; hessian[3 * l - 1, 3 * k - 1] += +(2 * K_phi) / (1 - G * G) * dGdYl * dGdYk; hessian[3 * l, 3 * k] += +(2 * K_phi) / (1 - G * G) * dGdZl * dGdZk; // off-diagonals of off-diagonal super elements hessian[3 * l - 2, 3 * k - 1] += +(2 * K_phi) / (1 - G * G) * dGdXl * dGdYk; hessian[3 * l - 2, 3 * k] += +(2 * K_phi) / (1 - G * G) * dGdXl * dGdZk; hessian[3 * l - 1, 3 * k - 2] += +(2 * K_phi) / (1 - G * G) * dGdYl * dGdXk; hessian[3 * l - 1, 3 * k] += +(2 * K_phi) / (1 - G * G) * dGdYl * dGdZk; hessian[3 * l, 3 * k - 2] += +(2 * K_phi) / (1 - G * G) * dGdZl * dGdXk; hessian[3 * l, 3 * k - 1] += +(2 * K_phi) / (1 - G * G) * dGdZl * dGdYk; //Hkl // diagonals of off-diagonal super elements hessian[3 * k - 2, 3 * l - 2] += +(2 * K_phi) / (1 - G * G) * dGdXk * dGdXl; hessian[3 * k - 1, 3 * l - 1] += +(2 * K_phi) / (1 - G * G) * dGdYk * dGdYl; hessian[3 * k, 3 * l] += +(2 * K_phi) / (1 - G * G) * dGdZk * dGdZl; // off-diagonals of off-diagonal super elements hessian[3 * k - 2, 3 * l - 1] += +(2 * K_phi) / (1 - G * G) * dGdXk * dGdYl; hessian[3 * k - 2, 3 * l] += +(2 * K_phi) / (1 - G * G) * dGdXk * dGdZl; hessian[3 * k - 1, 3 * l - 2] += +(2 * K_phi) / (1 - G * G) * dGdYk * dGdXl; hessian[3 * k - 1, 3 * l] += +(2 * K_phi) / (1 - G * G) * dGdYk * dGdZl; hessian[3 * k, 3 * l - 2] += +(2 * K_phi) / (1 - G * G) * dGdZk * dGdXl; hessian[3 * k, 3 * l - 1] += +(2 * K_phi) / (1 - G * G) * dGdZk * dGdYl; //Hii //update the diagonals of diagonal super elements hessian[3 * i - 2, 3 * i - 2] += +2 * K_phi / (1 - G * G) * dGdXi * dGdXi; hessian[3 * i - 1, 3 * i - 1] += +2 * K_phi / (1 - G * G) * dGdYi * dGdYi; hessian[3 * i, 3 * i] += +2 * K_phi / (1 - G * G) * dGdZi * dGdZi; // update the off-diagonals of diagonal super elements hessian[3 * i - 2, 3 * i - 1] += +2 * K_phi / (1 - G * G) * dGdXi * dGdYi; hessian[3 * i - 2, 3 * i] += +2 * K_phi / (1 - G * G) * dGdXi * dGdZi; hessian[3 * i - 1, 3 * i - 2] += +2 * K_phi / (1 - G * G) * dGdYi * dGdXi; hessian[3 * i - 1, 3 * i] += +2 * K_phi / (1 - G * G) * dGdYi * dGdZi; hessian[3 * i, 3 * i - 2] += +2 * K_phi / (1 - G * G) * dGdZi * dGdXi; hessian[3 * i, 3 * i - 1] += +2 * K_phi / (1 - G * G) * dGdZi * dGdYi; //Hjj //update the diagonals of diagonal super elements hessian[3 * j - 2, 3 * j - 2] += +2 * K_phi / (1 - G * G) * dGdXj * dGdXj; hessian[3 * j - 1, 3 * j - 1] += +2 * K_phi / (1 - G * G) * dGdYj * dGdYj; hessian[3 * j, 3 * j] += +2 * K_phi / (1 - G * G) * dGdZj * dGdZj; // update the off-diagonals of diagonal super elements hessian[3 * j - 2, 3 * j - 1] += +2 * K_phi / (1 - G * G) * dGdXj * dGdYj; hessian[3 * j - 2, 3 * j] += +2 * K_phi / (1 - G * G) * dGdXj * dGdZj; hessian[3 * j - 1, 3 * j - 2] += +2 * K_phi / (1 - G * G) * dGdYj * dGdXj; hessian[3 * j - 1, 3 * j] += +2 * K_phi / (1 - G * G) * dGdYj * dGdZj; hessian[3 * j, 3 * j - 2] += +2 * K_phi / (1 - G * G) * dGdZj * dGdXj; hessian[3 * j, 3 * j - 1] += +2 * K_phi / (1 - G * G) * dGdZj * dGdYj; //Hkk //update the diagonals of diagonal super elements hessian[3 * k - 2, 3 * k - 2] += +2 * K_phi / (1 - G * G) * dGdXk * dGdXk; hessian[3 * k - 1, 3 * k - 1] += +2 * K_phi / (1 - G * G) * dGdYk * dGdYk; hessian[3 * k, 3 * k] += +2 * K_phi / (1 - G * G) * dGdZk * dGdZk; // update the off-diagonals of diagonal super elements hessian[3 * k - 2, 3 * k - 1] += +2 * K_phi / (1 - G * G) * dGdXk * dGdYk; hessian[3 * k - 2, 3 * k] += +2 * K_phi / (1 - G * G) * dGdXk * dGdZk; hessian[3 * k - 1, 3 * k - 2] += +2 * K_phi / (1 - G * G) * dGdYk * dGdXk; hessian[3 * k - 1, 3 * k] += +2 * K_phi / (1 - G * G) * dGdYk * dGdZk; hessian[3 * k, 3 * k - 2] += +2 * K_phi / (1 - G * G) * dGdZk * dGdXk; hessian[3 * k, 3 * k - 1] += +2 * K_phi / (1 - G * G) * dGdZk * dGdYk; //Hll //update the diagonals of diagonal super elements hessian[3 * l - 2, 3 * l - 2] += +2 * K_phi / (1 - G * G) * dGdXl * dGdXl; hessian[3 * l - 1, 3 * l - 1] += +2 * K_phi / (1 - G * G) * dGdYl * dGdYl; hessian[3 * l, 3 * l] += +2 * K_phi / (1 - G * G) * dGdZl * dGdZl; // update the off-diagonals of diagonal super elements hessian[3 * l - 2, 3 * l - 1] += +2 * K_phi / (1 - G * G) * dGdXl * dGdYl; hessian[3 * l - 2, 3 * l] += +2 * K_phi / (1 - G * G) * dGdXl * dGdZl; hessian[3 * l - 1, 3 * l - 2] += +2 * K_phi / (1 - G * G) * dGdYl * dGdXl; hessian[3 * l - 1, 3 * l] += +2 * K_phi / (1 - G * G) * dGdYl * dGdZl; hessian[3 * l, 3 * l - 2] += +2 * K_phi / (1 - G * G) * dGdZl * dGdXl; hessian[3 * l, 3 * l - 1] += +2 * K_phi / (1 - G * G) * dGdZl * dGdYl; } if (checkComputable) { HDebug.Assert(hessian.matrix.IsComputable()); } return(hessian.matrix); }
public int UpdateAdd(HessMatrix other, double mul_other, IList <int> idxOther, double thres_NearZeroBlock, bool parallel = false) { Matrix debug_updateadd = null; if (UpdateAdd_SelfTest && idxOther == null && thres_NearZeroBlock == 0) { if ((100 < ColBlockSize) && (ColBlockSize < 1000) && (100 < RowBlockSize) && (RowBlockSize < 1000) && (other.NumUsedBlocks > 20)) { UpdateAdd_SelfTest = false; debug_updateadd = this.ToArray(); debug_updateadd.UpdateAdd(other, mul_other); } } int[] idx_other; if (idxOther == null) { //HDebug.Exception(ColSize == other.ColSize); //HDebug.Exception(RowSize == other.RowSize); idx_other = HEnum.HEnumCount(other.ColSize).ToArray(); } else { idx_other = idxOther.ToArray(); } int count = 0; int count_ignored = 0; object _lock = new object(); object _lock_ignored = new object(); Action <ValueTuple <int, int, MatrixByArr> > func = delegate(ValueTuple <int, int, MatrixByArr> bc_br_bval) { count++; int other_bc = bc_br_bval.Item1; int other_br = bc_br_bval.Item2; MatrixByArr other_bmat = bc_br_bval.Item3; if (other_bmat.HAbsMax() <= thres_NearZeroBlock) { lock (_lock_ignored) count_ignored++; //continue; return; } int bc = idx_other[other_bc]; int br = idx_other[other_br]; lock (_lock) { MatrixByArr this_bmat = GetBlock(bc, br); MatrixByArr new_bmat; if (this_bmat == null) { if (other_bmat == null) { new_bmat = null; } else { new_bmat = mul_other * other_bmat; } } else { if (other_bmat == null) { new_bmat = this_bmat.CloneT(); } else { new_bmat = this_bmat + mul_other * other_bmat; } } SetBlock(bc, br, new_bmat); } }; if (parallel) { Parallel.ForEach(other.EnumBlocks(), func); } else { foreach (var bc_br_bval in other.EnumBlocks()) { func(bc_br_bval); } } if (debug_updateadd != null) { Matrix debug_diff = debug_updateadd - this; double debug_absmax = debug_diff.HAbsMax(); HDebug.AssertToleranceMatrix(0, debug_diff); } return(count_ignored); }
static HessMatrix GetMulImpl(HessMatrix left, HessMatrix right, ILinAlg ila, bool warning) { if (HDebug.Selftest()) { Matrix h1 = new double[, ] { { 0, 1, 2, 3, 4, 5 } , { 1, 2, 3, 4, 5, 6 } , { 2, 3, 4, 5, 6, 7 } , { 3, 4, 5, 6, 7, 8 } , { 4, 5, 6, 7, 8, 9 } , { 5, 6, 7, 8, 9, 0 } }; HessMatrix h2 = HessMatrixSparse.FromMatrix(h1); Matrix h11 = Matrix.GetMul(h1, h1); HessMatrix h22 = HessMatrix.GetMulImpl(h2, h2, null, false); Matrix hdiff = h11 - h22; HDebug.AssertToleranceMatrix(0, hdiff); } if ((left is HessMatrixDense) && (right is HessMatrixDense)) { if (ila != null) { return(new HessMatrixDense { hess = ila.Mul(left, right) }); } if (warning) { HDebug.ToDo("Check (HessMatrixDense * HessMatrixDense) !!!"); } } Dictionary <int, Dictionary <int, Tuple <int, int, MatrixByArr> > > left_ic_rows = new Dictionary <int, Dictionary <int, Tuple <int, int, MatrixByArr> > >(); foreach (var ic_row in left.EnumRowBlocksAll()) { left_ic_rows.Add(ic_row.Item1, ic_row.Item2.HToDictionaryWithKeyItem2()); } Dictionary <int, Dictionary <int, Tuple <int, int, MatrixByArr> > > right_ir_cols = new Dictionary <int, Dictionary <int, Tuple <int, int, MatrixByArr> > >(); foreach (var ir_col in right.EnumColBlocksAll()) { right_ir_cols.Add(ir_col.Item1, ir_col.Item2.HToDictionaryWithKeyItem1()); } HessMatrix mul = null; if ((left is HessMatrixDense) && (right is HessMatrixDense)) { mul = HessMatrixDense.ZerosDense(left.ColSize, right.RowSize); } else { mul = HessMatrixSparse.ZerosSparse(left.ColSize, right.RowSize); } for (int ic = 0; ic < left.ColBlockSize; ic++) { var left_row = left_ic_rows[ic]; if (left_row.Count == 0) { continue; } for (int ir = 0; ir < right.RowBlockSize; ir++) { var right_col = right_ir_cols[ir]; if (right_col.Count == 0) { continue; } foreach (var left_ck in left_row) { int ik = left_ck.Key; HDebug.Assert(ic == left_ck.Value.Item1); HDebug.Assert(ik == left_ck.Value.Item2); if (right_col.ContainsKey(ik)) { var right_kr = right_col[ik]; HDebug.Assert(ik == right_kr.Item1); HDebug.Assert(ir == right_kr.Item2); MatrixByArr mul_ckr = mul.GetBlock(ic, ir) + left_ck.Value.Item3 * right_kr.Item3; mul.SetBlock(ic, ir, mul_ckr); } } } } return(mul); }
public HessMatrix SubMatrixByAtomsImpl (bool ignNegIdx // [false] , IList <int> idxColAtoms , IList <int> idxRowAtoms , bool bCloneBlock , bool parallel = false ) { Dictionary <int, int[]> col_idx2nidx = new Dictionary <int, int[]>(); HashSet <int> col_idxs = new HashSet <int>(); for (int nidx = 0; nidx < idxColAtoms.Count; nidx++) { int idx = idxColAtoms[nidx]; if (idx < 0) { if (ignNegIdx) { continue; } throw new IndexOutOfRangeException(); } if (col_idx2nidx.ContainsKey(idx) == false) { col_idx2nidx.Add(idx, new int[0]); } col_idx2nidx[idx] = col_idx2nidx[idx].HAdd(nidx); col_idxs.Add(idx); } Dictionary <int, int[]> row_idx2nidx = new Dictionary <int, int[]>(); for (int nidx = 0; nidx < idxRowAtoms.Count; nidx++) { int idx = idxRowAtoms[nidx]; if (idx < 0) { if (ignNegIdx) { continue; } throw new IndexOutOfRangeException(); } if (row_idx2nidx.ContainsKey(idx) == false) { row_idx2nidx.Add(idx, new int[0]); } row_idx2nidx[idx] = row_idx2nidx[idx].HAdd(nidx); } HessMatrix nhess = Zeros(idxColAtoms.Count * 3, idxRowAtoms.Count * 3); { Action <ValueTuple <int, int, MatrixByArr> > func = delegate(ValueTuple <int, int, MatrixByArr> bc_br_bval) { int bc = bc_br_bval.Item1; if (col_idx2nidx.ContainsKey(bc) == false) { return; } int br = bc_br_bval.Item2; if (row_idx2nidx.ContainsKey(br) == false) { return; } var bval = bc_br_bval.Item3; if (bCloneBlock) { foreach (int nbc in col_idx2nidx[bc]) { foreach (int nbr in row_idx2nidx[br]) { lock (nhess) nhess.SetBlock(nbc, nbr, bval.CloneT()); } } } else { foreach (int nbc in col_idx2nidx[bc]) { foreach (int nbr in row_idx2nidx[br]) { lock (nhess) nhess.SetBlock(nbc, nbr, bval); } } } }; if (parallel) { Parallel.ForEach(EnumBlocksInCols(col_idxs.ToArray()), func); } else { foreach (var bc_br_bval in EnumBlocksInCols(col_idxs.ToArray())) { func(bc_br_bval); } } } if (SubMatrixByAtomsImpl_selftest2) { SubMatrixByAtomsImpl_selftest2 = false; HessMatrix tnhess = SubMatrixByAtomsImpl0(idxColAtoms, idxRowAtoms); HDebug.Assert(HessMatrix.HessMatrixSparseEqual(nhess, tnhess)); ////////////////////////////////////////// Matrix thess1 = new double[, ] { { 0, 1, 2, 3, 4, 5 } , { 1, 2, 3, 4, 5, 6 } , { 2, 3, 4, 5, 6, 7 } , { 3, 4, 5, 6, 7, 8 } , { 4, 5, 6, 7, 8, 9 } , { 5, 6, 7, 8, 9, 0 } }; HessMatrix thess2 = HessMatrixDense.FromMatrix(thess1); HessMatrix thess3 = thess2.SubMatrixByAtomsImpl(false, new int[] { 0 }, new int[] { 1 }, true); Matrix thess4 = new double[, ] { { 3, 4, 5 } , { 4, 5, 6 } , { 5, 6, 7 } }; HDebug.AssertToleranceMatrix(0, thess3 - thess4); } return(nhess); }