Beispiel #1
0
        public static Mode[] GetModes(MatrixByArr hess, string cachepath = null)
        {
            Vector[] eigvec;
            double[] eigval;
            if (cachepath != null && HFile.Exists(cachepath))
            {
                HSerialize.Deserialize(cachepath, null, out eigval, out eigvec);
            }
            else
            {
                HDebug.Verify(NumericSolver.Eig(hess, out eigvec, out eigval));
                HSerialize.SerializeDepreciated(cachepath, null, eigval, eigvec);
            }

            List <Mode> modes;

            {   // sort by eigenvalues
                int[] idx = eigval.HAbs().HIdxSorted();
                modes = new List <Mode>(idx.Length);
                for (int i = 0; i < eigval.Length; i++)
                {
                    Mode mode = new Mode {
                        eigval = eigval[idx[i]],
                        eigvec = eigvec[idx[i]]
                    };
                    modes.Add(mode);
                }
            }

            return(modes.ToArray());
        }
        List <PointValue> point_values;                                         //Точечные оценки



        #region CONSTRUCTORS

        /// <summary>
        /// Создает новый объект NormalDistribution на основе объекта
        /// Distribution, содержащего статистические данные, для которых
        /// проверяется гипотеза
        /// </summary>
        /// <param name="distr"></param>
        public NormalDistribution(Distribution.Distribution distr) : base(distr)
        {
            //Если наш исходный ряд был обычным рядом (либо ввод ряда, либо ввод выборки),
            //то берем ряд частот. Иначе берем группированный ряд частот как его аналог для
            //интервального ряда
            if (distr.StatFreq != null)
            {
                raw_statistics = distr.StatFreq;
            }
            else
            {
                raw_statistics = distr.GroupFreq;
            }


            //Расчитываем точеченые оценки

            //Мат ожидание = выборочное средние
            //Дисперсия = выборочная дисперсия
            NumericSolver solver = new NumericSolver(raw_statistics);

            standart_deviation = solver.StandartDeviation();
            expected_value     = solver.Mean();

            //Создаем список с точечными оценками
            point_values = new List <PointValue>
            {
                new PointValue("Математическое ожидание", Resources.normal_expected_value, expected_value),
                new PointValue("Среднеквадратическое откланение", Resources.normal_standart_deviation, standart_deviation),
            };
        }
Beispiel #3
0
        public static void GetModes(Matrix hess, out Matrix modes, out Vector freqs)
        {
            HDebug.Depreciated("use others");
            HDebug.Assert(GetModesSelftest());

            HDebug.Assert(hess.RowSize == hess.ColSize);
            Matrix eigvec;
            Vector eigval;

            NumericSolver.Eig(hess.ToArray(), out eigvec, out eigval);
            int n = hess.RowSize;

            modes = new double[n, n - 6];
            freqs = new double[n - 6];
            for (int r = 0; r < 6; r++)
            {
                HDebug.AssertTolerance(0.00000001, eigval[r]);
            }
            for (int r = 6; r < n; r++)
            {
                int rr = r - 6;
                freqs[rr] = eigval[r];
                for (int c = 0; c < n; c++)
                {
                    modes[c, rr] = eigvec[c, r];
                }
            }
        }
Beispiel #4
0
            public static void Compute(Vector[] coords, ref double energy, ref Vector[] forces, ref MatrixByArr[,] hessian,
                                       double Kb, double b0, double[,] pwfrc = null, double[,] pwspr = null)
            {
                #region original source in mindy
                // double ComputeBonded::compute_bonds(const Vector *coords, Vector *f) const {
                //   double energy = 0.0;
                //   BondElem *bond = bonds;
                //   for (int i=0; i<nbonds; i++) {
                //     Vector r12 = coords[bond->atom1] - coords[bond->atom2];
                //     double r = r12.length();
                //     double diff = r - bond->x0;
                //     Vector f12 = r12 * diff * (-2*bond->k) / r;
                //     energy += bond->k * diff * diff;
                //     f[bond->atom1] += f12;
                //     f[bond->atom2] -= f12;
                //     bond++;
                //   }
                //   return energy;
                // }
                #endregion

                ///////////////////////////////////////////////////////////////////////////////
                // energy
                Vector pos1 = coords[0];
                Vector pos2 = coords[1];
                Vector r12  = pos1 - pos2;      //     Vector r12 = coords[bond->atom1] - coords[bond->atom2];
                double r    = r12.Dist;         //     double r = r12.length();
                HDebug.Assert(r != 0, double.IsNaN(r) == false, double.IsInfinity(r) == false);
                double diff = r - b0;           //     double diff = r - bond->x0;
                HDebug.Assert(double.IsNaN(Kb * diff * diff) == false, double.IsInfinity(Kb * diff * diff) == false);
                energy += Kb * diff * diff;     //     energy += bond->k * diff * diff;
                ///////////////////////////////////////////////////////////////////////////////
                // force
                if (forces != null)
                {
                    Vector f12 = r12 * diff * (-2 * Kb) / r; //     Vector f12 = r12 * diff * (-2*bond->k) / r;
                    forces[0] += f12;                        //     f[bond->atom1] += f12;
                    forces[1] -= f12;                        //     f[bond->atom2] -= f12;
                }
                ///////////////////////////////////////////////////////////////////////////////
                // hessian
                if (hessian != null)
                {
                    //// !V(bond) = Kb(b - b0)**2
                    //hessian[0,1].Kij = 2 * Kb;
                    //hessian[0,1].Fij = diff * (-2*Kb);
                    //hessian[1,0].Kij = 2 * Kb;
                    //hessian[1,0].Fij = diff * (-2*Kb);
                    //Debug.Assert(false);

                    //Debug.Assert(false);
                    double dcoord = 0.0001;
                    HDebug.Assert(hessian.GetLength(0) == 2, hessian.GetLength(1) == 2);
                    NumericSolver.Derivative2(ComputeFunc, coords, dcoord, ref hessian, Kb, b0);
                }
            }
Beispiel #5
0
        public NumCharacteristics(Dictionary <double, double> distr)
        {
            InitializeComponent();
            solver = new NumericSolver(distr);

            var mean               = solver.Mean();
            var dispersion         = solver.Dispersion();
            var standard_deviation = solver.StandartDeviation();
            var s_dispersion       = solver.SDispersion();

            tbMean.Text              = mean.ToString("N2");
            tbDispersion.Text        = dispersion.ToString("N2");
            tbStandartDeviation.Text = standard_deviation.ToString("N2");
        }
        Dictionary <double, double> raw_statistics; //Исходный ряд (либо группированный, либо простой)
                                                    //Используется для расчет точечных оценок и построения
                                                    //теоретической функции


        #region CONSTRUCTORS
        public BinomialDistribution(Distribution.Distribution distr, int number_of_experiments) : base(distr)
        {
            raw_statistics = distr.StatFreq;
            n = number_of_experiments;

            //Вычисляем вероятность благоприятного исхода
            double mean = new NumericSolver(raw_statistics).Mean();

            p = mean / n;

            point_values = new List <PointValue>
            {
                new PointValue("Вероятность появления события", Resources.binomial_p, p)
            };
        }
                public static NumericSolver FromBaseObject(BaseObject baseObj)
                {
                    if (baseObj == null || baseObj.NativeObject == IntPtr.Zero)
                    {
                        return(null);
                    }
                    NumericSolver obj = baseObj as  NumericSolver;

                    if (object.Equals(obj, null))
                    {
                        obj = new NumericSolver(CreatedWhenConstruct.CWC_NotToCreate);
                        obj.BindNativeObject(baseObj.NativeObject, "CNumericSolver");
                        obj.IncreaseCast();
                    }

                    return(obj);
                }
