// Statics // public static CellArray Clone(CellArray A) { CellArray x = new CellArray(); foreach (Cell c in A) { if (c.IsArray) { x.Append(CellArray.Clone(c)); } else { x.Append(c); } } return(x); }
public LUDecomposition(CellArray A) { // Use a "left-looking", dot-product, Crout/Doolittle algorithm. LU = CellArray.Clone(A); m = A.Count; n = ColumnCount(A); piv = new int[m]; for (int i = 0; i < m; i++) { piv[i] = i; } pivsign = 1; Cell[] LUcolj = new Cell[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].ARRAY[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); Cell s = this._zero; for (int k = 0; k < kmax; k++) { s += LU[i].ARRAY[k] * LUcolj[k]; } LU[i].ARRAY[j] = LUcolj[i] -= s; } // Find pivot and exchange if necessary. int p = j; for (int i = j + 1; i < m; i++) { if (CellFunctions.Abs(LUcolj[i]) > CellFunctions.Abs(LUcolj[p])) { p = i; } } if (p != j) { for (int k = 0; k < n; k++) { Cell t = LU[p, k]; LU[p].ARRAY[k] = LU[j].ARRAY[k]; LU[j].ARRAY[k] = t; } int l = piv[p]; piv[p] = piv[j]; piv[j] = l; pivsign = -pivsign; } // Compute multipliers. if (j < m && LU[j].ARRAY[j] != this._zero) { for (int i = j + 1; i < m; i++) { LU[i].ARRAY[j] /= LU[j].ARRAY[j]; } } } }