/// <summary> /// 获取指定参数的矩阵 /// </summary> /// <param name="rowNames">行参数列表</param> /// <param name="colNames">列参数列表</param> /// <returns></returns> public IMatrix GetMatrix(List <String> rowNames, List <String> colNames) { IMatrix newVector = new ArrayMatrix(rowNames.Count, rowNames.Count); newVector.RowNames = rowNames; newVector.ColNames = colNames; int i = 0; foreach (var row in rowNames) { if (!this.ContainsRowName(row)) { continue; } foreach (var col in colNames) { if (!this.ContainsColName(col)) { continue; } newVector[row, col] = this[row, col]; } i++; } return(newVector); }
/// <summary>Returns a sub matrix extracted from the current matrix.</summary> /// <param name="i0">Starttial row index</param> /// <param name="i1">End row index</param> /// <param name="c">Array of row indices</param> public ArrayMatrix Submatrix(int i0, int i1, int[] c) { if ((i0 > i1) || (i0 < 0) || (i0 >= this.rows) || (i1 < 0) || (i1 >= this.rows)) { throw new ArgumentException(); } ArrayMatrix X = new ArrayMatrix(i1 - i0 + 1, c.Length); double[][] x = X.Array; for (int i = i0; i <= i1; i++) { for (int j = 0; j < c.Length; j++) { if ((c[j] < 0) || (c[j] >= columns)) { throw new ArgumentException(); } x[i - i0][j] = data[i][c[j]]; } } return(X); }
/// <summary>Returns a sub matrix extracted from the current matrix.</summary> /// <param name="i0">Start row index</param> /// <param name="i1">End row index</param> /// <param name="j0">Start column index</param> /// <param name="j1">End column index</param> public ArrayMatrix Submatrix(int i0, int i1, int j0, int j1) { if ((i0 > i1) || (j0 > j1) || (i0 < 0) || (i0 >= this.rows) || (i1 < 0) || (i1 >= this.rows) || (j0 < 0) || (j0 >= this.columns) || (j1 < 0) || (j1 >= this.columns)) { throw new ArgumentException(); } ArrayMatrix X = new ArrayMatrix(i1 - i0 + 1, j1 - j0 + 1); double[][] x = X.Array; for (int i = i0; i <= i1; i++) { for (int j = j0; j <= j1; j++) { x[i - i0][j - j0] = data[i][j]; } } if (this.ColNames != null && this.ColNames.Count > 0) { X.ColNames = this.ColNames.GetRange(i0, i1 - i0 + 1); } if (this.RowNames != null && this.RowNames.Count > 0) { X.RowNames = this.RowNames.GetRange(j0, j1 - j0 + 1); } return(X); }
/// <summary> /// collexts integer vectors and corresponding squared distances /// </summary> /// <param name="MaxCan">number of minimum integer vectors required</param> /// <param name="D">diagonal matrix</param> /// <param name="Chic">Chi squared</param> /// <param name="cands">2-dimensional array to store the candidates</param> /// <param name="disal1">according squared norms \hat{a}-\check{a}</param> /// <param name="tmax">the largest distance of the Min(ncan, MaxCan) vectors with minimum distance found until now</param> /// <param name="imax">position in disall/cands of the vector with the largest distance of the Min (ncan, MaxCan) vectors with minimum distance found until now</param> /// <param name="right">vector</param> /// <param name="left">vector</param> /// <param name="ncan">number of integer vectors found</param> /// <param name="lef">vector</param> /// <param name="dist">difference between the integer tried and \hat{a}_n</param> /// <param name="endd">vector</param> private void Collects(int MaxCan, double[] D, double Chic, ArrayMatrix cands, ArrayMatrix disal1, ref double tmax, ref int imax, double[] right, double[] left, ref int ncan, double[] lef, double[] dist, double[] endd) { double t = Chic - (right[0] - left[0]) * D[0]; endd[0] = endd[0] + 1; //The following loop should be run through at least once while (dist[0] <= endd[0]) { ncan = ncan + 1; if (ncan <= MaxCan) { // Stores(ncan, ncan, t, cands, disal1, ref tmax, ref imax, dist); } else { if (t < tmax) { Stores(MaxCan, imax, t, cands, disal1, ref tmax, ref imax, dist); } } t = t + (2 * (dist[0] + lef[0]) + 1) * D[0]; dist[0] = dist[0] + 1; } }
/// <summary> /// factorization of Q into L^T D L /// </summary> /// <param name="D"></param> /// <param name="L"></param> private bool LTDL(double[] D, ArrayMatrix L) { for (int i = NumberOfFloatParam - 1; i >= 0; i--) { D[i] = Q[i, i]; if (Q[i, i] <= 0.0) { return(false); } for (int j = 0; j <= i; j++) { L[i, j] = Q[i, j] / Math.Sqrt(Q[i, i]); } for (int j = 0; j <= i - 1; j++) { for (int k = 0; k <= j; k++) { Q[j, k] = Q[j, k] - L[i, k] * L[i, j]; } } for (int j = 0; j <= i; j++) { L[i, j] = L[i, j] / L[i, i]; } } return(true); }
/// <summary>Returns a sub matrix extracted from the current matrix.</summary> /// <param name="r">Array of row indices</param> /// <param name="j0">Start column index</param> /// <param name="j1">End column index</param> public ArrayMatrix Submatrix(int[] r, int j0, int j1) { if ((j0 > j1) || (j0 < 0) || (j0 >= columns) || (j1 < 0) || (j1 >= columns)) { throw new ArgumentException(); } ArrayMatrix X = new ArrayMatrix(r.Length, j1 - j0 + 1); double[][] x = X.Array; for (int i = 0; i < r.Length; i++) { for (int j = j0; j <= j1; j++) { if ((r[i] < 0) || (r[i] >= this.rows)) { throw new ArgumentException(); } x[i][j - j0] = data[r[i]][j]; } } return(X); }
/// <summary> /// 对称阵相乘,不再是对称阵? /// </summary> /// <param name="left"></param> /// <param name="right"></param> /// <returns></returns> public static ArrayMatrix operator *(SymmetricMatrix left, SymmetricMatrix right) { //是否有更简便的方法??? ArrayMatrix mleft = new ArrayMatrix(left.Array); ArrayMatrix mright = new ArrayMatrix(right.Array); var result = mleft * mright; return(result); }
/// <summary>Least squares solution of <c>A * X = B</c></summary> /// <param name="rhs">Right-hand-side matrix with as many rows as <c>A</c> and any number of columns.</param> /// <returns>A matrix that minimized the two norm of <c>Q * R * X - B</c>.</returns> /// <exception cref="T:System.ArgumentException">Matrix row dimensions must be the same.</exception> /// <exception cref="T:System.InvalidOperationException">Matrix is rank deficient.</exception> public ArrayMatrix Solve(ArrayMatrix rhs) { if (rhs.RowCount != QR.RowCount) { throw new ArgumentException("Matrix row dimensions must agree."); } if (!IsFullRank) { throw new InvalidOperationException("Matrix is rank deficient."); } // Copy right hand side int count = rhs.Columns; ArrayMatrix X = (ArrayMatrix)rhs.Clone(); int m = QR.RowCount; int n = QR.Columns; double[][] qr = QR.Array; // Compute Y = transpose(Q)*B for (int k = 0; k < n; k++) { for (int j = 0; j < count; j++) { double s = 0.0; 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 < count; j++) { X[k, j] /= Rdiag[k]; } for (int i = 0; i < k; i++) { for (int j = 0; j < count; j++) { X[i, j] -= X[k, j] * qr[i][k]; } } } return(X.Submatrix(0, n - 1, 0, count - 1)); }
/// <summary> /// 返回新的乘法结果。 /// </summary> /// <param name="right"></param> /// <returns></returns> public IMatrix Multiply(VectorMatrix right) { int row = this.RowCount; int col = this.ColCount; IMatrix matrix = new ArrayMatrix(row, 1); for (int i = 0; i < row; i++) { matrix[i, 0] = this[i, i] * right[i, 0]; } return(matrix); }
//先将流解压缩为char[],再反序列化为string,再转为matrix public ArrayMatrix EecompressToMatrix(byte[] inBytes) { //解压缩 byte[] writeData = new byte[2048];//[4096] MemoryStream inStream = new MemoryStream(inBytes); GZipStream zipStream = new GZipStream(inStream, CompressionMode.Decompress); MemoryStream outStream = new MemoryStream(); while (true) { int size = zipStream.Read(writeData, 0, writeData.Length); if (size > 0) { outStream.Write(writeData, 0, size); } else { break; } } inStream.Close(); byte[] outData = outStream.ToArray(); zipStream.Close(); outStream.Close(); //byte to string string str = System.Text.Encoding.ASCII.GetString(outData, 0, outData.Length); string[] words = str.Split(' '); //根据规则,给矩阵赋值 int arows = Convert.ToInt32(words[0]); int columns = Convert.ToInt32(words[1]); ArrayMatrix outMatrix = new ArrayMatrix(arows, columns); int lengths = words.Length; if ((lengths - 3) >= 3 && (Math.IEEERemainder((lengths - 3), 3) != 0)) { throw new Exception("应该是3的倍数!"); } int tu = (int)((lengths - 3) / 3); for (int i = 0; i < tu; i++) { int ii = Convert.ToInt32(words[1 + i * 3 + 1]); int jj = Convert.ToInt32(words[1 + i * 3 + 2]); double s_value = Convert.ToDouble(words[1 + i * 3 + 3]); outMatrix[ii, jj] = s_value; } return(outMatrix); // }
/* * /// <summary>Adds a matrix to the current matrix.</summary> * public void Add(Matrix A) * { * if ((rows != A.Rows) || (columns != A.Columns)) throw new ArgumentException(); * double[][] a = A.Array; * for (int i = 0; i < rows; i++) * for (int j = 0; j < columns; j++) * data[i][j] += a[i][j]; * } * * /// <summary>Subtracts a matrix from the current matrix.</summary> * public void Sub(Matrix A) * { * if ((rows != A.Rows) || (this.columns != A.Columns)) throw new ArgumentException(); * double[][] a = A.Array; * for (int i = 0; i < rows; i++) * for (int j = 0; j < columns; j++) * data[i][j] -= a[i][j]; * } * * /// <summary>Multiplies the current matrix with a scalar factor.</summary> * public void Times(double s) * { * for (int i = 0; i < rows; i++) * for (int j = 0; j < columns; j++) * data[i][j] *= s; * } */ /// <summary>Returns the LHS solution vetor if the matrix is square or the least squares solution otherwise.</summary> public ArrayMatrix Solve(ArrayMatrix rhs) { int maxDoubleDim = 10000000; ArrayMatrix inv = null; if (rows == columns && this.IsSymmetric) { try { if (rhs.RowCount > maxDoubleDim) { inv = new SljMatrixInverseDecimal(this).Solve(rhs); } else { inv = new SljMatrixInverse(this).Solve(rhs); } if (false) { var I = this * inv; int i = 0; } return(inv); } catch (Exception ex) { log.Error(ex.Message + "SLJ_Inverse 矩阵求逆遇到问题了奇异矩阵! 将尝试其它方法计算。");; // throw new Exception("Warning:Matrix is singular to working precision!"); } } if (rhs.RowCount > maxDoubleDim) { inv = new QrDecompositionDecimal(this).Solve(rhs); } else { inv = new QrDecomposition(this).Solve(rhs); } if (false) { var I = this * inv; int i = 0; } return(inv); // return (rows == columns) ? new LuDecomposition(this).Solve(rhs) : new QrDecomposition(this).Solve(rhs); }
/// <summary>Construct a QR decomposition.</summary> public QrDecompositionDecimal(ArrayMatrix A) { QR = (ArrayMatrix)A.Clone(); decimal[][] qr = QR.ArrayDecimal; int m = A.RowCount; int n = A.Columns; Rdiag = new decimal[n]; for (int k = 0; k < n; k++) { // Compute 2-norm of k-th column without under/overflow. decimal nrm = 0m; for (int i = k; i < m; i++) { nrm = this.Hypotenuse(nrm, Convert.ToDecimal(qr[i][k])); } if (nrm != 0.0m) { // Form k-th Householder vector. if (qr[k][k] < 0) { nrm = -nrm; } for (int i = k; i < m; i++) { var val = Convert.ToDecimal(qr[i][k]); qr[i][k] = val / nrm; } qr[k][k] += 1.0m; // Apply transformation to remaining columns. for (int j = k + 1; j < n; j++) { decimal s = 0.0m; for (int i = k; i < m; i++) { s += qr[i][k] * qr[i][j]; } s = -s / qr[k][k]; for (int i = k; i < m; i++) { qr[i][j] += s * qr[i][k]; } } } Rdiag[k] = -nrm; } }
/// <summary>Solves a set of equation systems of type <c>A * X = B</c>.</summary> /// <param name="B">Right hand side matrix with as many rows as <c>A</c> and any number of columns.</param> /// <returns>Matrix <c>X</c> so that <c>L * U * X = B</c>.</returns> public ArrayMatrix Solve(ArrayMatrix B) { if (B.RowCount != LU.RowCount) { throw new ArgumentException("Invalid matrix dimensions."); } if (!IsNonSingular) { throw new InvalidOperationException("Matrix is singular"); } // Copy right hand side with pivoting int count = B.Columns; ArrayMatrix X = B.Submatrix(pivotVector, 0, count - 1); int rows = LU.RowCount; int columns = LU.Columns; double[][] lu = LU.Array; // Solve L*Y = B(piv,:) for (int k = 0; k < columns; k++) { for (int i = k + 1; i < columns; i++) { for (int j = 0; j < count; j++) { X[i, j] -= X[k, j] * lu[i][k]; } } } // Solve U*X = Y; for (int k = columns - 1; k >= 0; k--) { for (int j = 0; j < count; j++) { X[k, j] /= lu[k][k]; } for (int i = 0; i < k; i++) { for (int j = 0; j < count; j++) { X[i, j] -= X[k, j] * lu[i][k]; } } } return(X); }
/// <summary>Returns a matrix filled with random values.</summary> public static ArrayMatrix Random(int rows, int columns) { ArrayMatrix X = new ArrayMatrix(rows, columns); double[][] x = X.Array; for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { x[i][j] = random.NextDouble(); } } return(X); }
/// <summary>Construct an eigenvalue decomposition.</summary> public EigenvalueDecomposition(ArrayMatrix A) { if (A.RowCount != A.Columns) { throw new ArgumentException("Matrix is not a square matrix."); } n = A.Columns; V = new ArrayMatrix(n, n); d = new double[n]; e = new double[n]; // Check for symmetry. isSymmetric = A.IsSymmetric; if (isSymmetric) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { V[i, j] = A[i, j]; } } // Tridiagonalize. tred2(); // Diagonalize. tql2(); } else { H = new ArrayMatrix(n, n); ort = new double[n]; for (int j = 0; j < n; j++) { for (int i = 0; i < n; i++) { H[i, j] = A[i, j]; } } // Reduce to Hessenberg form. orthes(); // Reduce Hessenberg to real Schur form. hqr2(); } }
/// <summary>Returns a diagonal matrix of the given aboutSize.</summary> public static ArrayMatrix Diagonal(int rows, int columns, double value) { ArrayMatrix X = new ArrayMatrix(rows, columns); double[][] x = X.Array; for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { x[i][j] = ((i == j) ? value : 0.0); } } return(X); }
/// <summary>Construct a QR decomposition.</summary> public QrDecomposition(ArrayMatrix A) { QR = (ArrayMatrix)A.Clone(); double[][] qr = QR.Array; int m = A.RowCount; int n = A.Columns; Rdiag = new double[n]; for (int k = 0; k < n; k++) { // Compute 2-norm of k-th column without under/overflow. double nrm = 0; for (int i = k; i < m; i++) { nrm = this.Hypotenuse(nrm, qr[i][k]); } if (nrm != 0.0) { // Form k-th Householder vector. if (qr[k][k] < 0) { nrm = -nrm; } for (int i = k; i < m; i++) { qr[i][k] /= nrm; } qr[k][k] += 1.0; // Apply transformation to remaining columns. for (int j = k + 1; j < n; j++) { double s = 0.0; for (int i = k; i < m; i++) { s += qr[i][k] * qr[i][j]; } s = -s / qr[k][k]; for (int i = k; i < m; i++) { qr[i][j] += s * qr[i][k]; } } } Rdiag[k] = -nrm; } }
/// <summary> /// 返回矩阵 /// </summary> /// <param name="markerName"></param> /// <returns></returns> public Geo.Algorithm.IMatrix Get(string markerName) { ArrayMatrix Harmonics = null; if (blqData.OceanTidesData.ContainsKey(markerName)) { //Get harmonics satData from file Harmonics = blqData.GetTideHarmonics(markerName); } else { Harmonics = new Geo.Algorithm.ArrayMatrix(6, 11, 0.0); } return(Harmonics); }
/// <summary>Creates a copy of the matrix.</summary> public ArrayMatrix Clone() { ArrayMatrix X = new ArrayMatrix(rows, columns); double[][] x = X.Array; for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { x[i][j] = data[i][j]; } } return(X); }
/// <summary> /// 创建一个相同数的对角阵 /// </summary> /// <param name="dimension"></param> /// <param name="number"></param> /// <returns></returns> public static ArrayMatrix EyeMatrix(int dimension, double number) { ArrayMatrix X = new ArrayMatrix(dimension, dimension); double[][] x = X.Array; for (int i = 0; i < dimension; i++) { for (int j = 0; j < dimension; j++) { if (i == j) { x[i][j] = number; } } } return(X); }
/// <summary>Returns the transposed matrix.</summary> public ArrayMatrix Transpose() { ArrayMatrix X = new ArrayMatrix(columns, rows); double[][] x = X.Array; for (int i = 0; i < rows; i++) { var row = data[i]; for (int j = 0; j < columns; j++) { x[j][i] = row[j]; } } return(X); }
/// <summary> /// Stores candidates and correspoding distances /// </summary> /// <param name="ican">Min (number of vectors found until now, MaxCan)</param> /// <param name="ipos">position in disall/cands to put the new found vector </param> /// <param name="t">distance of the new found vector</param> /// <param name="cands">2d-array to store the integer vectors</param> /// <param name="disal1">distance of the MaxCan integer vectors</param> /// <param name="tmax">the largest distance of the ican vectors with minmum distance found until now</param> /// <param name="imax">position in disal1/cands of the vector with the largest distance of the ican vectors with minimum distance found until now</param> /// <param name="dist">difference between the integer tried and \hat{a}_n</param> private void Stores(int ican, int ipos, double t, ArrayMatrix cands, ArrayMatrix disal1, ref double tmax, ref int imax, double[] dist) { for (int i = 0; i < NumberOfFloatParam; i++) { cands[i, ipos - 1] = dist[i]; } disal1[0, ipos - 1] = t; tmax = t; imax = ipos - 1; for (int i = 0; i < ican; i++) { if (disal1[0, i] > tmax) { imax = i; tmax = disal1[0, i]; } } }
/// <summary> /// 比较并行和穿行矩阵乘法的速度。。 /// </summary> static public void CompareArraySpeed() { int length = 10; var start = DateTime.Now; ArrayMatrix Matrix = new Geo.Algorithm.ArrayMatrix(length, length); for (int i = 0; i < 100; i++) { var x = Matrix * Matrix; } var span = DateTime.Now - start; Console.WriteLine(span.TotalMilliseconds + " ms"); }
/// <summary>Construct a Cholesky Decomposition.</summary> public CholeskyDecomposition(Matrix A) { if (!A.IsSquare) { throw new ArgumentNullException("Matrix is not square."); } int dimension = A.RowCount; L = new ArrayMatrix(dimension, dimension); double[][] a = A.Array; double[][] l = L.Array; isPositiveDefinite = true; isSymmetric = true; for (int j = 0; j < dimension; j++) { double[] Lrowj = l[j]; double d = 0.0; for (int k = 0; k < j; k++) { double[] Lrowk = l[k]; double s = 0.0; for (int i = 0; i < k; i++) { s += Lrowk[i] * Lrowj[i]; } Lrowj[k] = s = (a[j][k] - s) / l[k][k]; d = d + s * s; isSymmetric = isSymmetric & (a[k][j] == a[j][k]); } d = a[j][j] - d; isPositiveDefinite = isPositiveDefinite & (d > 0.0); l[j][j] = Math.Sqrt(Math.Max(d, 0.0)); for (int k = j + 1; k < dimension; k++) { l[j][k] = 0.0; } } }
/// <summary>Matrix-scalar multiplication.</summary> public static ArrayMatrix operator *(ArrayMatrix a, double s) { int rows = a.Rows; int columns = a.Columns; double[][] data = a.Array; ArrayMatrix X = new ArrayMatrix(rows, columns); double[][] x = X.Array; for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { x[i][j] = data[i][j] * s; } } return(X); }
/// <summary>Returns a sub matrix extracted from the current matrix.</summary> /// <param name="r">Array of row indices</param> /// <param name="c">Array of row indices</param> public ArrayMatrix Submatrix(int[] r, int[] c) { ArrayMatrix X = new ArrayMatrix(r.Length, c.Length); double[][] x = X.Array; for (int i = 0; i < r.Length; i++) { for (int j = 0; j < c.Length; j++) { if ((r[i] < 0) || (r[i] >= rows) || (c[j] < 0) || (c[j] >= columns)) { throw new ArgumentException(); } x[i][j] = data[r[i]][c[j]]; } } return(X); }
/// <summary> /// 矩阵乘法,左边列数应该等于右边行 /// N * 1 列向量,只乘以 1 * M 的行向量,结果为 N*M 的矩阵。 /// </summary> /// <param name="right"></param> /// <returns></returns> public IMatrix Multiply(IMatrix right) { if (ColCount != right.RowCount) { throw new ArgumentException("维数不正确!不可及操作。"); } if (right.ColCount == 1)//返回仍然为列向量 { VectorMatrix matrix = new VectorMatrix(this.Count); double val = right[0, 0]; for (int i = 0; i < this.Count; i++) { matrix[i] = this[i] * val; } return(matrix); } ArrayMatrix my = new ArrayMatrix(this); return(my.Multiply(right)); }
/// <summary> /// Update integral Z-transform for L /// only column 'prevObj' until 'last'. /// the output is the inverse of Z transpose /// </summary> /// <param name="Zti">the inverse Z transposed transformation matrix</param> /// <param name="L">lower triangular matrix L</param> /// <param name="prevObj">prevObj column to be updated</param> /// <param name="last">last column to be updated</param> private void Ztransi(ArrayMatrix Zti, ArrayMatrix L, int first, int last) { for (int i = last; i >= first; i--) { for (int j = i + 1; j < NumberOfFloatParam; j++) { double mu = Math.Round(L[j, i]); if (mu != 0) { for (int s = j; s < NumberOfFloatParam; s++) { L[s, i] = L[s, i] - mu * L[s, j]; } for (int s = 0; s < NumberOfFloatParam; s++) { Zti[s, j] = Zti[s, j] + mu * Zti[s, i]; } FloatParams[i] = FloatParams[i] - mu * FloatParams[j]; } } } }
/// <summary> /// 先matrix转化为string,再string序列化char[],然后将数据压缩为流,便于传输 /// </summary> /// <param name="m"></param> /// <returns></returns> public byte[] CompressToByte(ArrayMatrix m) { string str = null; str += m.Rows.ToString(); str += " "; str += m.Columns.ToString(); str += " "; for (int i = 0; i < m.Rows; i++) { for (int j = 0; j < m.Columns; j++) { if (m[i, j] != 0) { str += i.ToString(); str += " "; str += j.ToString(); str += " "; str += m[i, j].ToString(); str += " "; } } } //string to byte byte[] bytes = System.Text.Encoding.ASCII.GetBytes(str); //利用内存流和GZip无损压缩 using (MemoryStream ms = new MemoryStream()) { using (GZipStream gzip = new GZipStream(ms, CompressionMode.Compress)) { gzip.Write(bytes, 0, bytes.Length); gzip.Close(); } bytes = ms.ToArray(); ms.Close(); } return(bytes); }
/// <summary> /// Compute the inverse of a lower triangular matrix /// </summary> /// <param name="L"></param> private ArrayMatrix L_Inv(ArrayMatrix L) { ArrayMatrix Lm = new ArrayMatrix(NumberOfFloatParam, NumberOfFloatParam); double[] vec = new double[NumberOfFloatParam]; for (int i = 0; i < NumberOfFloatParam; i++) { for (int j = 0; j <= i - 1; j++) { vec[j] = L[i, j]; } for (int j = 0; j <= i - 1; j++) { for (int k = j; k <= i - 1; k++) { Lm[i, j] += -Lm[k, j] * vec[k] / L[i, i]; } } Lm[i, i] = 1 / L[i, i]; } return(Lm); }