Beispiel #8
0
        public static Vector GetBFactor(Matrix hess
                                        , int numIgnoreSmallEigval = 6       // the number to ignore the eigenvalues
                                        , bool zeroForNegEigval    = true    // set zero for the negative eigen values
                                        )
        {
            HDebug.Assert(GetBFactorSelfTest());

            int n = hess.ColSize / 3;

            HDebug.Assert(n * 3 == hess.ColSize);

            HDebug.Assert(hess.RowSize == hess.ColSize);
            InfoPack lextra = new InfoPack();

            Vector[] eigvec;
            double[] eigval;
            NumericSolver.Eig(hess.ToArray(), out eigvec, out eigval);

            double[]   abs_eigval            = eigval.HAbs();
            List <int> idx_sorted_abs_eigval = new List <int>(abs_eigval.HIdxSorted());

            for (int i = 0; i < numIgnoreSmallEigval; i++)
            {
                idx_sorted_abs_eigval.RemoveAt(0);
            }

            Vector bfactor = new double[n];

            foreach (int idx in idx_sorted_abs_eigval)
            {
                if (eigval[idx] < 0)
                {
                    continue;
                }
                for (int i = 0; i < n; i++)
                {
                    double dx = eigvec[idx][i * 3 + 0];
                    double dy = eigvec[idx][i * 3 + 1];
                    double dz = eigvec[idx][i * 3 + 2];
                    bfactor[i] += (dx * dx + dy * dy + dz * dz) / eigval[idx];
                }
            }

            return(bfactor);
        }
Beispiel #9
0
            public static List <double> ScaleBFactorComp(List <double> bfactorExpr, List <double> bfactorComp, HPack <double> outScale4BfactorComp, HPack <double> outAdd4BfactorComp)
            {
                HDebug.Assert(bfactorExpr.Count == bfactorComp.Count);
                int    size = bfactorComp.Count;
                Matrix A    = new double[size, 2];
                Vector b    = new double[size];

                for (int i = 0; i < size; i++)
                {
                    A[i, 0] = bfactorComp[i];
                    A[i, 1] = 1;
                    b[i]    = bfactorExpr[i];
                }
                /// A x = b
                /// (A' A) x = (A' b)
                /// x = inv(A' A) * (A' b)
                Matrix At     = A.Tr();
                Matrix AtA    = At * A;
                Vector Atb    = LinAlg.MV(At, b);       // = At * b;
                Matrix invAtA = NumericSolver.Inv(AtA);
                Vector x      = LinAlg.MV(invAtA, Atb); // = invAtA * Atb;
                double scale  = x[0];
                double add    = x[1];

                double[] bfactorCompScaled = new double[size];
                for (int i = 0; i < size; i++)
                {
                    bfactorCompScaled[i] = bfactorComp[i] * scale + add;
                }
                if (outScale4BfactorComp != null)
                {
                    outScale4BfactorComp.value = scale;
                }
                if (outAdd4BfactorComp != null)
                {
                    outAdd4BfactorComp.value = add;
                }
                return(new List <double>(bfactorCompScaled));
            }
Beispiel #10
0
        //public static Mode[] GetModes(Matrix hess)
        //{
        //    return GetModesFromHess(hess);
        //}
        public static Mode[] GetModesFromHess(Matrix hess)
        {
            //string cachepath = null;
            HDebug.Depreciated("use Mode[] GetModesFromHess(Matrix hess, ILinAlg la)");

            Vector[] eigvec;
            double[] eigval;
            //if(cachepath != null && HFile.Exists(cachepath))
            //{
            //    HSerialize.Deserialize(cachepath, null, out eigval, out eigvec);
            //}
            //else
            //{
            HDebug.Verify(NumericSolver.Eig(hess.ToArray(), out eigvec, out eigval));
            //    if(cachepath != null)
            //        HSerialize.SerializeDepreciated(cachepath, null, eigval, eigvec);
            //}

            List <Mode> modes;

            {   // sort by eigenvalues
                int[] idx = eigval.HAbs().HIdxSorted();
                modes = new List <Mode>(idx.Length);
                for (int i = 0; i < eigval.Length; i++)
                {
                    Mode mode = new Mode
                    {
                        eigval = eigval[idx[i]],
                        eigvec = eigvec[idx[i]]
                    };
                    modes.Add(mode);
                }
            }

            return(modes.ToArray());
        }
