Exemplo n.º 1
0
        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);
        }