public static MatrixSparseLinkedList operator -(MatrixSparseLinkedList matrix1, MatrixSparseLinkedList matrix2) { MatrixSparseLinkedList matrix3 = new MatrixSparseLinkedList(); matrix3.InitializeMatrix(matrix1.n); AddMatrix_ToExistingMatrix(ref matrix3, matrix1); SubtractMatrix_FromExistingMatrix(ref matrix3, matrix2); return(matrix3); }
public static MatrixSparseLinkedList MultiplyMatrix_ByMatrix(MatrixSparseLinkedList Matrix1, MatrixSparseLinkedList Matrix2) { MatrixSparseLinkedList NewMatrix = new MatrixSparseLinkedList(); NewMatrix.InitializeMatrix(Matrix1.n); MatrixSparseLinkedList A = Matrix1; int NumberOfRows_A = A.n; MatrixSparseLinkedList B = Matrix2; int NumberOfRows_B = B.n; for (int i = 0; i < NumberOfRows_A; i++) { if (!A.Rows[i].RowNotPopulated) { MatrixElement E_A = A.Rows[i].FirsElement; while (E_A.NotLastItem) { for (int j = 0; j < NumberOfRows_B; j++) { if (!B.Rows[j].RowNotPopulated) { MatrixElement E_B = B.Rows[j].FirsElement; while (E_B.NotLastItem) { NewMatrix.AddToMatrixElement(i, E_B.Index, E_A.Value * E_B.Value); E_B = E_B.NextItem; } NewMatrix.AddToMatrixElement(i, E_B.Index, E_A.Value * E_B.Value); } } E_A = E_A.NextItem; } for (int j = 0; j < NumberOfRows_B; j++) { if (!B.Rows[j].RowNotPopulated) { MatrixElement E_B = B.Rows[j].FirsElement; while (E_B.NotLastItem) { NewMatrix.AddToMatrixElement(i, E_B.Index, E_A.Value * E_B.Value); E_B = E_B.NextItem; } NewMatrix.AddToMatrixElement(i, E_B.Index, E_A.Value * E_B.Value); } } } } return(NewMatrix); }
public static void MultiplyScalar_ByExistingMatrix(ref MatrixSparseLinkedList ExistingMatrix, double Scalar) { MatrixSparseLinkedList A = ExistingMatrix; int NumberOfRows = A.n; for (int i = 0; i < NumberOfRows; i++) { if (!A.Rows[i].RowNotPopulated) { MatrixElement E = A.Rows[i].FirsElement; while (E.NotLastItem) { E.Value *= Scalar; E = E.NextItem; } E.Value *= Scalar; } } }
public static void SubtractMatrix_FromExistingMatrix(ref MatrixSparseLinkedList ExistingMatrix, MatrixSparseLinkedList MatrixToSubtract) { MatrixSparseLinkedList A = MatrixToSubtract; int NumberOfRows = A.n; for (int i = 0; i < NumberOfRows; i++) { if (!A.Rows[i].RowNotPopulated) { MatrixElement E = A.Rows[i].FirsElement; while (E.NotLastItem) { ExistingMatrix.AddToMatrixElement(i, E.Index, -E.Value); E = E.NextItem; } ExistingMatrix.AddToMatrixElement(i, E.Index, -E.Value); } } }
public Vector ATx_Symmetric(MatrixSparseLinkedList A, Vector x) { //Calculate the product y = A^T x int NumberOfRows = A.n; Vector y = new Vector(NumberOfRows); for (int i = 0; i < NumberOfRows; i++) { MatrixElement StartElement = A.Rows[i].FirsElement; double xi = x.Values[i]; int index; while (StartElement.NotLastItem) { index = StartElement.Index; y.Values[index] += StartElement.Value * xi; StartElement = StartElement.NextItem; } index = StartElement.Index; y.Values[index] += StartElement.Value * xi; } return(y); }
public static MatrixSparseLinkedList MultiplyScalar_ByMatrix(MatrixSparseLinkedList Matrix1, double Scalar) { MatrixSparseLinkedList A = Matrix1; int NumberOfRows = A.n; MatrixSparseLinkedList NewMatrix = new MatrixSparseLinkedList(); NewMatrix.InitializeMatrix(NumberOfRows); for (int i = 0; i < NumberOfRows; i++) { if (!A.Rows[i].RowNotPopulated) { MatrixElement E = A.Rows[i].FirsElement; while (E.NotLastItem) { NewMatrix.AddToMatrixElement(i, E.Index, E.Value * Scalar); E = E.NextItem; } NewMatrix.AddToMatrixElement(i, E.Index, E.Value * Scalar); } } return(NewMatrix); }
public Vector Ax_Parallel(MatrixSparseLinkedList A, Vector x) { //Calculate the product y = A x int NumberOfRows = A.n; Vector y = new Vector(NumberOfRows); Parallel.For(0, NumberOfRows, i => { MatrixElement StartElement = A.Rows[i].FirsElement; double temp = 0.0D; int index; while (StartElement.NotLastItem) { index = StartElement.Index; temp += StartElement.Value * x.Values[index]; StartElement = StartElement.NextItem; } index = StartElement.Index; temp += StartElement.Value * x.Values[index]; y.Values[i] = temp; }); return(y); }
public static Vector MultiplyExistingMatrix_ByVector(ref MatrixSparseLinkedList ExistingMatrix, Vector V) { Vector NewVector = new Vector(ExistingMatrix.n); MatrixSparseLinkedList A = ExistingMatrix; int NumberOfRows = A.n; for (int i = 0; i < NumberOfRows; i++) { double Temp = 0.0D; if (!A.Rows[i].RowNotPopulated) { MatrixElement E = A.Rows[i].FirsElement; while (E.NotLastItem) { Temp += E.Value * V.Values[E.Index]; E = E.NextItem; } Temp += E.Value * V.Values[E.Index]; } NewVector.Values[i] = Temp; } return(NewVector); }
public Vector SolveUsingSingularValueDecomposition(Vector RHS, out double ConditionNumber, out Vector W, out MatrixSparseLinkedList V) { MatrixSparseLinkedList A = this; //Matrix V; //Vector W; SingularValueDecomposition(ref A, out W, out V); Vector x = ATx_Symmetric(A, RHS); int n = x.Values.Length; for (int i = 0; i < n; i++) { if (W.Values[i] == 0.0D) { x.Values[i] = 0.0D; } else { x.Values[i] /= W.Values[i]; } } x = Ax(V, x); double Max = W.Max(); double Min = W.Min(); if (Min == 0.0D) { ConditionNumber = 1.0E100; } else { ConditionNumber = Max / Min; } return(x); }
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; }