public static CGetHessCoarseResiIterImpl GetHessCoarseResiIterImpl_Matlab_IterLowerTri (object[] atoms , HessMatrix H , List <int>[] lstNewIdxRemv , double thres_zeroblk , ILinAlg ila , bool cloneH , string[] options // { "pinv(D)" } ) { ila = null; if (cloneH) { H = H.CloneHess(); } bool process_disp_console = true; if (options != null && options.Contains("print process")) { process_disp_console = true; } bool parallel = true; /// 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(); List <DateTime> process_time = new List <DateTime>(); //System.Console.WriteLine("begin coarse-graining"); List <HessCoarseResiIterInfo> iterinfos = new List <HessCoarseResiIterInfo>(); for (int iter = lstNewIdxRemv.Length - 1; iter >= 0; iter--) { process_time.Clear(); if (process_disp_console) { process_time.Add(DateTime.UtcNow); System.Console.Write(" - {0:000} : ", iter); } //int[] ikeep = lstNewIdxRemv[iter].Item1; int[] iremv = lstNewIdxRemv[iter].ToArray(); int iremv_min = iremv.Min(); int iremv_max = iremv.Max(); HDebug.Assert(H.ColBlockSize == H.RowBlockSize); int blksize = H.ColBlockSize; //HDebug.Assert(ikeep.Max() < blksize); //HDebug.Assert(iremv.Max() < blksize); //HDebug.Assert(iremv.Max()+1 == blksize); //HDebug.Assert(iremv.Max() - iremv.Min() + 1 == iremv.Length); int[] idxkeep = HEnum.HEnumFromTo(0, iremv_min - 1).ToArray(); int[] idxremv = HEnum.HEnumFromTo(iremv_min, iremv_max).ToArray(); //HDebug.Assert(idxkeep.HUnionWith(idxremv).Length == blksize); HessCoarseResiIterInfo iterinfo = new HessCoarseResiIterInfo(); iterinfo.sizeHessBlkMat = idxremv.Max() + 1; // H.ColBlockSize; iterinfo.numAtomsRemoved = idxremv.Length; iterinfo.time0 = DateTime.UtcNow; //////////////////////////////////////////////////////////////////////////////////////// // make C sparse double C_density0; double C_density1; { double thres_absmax = thres_zeroblk; C_density0 = 0; List <Tuple <int, int> > lstIdxToMakeZero = new List <Tuple <int, int> >(); foreach (var bc_br_bval in H.EnumBlocksInCols(idxremv)) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; var bval = bc_br_bval.Item3; if (br >= iremv_min) { // bc_br is in D, not in C continue; } C_density0++; double absmax_bval = bval.HAbsMax(); if (absmax_bval < thres_absmax) { lstIdxToMakeZero.Add(new Tuple <int, int>(bc, br)); } } C_density1 = C_density0 - lstIdxToMakeZero.Count; foreach (var bc_br in lstIdxToMakeZero) { int bc = bc_br.Item1; int br = bc_br.Item2; HDebug.Assert(bc > br); var Cval = H.GetBlock(bc, br); var Dval = H.GetBlock(bc, bc); var Aval = H.GetBlock(br, br); var Bval = Cval.Tr(); H.SetBlock(bc, br, null); // nCval = Cval -Cval H.SetBlock(bc, bc, Dval + Cval); // nDval = Dval - (-Cval) = Dval + Cval // nBval = Bval -Bval H.SetBlock(br, br, Aval + Bval); // nAval = Aval - (-Bval) = Aval + Bval } iterinfo.numSetZeroBlock = lstIdxToMakeZero.Count; iterinfo.numNonZeroBlock = (int)C_density1; C_density0 /= (idxkeep.Length * idxremv.Length); C_density1 /= (idxkeep.Length * idxremv.Length); } //////////////////////////////////////////////////////////////////////////////////////// // get A, B, C, D HessMatrix A = H; // HessMatrix A = H.SubMatrixByAtoms(false, idxkeep, idxkeep); // HessMatrix B = H.SubMatrixByAtoms(false, idxkeep, idxremv); HessMatrix C; // HessMatrix C = H.SubMatrixByAtoms(false, idxremv, idxkeep, parallel:parallel); HessMatrix D; // HessMatrix D = H.SubMatrixByAtoms(false, idxremv, idxremv, parallel:parallel); { C = H.Zeros(idxremv.Length * 3, idxkeep.Length * 3); D = H.Zeros(idxremv.Length * 3, idxremv.Length * 3); //List<Tuple<int, int, MatrixByArr>> lst_bc_br_bval = H.EnumBlocksInCols(idxremv).ToList(); //foreach(var bc_br_bval in lst_bc_br_bval) foreach (var bc_br_bval in H.EnumBlocksInCols(idxremv)) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; var bval = bc_br_bval.Item3; H.SetBlock(bc, br, null); if (bc > iremv_max) { HDebug.Assert(false); continue; } if (br > iremv_max) { HDebug.Assert(false); continue; } if (br < iremv_min) { int nc = bc - iremv_min; int nr = br; HDebug.Assert(C.HasBlock(nc, nr) == false); C.SetBlock(nc, nr, bval.CloneT()); } else { int nc = bc - iremv_min; int nr = br - iremv_min; HDebug.Assert(D.HasBlock(nc, nr) == false); D.SetBlock(nc, nr, bval); if (nc != nr) { HDebug.Assert(D.HasBlock(nr, nc) == false); D.SetBlock(nr, nc, bval.Tr()); } } } HDebug.Assert(H.EnumBlocksInCols(idxremv).Count() == 0); } if (process_disp_console) { process_time.Add(DateTime.UtcNow); int ptc = process_time.Count; System.Console.Write("CD({0:00.00} min), ", (process_time[ptc - 1] - process_time[ptc - 2]).TotalMinutes); } //////////////////////////////////////////////////////////////////////////////////////// // Get B.inv(D).C HessMatrix B_invD_C; { { B_invD_C = GetHessCoarseResiIterImpl_Matlab_IterLowerTri_Get_BInvDC(A, C, D, process_disp_console , options , thld_BinvDC: thres_zeroblk / lstNewIdxRemv.Length , parallel: parallel ); } if (process_disp_console) { process_time.Add(DateTime.UtcNow); int ptc = process_time.Count; System.Console.Write("B.invD.C({0:00.00} min), ", (process_time[ptc - 1] - process_time[ptc - 2]).TotalMinutes); } GC.Collect(0); } //////////////////////////////////////////////////////////////////////////////////////// // Get A - B.inv(D).C /// iterinfo.numAddIgnrBlock = A.UpdateAdd(B_invD_C, -1, null, thres_zeroblk/lstNewIdxRemv.Length, parallel:parallel); { HessMatrix __this = A; HessMatrix other = B_invD_C; double _thres_NearZeroBlock = thres_zeroblk / lstNewIdxRemv.Length; int[] _count = new int[1]; int[] _count_ignored = new int[1]; //foreach(var bc_br_bval in other.EnumBlocks()) Action <ValueTuple <int, int, MatrixByArr> > func = delegate(ValueTuple <int, int, MatrixByArr> bc_br_bval) { _count[0]++; int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; MatrixByArr other_bmat = bc_br_bval.Item3; if (bc < br) { return; // continue; } if (other_bmat.HAbsMax() <= _thres_NearZeroBlock) { /// other_bmat = other_bmat -other_bmat; /// other_diag = other_diag - (-other_bmat) = other_diag + other_bmat; /// this_diag = this_diat - B_invD_C /// = this_diat - other_diag /// = this_diat - (other_diag + other_bmat) /// = this_diat - other_diag - other_bmat /// = (this_diat - other_bmat) - other_diag /// = (this_diat - other_bmat) - (processed later) /// = (this_diat - other_bmat) MatrixByArr this_diag = __this.GetBlock(bc, bc); MatrixByArr new_diag = this_diag - other_bmat; __this.SetBlockLock(bc, bc, new_diag); other_bmat = null; lock (_count_ignored) _count_ignored[0]++; } if (other_bmat != null) { MatrixByArr this_bmat = __this.GetBlock(bc, br); if (this_bmat == null) { this_bmat = new double[3, 3]; } MatrixByArr new_bmat = this_bmat - other_bmat; __this.SetBlockLock(bc, br, new_bmat); } }; if (parallel) { HParallel.ForEach(other.EnumBlocks(), func); } else { foreach (var bc_br_bval in other.EnumBlocks()) { func(bc_br_bval); } } iterinfo.numAddIgnrBlock = _count_ignored[0]; } if (process_disp_console) { process_time.Add(DateTime.UtcNow); int ptc = process_time.Count; System.Console.Write("A-BinvDC({0:00.00} min), ", (process_time[ptc - 1] - process_time[ptc - 2]).TotalMinutes); } //HessMatrix nH = A - B_invD_C; //nH = ((nH + nH.Tr())/2).ToHessMatrix(); //////////////////////////////////////////////////////////////////////////////////////// // Replace A -> H H = A; //////////////////////////////////////////////////////////////////////////////////////// // print iteration log iterinfo.usedMemoryByte = GC.GetTotalMemory(false); iterinfo.time1 = DateTime.UtcNow; iterinfos.Add(iterinfo); if (process_disp_console) { System.Console.Write("summary(makezero {0,5}, nonzero {1,5}, numIgnMul {2,7}, numRemvAtoms {3,3}, {4,5:0.00} min, {5} mb, {6}x{6}, nzeroBlk/Atom {7:0.00}), GC(" , iterinfo.numSetZeroBlock , iterinfo.numNonZeroBlock , iterinfo.numAddIgnrBlock , iterinfo.numAtomsRemoved , iterinfo.compTime.TotalMinutes , iterinfo.usedMemoryByte / (1024 * 1024) , (idxkeep.Length * 3) , ((double)iterinfo.numNonZeroBlock / idxremv.Length) ); } GC.Collect(); if (process_disp_console) { System.Console.WriteLine(")"); } } 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(); //System.Console.WriteLine("finish resizing"); return(new CGetHessCoarseResiIterImpl { iterinfos = iterinfos, H = H, }); }
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, }); }
public static CGetHessCoarseResiIterImpl GetHessCoarseResiIterImpl_ILinAlg_20150329(HessMatrix H, List <int>[] lstNewIdxRemv, double thres_zeroblk, ILinAlg ila, bool cloneH) { if (cloneH) { H = H.CloneHess(); } //System.Console.WriteLine("begin coarse-graining"); List <HessCoarseResiIterInfo> iterinfos = new List <HessCoarseResiIterInfo>(); for (int iter = lstNewIdxRemv.Length - 1; iter >= 0; iter--) { //int[] ikeep = lstNewIdxRemv[iter].Item1; int[] iremv = lstNewIdxRemv[iter].ToArray(); HDebug.Assert(H.ColBlockSize == H.RowBlockSize); int blksize = H.ColBlockSize; //HDebug.Assert(ikeep.Max() < blksize); //HDebug.Assert(iremv.Max() < blksize); //HDebug.Assert(iremv.Max()+1 == blksize); //HDebug.Assert(iremv.Max() - iremv.Min() + 1 == iremv.Length); int[] idxkeep = HEnum.HEnumFromTo(0, iremv.Min() - 1).ToArray(); int[] idxremv = HEnum.HEnumFromTo(iremv.Min(), iremv.Max()).ToArray(); //HDebug.Assert(idxkeep.HUnionWith(idxremv).Length == blksize); HessCoarseResiIterInfo iterinfo = new HessCoarseResiIterInfo(); iterinfo.sizeHessBlkMat = idxremv.Max() + 1; // H.ColBlockSize; iterinfo.numAtomsRemoved = idxremv.Length; iterinfo.time0 = DateTime.UtcNow; { //HessMatrix A = H.SubMatrixByAtoms(false, idxkeep, idxkeep); HessMatrix A = H; //HessMatrix B = H.SubMatrixByAtoms(false, idxkeep, idxremv); HessMatrix C = H.SubMatrixByAtoms(false, idxremv, idxkeep); HessMatrix D = H.SubMatrixByAtoms(false, idxremv, idxremv); HessMatrix invD = new HessMatrixDense { hess = ila.InvSymm(D) }; // make B,C sparse //int B_cntzero = B.MakeNearZeroBlockAsZero(thres_zeroblk); iterinfo.numSetZeroBlock = C.MakeNearZeroBlockAsZero(thres_zeroblk); //int B_nzeros = B.NumUsedBlocks; double B_nzeros_ = Math.Sqrt(B_nzeros); iterinfo.numNonZeroBlock = C.NumUsedBlocks; HessMatrix B = C.Tr(); HessMatrix B_invD_C = B * invD * C; iterinfo.numAddIgnrBlock = A.UpdateAdd(B_invD_C, -1, null, thres_zeroblk / lstNewIdxRemv.Length); //HessMatrix nH = A - B_invD_C; //nH = ((nH + nH.Tr())/2).ToHessMatrix(); H = A; } iterinfo.usedMemoryByte = GC.GetTotalMemory(false); iterinfo.time1 = DateTime.UtcNow; iterinfos.Add(iterinfo); //System.Console.WriteLine(" - {0:000} : makezero {1,5}, nonzero {2,5}, numIgnMul {3,7}, numRemvAtoms {4,3}, {5,5:0.00} sec, {6} mb, {7}x{7}" // , iter // , iterinfo.numSetZeroBlock // , iterinfo.numNonZeroBlock // , iterinfo.numAddIgnrBlock // , iterinfo.numAtomsRemoved // , iterinfo.compSec // , iterinfo.usedMemoryByte/(1024*1024) // , (idxkeep.Length*3) // ); GC.Collect(); } 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(); //System.Console.WriteLine("finish resizing"); return(new CGetHessCoarseResiIterImpl { iterinfos = iterinfos, H = H, }); }
public static CGetHessCoarseResiIterImpl GetHessCoarseResiIterImpl_ILinAlg(HessMatrix H, List <int>[] lstNewIdxRemv, double thres_zeroblk, ILinAlg ila, bool cloneH) { if (cloneH) { H = H.CloneHess(); } bool process_disp_console = true; DateTime[] process_time = new DateTime[7]; //System.Console.WriteLine("begin coarse-graining"); List <HessCoarseResiIterInfo> iterinfos = new List <HessCoarseResiIterInfo>(); for (int iter = lstNewIdxRemv.Length - 1; iter >= 0; iter--) { if (process_disp_console) { process_time[0] = DateTime.UtcNow; System.Console.Write(" - {0:000} : ", iter); } //int[] ikeep = lstNewIdxRemv[iter].Item1; int[] iremv = lstNewIdxRemv[iter].ToArray(); HDebug.Assert(H.ColBlockSize == H.RowBlockSize); int blksize = H.ColBlockSize; //HDebug.Assert(ikeep.Max() < blksize); //HDebug.Assert(iremv.Max() < blksize); //HDebug.Assert(iremv.Max()+1 == blksize); //HDebug.Assert(iremv.Max() - iremv.Min() + 1 == iremv.Length); int[] idxkeep = HEnum.HEnumFromTo(0, iremv.Min() - 1).ToArray(); int[] idxremv = HEnum.HEnumFromTo(iremv.Min(), iremv.Max()).ToArray(); //HDebug.Assert(idxkeep.HUnionWith(idxremv).Length == blksize); HessCoarseResiIterInfo iterinfo = new HessCoarseResiIterInfo(); iterinfo.sizeHessBlkMat = idxremv.Max() + 1; // H.ColBlockSize; iterinfo.numAtomsRemoved = idxremv.Length; iterinfo.time0 = DateTime.UtcNow; double C_density0 = double.NaN; double C_density1 = double.NaN; { //HessMatrix A = H.SubMatrixByAtoms(false, idxkeep, idxkeep); HessMatrix A = H; //HessMatrix B = H.SubMatrixByAtoms(false, idxkeep, idxremv); HessMatrix C = H.SubMatrixByAtoms(false, idxremv, idxkeep); if (process_disp_console) { process_time[1] = DateTime.UtcNow; System.Console.Write("C({0:00.00} min), ", (process_time[1] - process_time[0]).TotalMinutes); } HessMatrix D = H.SubMatrixByAtoms(false, idxremv, idxremv); if (process_disp_console) { process_time[2] = DateTime.UtcNow; System.Console.Write("D({0:00.00} min), ", (process_time[2] - process_time[1]).TotalMinutes); } HessMatrix invD = new HessMatrixDense { hess = ila.InvSymm(D) }; if (process_disp_console) { process_time[3] = DateTime.UtcNow; System.Console.Write("invD({0:00.00} min), ", (process_time[3] - process_time[2]).TotalMinutes); } // make B,C sparse //int B_cntzero = B.MakeNearZeroBlockAsZero(thres_zeroblk); C_density0 = C.RatioUsedBlocks; iterinfo.numSetZeroBlock = C.MakeNearZeroBlockAsZero(thres_zeroblk); if (process_disp_console) { process_time[4] = DateTime.UtcNow; System.Console.Write("sparseC({0:00.00} min), ", (process_time[4] - process_time[3]).TotalMinutes); } //int B_nzeros = B.NumUsedBlocks; double B_nzeros_ = Math.Sqrt(B_nzeros); iterinfo.numNonZeroBlock = C.NumUsedBlocks; C_density1 = C.RatioUsedBlocks; HessMatrix B = C.Tr(); HessMatrix B_invD_C = HessMatrix.GetMul(ila, B, invD, C); /* B * invD * C;*/ if (process_disp_console) { process_time[5] = DateTime.UtcNow; System.Console.Write("B.invD.C({0:00.00} min), ", (process_time[5] - process_time[4]).TotalMinutes); } iterinfo.numAddIgnrBlock = A.UpdateAdd(B_invD_C, -1, null, thres_zeroblk / lstNewIdxRemv.Length); if (process_disp_console) { process_time[6] = DateTime.UtcNow; System.Console.Write("A+BinvDC({0:00.00} min), ", (process_time[6] - process_time[5]).TotalMinutes); } //HessMatrix nH = A - B_invD_C; //nH = ((nH + nH.Tr())/2).ToHessMatrix(); H = A; } iterinfo.usedMemoryByte = GC.GetTotalMemory(false); iterinfo.time1 = DateTime.UtcNow; iterinfos.Add(iterinfo); if (process_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})" , iterinfo.numSetZeroBlock , iterinfo.numNonZeroBlock , iterinfo.numAddIgnrBlock , iterinfo.numAtomsRemoved , iterinfo.compSec , iterinfo.usedMemoryByte / (1024 * 1024) , (idxkeep.Length * 3) , ((double)iterinfo.numNonZeroBlock / idxremv.Length) ); } GC.Collect(0); } 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, }); }
public static CGetHessCoarseResiIterImpl GetHessCoarseResiIterImpl_Matlab(HessMatrix H, List <int>[] lstNewIdxRemv, double thres_zeroblk) { HessMatrix CGH = null; List <HessCoarseResiIterInfo> iterinfos = new List <HessCoarseResiIterInfo>(); using (new Matlab.NamedLock("CGHessIter")) { Matlab.PutSparseMatrix("CG.H", H.GetMatrixSparse(), 3, 3); Matlab.PutValue("CG.th", thres_zeroblk); Matlab.PutValue("CG.iter", lstNewIdxRemv.Length); for (int iter = lstNewIdxRemv.Length - 1; iter >= 0; iter--) { int[] iremv = lstNewIdxRemv[iter].ToArray(); int[] idxkeep = HEnum.HEnumFromTo(0, iremv.Min() - 1).ToArray(); int[] idxremv = HEnum.HEnumFromTo(iremv.Min(), iremv.Max()).ToArray(); Matlab.PutVector("CG.idxkeep", idxkeep); Matlab.PutVector("CG.idxremv", idxremv); Matlab.Execute("CG.idxkeep = sort([CG.idxkeep*3+1; CG.idxkeep*3+2; CG.idxkeep*3+3]);"); Matlab.Execute("CG.idxremv = sort([CG.idxremv*3+1; CG.idxremv*3+2; CG.idxremv*3+3]);"); HessCoarseResiIterInfo iterinfo = new HessCoarseResiIterInfo(); iterinfo.sizeHessBlkMat = idxremv.Max() + 1; // H.ColBlockSize; iterinfo.numAtomsRemoved = idxremv.Length; iterinfo.idxkeep = idxkeep.HClone(); iterinfo.idxremv = idxremv.HClone(); iterinfo.time0 = DateTime.UtcNow; if (HDebug.IsDebuggerAttached) { int maxkeep = Matlab.GetValueInt("max(CG.idxkeep)"); int minremv = Matlab.GetValueInt("min(CG.idxremv)"); HDebug.Assert(maxkeep + 1 == minremv); int maxremv = Matlab.GetValueInt("max(CG.idxremv)"); int Hsize = Matlab.GetValueInt("max(size(CG.H))"); HDebug.Assert(Hsize == maxremv); int idxsize = Matlab.GetValueInt("length(union(CG.idxkeep,CG.idxremv))"); HDebug.Assert(Hsize == idxsize); } Matlab.Execute("CG.A = CG.H(CG.idxkeep, CG.idxkeep);"); Matlab.Execute("CG.B = CG.H(CG.idxkeep, CG.idxremv);"); //Matlab.Execute("CG.C = CG.H(CG.idxremv, CG.idxkeep);"); Matlab.Execute("CG.D = CG.H(CG.idxremv, CG.idxremv);"); HDebug.Assert(false); Matlab.Execute("CG.B(abs(CG.B) < CG.th) = 0;"); /// matlab cannot handle this call. Matlab try to use 20G memory. Matlab.Execute("CG.BDC = CG.B * inv(full(CG.D)) * CG.B';"); Matlab.Execute("CG.BDC = sparse(CG.BDC);"); Matlab.Execute("CG.BDC(abs(CG.BDC) < (CG.th / CG.iter)) = 0;"); Matlab.Execute("CG.H = CG.A - sparse(CG.BDC);"); iterinfo.numSetZeroBlock = -1; iterinfo.numNonZeroBlock = -1; iterinfo.numAddIgnrBlock = -1; iterinfo.usedMemoryByte = -1; iterinfo.time1 = DateTime.UtcNow; iterinfos.Add(iterinfo); System.Console.WriteLine(" - {0:000} : makezero {1,5}, nonzero {2,5}, numIgnMul {3,7}, numRemvAtoms {4,3}, {5,5:0.00} sec, {6} mb, {7}x{7}" , iter , iterinfo.numSetZeroBlock , iterinfo.numNonZeroBlock , iterinfo.numAddIgnrBlock , iterinfo.numAtomsRemoved , iterinfo.compSec , iterinfo.usedMemoryByte / (1024 * 1024) , (idxkeep.Length * 3) ); } Matrix CG_H = Matlab.GetMatrix("CG.H"); CGH = new HessMatrixDense { hess = CG_H }; } return(new CGetHessCoarseResiIterImpl { iterinfos = iterinfos, H = CGH, }); }
public static CGetHessCoarseResiIterImpl GetHessCoarseResiIterImpl_Matlab_experimental (object[] atoms , HessMatrix H , List <int>[] lstNewIdxRemv , double thres_zeroblk , ILinAlg ila , bool cloneH , string[] options ) { ila = null; if (cloneH) { H = H.CloneHess(); } bool process_disp_console = true; if (options != null && options.Contains("print process")) { process_disp_console = true; } bool parallel = true; GC.Collect(0); 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--) { if (process_disp_console) { process_time[0] = DateTime.UtcNow; System.Console.Write(" - {0:000} : ", iter); } //int[] ikeep = lstNewIdxRemv[iter].Item1; int[] iremv = lstNewIdxRemv[iter].ToArray(); HDebug.Assert(H.ColBlockSize == H.RowBlockSize); int blksize = H.ColBlockSize; //HDebug.Assert(ikeep.Max() < blksize); //HDebug.Assert(iremv.Max() < blksize); //HDebug.Assert(iremv.Max()+1 == blksize); //HDebug.Assert(iremv.Max() - iremv.Min() + 1 == iremv.Length); int[] idxkeep = HEnum.HEnumFromTo(0, iremv.Min() - 1).ToArray(); int[] idxremv = HEnum.HEnumFromTo(iremv.Min(), iremv.Max()).ToArray(); //HDebug.Assert(idxkeep.HUnionWith(idxremv).Length == blksize); HessCoarseResiIterInfo iterinfo = new HessCoarseResiIterInfo(); iterinfo.sizeHessBlkMat = idxremv.Max() + 1; // H.ColBlockSize; iterinfo.numAtomsRemoved = idxremv.Length; iterinfo.time0 = DateTime.UtcNow; double C_density0 = double.NaN; double C_density1 = double.NaN; { //HessMatrix A = H.SubMatrixByAtoms(false, idxkeep, idxkeep); HessMatrix A = H; //HessMatrix B = H.SubMatrixByAtoms(false, idxkeep, idxremv); HessMatrix C, D; /// HessMatrix C = H.SubMatrixByAtoms(false, idxremv, idxkeep, parallel:parallel); /// HessMatrix D = H.SubMatrixByAtoms(false, idxremv, idxremv, parallel:parallel); { C = H.Zeros(idxremv.Length * 3, idxkeep.Length * 3); D = H.Zeros(idxremv.Length * 3, idxremv.Length * 3); int iremv_min = iremv.Min(); int iremv_max = iremv.Max(); foreach (var bc_br_bval in H.EnumBlocksInCols(idxremv)) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; var bval = bc_br_bval.Item3; if (bc > iremv_max) { continue; } if (br > iremv_max) { continue; } if (br < iremv_min) { int nc = bc - iremv_min; int nr = br; C.SetBlock(nc, nr, bval.CloneT()); } else { int nc = bc - iremv_min; int nr = br - iremv_min; D.SetBlock(nc, nr, bval.CloneT()); } } } if (process_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); } // make B,C sparse //int B_cntzero = B.MakeNearZeroBlockAsZero(thres_zeroblk); C_density0 = C.RatioUsedBlocks; /// iterinfo.numSetZeroBlock = C.MakeNearZeroBlockAsZero(thres_zeroblk); { double thres_absmax = thres_zeroblk; List <Tuple <int, int> > lstIdxToMakeZero = new List <Tuple <int, int> >(); foreach (var bc_br_bval in C.EnumBlocks()) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; var bval = bc_br_bval.Item3; double absmax_bval = bval.HAbsMax(); if (absmax_bval < thres_absmax) { lstIdxToMakeZero.Add(new Tuple <int, int>(bc, br)); } } foreach (var bc_br in lstIdxToMakeZero) { int cc = bc_br.Item1; int cr = bc_br.Item2; var Cval = C.GetBlock(cc, cr); C.SetBlock(cc, cr, null); var Dval = D.GetBlock(cc, cc); // nCval = Cval -Cval D.SetBlock(cc, cc, Dval + Cval); // nDval = Dval - (-Cval) = Dval + Cval int bc = cr; int br = cc; var Bval = Cval.Tr(); var Aval = A.GetBlock(bc, bc); // nBval = Bval -Bval A.SetBlock(bc, bc, Aval + Bval); // nAval = Aval - (-Bval) = Aval + Bval } iterinfo.numSetZeroBlock = lstIdxToMakeZero.Count; } //int B_nzeros = B.NumUsedBlocks; double B_nzeros_ = Math.Sqrt(B_nzeros); iterinfo.numNonZeroBlock = C.NumUsedBlocks; C_density1 = C.RatioUsedBlocks; HessMatrix B_invD_C = Get_BInvDC(A, C, D, process_disp_console , options , parallel: parallel ); if (process_disp_console) { process_time[4] = DateTime.UtcNow; System.Console.Write("B.invD.C({0:00.00} min), ", (process_time[4] - process_time[3]).TotalMinutes); } /// iterinfo.numAddIgnrBlock = A.UpdateAdd(B_invD_C, -1, null, thres_zeroblk/lstNewIdxRemv.Length, parallel:parallel); { HessMatrix _this = A; HessMatrix other = B_invD_C; double thres_NearZeroBlock = thres_zeroblk / lstNewIdxRemv.Length; int count = 0; int count_ignored = 0; foreach (var bc_br_bval in other.EnumBlocks()) { count++; int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; MatrixByArr other_bmat = bc_br_bval.Item3; if (other_bmat.HAbsMax() <= thres_NearZeroBlock) { // other_bmat = other_bmat -other_bmat; // other_diag = other_diag - (-other_bmat) = other_diag + other_bmat; // this_diag = this_diat - B_invD_C // = this_diat - other_diag // = this_diat - (other_diag + other_bmat) // = this_diat - other_diag - other_bmat // = (this_diat - other_bmat) - other_diag // = (this_diat - other_bmat) - (processed later) // = (this_diat - other_bmat) MatrixByArr this_diag = _this.GetBlock(bc, bc); MatrixByArr new_diag = this_diag - other_bmat; _this.SetBlock(bc, bc, new_diag); other_bmat = null; count_ignored++; } if (other_bmat != null) { MatrixByArr this_bmat = _this.GetBlock(bc, br); MatrixByArr new_bmat = this_bmat - other_bmat; _this.SetBlock(bc, br, new_bmat); } } iterinfo.numAddIgnrBlock = count_ignored; } //HessMatrix nH = A - B_invD_C; //nH = ((nH + nH.Tr())/2).ToHessMatrix(); H = A; } iterinfo.usedMemoryByte = GC.GetTotalMemory(false); iterinfo.time1 = DateTime.UtcNow; iterinfos.Add(iterinfo); if (process_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})" , iterinfo.numSetZeroBlock , iterinfo.numNonZeroBlock , iterinfo.numAddIgnrBlock , iterinfo.numAtomsRemoved , iterinfo.compSec , iterinfo.usedMemoryByte / (1024 * 1024) , (idxkeep.Length * 3) , ((double)iterinfo.numNonZeroBlock / idxremv.Length) ); } GC.Collect(0); } 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, }); }