Beispiel #11
0
            public static void Compute(Vector[] coords, ref double energy, ref Vector[] forces, ref MatrixByArr[,] hessian,
                                       double Kchi, double n, double delta, double[,] pwfrc = null, double[,] pwspr = null)
            {
                #region original source in mindy
                // double ComputeBonded::compute_dihedrals(const Vector *coords, Vector *f) const {
                //   double energy = 0.0;
                //   DihedralElem *dihedral = dihedrals;
                //   for (int i=0; i<ndihedrals; i++) {
                //     const Vector *pos0 = coords + dihedral->atom1;
                //     const Vector *pos1 = coords + dihedral->atom2;
                //     const Vector *pos2 = coords + dihedral->atom3;
                //     const Vector *pos3 = coords + dihedral->atom4;
                //     const Vector r12 = *pos0 - *pos1;
                //     const Vector r23 = *pos1 - *pos2;
                //     const Vector r34 = *pos2 - *pos3;
                //
                //     Vector dcosdA;
                //     Vector dcosdB;
                //     Vector dsindC;
                //     Vector dsindB;
                //     Vector f1, f2, f3;
                //
                //     Vector A, B, C;
                //     A.cross(r12, r23);
                //     B.cross(r23, r34);
                //     C.cross(r23, A);
                //
                //     double rA = A.length();
                //     double rB = B.length();
                //     double rC = C.length();
                //
                //     double cos_phi = (A*B)/(rA*rB);
                //     double sin_phi = (C*B)/(rC*rB);
                //
                //     // Normalize B
                //     rB = 1.0/rB;
                //     B *= rB;
                //
                //     double phi = -atan2(sin_phi, cos_phi);
                //
                //     if (fabs(sin_phi) > 0.1) {
                //       // Normalize A
                //       rA = 1.0/rA;
                //       A *= rA;
                //       dcosdA = rA*(cos_phi*A-B);
                //       dcosdB = rB*(cos_phi*B-A);
                //     }
                //     else {
                //       // Normalize C
                //       rC = 1.0/rC;
                //       C *= rC;
                //       dsindC = rC*(sin_phi*C-B);
                //       dsindB = rB*(sin_phi*B-C);
                //     }
                //
                //     int mult = dihedral->multiplicity;
                //     for (int j=0; j<mult; j++) {
                //       double k = dihedral->k[j];
                //       double n = dihedral->n[j];
                //       double delta = dihedral->delta[j];
                //       double K, K1;
                //       if (n) {
                //         K = k * (1.0+cos(n*phi + delta));
                //         K1 = -n*k*sin(n*phi + delta);
                //       }
                //       else {
                //         double diff = phi-delta;
                //         if (diff < -M_PI) diff += 2.0*M_PI;
                //         else if (diff > M_PI) diff -= 2.0*M_PI;
                //         K = k*diff*diff;
                //         K1 = 2.0*k*diff;
                //       }
                //       energy += K;
                //
                //       // forces
                //       if (fabs(sin_phi) > 0.1) {
                //         K1 = K1/sin_phi;
                //         f1.x += K1*(r23.y*dcosdA.z - r23.z*dcosdA.y);
                //         f1.y += K1*(r23.z*dcosdA.x - r23.x*dcosdA.z);
                //         f1.z += K1*(r23.x*dcosdA.y - r23.y*dcosdA.x);
                //
                //         f3.x += K1*(r23.z*dcosdB.y - r23.y*dcosdB.z);
                //         f3.y += K1*(r23.x*dcosdB.z - r23.z*dcosdB.x);
                //         f3.z += K1*(r23.y*dcosdB.x - r23.x*dcosdB.y);
                //
                //         f2.x += K1*(r12.z*dcosdA.y - r12.y*dcosdA.z
                //                  + r34.y*dcosdB.z - r34.z*dcosdB.y);
                //         f2.y += K1*(r12.x*dcosdA.z - r12.z*dcosdA.x
                //                  + r34.z*dcosdB.x - r34.x*dcosdB.z);
                //         f2.z += K1*(r12.y*dcosdA.x - r12.x*dcosdA.y
                //                  + r34.x*dcosdB.y - r34.y*dcosdB.x);
                //       }
                //       else {
                //         //  This angle is closer to 0 or 180 than it is to
                //         //  90, so use the cos version to avoid 1/sin terms
                //         K1 = -K1/cos_phi;
                //
                //         f1.x += K1*((r23.y*r23.y + r23.z*r23.z)*dsindC.x
                //                 - r23.x*r23.y*dsindC.y
                //                 - r23.x*r23.z*dsindC.z);
                //         f1.y += K1*((r23.z*r23.z + r23.x*r23.x)*dsindC.y
                //                 - r23.y*r23.z*dsindC.z
                //                 - r23.y*r23.x*dsindC.x);
                //         f1.z += K1*((r23.x*r23.x + r23.y*r23.y)*dsindC.z
                //                 - r23.z*r23.x*dsindC.x
                //                 - r23.z*r23.y*dsindC.y);
                //
                //         f3 += cross(K1,dsindB,r23);
                //
                //         f2.x += K1*(-(r23.y*r12.y + r23.z*r12.z)*dsindC.x
                //                +(2.0*r23.x*r12.y - r12.x*r23.y)*dsindC.y
                //                +(2.0*r23.x*r12.z - r12.x*r23.z)*dsindC.z
                //                +dsindB.z*r34.y - dsindB.y*r34.z);
                //         f2.y += K1*(-(r23.z*r12.z + r23.x*r12.x)*dsindC.y
                //                +(2.0*r23.y*r12.z - r12.y*r23.z)*dsindC.z
                //                +(2.0*r23.y*r12.x - r12.y*r23.x)*dsindC.x
                //                +dsindB.x*r34.z - dsindB.z*r34.x);
                //         f2.z += K1*(-(r23.x*r12.x + r23.y*r12.y)*dsindC.z
                //                +(2.0*r23.z*r12.x - r12.z*r23.x)*dsindC.x
                //                +(2.0*r23.z*r12.y - r12.z*r23.y)*dsindC.y
                //                +dsindB.y*r34.x - dsindB.x*r34.y);
                //       }
                //     }    // end loop over multiplicity
                //     f[dihedral->atom1] += f1;
                //     f[dihedral->atom2] += f2-f1;
                //     f[dihedral->atom3] += f3-f2;
                //     f[dihedral->atom4] += -f3;
                //
                //     dihedral++;
                //   }
                //   return energy;
                // }
                #endregion

                ///////////////////////////////////////////////////////////////////////////////
                // energy
                Vector pos0 = coords[0];                             //     const Vector *pos0 = coords + dihedral->atom1;
                Vector pos1 = coords[1];                             //     const Vector *pos1 = coords + dihedral->atom2;
                Vector pos2 = coords[2];                             //     const Vector *pos2 = coords + dihedral->atom3;
                Vector pos3 = coords[3];                             //     const Vector *pos3 = coords + dihedral->atom4;
                Vector r12  = pos0 - pos1;                           //     const Vector r12 = *pos0 - *pos1;
                Vector r23  = pos1 - pos2;                           //     const Vector r23 = *pos1 - *pos2;
                Vector r34  = pos2 - pos3;                           //     const Vector r34 = *pos2 - *pos3;
                                                                     //
                Vector dcosdA = null;                                //     Vector dcosdA;
                Vector dcosdB = null;                                //     Vector dcosdB;
                Vector dsindC = null;                                //     Vector dsindC;
                Vector dsindB = null;                                //     Vector dsindB;
                                                                     //
                Vector A, B, C;                                      //     Vector A, B, C;
                A = LinAlg.CrossProd(r12, r23);                      //     A.cross(r12, r23);
                B = LinAlg.CrossProd(r23, r34);                      //     B.cross(r23, r34);
                C = LinAlg.CrossProd(r23, A);                        //     C.cross(r23, A);
                //
                double rA = A.Dist;                                  //     double rA = A.length();
                double rB = B.Dist;                                  //     double rB = B.length();
                double rC = C.Dist;                                  //     double rC = C.length();
                //
                double cos_phi = LinAlg.DotProd(A, B) / (rA * rB);   //     double cos_phi = (A*B)/(rA*rB);
                double sin_phi = LinAlg.DotProd(C, B) / (rC * rB);   //     double sin_phi = (C*B)/(rC*rB);
                //
                // Normalize B                                       //     // Normalize B
                rB = 1.0 / rB;                                       //     rB = 1.0/rB;
                B *= rB;                                             //     B *= rB;
                                                                     //
                double phi = -Math.Atan2(sin_phi, cos_phi);          //     double phi = -atan2(sin_phi, cos_phi);
                                                                     //
                if (Math.Abs(sin_phi) > 0.1)                         //     if (fabs(sin_phi) > 0.1) {
                // Normalize A                                       //       // Normalize A
                {
                    rA     = 1.0 / rA;                               //       rA = 1.0/rA;
                    A     *= rA;                                     //       A *= rA;
                    dcosdA = rA * (cos_phi * A - B);                 //       dcosdA = rA*(cos_phi*A-B);
                    dcosdB = rB * (cos_phi * B - A);                 //       dcosdB = rB*(cos_phi*B-A);
                }                                                    //     }
                else                                                 //     else {
                // Normalize C                                       //       // Normalize C
                {
                    rC     = 1.0 / rC;                               //       rC = 1.0/rC;
                    C     *= rC;                                     //       C *= rC;
                    dsindC = rC * (sin_phi * C - B);                 //       dsindC = rC*(sin_phi*C-B);
                    dsindB = rB * (sin_phi * B - C);                 //       dsindB = rB*(sin_phi*B-C);
                }                                                    //     }
                                                                     //
                //int mult = dihedral->multiplicity;                 //     int mult = dihedral->multiplicity;
                //for (int j=0; j<mult; j++) {                       //     for (int j=0; j<mult; j++) {
                //double k = dihedral->k[j];                         //       double k = dihedral->k[j];
                //double n = dihedral->n[j];                         //       double n = dihedral->n[j];
                //double delta = dihedral->delta[j];                 //       double delta = dihedral->delta[j];
                double K, K1;                                        //       double K, K1;
                if (n != 0)                                          //       if (n) {
                {
                    K  = Kchi * (1.0 + Math.Cos(n * phi + delta));   //         K = k * (1.0+cos(n*phi + delta));
                    K1 = -n *Kchi *Math.Sin(n *phi + delta);         //         K1 = -n*k*sin(n*phi + delta);
                }                                                    //       }
                else                                                 //       else {
                {
                    double diff = phi - delta;                       //         double diff = phi-delta;
                    if (diff < -Math.PI)
                    {
                        diff += 2.0 * Math.PI;                       //         if (diff < -M_PI) diff += 2.0*M_PI;
                    }
                    else if (diff > Math.PI)
                    {
                        diff -= 2.0 * Math.PI;                       //         else if (diff > M_PI) diff -= 2.0*M_PI;
                    }
                    K  = Kchi * diff * diff;                         //         K = k*diff*diff;
                    K1 = 2.0 * Kchi * diff;                          //         K1 = 2.0*k*diff;
                }                                                    //       }
                HDebug.Assert(double.IsNaN(K) == false, double.IsInfinity(K) == false);
                energy += K;                                         //       energy += K;
                ///////////////////////////////////////////////////////////////////////////////
                // force
                if (forces != null)
                {
                    Vector f1 = new double[3];                                                        //     Vector f1, f2, f3;
                    Vector f2 = new double[3];                                                        //
                    Vector f3 = new double[3];                                                        //
                    // forces                                                     //       // forces
                    if (Math.Abs(sin_phi) > 0.1)                                                      //       if (fabs(sin_phi) > 0.1) {
                    {
                        K1     = K1 / sin_phi;                                                        //         K1 = K1/sin_phi;
                        f1[0] += K1 * (r23[1] * dcosdA[2] - r23[2] * dcosdA[1]);                      //         f1.x += K1*(r23.y*dcosdA.z - r23.z*dcosdA.y);
                        f1[1] += K1 * (r23[2] * dcosdA[0] - r23[0] * dcosdA[2]);                      //         f1.y += K1*(r23.z*dcosdA.x - r23.x*dcosdA.z);
                        f1[2] += K1 * (r23[0] * dcosdA[1] - r23[1] * dcosdA[0]);                      //         f1.z += K1*(r23.x*dcosdA.y - r23.y*dcosdA.x);
                                                                                                      //
                        f3[0] += K1 * (r23[2] * dcosdB[1] - r23[1] * dcosdB[2]);                      //         f3.x += K1*(r23.z*dcosdB.y - r23.y*dcosdB.z);
                        f3[1] += K1 * (r23[0] * dcosdB[2] - r23[2] * dcosdB[0]);                      //         f3.y += K1*(r23.x*dcosdB.z - r23.z*dcosdB.x);
                        f3[2] += K1 * (r23[1] * dcosdB[0] - r23[0] * dcosdB[1]);                      //         f3.z += K1*(r23.y*dcosdB.x - r23.x*dcosdB.y);
                                                                                                      //
                        f2[0] += K1 * (r12[2] * dcosdA[1] - r12[1] * dcosdA[2]                        //         f2.x += K1*(r12.z*dcosdA.y - r12.y*dcosdA.z
                                       + r34[1] * dcosdB[2] - r34[2] * dcosdB[1]);                    //                  + r34.y*dcosdB.z - r34.z*dcosdB.y);
                        f2[1] += K1 * (r12[0] * dcosdA[2] - r12[2] * dcosdA[0]                        //         f2.y += K1*(r12.x*dcosdA.z - r12.z*dcosdA.x
                                       + r34[2] * dcosdB[0] - r34[0] * dcosdB[2]);                    //                  + r34.z*dcosdB.x - r34.x*dcosdB.z);
                        f2[2] += K1 * (r12[1] * dcosdA[0] - r12[0] * dcosdA[1]                        //         f2.z += K1*(r12.y*dcosdA.x - r12.x*dcosdA.y
                                       + r34[0] * dcosdB[1] - r34[1] * dcosdB[0]);                    //                  + r34.x*dcosdB.y - r34.y*dcosdB.x);
                    }                                                                                 //       }
                    else                                                                              //       else {
                    //  This angle is closer to 0 or 180 than it is to        //         //  This angle is closer to 0 or 180 than it is to
                    //  90, so use the cos version to avoid 1/sin terms       //         //  90, so use the cos version to avoid 1/sin terms
                    {
                        K1 = -K1 / cos_phi;                                                           //         K1 = -K1/cos_phi;
                                                                                                      //
                        f1[0] += K1 * ((r23[1] * r23[1] + r23[2] * r23[2]) * dsindC[0]                //         f1.x += K1*((r23.y*r23.y + r23.z*r23.z)*dsindC.x
                                       - r23[0] * r23[1] * dsindC[1]                                  //                 - r23.x*r23.y*dsindC.y
                                       - r23[0] * r23[2] * dsindC[2]);                                //                 - r23.x*r23.z*dsindC.z);
                        f1[1] += K1 * ((r23[2] * r23[2] + r23[0] * r23[0]) * dsindC[1]                //         f1.y += K1*((r23.z*r23.z + r23.x*r23.x)*dsindC.y
                                       - r23[1] * r23[2] * dsindC[2]                                  //                 - r23.y*r23.z*dsindC.z
                                       - r23[1] * r23[0] * dsindC[0]);                                //                 - r23.y*r23.x*dsindC.x);
                        f1[2] += K1 * ((r23[0] * r23[0] + r23[1] * r23[1]) * dsindC[2]                //         f1.z += K1*((r23.x*r23.x + r23.y*r23.y)*dsindC.z
                                       - r23[2] * r23[0] * dsindC[0]                                  //                 - r23.z*r23.x*dsindC.x
                                       - r23[2] * r23[1] * dsindC[1]);                                //                 - r23.z*r23.y*dsindC.y);
                                                                                                      //
                        f3 += K1 * LinAlg.CrossProd(dsindB, r23);                                     //         f3 += cross(K1,dsindB,r23);
                                                                                                      //
                        f2[0] += K1 * (-(r23[1] * r12[1] + r23[2] * r12[2]) * dsindC[0]               //         f2.x += K1*(-(r23.y*r12.y + r23.z*r12.z)*dsindC.x
                                       + (2.0 * r23[0] * r12[1] - r12[0] * r23[1]) * dsindC[1]        //                +(2.0*r23.x*r12.y - r12.x*r23.y)*dsindC.y
                                       + (2.0 * r23[0] * r12[2] - r12[0] * r23[2]) * dsindC[2]        //                +(2.0*r23.x*r12.z - r12.x*r23.z)*dsindC.z
                                       + dsindB[2] * r34[1] - dsindB[1] * r34[2]);                    //                +dsindB.z*r34.y - dsindB.y*r34.z);
                        f2[1] += K1 * (-(r23[2] * r12[2] + r23[0] * r12[0]) * dsindC[1]               //         f2.y += K1*(-(r23.z*r12.z + r23.x*r12.x)*dsindC.y
                                       + (2.0 * r23[1] * r12[2] - r12[1] * r23[2]) * dsindC[2]        //                +(2.0*r23.y*r12.z - r12.y*r23.z)*dsindC.z
                                       + (2.0 * r23[1] * r12[0] - r12[1] * r23[0]) * dsindC[0]        //                +(2.0*r23.y*r12.x - r12.y*r23.x)*dsindC.x
                                       + dsindB[0] * r34[2] - dsindB[2] * r34[0]);                    //                +dsindB.x*r34.z - dsindB.z*r34.x);
                        f2[2] += K1 * (-(r23[0] * r12[0] + r23[1] * r12[1]) * dsindC[2]               //         f2.z += K1*(-(r23.x*r12.x + r23.y*r12.y)*dsindC.z
                                       + (2.0 * r23[2] * r12[0] - r12[2] * r23[0]) * dsindC[0]        //                +(2.0*r23.z*r12.x - r12.z*r23.x)*dsindC.x
                                       + (2.0 * r23[2] * r12[1] - r12[2] * r23[1]) * dsindC[1]        //                +(2.0*r23.z*r12.y - r12.z*r23.y)*dsindC.y
                                       + dsindB[1] * r34[0] - dsindB[0] * r34[1]);                    //                +dsindB.y*r34.x - dsindB.x*r34.y);
                    }                                                                                 //       }
                    //}    // end loop over multiplicity                          //     }    // end loop over multiplicity
                    forces[0] += f1;                                                                  //     f[dihedral->atom1] += f1;
                    forces[1] += f2 - f1;                                                             //     f[dihedral->atom2] += f2-f1;
                    forces[2] += f3 - f2;                                                             //     f[dihedral->atom3] += f3-f2;
                    forces[3] += -f3;                                                                 //     f[dihedral->atom4] += -f3;
                }
                ///////////////////////////////////////////////////////////////////////////////
                // hessian
                if (hessian != null)
                {
                    //Debug.Assert(false);
                    double dcoord = 0.0001;
                    HDebug.Assert(hessian.GetLength(0) == 4, hessian.GetLength(1) == 4);
                    NumericSolver.Derivative2(ComputeFunc, coords, dcoord, ref hessian, Kchi, n, delta);
                }
            }
                public BaseObject Create()
                {
                    NumericSolver emptyInstance = new NumericSolver(CreatedWhenConstruct.CWC_NotToCreate);

                    return(emptyInstance);
                }
            public void Add3(int id0, int id1, int id2, int id3, Vector[] lcoords, Vector[] lforces)
            {
                if (forceij == null)
                {
                    return;
                }

                Vector ud01 = (lcoords[1] - lcoords[0]).UnitVector();
                Vector ud02 = (lcoords[2] - lcoords[0]).UnitVector();
                Vector ud03 = (lcoords[3] - lcoords[0]).UnitVector();
                Vector ud12 = (lcoords[2] - lcoords[1]).UnitVector();
                Vector ud13 = (lcoords[3] - lcoords[1]).UnitVector();
                Vector ud23 = (lcoords[3] - lcoords[2]).UnitVector();
                //     f01     f02      f03      f12      f13      f23
                // [ ud01_x,  ud02_x,  ud03_x,       0,       0,       0]   [f01]   [lf0x]
                // [-ud01_x,       0,       0,  ud12_x,  ud13_x,       0]   [f02]   [lf1x]
                // [      0, -ud02_x,       0, -ud12_x,       0,  ud23_x] * [f03] = [lf2x]
                // [      0,       0, -ud03_x,       0, -ud13_x, -ud23_x] * [f03] = [lf3x]
                //                                                          [f12]
                // [ ud01_y,  ud02_y,  ud03_y,       0,       0,       0]   [f13]   [lf0y]
                // [-ud01_y,       0,       0,  ud12_y,  ud13_y,       0]   [f23]   [lf1y]
                // [      0, -ud02_y,       0, -ud12_y,       0,  ud23_y]           [lf2y]
                // [      0,       0, -ud03_y,       0, -ud13_y, -ud23_y]           [lf3y]
                //
                // [ ud01_z,  ud02_z,  ud03_z,       0,       0,       0]           [lf0z]
                // [-ud01_z,       0,       0,  ud12_z,  ud13_z,       0]           [lf1z]
                // [      0, -ud02_z,       0, -ud12_z,       0,  ud23_z]           [lf2z]
                // [      0,       0, -ud03_z,       0, -ud13_z, -ud23_z]           [lf3z]
                /////////////////////////////////////////////////
                //    A                                                   *   x   =  b
                MatrixByArr A = new double[12, 6];
                Vector      b = new double[12];

                for (int i = 0; i < 3; i++)
                {
                    A[i + 3 * 0, 0] = ud01[i]; A[i + 3 * 0, 1] = ud02[i]; A[i + 3 * 0, 2] = ud03[i]; A[i + 3 * 0, 3] = 0; A[i + 3 * 0, 4] = 0; A[i + 3 * 0, 5] = 0; b[i + 3 * 0] = lforces[0][i];
                    A[i + 3 * 1, 0] = -ud01[i]; A[i + 3 * 1, 1] = 0; A[i + 3 * 1, 2] = 0; A[i + 3 * 1, 3] = ud12[i]; A[i + 3 * 1, 4] = ud13[i]; A[i + 3 * 1, 5] = 0; b[i + 3 * 1] = lforces[1][i];
                    A[i + 3 * 2, 0] = 0; A[i + 3 * 2, 1] = -ud02[i]; A[i + 3 * 2, 2] = 0; A[i + 3 * 2, 3] = -ud12[i]; A[i + 3 * 2, 4] = 0; A[i + 3 * 2, 5] = ud23[i]; b[i + 3 * 2] = lforces[2][i];
                    A[i + 3 * 3, 0] = 0; A[i + 3 * 3, 1] = 0; A[i + 3 * 3, 2] = -ud03[i]; A[i + 3 * 3, 3] = 0; A[i + 3 * 3, 4] = -ud13[i]; A[i + 3 * 3, 5] = -ud23[i]; b[i + 3 * 3] = lforces[3][i];
                }
                InfoPack extra = HDebug.IsDebuggerAttached ? new InfoPack() : null;
                Matrix   pinvA = NumericSolver.Pinv(A, extra);

                HDebug.Assert(extra.GetValueInt("rank") == 6);
                Vector x   = LinAlg.MV(pinvA, b);
                Vector f01 = ud01 * x[0];
                Vector f02 = ud02 * x[1];
                Vector f03 = ud03 * x[2];
                Vector f12 = ud12 * x[3];
                Vector f13 = ud13 * x[4];
                Vector f23 = ud23 * x[5];

                if (HDebug.IsDebuggerAttached)
                {
                    // check net force
                    Vector sumforces = lforces[0];
                    for (int i = 1; i < lforces.Length; i++)
                    {
                        sumforces += lforces[i];
                    }
                    HDebug.AssertTolerance(0.00000001, sumforces);

                    Vector f0 = f01 + f02 + f03;
                    Vector f1 = -f01 + f12 + f13;
                    Vector f2 = -f02 - f12 + f23;
                    Vector f3 = -f03 - f13 - f23;
                    HDebug.AssertTolerance(0.00000001, f0 - lforces[0]);
                    HDebug.AssertTolerance(0.00000001, f1 - lforces[1]);
                    HDebug.AssertTolerance(0.00000001, f2 - lforces[2]);
                    HDebug.AssertTolerance(0.00000001, f3 - lforces[3]);
                }
                this[id0, id1] += f01;    this[id0, id2] += f02;    this[id0, id3] += f03;    this[id1, id2] += f12;    this[id1, id3] += f13;    this[id2, id3] += f23;
                this[id1, id0] += -f01;    this[id2, id0] += -f02;    this[id3, id0] += -f03;    this[id2, id1] += -f12;    this[id3, id1] += -f13;    this[id3, id2] += -f23;
            }
            public void Add3(int id0, int id1, int id2, Vector[] lcoords, Vector[] lforces)
            {
                if (forceij == null)
                {
                    return;
                }

                Vector ud01 = (lcoords[1] - lcoords[0]).UnitVector();
                Vector ud12 = (lcoords[2] - lcoords[1]).UnitVector();
                Vector ud20 = (lcoords[0] - lcoords[2]).UnitVector();
                // [ ud01_x,       0, -ud20_x]   [f01]   [lf0x]
                // [-ud01_x,  ud12_x,       0]   [f12]   [lf1x]
                // [      0, -ud12_x,  ud20_x] * [f20] = [lf2x]
                //
                // [ ud01_y,       0, -ud20_y]           [lf0y]
                // [-ud01_y,  ud12_y,       0]           [lf1y]
                // [      0, -ud12_y,  ud20_y]           [lf2y]
                //
                // [ ud01_z,       0, -ud20_z]           [lf0z]
                // [-ud01_z,  ud12_z,       0]           [lf1z]
                // [      0, -ud12_z,  ud20_z]           [lf2z]
                /////////////////////////////////////////////////
                //    A                        *   x   =  b
                MatrixByArr A = new double[9, 3];
                Vector      b = new double[9];

                for (int i = 0; i < 3; i++)
                {
                    A[i + 3 * 0, 0] = ud01[i]; A[i + 3 * 0, 1] = 0; A[i + 3 * 0, 2] = -ud20[i]; b[i + 3 * 0] = lforces[0][i];
                    A[i + 3 * 1, 0] = -ud01[i]; A[i + 3 * 1, 1] = ud12[i]; A[i + 3 * 1, 2] = 0; b[i + 3 * 1] = lforces[1][i];
                    A[i + 3 * 2, 0] = 0; A[i + 3 * 2, 1] = -ud12[i]; A[i + 3 * 2, 2] = ud20[i]; b[i + 3 * 2] = lforces[2][i];
                }
                InfoPack extra = HDebug.IsDebuggerAttached ? new InfoPack() : null;
                Matrix   pinvA = NumericSolver.Pinv(A, extra);

                HDebug.Assert(extra.GetValueInt("rank") == 3);
                Vector x   = LinAlg.MV(pinvA, b);
                Vector f01 = ud01 * x[0];
                Vector f12 = ud12 * x[1];
                Vector f20 = ud20 * x[2];

                if (HDebug.IsDebuggerAttached)
                {
                    // check net force
                    Vector sumforces = lforces[0];
                    for (int i = 1; i < lforces.Length; i++)
                    {
                        sumforces += lforces[i];
                    }
                    HDebug.AssertTolerance(0.00000001, sumforces);

                    Vector f0 = f01 - f20;
                    Vector f1 = f12 - f01;
                    Vector f2 = -f12 + f20;
                    HDebug.AssertTolerance(0.00000001, f0 - lforces[0]);
                    HDebug.AssertTolerance(0.00000001, f1 - lforces[1]);
                    HDebug.AssertTolerance(0.00000001, f2 - lforces[2]);
                }
                this[id0, id1] += f01; this[id1, id2] += f12; this[id2, id0] += f20;
                this[id1, id0] += -f01; this[id2, id1] += -f12; this[id0, id2] += -f20;
            }
