Beispiel #1
0
 public static decimal[] LinearLeastSquares(decimal[,] A, decimal[] r)
 {
     decimal[,] B = MathDecimal.Prod(MathDecimal.Transpose(A), A);
     decimal[] y   = MathDecimal.Prod(MathDecimal.Transpose(A), r);
     decimal[] res = LinearAlgebra.Gauss(B, y);
     return(res);
 }
Beispiel #2
0
        public static decimal[] LinearLeastSquares(decimal[,] A, decimal[] b, String method = "SVD")
        {
            decimal[] res = new decimal[A.GetLength(1)];

            if (method == "Gauss")
            {
                decimal[,] B = MathDecimal.Prod(MathDecimal.Transpose(A), A);
                decimal[] y = MathDecimal.Prod(MathDecimal.Transpose(A), b);
                res = LinearAlgebra.Gauss(B, y);
            }
            else if (method == "LUDecomposition")
            {
                List <decimal[, ]> LU = LinearAlgebra.LUDecomposition(A);// L, U, PI1, Pi2;
                //Solve system Ly=b1, where b1=PI1*b
                //L^T*L*y=L^T*b1
                // M=L^T * L , N=L^T*PI1*b
                decimal[,] M = MathDecimal.Prod(MathDecimal.Transpose(LU[0]), LU[0]);
                decimal[] N = MathDecimal.Prod(MathDecimal.Transpose(LU[0]), MathDecimal.Prod(LU[2], b));
                decimal[] y = LinearAlgebra.Gauss(M, N);

                //Solve system y=U*x1=U*PI2^T*x
                res = MathDecimal.Prod(LU[3], LinearAlgebra.BackwardSubstitutionUpp(LU[1], y));
            }
            else if (method == "SVD")
            {
                double[,] ADouble = new double[A.GetLength(0), A.GetLength(1)];
                for (int i = 0; i < A.GetLength(0); i++)
                {
                    for (int j = 0; j < A.GetLength(1); j++)
                    {
                        ADouble[i, j] = (double)A[i, j];
                    }
                }

                Matrix <double> JMatrix = DenseMatrix.OfArray(ADouble);
                MathNet.Numerics.LinearAlgebra.Factorization.Svd <double> Jsvd = JMatrix.Svd();

                double[,] LDouble  = Jsvd.W.ToArray();
                double[,] UDouble  = Jsvd.U.ToArray();
                double[,] VtDouble = Jsvd.VT.ToArray();

                decimal[,] L  = new decimal[A.GetLength(0), A.GetLength(1)];
                decimal[,] U  = new decimal[A.GetLength(0), A.GetLength(0)];
                decimal[,] Vt = new decimal[A.GetLength(1), A.GetLength(1)];

                for (int i = 0; i < A.GetLength(0); i++)
                {
                    for (int j = 0; j < A.GetLength(1); j++)
                    {
                        L[i, j] = (decimal)LDouble[i, j];
                    }
                }

                for (int i = 0; i < A.GetLength(0); i++)
                {
                    for (int j = 0; j < A.GetLength(0); j++)
                    {
                        U[i, j] = (decimal)UDouble[i, j];
                    }
                }

                for (int i = 0; i < A.GetLength(1); i++)
                {
                    for (int j = 0; j < A.GetLength(1); j++)
                    {
                        Vt[i, j] = (decimal)VtDouble[i, j];
                    }
                }

                for (int i = 0; i < L.GetLength(1); i++)
                {
                    if (L[i, i] < 0.0000000000001M && L[i, i] > -0.0000000000001M)
                    {
                        L[i, i] = 0;
                    }
                    else
                    {
                        L[i, i] = 1 / L[i, i];
                    }
                }

                res = MathDecimal.Prod(MathDecimal.Transpose(Vt), MathDecimal.Prod(MathDecimal.Transpose(L), MathDecimal.Prod(MathDecimal.Transpose(U), b)));
            }

            return(res);
        }