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)); }
/// <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); }
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; } }
/// <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)); }