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 IMatrixSparse <MatrixByArr> GetMatrixSparse() { if (this is HessMatrixSparse) { return((this as HessMatrixSparse).GetMatrixSparse()); } if (this is HessMatrixDense) { return(HessMatrixSparse.FromMatrix(this).GetMatrixSparse()); } if (this is HessMatrixLayeredArray) { return(this as IMatrixSparse <MatrixByArr>); } throw new NotImplementedException(); }
private static HessMatrix Get_BInvDC (HessMatrix A , HessMatrix C , HessMatrix D , bool process_disp_console , string[] options , 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 } }); } } HessMatrixSparse 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 (process_disp_console) { System.Console.Write("Y"); } //Matlab.Execute("[i,j,s] = find(sparse(BinvDC));"); //int[] listi = Matlab.GetVectorInt("i"); //int[] listj = Matlab.GetVectorInt("j"); //double[] lists = Matlab.GetVector("s"); //int colsize = Matlab.GetValueInt("size(BinvDC,1)"); //int rowsize = Matlab.GetValueInt("size(BinvDC,2)"); //Matrix BBinvDDCC = Matrix.Zeros(colsize, rowsize); //for(int i=0; i<listi.Length; i++) // BBinvDDCC[listi[i], listj[i]] = lists[i]; //GC.Collect(0); BB_invDD_CC = HessMatrixSparse.FromMatrix(BBinvDDCC, parallel); if (process_disp_console) { System.Console.Write("Z), "); } 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); }
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); }