예제 #1
0
        public Matrix <double> SingulerValueDecomposition(Matrix <double> A, Matrix <double> b)
        {
            /*
             * Svd<double> svd = A.Svd(true);
             * double ConditionMumber = svd.ConditionNumber;
             * Debug.WriteLine("Cond: {0}", svd.ConditionNumber);
             *
             * if((svd.ConditionNumber == double.PositiveInfinity) || (svd.ConditionNumber == double.NegativeInfinity)) {
             *      Debug.WriteLine("Condition number is infinity");
             *      return null;
             * }
             *
             * // get matrix of left singular vectors with first n columns of U
             * Matrix<double> U1 = svd.U.SubMatrix(0, A.RowCount, 0, A.ColumnCount);
             *
             * // get matrix of singular values
             * Matrix<double> S = new DiagonalMatrix(A.ColumnCount, A.ColumnCount, svd.S.ToArray());
             *
             * // get matrix of right singular vectors
             * Matrix<double> V = svd.VT.Transpose();
             *
             * return V.Multiply(S.Inverse()).Multiply(U1.Transpose().Multiply(b));
             */

            Svd <double> svd             = A.Svd(true);
            double       ConditionMumber = svd.ConditionNumber;

            Debug.WriteLine("Rank, Det, Cond: {0},{1},{2}", svd.Rank, svd.Determinant, svd.ConditionNumber);


            if ((svd.ConditionNumber == double.PositiveInfinity) || (svd.ConditionNumber == double.NegativeInfinity))
            {
                Debug.WriteLine("Condition number is infinity");
                return(null);
            }

            return(svd.Solve(b));
        }
예제 #2
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="stiffnessMatrix"></param>
 /// <param name="forceVector"></param>
 /// <returns></returns>
 protected override KeyedVector<NodalDegreeOfFreedom> Solve(StiffnessMatrix stiffnessMatrix, KeyedVector<NodalDegreeOfFreedom> forceVector)
 {
     Svd<NodalDegreeOfFreedom, NodalDegreeOfFreedom> svd = new Svd<NodalDegreeOfFreedom, NodalDegreeOfFreedom>(stiffnessMatrix, true);
     return svd.Solve(forceVector);
 }
예제 #3
0
        private static void FindFit(X[] x, double[] y, double[] sig, int cFuncs, BasisFuncs funcs, out double[] coeff, out double[,] u, out double[,] v, out double[] w, out double chiSq)
        {
            int cData = x.Length;


            // - evaluate basis functions over domain set (x)
            // - scale the basis by the significance

            u = new double[cData, cFuncs];
            double[] b     = new double[cData];
            double[] funcY = new double[cFuncs];
            for (int i = 0; i < cData; i++)
            {
                funcs(x[i], funcY, cFuncs);
                double sigInv = 1 / sig[i];
                for (int j = 0; j < cFuncs; j++)
                {
                    u[i, j] = funcY[j] * sigInv;
                }
                b[i] = y[i] * sigInv;
            }


            // singular value decomposition

            Matrix <double> U = Matrix <double> .Build.DenseOfArray(u);

            Svd <double> SVD = U.Svd();

            w = SVD.S.ToArray();
            Debug.Assert((SVD.VT.RowCount == cFuncs) && (SVD.VT.ColumnCount == cFuncs));
            v = SVD.VT.Transpose().ToArray();
            // Math.Net computes full mxm U matrix but we're using only the first n columns. (like LAPACK DGESVD() with JOBU='O')
            for (int i = 0; i < cData; i++)
            {
                for (int j = 0; j < cFuncs; j++)
                {
                    u[i, j] = SVD.U.At(i, j);
                }
            }


            // zero out insignificant values

            double wMax = 0;

            for (int j = 0; j < cFuncs; j++)
            {
                wMax = Math.Max(wMax, w[j]);
            }
            const double Tolerance = 1e-5;
            double       cutoff    = Tolerance * wMax;

            for (int j = 0; j < cFuncs; j++)
            {
                if (w[j] < cutoff)
                {
                    w[j] = 0;
                }
            }


            // solve for coefficients (uses backsubstitution)

            Vector <double> X = SVD.Solve(Vector <double> .Build.DenseOfArray(b));

            coeff = X.ToArray();


            // compute quality of fit

            chiSq = 0;
            for (int i = 0; i < cData; i++)
            {
                funcs(x[i], funcY, cFuncs);
                double sum = 0;
                for (int j = 0; j < cFuncs; j++)
                {
                    sum += coeff[j] * funcY[j];
                }
                double diff = (y[i] - sum) / sig[i];
                chiSq += diff * diff;
            }
        }
예제 #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="stiffnessMatrix"></param>
        /// <param name="forceVector"></param>
        /// <returns></returns>
        protected override KeyedVector <NodalDegreeOfFreedom> Solve(StiffnessMatrix stiffnessMatrix, KeyedVector <NodalDegreeOfFreedom> forceVector)
        {
            Svd <NodalDegreeOfFreedom, NodalDegreeOfFreedom> svd = new Svd <NodalDegreeOfFreedom, NodalDegreeOfFreedom>(stiffnessMatrix, true);

            return(svd.Solve(forceVector));
        }