Beispiel #15
0
        public double CorrBFactor(IList <string> name, IList <int> resSeq, IList <double> BFactor, char selAltLoc = 'A', InfoPack extre = null, bool ignoreHydrogen = true)
        {
            List <double> bfactor_pdb   = new List <double>();
            List <double> bfactor_input = new List <double>();

            HDebug.Assert(name.Count == resSeq.Count);
            HDebug.Assert(name.Count == BFactor.Count);
            int count = name.Count;

            for (int i = 0; i < count; i++)
            {
                List <Atom> found = atoms.FindAtoms(name[i], resSeq[i]);
                if (found.Count == 0)
                {
                    continue;
                }

                int idx = -1;
                for (int j = 0; j < found.Count; j++)
                {
                    if (found[j].altLoc == ' ')
                    {
                        idx = j;
                    }
                }
                for (int j = 0; j < found.Count; j++)
                {
                    if (found[j].altLoc == selAltLoc)
                    {
                        idx = j;
                    }
                }

                HDebug.Assert(idx != -1); // only one atom should be found
                                          // handle altLoc later
                if (ignoreHydrogen)
                {
                    if (found[idx].IsHydrogen())
                    {
                        continue;
                    }
                }

                bfactor_pdb.Add(found[idx].tempFactor);
                bfactor_input.Add(BFactor[i]);
            }

            double corr = NumericSolver.Corr(bfactor_pdb.ToArray(), bfactor_input.ToArray());

            if (extre != null)
            {
                MatrixByArr A = new double[bfactor_input.Count, 2];
                for (int i = 0; i < bfactor_input.Count; i++)
                {
                    A[i, 0] = bfactor_input[i];
                    A[i, 1] = 1;
                }
                Vector b     = bfactor_pdb.ToArray();
                Matrix pinvA = NumericSolver.Pinv(A);
                Vector x     = LinAlg.MV(pinvA, b);

                extre["bfactor_pdb"]   = bfactor_pdb;
                extre["bfactor_input"] = bfactor_input;
                extre["info1"]         = "approx (bfactor_input * scale1 + shift1 = bfactor_pdb)";
                extre["scale1"]        = x[0];
                extre["shift1"]        = x[1];
                extre["info2"]         = "approx (bfactor_input * scale2 = bfactor_pdb)";
                extre["scale2"]        = LinAlg.VtV(bfactor_input.ToArray(), bfactor_pdb.ToArray())      // x = (A' * A)^-1 * (A' * b)  <= a,b: column vector
                                         / LinAlg.VtV(bfactor_input.ToArray(), bfactor_input.ToArray()); //     (a' * a) / (a' * a)     <= A  : matrix
            }
            return(corr);
        }
