public static CGetHessCoarseResiIterImpl Do (object[] atoms , HessMatrix H , List <int>[] lstNewIdxRemv , double thres_zeroblk , ILinAlg ila , bool cloneH , string[] options ) { //HDebug.ToDo(); ila = null; cloneH = true; if (cloneH) { H = H.CloneHess(); } bool process_disp_console = true; if (options != null && options.Contains("print process")) { process_disp_console = true; } bool parallel = false; /// keep only lower triangle of H (lower block triangles) { HashSet <Tuple <int, int, MatrixByArr> > lstUppTrig = new HashSet <Tuple <int, int, MatrixByArr> >(); foreach (ValueTuple <int, int, MatrixByArr> bc_br_bval in H.EnumBlocks()) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; if (bc < br) { lstUppTrig.Add(bc_br_bval.ToTuple()); } } foreach (Tuple <int, int, MatrixByArr> bc_br_bval in lstUppTrig) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; HDebug.Assert(bc < br); H.SetBlock(bc, br, null); } } GC.Collect(); DateTime[] process_time = new DateTime[6]; //System.Console.WriteLine("begin coarse-graining"); List <HessCoarseResiIterInfo> iterinfos = new List <HessCoarseResiIterInfo>(); for (int iter = lstNewIdxRemv.Length - 1; iter >= 0; iter--) { bool lprocess_disp_console = (process_disp_console && iter % 5 == 0); lprocess_disp_console = true; if (lprocess_disp_console) { process_time[0] = DateTime.UtcNow; System.Console.Write(" - {0:000} : ", iter); } //int[] ikeep = lstNewIdxRemv[iter].Item1; HessCoarseResiIterInfo iterinfo = new HessCoarseResiIterInfo(); iterinfo.sizeHessBlkMat = 1; iterinfo.numAtomsRemoved = 1; iterinfo.time0 = DateTime.UtcNow; int _count_update = 0; { HDebug.Assert(lstNewIdxRemv[iter].Count == 1); int iremv = lstNewIdxRemv[iter][0]; HessMatrix A = H; MatrixByArr D = null; double D_absmin = 0; List <int> C_lstbr = new List <int>(); List <MatrixByArr> C_lstbval = new List <MatrixByArr>(); { // get C and D foreach (var(bc, br, bval) in H.EnumBlocksInCols(new int[] { iremv })) { HDebug.Assert(iremv == bc); if (bc == br) { HDebug.Assert(D == null); D = bval; D_absmin = D.HAbsMin(); } else { if (bval.HAbsMin() >= thres_zeroblk) { C_lstbr.Add(br); C_lstbval.Add(bval); } } } // remove C and D { int bc = iremv; H.SetBlock(bc, bc, null); foreach (int br in C_lstbr) { H.SetBlock(bc, br, null); } } } if (lprocess_disp_console) { process_time[1] = process_time[2] = DateTime.UtcNow; System.Console.Write("CD({0:00.00} min), ", (process_time[2] - process_time[0]).TotalMinutes); } double threshold = thres_zeroblk / lstNewIdxRemv.Length; // DD ={ { d00,d01,d02},{ d10,d11,d12},{ d20,d21,d22} }; MatrixForm[DD] // BB ={ { b00,b01,b02},{ b10,b11,b12},{ b20,b21,b22} }; MatrixForm[BB] // CC ={ { c00,c01,c02},{ c10,c11,c12},{ c20,c21,c22} }; MatrixForm[CC] // object[] dbginfo = null; // new object[] { iremv, atoms, H, D, C_lstbr, C_lstbval }; Action <ValueTuple <int, int, MatrixByArr, MatrixByArr> > Update_A_B_invD_C = delegate(ValueTuple <int, int, MatrixByArr, MatrixByArr> info) { int bc = info.Item1; // bc int br = info.Item2; // br MatrixByArr DC = info.Item3; // invDD_CC // XX ={ { x00,x01,x02},{ x10,x11,x12},{ x20,x21,x22} }; MatrixForm[CC] MatrixByArr B = info.Item4; // BB // BB ={ { b00,b01,b02},{ b10,b11,b12},{ b20,b21,b22} }; MatrixForm[BB] //var _iremv = (int)dbginfo[0]; //var _atoms = dbginfo[1] as Universe.Atom[] ; //var _H = dbginfo[2] as HessMatrix ; //var _D = dbginfo[3] as MatrixByArr ; //var _C_lstbr = dbginfo[4] as List<int> ; //var _C_lstbval = dbginfo[5] as List<MatrixByArr>; //MatrixByArr BB_invDD_CC = BB * invDD_CC; double _BDC00 = 0 - B[0, 0] * DC[0, 0] - B[0, 1] * DC[1, 0] - B[0, 2] * DC[2, 0]; // { { b00 x00 +b01 x10 + b02 x20 double _BDC01 = 0 - B[0, 0] * DC[0, 1] - B[0, 1] * DC[1, 1] - B[0, 2] * DC[2, 1]; // , b00 x01 +b01 x11 + b02 x21 double _BDC02 = 0 - B[0, 0] * DC[0, 2] - B[0, 1] * DC[1, 2] - B[0, 2] * DC[2, 2]; // , b00 x02 +b01 x12 + b02 x22 double _BDC10 = 0 - B[1, 0] * DC[0, 0] - B[1, 1] * DC[1, 0] - B[1, 2] * DC[2, 0]; // },{ b10 x00 +b11 x10 + b12 x20 double _BDC11 = 0 - B[1, 0] * DC[0, 1] - B[1, 1] * DC[1, 1] - B[1, 2] * DC[2, 1]; // , b10 x01 +b11 x11 + b12 x21 double _BDC12 = 0 - B[1, 0] * DC[0, 2] - B[1, 1] * DC[1, 2] - B[1, 2] * DC[2, 2]; // , b10 x02 +b11 x12 + b12 x22 double _BDC20 = 0 - B[2, 0] * DC[0, 0] - B[2, 1] * DC[1, 0] - B[2, 2] * DC[2, 0]; // },{ b20 x00 +b21 x10 + b22 x20 double _BDC21 = 0 - B[2, 0] * DC[0, 1] - B[2, 1] * DC[1, 1] - B[2, 2] * DC[2, 1]; // , b20 x01 +b21 x11 + b22 x21 double _BDC22 = 0 - B[2, 0] * DC[0, 2] - B[2, 1] * DC[1, 2] - B[2, 2] * DC[2, 2]; // , b20 x02 +b21 x12 + b22 x22 }} if (A.HasBlockLock(bc, br)) { MatrixByArr A_bc_br = A.GetBlockLock(bc, br); A_bc_br[0, 0] += _BDC00; // A = A + (-B.invD.C) A_bc_br[0, 1] += _BDC01; // A = A + (-B.invD.C) A_bc_br[0, 2] += _BDC02; // A = A + (-B.invD.C) A_bc_br[1, 0] += _BDC10; // A = A + (-B.invD.C) A_bc_br[1, 1] += _BDC11; // A = A + (-B.invD.C) A_bc_br[1, 2] += _BDC12; // A = A + (-B.invD.C) A_bc_br[2, 0] += _BDC20; // A = A + (-B.invD.C) A_bc_br[2, 1] += _BDC21; // A = A + (-B.invD.C) A_bc_br[2, 2] += _BDC22; // A = A + (-B.invD.C) // (small && small && small) == !(large || large || large) bool toosmall = !(Math.Abs(A_bc_br[0, 0]) > threshold || Math.Abs(A_bc_br[0, 1]) > threshold || Math.Abs(A_bc_br[0, 2]) > threshold || Math.Abs(A_bc_br[1, 0]) > threshold || Math.Abs(A_bc_br[1, 1]) > threshold || Math.Abs(A_bc_br[1, 2]) > threshold || Math.Abs(A_bc_br[2, 0]) > threshold || Math.Abs(A_bc_br[2, 1]) > threshold || Math.Abs(A_bc_br[2, 2]) > threshold); if (toosmall) { HDebug.Assert(bc != br); A.SetBlockLock(bc, br, null); } } else { // (small && small && small) == !(large || large || large) bool toosmall = !(Math.Abs(_BDC00) > threshold || Math.Abs(_BDC01) > threshold || Math.Abs(_BDC02) > threshold || Math.Abs(_BDC10) > threshold || Math.Abs(_BDC11) > threshold || Math.Abs(_BDC12) > threshold || Math.Abs(_BDC20) > threshold || Math.Abs(_BDC21) > threshold || Math.Abs(_BDC22) > threshold); if (!toosmall) { MatrixByArr A_bc_br = new double[3, 3] { { _BDC00, _BDC01, _BDC02 } // A = 0 + (-B.invD.C) , { _BDC10, _BDC11, _BDC12 } // A = 0 + (-B.invD.C) , { _BDC20, _BDC21, _BDC22 } // A = 0 + (-B.invD.C) }; A.SetBlockLock(bc, br, A_bc_br); } } System.Threading.Interlocked.Increment(ref _count_update); }; var lstCompInfo = EnumComput(D, C_lstbr, C_lstbval, threshold); if (parallel) { Parallel.ForEach(lstCompInfo, Update_A_B_invD_C); } else { foreach (var info in lstCompInfo) { Update_A_B_invD_C(info); } } //GC.Collect(0); if (lprocess_disp_console) { process_time[4] = DateTime.UtcNow; System.Console.Write("B.invD.C({0:00.00} min), ", (process_time[4] - process_time[3]).TotalMinutes); } H = A; } iterinfo.usedMemoryByte = GC.GetTotalMemory(false); iterinfo.time1 = DateTime.UtcNow; iterinfos.Add(iterinfo); if (lprocess_disp_console) { System.Console.WriteLine("summary(makezero {0,5}, nonzero {1,5}, numIgnMul {2,7}, numRemvAtoms {3,3}, {4,5:0.00} sec, {5} mb, {6}x{6}, nzeroBlk/Atom {7:0.00}, cntUpdateBlk({8}))" , iterinfo.numSetZeroBlock , iterinfo.numNonZeroBlock , iterinfo.numAddIgnrBlock , iterinfo.numAtomsRemoved , iterinfo.compSec , iterinfo.usedMemoryByte / (1024 * 1024) , (0 * 3) , 0//((double)iterinfo.numNonZeroBlock / idxremv.Length) , _count_update ); } } int numca = H.ColBlockSize - lstNewIdxRemv.HListCount().Sum(); //System.Console.WriteLine("finish coarse-graining"); { int[] idxkeep = HEnum.HEnumCount(numca).ToArray(); H = H.SubMatrixByAtoms(false, idxkeep, idxkeep, false); } { H.MakeNearZeroBlockAsZero(thres_zeroblk); } GC.Collect(0); //System.Console.WriteLine("finish resizing"); return(new CGetHessCoarseResiIterImpl { iterinfos = iterinfos, H = H, }); }