protected MatrixRow[] GetLocalRows(MatrixRow[] OldRows, int PivotColumn) { MatrixRow[] NewLocalRows = new MatrixRow[OldRows.Length - 1]; MatrixElement a; for (int i = 0; i < NewLocalRows.Length; i++) { a = OldRows[i + 1].FirsElement; if (a.NotLastItem) { if (a.NextItem.Index <= PivotColumn) { NewLocalRows[i].FirsElement = a.NextItem; } else { NewLocalRows[i] = OldRows[i + 1]; } } else { NewLocalRows[i] = OldRows[i + 1]; } } return(NewLocalRows); }
protected void InitializeLocalRows() { LocalRows = new MatrixRow[n]; for (int i = 0; i < n; i++) { LocalRows[i] = new MatrixRow(); LocalRows[i].FirsElement = Rows[i].FirsElement; LocalRows[i].RowNotPopulated = false; } }
public double GetElementValueInRow(ref MatrixRow Row, int column) { if (Row.RowNotPopulated) { return(0.0d); } else { return(this.GetElementValueInRow(ref Row.FirsElement, column)); } }
public MatrixElement GetElementInRowOrClosestBefore(ref MatrixRow Row, int column) { if (Row.RowNotPopulated) { return(null); } else { return(this.GetElementInRowOrClosestBefore(ref Row.FirsElement, column)); } }
public void LUDecomposition() { DiagonalElements = new MatrixRow[n]; InitializeLocalRows(); for (int i = 0; i < n - 1; i++) { MatrixColumn PivotColumn = GetColumn(ref LocalRows, i); MatrixColumnElement MaxColumnElement; int newRelativePivotRow = GetRowOfMaxElementInColumn(ref PivotColumn, out MaxColumnElement); SwapRowDuringPivoting(i, newRelativePivotRow, ref PivotColumn, ref LocalRows); ScalePivotColumnToPivot(ref PivotColumn); DiagonalElements[i] = new MatrixRow(); DiagonalElements[i].RowNotPopulated = false; DiagonalElements[i].FirsElement = PivotColumn.FirsElement.RowElement; MatrixColumnElement a = PivotColumn.FirsElement; MatrixElement b = PivotColumn.FirsElement.RowElement; double colVal; double change; MatrixElement StartRowSearch; MatrixElement c; if (b.NotLastItem) { if (a.NotLastItem) { //normal while (a.NotLastItem) { a = a.NextElement; StartRowSearch = LocalRows[a.Index].FirsElement; colVal = a.RowElement.Value; c = b; while (c.NotLastItem) { c = c.NextItem; change = -colVal * c.Value; StartRowSearch = AddToElementInRow(ref StartRowSearch, c.Index, change); } } } } LocalRows = GetLocalRows(LocalRows, i + 1); } DiagonalElements[n - 1].FirsElement = LocalRows[0].FirsElement; }
protected void RemoveZeros(ref MatrixRow Row) { MatrixElement a = Row.FirsElement; bool test = true; while (test) { if (a.NotLastItem) { if (Math.Abs(a.NextItem.Value) < RealZero) { if (a.NextItem.NotLastItem) { a.NextItem = a.NextItem.NextItem; } else { a.NextItem = null; a.NotLastItem = false; test = false; } } if (test) { a = a.NextItem; } } else { test = false; } } a = Row.FirsElement; if (Math.Abs(a.Value) < RealZero) { if (a.NotLastItem) { Row.FirsElement = a.NextItem; } else { Row.RowNotPopulated = true; Row.FirsElement = null; } } }
private void RemoveElementsFromStartOfRow(ref MatrixRow Row, int LastColumnToRemive) { MatrixElement a = Row.FirsElement; bool test = true; while (test) { if (a.NotLastItem) { if (a.NextItem.Index < LastColumnToRemive + 1) { if (a.NextItem.NextItem.NotLastItem) { a.NextItem = a.NextItem.NextItem; //a = a.NextItem; } else { a.NotLastItem = false; a.NextItem = null; test = false; } } else { test = false; } } else { test = false; } } a = Row.FirsElement; if (a.Index < LastColumnToRemive + 1) { if (a.NotLastItem) { Row.FirsElement = a.NextItem; } else { Row.FirsElement = null; Row.RowNotPopulated = true; } } }
private int LUDecomposition_CountElementsRow(MatrixRow Row, out MatrixElement[] RowArray) { MatrixElement a = Row.FirsElement; int count = 1; while (a.NotLastItem) { count++; a = a.NextItem; } RowArray = new MatrixElement[count - 1]; a = Row.FirsElement; for (int i = 0; i < count - 1; i++) { a = a.NextItem; RowArray[i] = a; } return(count); }
protected MatrixElement AddToElementInRow_Parallel(ref MatrixRow LocalRow, ref MatrixElement FirstElement, int col, double value) { MatrixElement a = FirstElement; while (a.NotLastItem) { if (a.Index == col) { a.Value += value; return(a); } else if ((a.Index < col) && (col < a.NextItem.Index)) { MatrixElement newElement = new MatrixElement(); newElement.Index = col; newElement.Value = value; newElement.NotLastItem = true; newElement.NextItem = a.NextItem; a.NextItem = newElement; return(newElement); } a = a.NextItem; } if (a.Index == col) { a.Value += value; return(a); } else { MatrixElement newElement = new MatrixElement(); newElement.Index = col; newElement.Value = value; newElement.NotLastItem = false; a.NotLastItem = true; a.NextItem = newElement; return(newElement); } }
protected void AddToElementInRow(ref MatrixRow Row, int col, double value) { if (Math.Abs(value) < RealZero) { return; } else { if (Row.RowNotPopulated) { MatrixElement newElement = new MatrixElement(); newElement.Index = col; newElement.Value = value; newElement.NotLastItem = false; Row.FirsElement = newElement; Row.RowNotPopulated = false; return; } else { AddToElementInRow(ref Row.FirsElement, col, value); } } }
public void LUDecomposition_Parallel() { // LUDecomposition with Parallel operations conducted for multi-processors // M. Negahban // 5-8-2011 DiagonalElements = new MatrixRow[n]; InitializeLocalRows(); //For parallel double[] A_values = new double[n]; int[] A_Indecies = new int[n]; int NumberOfRows; for (int i = 0; i < n - 1; i++) { MatrixColumn PivotColumn = GetColumn(ref LocalRows, i); MatrixColumnElement MaxColumnElement; int newRelativePivotRow = GetRowOfMaxElementInColumn(ref PivotColumn, out MaxColumnElement); SwapRowDuringPivoting(i, newRelativePivotRow, ref PivotColumn, ref LocalRows); ScalePivotColumnToPivot(ref PivotColumn); DiagonalElements[i] = new MatrixRow(); DiagonalElements[i].RowNotPopulated = false; DiagonalElements[i].FirsElement = PivotColumn.FirsElement.RowElement; MatrixColumnElement a = PivotColumn.FirsElement; MatrixElement b = PivotColumn.FirsElement.RowElement; if (b.NotLastItem) { if (a.NotLastItem) { //Parallel NumberOfRows = 0; while (a.NotLastItem) { a = a.NextElement; A_values[NumberOfRows] = a.RowElement.Value; A_Indecies[NumberOfRows] = a.Index; NumberOfRows++; } //If you want to control level of parallelism Add //ParallelOptions po = new ParallelOptions(); //po.MaxDegreeOfParallelism = 100; // select any number grater than 0 //Parallel.For(0, NumberOfRows, po, j => Parallel.For(0, NumberOfRows, j => { double colValJ = A_values[j]; MatrixElement StartRowSearchJ = LocalRows[A_Indecies[j]].FirsElement; MatrixElement cJ = b; while (cJ.NotLastItem) { cJ = cJ.NextItem; double changeJ = -colValJ * cJ.Value; StartRowSearchJ = AddToElementInRow(ref StartRowSearchJ, cJ.Index, changeJ); } }); } } LocalRows = GetLocalRows(LocalRows, i + 1); } DiagonalElements[n - 1].FirsElement = LocalRows[0].FirsElement; }
public void DeleteMatrixElement(int row, int col) { MatrixRow TheRow = Rows[row]; if (TheRow.RowNotPopulated) { return; } else { MatrixElement a = TheRow.FirsElement; if (a.Index > col) { return; } else { if (a.Index == col) { if (a.NotLastItem) { TheRow.FirsElement = a.NextItem; return; } else { TheRow.RowNotPopulated = true; TheRow.FirsElement = null; return; } } else { while (a.NotLastItem) { if ((a.Index < col) && (col < a.NextItem.Index)) { return; } else if (a.NextItem.Index == col) { if (a.NextItem.NotLastItem) { a.NextItem = a.NextItem.NextItem; return; } else { a.NotLastItem = false; a.NextItem = null; return; } } else if (a.NextItem.NotLastItem == false) { return; } a = a.NextItem; } } } } }
public void SingularValueDecomposition(ref MatrixSparseLinkedList A, out Vector W, out MatrixSparseLinkedList V) { //Adaptation of singular value decomposition from Numerical Recipes // A = U W V^T // Replaces A with U int m, mp, n, np, NMAX; m = A.n; n = A.n; mp = m; np = n; MatrixSparseLinkedList a = A; V = new MatrixSparseLinkedList(); V.InitializeMatrix(n); MatrixSparseLinkedList v = V; double[] w = new double[np]; NMAX = np; int l = 0; int nm = 0; int i, its, j, jj, k; double anorm, c, f, g, h, s, scale, x, y, z; double[] rv1 = new double[NMAX]; g = 0.0d; scale = 0.0d; anorm = 0.0d; for (i = 0; i < n; i++) { l = i + 2; rv1[i] = scale * g; g = 0.0d; s = 0.0d; scale = 0.0d; if (i < m) { for (k = i; k < m; k++) { scale += Math.Abs(a.GetMatrixElement(k, i)); } if (scale != 0.0d) { for (k = i; k < m; k++) { double temp = a.GetMatrixElement(k, i); temp /= scale; s += temp * temp; } f = a.GetMatrixElement(i, i); g = -FortranSign(Math.Sqrt(s), f); h = f * g - s; a.SetMatrixElement(i, i, f - g); for (j = l - 1; j < n; j++) { s = 0.0d; for (k = i; k < m; k++) { MatrixRow TempRow = Rows[k]; s += a.GetElementValueInRow(ref TempRow, i) * a.GetElementValueInRow(ref TempRow, j); } f = s / h; for (k = i; k < m; k++) { MatrixRow TempRow = Rows[k]; a.AddToElementInRow(ref TempRow, j, f * a.GetElementValueInRow(ref TempRow, i)); } } for (k = i; k < m; k++) { double temp = a.GetMatrixElement(k, i); temp *= scale; a.SetMatrixElement(k, i, temp); } } } w[i] = scale * g; g = 0.0d; s = 0.0d; scale = 0.0d; if ((i + 1 <= m) && (i + 1 != n)) { MatrixRow TempRowI = Rows[i]; MatrixElement ElementLMinus1 = a.GetElementInRowOrClosestAfter(ref TempRowI, l - 1); MatrixElement StartElement = ElementLMinus1; if (StartElement != null) { while (StartElement.NotLastItem) { scale += Math.Abs(StartElement.Value); StartElement = StartElement.NextItem; } scale += Math.Abs(StartElement.Value); if (scale != 0.0d) { StartElement = ElementLMinus1; while (StartElement.NotLastItem) { StartElement.Value /= scale; s += StartElement.Value * StartElement.Value; StartElement = StartElement.NextItem; } StartElement.Value /= scale; s += StartElement.Value * StartElement.Value; if (ElementLMinus1.Index == l - 1) { f = ElementLMinus1.Value; g = -FortranSign(Math.Sqrt(s), f); h = f * g - s; ElementLMinus1.Value = f - g; } else { f = 0.0; g = -FortranSign(Math.Sqrt(s), f); h = -s; a.AddToElementInRow(ref TempRowI, l - 1, f - g); ElementLMinus1 = a.GetElementInRowOrClosestAfter(ref TempRowI, l - 1); } for (k = l - 1; k < n; k++) { rv1[k] = a.GetElementValueInRow(ref ElementLMinus1, k) / h; } for (j = l - 1; j < m; j++) { s = 0.0d; MatrixRow TempRowJ = Rows[j]; MatrixElement ElementRowJLMinus1 = a.GetElementInRowOrClosestAfter(ref TempRowJ, l - 1); MatrixElement StartElementJ = ElementRowJLMinus1; for (k = l - 1; k < n; k++) { s += a.GetElementValueInRow(ref ElementRowJLMinus1, k) * a.GetElementValueInRow(ref ElementLMinus1, k); } for (k = l - 1; k < n; k++) { a.AddToElementInRow(ref ElementRowJLMinus1, k, s * rv1[k]); } } StartElement = ElementLMinus1; while (StartElement.NotLastItem) { StartElement.Value *= scale; StartElement = StartElement.NextItem; } StartElement.Value *= scale; } } } anorm = Math.Max(anorm, (Math.Abs(w[i]) + Math.Abs(rv1[i]))); } for (i = n - 1; i > -1; i--) { MatrixRow VRowI = V.Rows[i]; if (i < n - 1) { if (g != 0.0d) { MatrixRow ARowI = Rows[i]; double AIl = a.GetElementValueInRow(ref ARowI, l); MatrixElement StartElement = a.GetElementInRowOrClosestBefore(ref ARowI, l); for (j = l; j < n; j++) { double temp = (a.GetElementValueInRow(ref StartElement, j) / AIl) / g; V.SetMatrixElement(j, i, temp); } for (j = l; j < n; j++) { s = 0.0d; for (k = l; k < n; k++) { s += a.GetElementValueInRow(ref StartElement, k) * V.GetMatrixElement(k, j); } for (k = l; k < n; k++) { V.AddToMatrixElement(k, j, s * V.GetMatrixElement(k, i)); } } } for (j = l; j < n; j++) { V.DeleteMatrixElement(i, j); V.DeleteMatrixElement(j, i); } } V.SetMatrixElement(i, i, 1.0D); g = rv1[i]; l = i; } for (i = Math.Min(m, n) - 1; i > -1; i--) { l = i + 1; g = w[i]; for (j = l; j < n; j++) { a.DeleteMatrixElement(i, j); } if (g != 0.0d) { g = 1.0d / g; for (j = l; j < n; j++) { s = 0.0d; for (k = l; k < m; k++) { s += a.GetMatrixElement(k, i) * a.GetMatrixElement(k, j); } f = (s / a.GetMatrixElement(i, i)) * g; for (k = i; k < m; k++)//i was l { double temp = f * a.GetMatrixElement(k, i); a.AddToMatrixElement(k, j, temp); } } for (j = i; j < m; j++) { double temp = a.GetMatrixElement(j, i) * g; a.SetMatrixElement(j, i, temp); } } else { for (j = i; j < m; j++) { a.DeleteMatrixElement(j, i); } } a.AddToMatrixElement(i, i, 1.0D); } for (k = n - 1; k > -1; k--) { for (its = 0; its < 30; its++) { for (l = k; l > -1; l--) { nm = l - 1; if ((Math.Abs(rv1[l]) + anorm) == anorm) { goto L2; } if ((Math.Abs(w[nm]) + anorm) == anorm) { goto L1; } } L1 : c = 0.0d; s = 1.0d; for (i = l; i < k + 1; i++) { f = s * rv1[i]; rv1[i] *= c; if ((Math.Abs(f) + anorm) == anorm) { goto L2; } g = w[i]; h = PYTHAG(f, g); w[i] = h; h = 1.0d / h; c = (g * h); s = -(f * h); for (j = 0; j < m; j++) { y = a.GetMatrixElement(j, nm); z = a.GetMatrixElement(j, i); a.SetMatrixElement(j, nm, (y * c) + (z * s)); a.SetMatrixElement(j, i, -(y * s) + (z * c)); } } L2 : z = w[k]; if (l == k) { if (z < 0.0d) { w[k] = -z; for (j = 0; j < n; j++) { MatrixElement VJK = V.GetElementInRow(ref V.Rows[j], k); if (VJK != null) { VJK.Value = -VJK.Value; } // V.SetMatrixElement(j, k, -V.GetMatrixElement(j, k)); } } goto L3; } if (its == 29) { Console.Write("no convergence in svdcmp"); } x = w[l]; nm = k - 1; y = w[nm]; g = rv1[nm]; h = rv1[k]; f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0d * h * y); g = PYTHAG(f, 1.0d); f = ((x - z) * (x + z) + h * ((y / (f + FortranSign(g, f))) - h)) / x; c = 1.0d; s = 1.0d; for (j = l; j < nm; j++) { i = j + 1; g = rv1[i]; y = w[i]; h = s * g; g = c * g; z = PYTHAG(f, h); rv1[j] = z; c = f / z; s = h / z; f = (x * c) + (g * s); g = -(x * s) + (g * c); h = y * s; y = y * c; for (jj = 0; jj < n; jj++) { x = V.GetMatrixElement(jj, j); z = V.GetMatrixElement(jj, i); V.SetMatrixElement(jj, j, (x * c) + (z * s)); V.SetMatrixElement(jj, i, -(x * s) + (z * c)); } z = PYTHAG(f, h); w[j] = z; if (z != 0.0d) { z = 1.0d / z; c = f * z; s = h * z; } f = (c * g) + (s * y); x = -(s * g) + (c * y); for (jj = 0; jj < m; jj++) { y = a.GetMatrixElement(jj, j); z = a.GetMatrixElement(jj, i); a.SetMatrixElement(jj, j, (y * c) + (z * s)); a.SetMatrixElement(jj, i, -(y * s) + (z * c)); } } rv1[l] = 0.0d; rv1[k] = f; w[k] = x; } L3 : continue; } W = new Vector(); W.Values = w; }