Beispiel #16
0
            public static void Compute(Vector[] coords, ref double energy, ref Vector[] forces, ref MatrixByArr[,] hessian,
                                       double Ktheta, double Theta0, double Kub, double S0, double[,] pwfrc = null, double[,] pwspr = null)
            {
                #region original source in mindy
                // double ComputeBonded::compute_angles(const Vector *coords, Vector *f) const {
                //   double energy = 0.0;
                //   AngleElem *angle = angles;
                //   for (int i=0; i<nangles; i++) {
                //     Vector f1, f2, f3;
                //     const Vector *pos1 = coords + angle->atom1;
                //     const Vector *pos2 = coords + angle->atom2;
                //     const Vector *pos3 = coords + angle->atom3;
                //     Vector r12 = *pos1 - *pos2;
                //     Vector r32 = *pos3 - *pos2;
                //     double d12 = r12.length();
                //     double d32 = r32.length();
                //     double cos_theta = (r12*r32)/(d12*d32);
                //     if (cos_theta > 1.0) cos_theta = 1.0;
                //     else if (cos_theta < -1.0) cos_theta = -1.0;
                //     double sin_theta = sqrt(1.0 - cos_theta * cos_theta);
                //     double theta = acos(cos_theta);
                //     double diff = theta-angle->theta0;
                //     energy += angle->k * diff * diff;
                //
                //     // forces
                //     double d12inv = 1.0/d12;
                //     double d32inv = 1.0/d32;
                //     diff *= (-2.0*angle->k) / sin_theta;
                //     double c1 = diff * d12inv;
                //     double c2 = diff * d32inv;
                //     Vector f12 = c1*(r12*(d12inv*cos_theta) - r32*d32inv);
                //     f1 = f12;
                //     Vector f32 = c2*(r32*(d32inv*cos_theta) - r12*d12inv);
                //     f3 = f32;
                //     f2 = -f12 - f32;
                //
                //     if (angle->k_ub > 0.0) {
                //       Vector r13 = r12 - r32;
                //       double d13 = r13.length();
                //       diff = d13 - angle->r_ub;
                //       energy += angle->k_ub * diff * diff;
                //
                //       // ub forces
                //       diff *= -2.0*angle->k_ub / d13;
                //       r13 *= diff;
                //       f1 += r13;
                //       f3 -= r13;
                //     }
                //     f[angle->atom1] += f1;
                //     f[angle->atom2] += f2;
                //     f[angle->atom3] += f3;
                //
                //     angle++;
                //   }
                //   return energy;
                // }
                #endregion

                ///////////////////////////////////////////////////////////////////////////////
                // energy
                Vector f1, f2, f3;
                Vector pos1      = coords[0];                               // const Vector *pos1 = coords + angle->atom1;
                Vector pos2      = coords[1];                               // const Vector *pos2 = coords + angle->atom2;
                Vector pos3      = coords[2];                               // const Vector *pos3 = coords + angle->atom3;
                Vector r12       = pos1 - pos2;                             // Vector r12 = *pos1 - *pos2;
                Vector r32       = pos3 - pos2;                             // Vector r32 = *pos3 - *pos2;
                Vector r13       = r12 - r32;                               // Vector r13 = r12 - r32;
                double d12       = r12.Dist;                                // double d12 = r12.length();
                double d32       = r32.Dist;                                // double d32 = r32.length();
                double d13       = r13.Dist;                                // double d13 = r13.length();
                double cos_theta = LinAlg.DotProd(r12, r32) / (d12 * d32);  // double cos_theta = (r12*r32)/(d12*d32);
                if (cos_theta > 1.0)
                {
                    cos_theta = 1.0;                                        // if (cos_theta > 1.0) cos_theta = 1.0;
                }
                else if (cos_theta < -1.0)
                {
                    cos_theta = -1.0;                                       // else if (cos_theta < -1.0) cos_theta = -1.0;
                }
                double sin_theta = Math.Sqrt(1.0 - cos_theta * cos_theta);  // double sin_theta = sqrt(1.0 - cos_theta * cos_theta);
                double theta     = Math.Acos(cos_theta);                    // double theta = acos(cos_theta);
                double diff      = theta - Theta0;                          // double diff = theta-angle->theta0;
                double diff_ub   = d13 - S0;                                // double diff_ub = d13 - angle->r_ub;
                HDebug.Assert(double.IsNaN(Ktheta * diff * diff) == false, double.IsInfinity(Ktheta * diff * diff) == false);
                energy += Ktheta * diff * diff;                             // energy += angle->k * diff * diff;
                if (Kub > 0.0)
                {                                                           //     if (angle->k_ub > 0.0) {
                    energy += Kub * diff_ub * diff_ub;                      //       energy += angle->k_ub * diff_ub * diff_ub;
                }                                                           //     }
                ///////////////////////////////////////////////////////////////////////////////
                // force
                //
                //
                // assume: * angle-change(p1,p2,p3) is close to zero
                //        -> angle-force(p1,p2,p3) is close to arc  p1-p3
                //        -> angle-force(p1,p2,p3) is close to line p1-q
                //        -> force magnitude p2-p1 = force p1-q / sin(p1,p2,p3)
                //           force magnitude p2-p3 = force p1-q / tan(p1,p2,p3)
                //        -> force p2->p1 = f21 = unitvec(p1-p2) * force p1-q / sin(p1,p2,p3)
                //           force p2->p3 = f23 = unitvec(p3-p2) * force p1-q / tan(p1,p2,p3)
                //        -> force p1     = f21
                //           force p3     = f23
                //           force p2     = -f21 + -f23
                //
                //           p1
                //         / |
                //       /   |
                //     /     |
                //  p2 ------+--p3
                //           q
                //
                if (forces != null)
                {
                    // forces                                               //     // forces
                    double d12inv = 1.0 / d12;                                     //     double d12inv = 1.0/d12;
                    double d32inv = 1.0 / d32;                                     //     double d32inv = 1.0/d32;
                    diff *= (-2.0 * Ktheta) / sin_theta;                           //     diff *= (-2.0*angle->k) / sin_theta;
                    double c1  = diff * d12inv;                                    //     double c1 = diff * d12inv;
                    double c2  = diff * d32inv;                                    //     double c2 = diff * d32inv;
                    Vector f12 = c1 * (r12 * (d12inv * cos_theta) - r32 * d32inv); //     Vector f12 = c1*(r12*(d12inv*cos_theta) - r32*d32inv);
                    f1 = f12;                                                      //     f1 = f12;
                    Vector f32 = c2 * (r32 * (d32inv * cos_theta) - r12 * d12inv); //     Vector f32 = c2*(r32*(d32inv*cos_theta) - r12*d12inv);
                    f3 = f32;                                                      //     f3 = f32;
                    f2 = -f12 - f32;                                               //     f2 = -f12 - f32;
                    //
                    if (Kub > 0.0)
                    {                                                       //     if (angle->k_ub > 0.0) {
                        // ub forces                                        //       // ub forces
                        double diff_ub_ = diff_ub * -2.0 * Kub / d13;       //       diff_ub *= -2.0*angle->k_ub / d13;
                        r13 *= diff_ub_;                                    //       r13 *= diff_ub;
                        f1  += r13;                                         //       f1 += r13;
                        f3  -= r13;                                         //       f3 -= r13;
                    }                                                       //     }
                    forces[0] += f1;                                        //     f[angle->atom1] += f1;
                    forces[1] += f2;                                        //     f[angle->atom2] += f2;
                    forces[2] += f3;                                        //     f[angle->atom3] += f3;
                }
                ///////////////////////////////////////////////////////////////////////////////
                // hessian
                if (hessian != null)
                {
                    //// !V(angle) = Ktheta(Theta - Theta0)**2
                    //Debug.Assert(false);
                    //// !V(Urey-Bradley) = Kub(S - S0)**2
                    //hessian[0, 2].Kij += 2 * Kub;
                    //hessian[0, 2].Fij += diff_ub * (2*Kub);
                    //hessian[2, 0].Kij += 2 * Kub;
                    //hessian[2, 0].Fij += diff_ub  * (2*Kub);

                    //Debug.Assert(false);
                    double dcoord = 0.0001;
                    HDebug.Assert(hessian.GetLength(0) == 3, hessian.GetLength(1) == 3);
                    NumericSolver.Derivative2(ComputeFunc, coords, dcoord, ref hessian, Ktheta, Theta0, Kub, S0);
                }
            }
