public static HessMatrix GetMulImpl(ILinAlg ila, bool warning, params HessMatrix[] mats) { if (ila != null) { if (HDebug.Selftest()) { Matrix h0 = 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 h1 = HessMatrixDense.FromMatrix(h0); HessMatrix h2 = HessMatrixSparse.FromMatrix(h0); Matrix t0 = Matrix.GetMul(Matrix.GetMul(h1, h1), h1); { Matrix t1 = GetMulImpl(ila, false, h1, h1, h1); double d1 = (t0 - t1).HAbsMax(); HDebug.Assert(0 == d1); Matrix t2 = GetMulImpl(ila, false, h1, h1, h2); double d2 = (t0 - t2).HAbsMax(); HDebug.Assert(0 == d2); Matrix t3 = GetMulImpl(ila, false, h1, h2, h1); double d3 = (t0 - t3).HAbsMax(); HDebug.Assert(0 == d3); Matrix t4 = GetMulImpl(ila, false, h1, h2, h2); double d4 = (t0 - t4).HAbsMax(); HDebug.Assert(0 == d4); Matrix t5 = GetMulImpl(ila, false, h2, h1, h1); double d5 = (t0 - t5).HAbsMax(); HDebug.Assert(0 == d5); Matrix t6 = GetMulImpl(ila, false, h2, h1, h2); double d6 = (t0 - t6).HAbsMax(); HDebug.Assert(0 == d6); Matrix t7 = GetMulImpl(ila, false, h2, h2, h1); double d7 = (t0 - t7).HAbsMax(); HDebug.Assert(0 == d7); Matrix t8 = GetMulImpl(ila, false, h2, h2, h2); double d8 = (t0 - t8).HAbsMax(); HDebug.Assert(0 == d8); } { Matrix t1 = GetMulImpl(null, false, h1, h1, h1); double d1 = (t0 - t1).HAbsMax(); HDebug.Assert(0 == d1); Matrix t2 = GetMulImpl(null, false, h1, h1, h2); double d2 = (t0 - t2).HAbsMax(); HDebug.Assert(0 == d2); Matrix t3 = GetMulImpl(null, false, h1, h2, h1); double d3 = (t0 - t3).HAbsMax(); HDebug.Assert(0 == d3); Matrix t4 = GetMulImpl(null, false, h1, h2, h2); double d4 = (t0 - t4).HAbsMax(); HDebug.Assert(0 == d4); Matrix t5 = GetMulImpl(null, false, h2, h1, h1); double d5 = (t0 - t5).HAbsMax(); HDebug.Assert(0 == d5); Matrix t6 = GetMulImpl(null, false, h2, h1, h2); double d6 = (t0 - t6).HAbsMax(); HDebug.Assert(0 == d6); Matrix t7 = GetMulImpl(null, false, h2, h2, h1); double d7 = (t0 - t7).HAbsMax(); HDebug.Assert(0 == d7); Matrix t8 = GetMulImpl(null, false, h2, h2, h2); double d8 = (t0 - t8).HAbsMax(); HDebug.Assert(0 == d8); } } } HessMatrix mul = null; foreach (HessMatrix mat in mats) { if (mul == null) { mul = mat; } else { mul = GetMulImpl(mul, mat, ila, warning); } } return(mul); }
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); }
private static HessMatrix GetHessCoarseResiIterImpl_Matlab_IterLowerTri_Get_BInvDC (HessMatrix A , HessMatrix C , HessMatrix D , bool process_disp_console , string[] options , double?thld_BinvDC = null , bool parallel = false ) { HessMatrix B_invD_C; Dictionary <int, int> Cbr_CCbr = new Dictionary <int, int>(); List <int> CCbr_Cbr = new List <int>(); foreach (ValueTuple <int, int, MatrixByArr> bc_br_bval in C.EnumBlocks()) { int Cbr = bc_br_bval.Item2; if (Cbr_CCbr.ContainsKey(Cbr) == false) { HDebug.Assert(Cbr_CCbr.Count == CCbr_Cbr.Count); int CCbr = Cbr_CCbr.Count; Cbr_CCbr.Add(Cbr, CCbr); CCbr_Cbr.Add(Cbr); HDebug.Assert(CCbr_Cbr[CCbr] == Cbr); } } HessMatrix CC = HessMatrixSparse.ZerosSparse(C.ColSize, Cbr_CCbr.Count * 3); { Action <ValueTuple <int, int, MatrixByArr> > func = delegate(ValueTuple <int, int, MatrixByArr> bc_br_bval) { int Cbc = bc_br_bval.Item1; int CCbc = Cbc; int Cbr = bc_br_bval.Item2; int CCbr = Cbr_CCbr[Cbr]; var bval = bc_br_bval.Item3; lock (CC) CC.SetBlock(CCbc, CCbr, bval); }; if (parallel) { Parallel.ForEach(C.EnumBlocks(), func); } else { foreach (var bc_br_bval in C.EnumBlocks()) { func(bc_br_bval); } } } if (process_disp_console) { System.Console.Write("squeezeC({0,6}->{1,6} blk), ", C.RowBlockSize, CC.RowBlockSize); } { /// If a diagonal element of D is null, that row and column should be empty. /// This assume that the atom is removed. In this case, the removed diagonal block /// is replace as the 3x3 identity matrix. /// /// [B1 0] [ A 0 ]^-1 [C1 C2 C3] = [B1 0] [ A^-1 0 ] [C1 C2 C3] /// [B2 0] [ 0 I ] [ 0 0 0] [B2 0] [ 0 I^-1 ] [ 0 0 0] /// [B3 0] [B3 0] /// = [B1.invA 0] [C1 C2 C3] /// [B2.invA 0] [ 0 0 0] /// [B3.invA 0] /// = [B1.invA.C1 B1.invA.C2 B1.invA.C3] /// [B2.invA.C1 B2.invA.C2 B2.invA.C3] /// [B3.invA.C1 B3.invA.C2 B3.invA.C3] /// { //HDebug.Exception(D.ColBlockSize == D.RowBlockSize); for (int bi = 0; bi < D.ColBlockSize; bi++) { if (D.HasBlock(bi, bi) == true) { continue; } //for(int bc=0; bc< D.ColBlockSize; bc++) HDebug.Exception( D.HasBlock(bc, bi) == false); //for(int br=0; br< D.RowBlockSize; br++) HDebug.Exception( D.HasBlock(bi, br) == false); //for(int br=0; br<CC.RowBlockSize; br++) HDebug.Exception(CC.HasBlock(bi, br) == false); D.SetBlock(bi, bi, new double[3, 3] { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }); } } HessMatrix BB_invDD_CC; using (new Matlab.NamedLock("")) { Matlab.Execute("clear;"); if (process_disp_console) { System.Console.Write("matlab("); } Matlab.PutMatrix("C", CC); if (process_disp_console) { System.Console.Write("C"); //Matlab.PutSparseMatrix("C", CC.GetMatrixSparse(), 3, 3); } Matlab.PutMatrix("D", D); if (process_disp_console) { System.Console.Write("D"); } { // Matlab.Execute("BinvDC = (C' / D) * C;"); if (options != null && options.Contains("pinv(D)")) { string msg = Matlab.Execute("BinvDC = (C' / D) * C;", true); if (msg != "") { Matlab.Execute("BinvDC = C' * pinv(D) * C;"); } } else { Matlab.Execute("BinvDC = (C' / D) * C;"); } } if (process_disp_console) { System.Console.Write("X"); } /// » whos /// Name Size Bytes Class Attributes /// // before compressing C matrix /// C 1359x507 5512104 double // C 1359x1545 16797240 double /// CC 1359x507 198464 double sparse // CC 1359x1545 206768 double sparse /// D 1359x1359 14775048 double // D 1359x1359 14775048 double /// DD 1359x1359 979280 double sparse // DD 1359x1359 979280 double sparse /// ans 1x1 8 double /// /// » tic; for i=1:30; A=(C' / D) * C; end; toc dense * dense * dense => 8.839463 seconds. (win) /// Elapsed time is 8.839463 seconds. /// » tic; for i=1:30; AA=(CC' / DD) * CC; end; toc sparse * sparse * sparse => 27.945534 seconds. /// Elapsed time is 27.945534 seconds. /// » tic; for i=1:30; AAA=(C' / DD) * C; end; toc sparse * dense * sparse => 29.136144 seconds. /// Elapsed time is 29.136144 seconds. /// » /// » tic; for i=1:30; A=(C' / D) * C; end; toc dense * dense * dense => 8.469071 seconds. (win) /// Elapsed time is 8.469071 seconds. /// » tic; for i=1:30; AA=(CC' / DD) * CC; end; toc sparse * sparse * sparse => 28.309953 seconds. /// Elapsed time is 28.309953 seconds. /// » tic; for i=1:30; AAA=(C' / DD) * C; end; toc sparse * dense * sparse => 28.586375 seconds. /// Elapsed time is 28.586375 seconds. //Matrix BBinvDDCC = Matlab.GetMatrix("BinvDC", true); if (thld_BinvDC != null) { Matlab.Execute("BinvDC(find(BinvDC < " + thld_BinvDC.ToString() + ")) = 0;"); } if (Matlab.GetValue("nnz(BinvDC)/numel(BinvDC)") > 0.5) { double[,] arr = Matlab.GetMatrix("BinvDC", true); BB_invDD_CC = HessMatrixDense.FromMatrix(arr); if (process_disp_console) { System.Console.Write("Y), "); } } else { Matlab.Execute("[i,j,s] = find(sparse(BinvDC));"); TVector <int> listi = Matlab.GetVectorLargeInt("i", true); TVector <int> listj = Matlab.GetVectorLargeInt("j", true); TVector <double> lists = Matlab.GetVectorLarge("s", true); int colsize = Matlab.GetValueInt("size(BinvDC,1)"); int rowsize = Matlab.GetValueInt("size(BinvDC,2)"); Dictionary <ValueTuple <int, int>, MatrixByArr> lst_bc_br_bval = new Dictionary <ValueTuple <int, int>, MatrixByArr>(); for (long i = 0; i < listi.SizeLong; i++) { int c = listi[i] - 1; int bc = c / 3; int ic = c % 3; int r = listj[i] - 1; int br = r / 3; int ir = r % 3; double v = lists[i]; ValueTuple <int, int> bc_br = new ValueTuple <int, int>(bc, br); if (lst_bc_br_bval.ContainsKey(bc_br) == false) { lst_bc_br_bval.Add(bc_br, new double[3, 3]); } lst_bc_br_bval[bc_br][ic, ir] = v; } // Matrix BBinvDDCC = Matrix.Zeros(colsize, rowsize); // for(int i=0; i<listi.Length; i++) // BBinvDDCC[listi[i]-1, listj[i]-1] = lists[i]; // //GC.Collect(0); BB_invDD_CC = HessMatrixSparse.ZerosSparse(colsize, rowsize); foreach (var bc_br_bval in lst_bc_br_bval) { int bc = bc_br_bval.Key.Item1; int br = bc_br_bval.Key.Item2; var bval = bc_br_bval.Value; BB_invDD_CC.SetBlock(bc, br, bval); } if (process_disp_console) { System.Console.Write("Z), "); } if (HDebug.IsDebuggerAttached) { for (int i = 0; i < listi.Size; i++) { int c = listi[i] - 1; int r = listj[i] - 1; double v = lists[i]; HDebug.Assert(BB_invDD_CC[c, r] == v); } } } Matlab.Execute("clear;"); } //GC.Collect(0); B_invD_C = HessMatrixSparse.ZerosSparse(C.RowSize, C.RowSize); { // for(int bcc=0; bcc<CCbr_Cbr.Count; bcc++) // { // int bc = CCbr_Cbr[bcc]; // for(int brr=0; brr<CCbr_Cbr.Count; brr++) // { // int br = CCbr_Cbr[brr]; // HDebug.Assert(B_invD_C.HasBlock(bc, br) == false); // if(BB_invDD_CC.HasBlock(bcc, brr) == false) // continue; // var bval = BB_invDD_CC.GetBlock(bcc, brr); // B_invD_C.SetBlock(bc, br, bval); // HDebug.Exception(A.HasBlock(bc, bc)); // HDebug.Exception(A.HasBlock(br, br)); // } // } Action <ValueTuple <int, int, MatrixByArr> > func = delegate(ValueTuple <int, int, MatrixByArr> bcc_brr_bval) { int bcc = bcc_brr_bval.Item1; int brr = bcc_brr_bval.Item2; var bval = bcc_brr_bval.Item3; int bc = CCbr_Cbr[bcc]; int br = CCbr_Cbr[brr]; lock (B_invD_C) B_invD_C.SetBlock(bc, br, bval); }; if (parallel) { Parallel.ForEach(BB_invDD_CC.EnumBlocks(), func); } else { foreach (var bcc_brr_bval in BB_invDD_CC.EnumBlocks()) { func(bcc_brr_bval); } } } } GC.Collect(0); return(B_invD_C); }
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); }