/// <summary> /// //gives R, the rotation matrix, U - the left eigenvectors, VT - right transposed eigenvectors, EV - the eigenvalues /// </summary> /// <param name="H"></param> public static void Eigenvalues_Helper_Alglib(Matrix3d H) { double[,] Harray = H.ToDoubleArray(); double[,] Uarray = new double[3, 3]; double[,] VTarray = new double[3, 3]; double[] EVarray = new double[3]; alglib.svd.rmatrixsvd(Harray, 3, 3, 2, 2, 2, ref EVarray, ref Uarray, ref VTarray); U = U.FromDoubleArray(Uarray); VT = VT.FromDoubleArray(VTarray); EV = EV.FromDoubleArray(EVarray); R = Matrix3d.Mult(U, VT); }
///<summary> Return triangular factor</summary> ///<returns>L</returns> public Matrix3d getL() { Matrix3d mat = new Matrix3d(); mat = mat.FromDoubleArray(L); return(mat); }
/// <summary> /// parses a string to produce a matrix /// </summary> /// <param name="str">The string to parse</param> /// <param name="matrixFrontCap">placed at the beginning of the string</param> /// <param name="rowFrontCap">placed at the beginning of each row</param> /// <param name="rowDelimiter">delimiter for rows</param> /// <param name="columnDelimiter">delimiter for Columns</param> /// <param name="rowEndCap">placed at the end of each row</param> /// <param name="matrixEndCap">placed at the beginning of the string</param> /// <returns></returns> public static Matrix3d Parse(this Matrix3d mat, string str, string matrixFrontCap, string rowFrontCap, string rowDelimiter, string columnDelimiter, string rowEndCap, string matrixEndCap) { if (!str.StartsWith(matrixFrontCap)) { throw new Exception("string does not begin with proper value: " + matrixFrontCap + " was expected, but " + str.Substring(0, matrixFrontCap.Length) + " was found."); } if (!str.StartsWith(matrixFrontCap)) { throw new Exception("string does not end with proper value: " + matrixEndCap + " was expected, but " + str.Substring(str.Length - matrixEndCap.Length, matrixEndCap.Length) + " was found."); } string working = str.Substring(matrixFrontCap.Length, str.Length - matrixFrontCap.Length - matrixEndCap.Length); string[] rDelim = { rowEndCap + rowDelimiter + rowFrontCap }; string[] rows = working.Split(rDelim, StringSplitOptions.RemoveEmptyEntries); if (rows.Length == 0) { throw new Exception("No rows present"); } rows[0] = rows[0].Substring(rowFrontCap.Length); rows[rows.Length - 1] = rows[rows.Length - 1].Substring(0, rows[rows.Length - 1].Length - rowEndCap.Length); double[,] matrixArray = new double[rows.Length, rows.Length]; int columnCount = 0; for (int iRow = 0; iRow < rows.Length; iRow++) { string[] cols = rows[iRow].Split(new string[] { columnDelimiter }, StringSplitOptions.RemoveEmptyEntries); if (columnCount != 0) { if (columnCount != cols.Length) { throw new Exception("Rows are not of consistant lenght"); } } else { columnCount = cols.Length; } double[] row = new double[columnCount]; for (int iCol = 0; iCol < columnCount; iCol++) { row[iCol] = double.Parse(cols[iCol]); } for (int i = 0; i < cols.Length; i++) { matrixArray[iRow, i] = row[i]; } } mat = mat.FromDoubleArray(matrixArray); return(mat); }
///<Sumary>Least squares solution of A*X = B</Sumary> ///<param name="B">A Matrix with as many rows as A and any number of columns.</param> ///<returns> X that minimizes the two norm of Q*R*X-B.</returns> public Matrix3d Solve(Matrix3d B) { if (B.RowLength() != m) { throw new ArgumentException("Matrix row dimensions must agree."); } if (!IsFullRank()) { throw new Exception("Matrix is rank deficient."); } // Copy right hand side int nx = B.ColumnLength(); double[,] X = B.ToArray(); // Compute Y = transpose(Q)*B for (int k = 0; k < n; k++) { for (int j = 0; j < nx; j++) { double s = 0.0f; for (int i = k; i < m; i++) { s += QR[i, k] * X[i, j]; } s = -s / QR[k, k]; for (int i = k; i < m; i++) { X[i, j] += s * QR[i, k]; } } } // Solve R*X = Y; for (int k = n - 1; k >= 0; k--) { for (int j = 0; j < nx; j++) { X[k, j] /= Rdiag[k]; } for (int i = 0; i < k; i++) { for (int j = 0; j < nx; j++) { X[i, j] -= X[k, j] * QR[i, k]; } } } Matrix3d mat = new Matrix3d(); mat = mat.FromDoubleArray(X); return(mat.GetMatrix(0, n - 1, 0, nx - 1)); }
public static Matrix3d FromDataTable(this Matrix3d mat, DataTable dt) { double[,] X = new double[dt.Rows.Count, dt.Columns.Count]; for (int iRow = 0; iRow < dt.Rows.Count; iRow++) { double[] row = new double[dt.Columns.Count]; for (int iCol = 0; iCol < dt.Columns.Count; iCol++) { X[iRow, iCol] = (double)dt.Rows[iRow][iCol]; } } mat = mat.FromDoubleArray(X); return(mat); }
///<summary>Solve A*X = B</summary> ///<param name="B">A Matrix with as many rows as A and any number of columns.</param> ///<returns>X so that L*L'*X = B</returns> ///<exception cref="ArgumentException">System.ArgumentException Matrix row dimensions must agree.</exception> ///<exception cref="Exception">System.Exception Matrix is not symmetric positive definite.</exception> public Matrix3d Solve(Matrix3d B) { if (B.RowLength() != n) { throw new ArgumentException("Matrix row dimensions must agree."); } if (!isspd) { throw new Exception("Matrix is not symmetric positive definite."); } // Copy right hand side. double[,] X = B.ToArray(); int nx = B.ColumnLength(); // Solve L*Y = B; for (int k = 0; k < n; k++) { for (int j = 0; j < nx; j++) { for (int i = 0; i < k; i++) { X[k, j] -= X[i, j] * L[k, i]; } X[k, j] /= L[k, k]; } } // Solve L'*X = Y; for (int k = n - 1; k >= 0; k--) { for (int j = 0; j < nx; j++) { for (int i = k + 1; i < n; i++) { X[k, j] -= X[i, j] * L[i, k]; } X[k, j] /= L[k, k]; } } Matrix3d mat = new Matrix3d(); mat = mat.FromDoubleArray(X); return(mat); }
/// <summary> /// //gives R, the rotation matrix, U - the left eigenvectors, VT - right transposed eigenvectors, EV - the eigenvalues /// </summary> /// <param name="H"></param> public static void Eigenvalues_Helper_VTK(Matrix3d H) { double[,] Harray = H.ToDoubleArray(); double[,] Uarray = new double[3, 3]; double[,] VTarray = new double[3, 3]; double[] EVarray = new double[3]; //alglib.svd.rmatrixsvd(Harray, 3, 3, 2, 2, 2, ref EVarray, ref Uarray, ref VTarray); csharpMath.SingularValueDecomposition3x3(Harray, Uarray, EVarray, VTarray); //U = new Matrix3d(); U = U.FromDoubleArray(Uarray); U = U.FromDoubleArray(Uarray); VT = VT.FromDoubleArray(VTarray); EV = EV.FromDoubleArray(EVarray); R = Matrix3d.Mult(U, VT); }
public Matrix3d LUDecompose(Matrix3d A) { // Use a "left-looking", dot-product, Crout/Doolittle algorithm. LU = A.ToArray(); m = A.RowLength(); n = A.ColumnLength(); piv = new int[m]; for (int i = 0; i < m; i++) { piv[i] = i; } pivsign = 1; //double[] LUrowi; //double[] LUcolj = new double[m]; // Outer loop. for (int j = 0; j < n; j++) { // Make a copy of the j-th column to localize references. //for (int i = 0; i < m; i++) //{ // LUcolj[i] = LU[i,j]; //} // Apply previous transformations. for (int i = 0; i < m; i++) { // Most of the time is spent in the following dot product. int kmax = Math.Min(i, j); double s = 0.0f; for (int k = 0; k < kmax; k++) { s += LU[i, k] * LU[k, i]; } LU[j, i] = LU[i, j] -= s; } // Find pivot and exchange if necessary. int p = j; for (int i = j + 1; i < m; i++) { if (Math.Abs(LU[i, j]) > Math.Abs(LU[p, j])) { p = i; } } if (p != j) { for (int k = 0; k < n; k++) { double t = LU[p, k]; LU[p, k] = LU[j, k]; LU[j, k] = t; } int k2 = piv[p]; piv[p] = piv[j]; piv[j] = k2; pivsign = -pivsign; } // Compute multipliers. if (j < m && LU[j, j] != 0) { for (int i = j + 1; i < m; i++) { LU[i, j] /= LU[j, j]; } } } Matrix3d mat = new Matrix3d(); mat = mat.FromDoubleArray(LU); return(mat); }