Beispiel #17
0
            void Compute(Vector[] coords, ref double energy, ref Vector[] forces, ref MatrixByArr[,] hessian, double radij, double epsij, double[,] pwfrc = null, double[,] pwspr = null)
            {
                #region original source in mindy
                // if(dist > cut2) continue;
                //
                // double r = sqrt(dist);
                // double r_1 = 1.0/r;
                // double r_2 = r_1*r_1;
                // double r_6 = r_2*r_2*r_2;
                // double r_12 = r_6*r_6;
                // double switchVal = 1, dSwitchVal = 0;
                // if (dist > switch2) {
                //     double c2 = cut2 - dist;
                //     double c4 = c2*(cut2 + 2*dist - 3.0*switch2);
                //     switchVal = c2*c4*c1;
                //     dSwitchVal = c3*r*(c2*c2-c4);
                // }
                //
                // // get VDW constants
                // Index vdwtype2 = mol->atomvdwtype(ind2);
                // const LJTableEntry *entry;
                //
                // if (mol->check14excl(ind1,ind2))
                //     entry = ljTable->table_val_scaled14(vdwtype1, vdwtype2);
                // else
                //     entry = ljTable->table_val(vdwtype1, vdwtype2);
                // double vdwA = entry->A;
                // double vdwB = entry->B;
                // double AmBterm = (vdwA * r_6 - vdwB)*r_6;
                // Evdw += switchVal*AmBterm;
                // double force_r = ( switchVal * 6.0 * (vdwA*r_12 + AmBterm) *
                //                     r_1 - AmBterm*dSwitchVal )*r_1;
                //
                // // Electrostatics
                // double kqq = kq * mol->atomcharge(ind2);
                // double efac = 1.0-dist/cut2;
                // double prefac = kqq * r_1 * efac;
                // Eelec += prefac * efac;
                // force_r += prefac * r_1 * (r_1 + 3.0*r/cut2);
                //
                // tmpf -= force_r * dr;
                // nbrbox[j].force += force_r * dr;
                #endregion
                int idx1 = 0;
                int idx2 = 1;

                Vector diff = (coords[idx2] - coords[idx1]);

                double Evdw    = 0;
                double force_r = 0;

                double dist = diff.Dist2;

                if (dist > cut2)
                {
                    return;                                                        // if(dist > cut2) continue;
                }
                //                                                                 //
                double r = Math.Sqrt(dist);                                        // double r = sqrt(dist);
                double r_1 = 1.0 / r;                                              // double r_1 = 1.0/r;
                double r_2 = r_1 * r_1;                                            // double r_2 = r_1*r_1;
                double r_6 = r_2 * r_2 * r_2;                                      // double r_6 = r_2*r_2*r_2;
                double r_12 = r_6 * r_6;                                           // double r_12 = r_6*r_6;
                double switchVal = 1, dSwitchVal = 0;                              // double switchVal = 1, dSwitchVal = 0;
                if (dist > switch2)                                                // if (dist > switch2) {
                {
                    double c2 = cut2 - dist;                                       //     double c2 = cut2 - dist;
                    double c4 = c2 * (cut2 + 2 * dist - 3.0 * switch2);            //     double c4 = c2*(cut2 + 2*dist - 3.0*switch2);
                    switchVal  = c2 * c4 * c1;                                     //     switchVal = c2*c4*c1;
                    dSwitchVal = c3 * r * (c2 * c2 - c4);                          //     dSwitchVal = c3*r*(c2*c2-c4);
                }                                                                  // }
                //                                                                 //
                // get VDW constants                                               // // get VDW constants
                // Index vdwtype2 = mol->atomvdwtype(ind2);                        // Index vdwtype2 = mol->atomvdwtype(ind2);
                // const LJTableEntry *entry;                                      // const LJTableEntry *entry;
                //                                                                 //
                // if (mol->check14excl(ind1,ind2))                                // if (mol->check14excl(ind1,ind2))
                //     entry = ljTable->table_val_scaled14(vdwtype1, vdwtype2);    //     entry = ljTable->table_val_scaled14(vdwtype1, vdwtype2);
                // else                                                            // else
                //     entry = ljTable->table_val(vdwtype1, vdwtype2);             //     entry = ljTable->table_val(vdwtype1, vdwtype2);
                double vdwA    = 4 * epsij * Math.Pow(radij, 12);                  // double vdwA = entry->A;
                double vdwB    = 4 * epsij * Math.Pow(radij, 6);                   // double vdwB = entry->B;
                double AmBterm = (vdwA * r_6 - vdwB) * r_6;                        // double AmBterm = (vdwA * r_6 - vdwB)*r_6;
                Evdw    += switchVal * AmBterm;                                    // Evdw += switchVal*AmBterm;
                force_r += (switchVal * 6.0 * (vdwA * r_12 + AmBterm) *            // double force_r = ( switchVal * 6.0 * (vdwA*r_12 + AmBterm) *
                            r_1 - AmBterm * dSwitchVal) * r_1;                     //                     r_1 - AmBterm*dSwitchVal )*r_1;
                                                                                   //
                // // Electrostatics                                               // // Electrostatics
                // double kqq = kq * mol->atomcharge(ind2);                        // double kqq = kq * mol->atomcharge(ind2);
                // double efac = 1.0-dist/cut2;                                    // double efac = 1.0-dist/cut2;
                // double prefac = kqq * r_1 * efac;                               // double prefac = kqq * r_1 * efac;
                // Eelec += prefac * efac;                                         // Eelec += prefac * efac;
                // force_r += prefac * r_1 * (r_1 + 3.0*r/cut2);                   // force_r += prefac * r_1 * (r_1 + 3.0*r/cut2);

                HDebug.Assert(double.IsNaN(Evdw) == false, double.IsInfinity(Evdw) == false);
                energy += Evdw;
//System.Console.Write("" + Math.Min(idx1,idx2) + ", " + Math.Max(idx1,idx2) + " - vdw(" + Evdw + "), ");
                ///////////////////////////////////////////////////////////////////////////////
                // force
                if (forces != null)
                {
                    Vector force = diff * force_r;                                      // Vector tmppos = tmpbox[i].pos;
                                                                                        // Vector dr = nbrbox[j].pos - tmppos;
                    forces[idx1] -= force;                                              // tmpf -= force_r * dr;
                    forces[idx2] += force;                                              // nbrbox[j].force += force_r * dr;
                }
                ///////////////////////////////////////////////////////////////////////////////
                // hessian
                if (hessian != null)
                {
                    //Debug.Assert(false);
                    double dcoord = 0.0001;
                    HDebug.Assert(hessian.GetLength(0) == 2, hessian.GetLength(1) == 2);
                    NumericSolver.Derivative2(ComputeFunc, coords, dcoord, ref hessian, radij, epsij);
                }
            }