public HessMatrix ReshapeByAtomImpl(IList <int> idxatms, bool ignNegIdx) { HessMatrix reshape = SubMatrixByAtoms(ignNegIdx, idxatms); if (ReshapeByAtomImpl_selftest && idxatms.Count < 3000) { ReshapeByAtomImpl_selftest = false; HessMatrix treshape = ReshapeByAtomImpl0(idxatms, ignNegIdx); HDebug.Assert(HessMatrix.HessMatrixSparseEqual(reshape, treshape)); } return(reshape); }
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); }