public static Vector operator -(Vector vector, double val) { if (!vector.IsValid()) throw new ApplicationException("Vector is not initialized"); Vector vector1 = new Vector(vector.nrows); for (int index = 0; index < vector.nrows; ++index) vector1[index] = vector[index] - val; return vector1; }
public static bool AreCompatible(Vector v1, Vector v2) { if (!v1.IsValid()) { throw new ArgumentException("Vector 1 is not initialized"); } if (!v2.IsValid()) { throw new ArgumentException("Vector 2 is not initialized"); } return v1.fNRows == v2.fNRows; }
public void MakeTridiagonal(Matrix a, Vector d, Vector e) { int num1 = a.rows; if (a.rows != a.cols) throw new ApplicationException("Matrix to tridiagonalize must be square"); if (!a.IsSymmetric) throw new ApplicationException("Can only tridiagonalise symmetric matrix"); double[] numArray = new double[this.M * this.N]; for (int index = 0; index < this.M * this.N; ++index) numArray[index] = a.Elements[index / this.M, index % this.N]; double[] elements1 = d.Elements; double[] elements2 = e.Elements; for (int index1 = num1 - 1; index1 > 0; --index1) { int num2 = index1 - 1; double d1 = 0.0; double num3 = 0.0; if (num2 > 0) { for (int index2 = 0; index2 <= num2; ++index2) num3 += Math.Abs(numArray[index1 + index2 * num1]); if (num3 == 0.0) { elements2[index1] = numArray[index1 + num2 * num1]; } else { for (int index2 = 0; index2 <= num2; ++index2) { numArray[index1 + index2 * num1] /= num3; d1 += numArray[index1 + index2 * num1] * numArray[index1 + index2 * num1]; } double num4 = numArray[index1 + num2 * num1]; double num5 = num4 < 0.0 ? Math.Sqrt(d1) : -Math.Sqrt(d1); elements2[index1] = num3 * num5; d1 -= num4 * num5; numArray[index1 + num2 * num1] = num4 - num5; double num6 = 0.0; for (int index2 = 0; index2 <= num2; ++index2) { numArray[index2 + index1 * num1] = numArray[index1 + index2 * num1] / d1; double num7 = 0.0; for (int index3 = 0; index3 <= index2; ++index3) num7 += numArray[index2 + index3 * num1] * numArray[index1 + index3 * num1]; for (int index3 = index2 + 1; index3 <= num2; ++index3) num7 += numArray[index3 + index2 * num1] * numArray[index1 + index3 * num1]; elements2[index2] = num7 / d1; num6 += elements2[index2] * numArray[index1 + index2 * num1]; } double num8 = num6 / (d1 + d1); for (int index2 = 0; index2 <= num2; ++index2) { double num7 = numArray[index1 + index2 * num1]; double num9; elements2[index2] = num9 = elements2[index2] - num8 * num7; for (int index3 = 0; index3 <= index2; ++index3) numArray[index2 + index3 * num1] -= num7 * elements2[index3] + num9 * numArray[index1 + index3 * num1]; } } } else elements2[index1] = numArray[index1 + num2 * num1]; elements1[index1] = d1; } elements1[0] = 0.0; elements2[0] = 0.0; for (int index1 = 0; index1 < num1; ++index1) { int num2 = index1 - 1; if (elements1[index1] != 0.0) { for (int index2 = 0; index2 <= num2; ++index2) { double num3 = 0.0; for (int index3 = 0; index3 <= num2; ++index3) num3 += numArray[index1 + index3 * num1] * numArray[index3 + index2 * num1]; for (int index3 = 0; index3 <= num2; ++index3) numArray[index3 + index2 * num1] -= num3 * numArray[index3 + index1 * num1]; } } elements1[index1] = numArray[index1 + index1 * num1]; numArray[index1 + index1 * num1] = 1.0; for (int index2 = 0; index2 <= num2; ++index2) numArray[index2 + index1 * num1] = numArray[index1 + index2 * num1] = 0.0; } for (int index = 0; index < this.M * this.N; ++index) a.Elements[index / this.M, index % this.N] = numArray[index]; }
public Matrix EigenVectors(Vector eigenValues) { if (!this.IsSymmetric) throw new ApplicationException("Not yet implemented for non-symmetric matrix"); Matrix matrix = new Matrix(this.Rows, this.Cols); for (int index1 = 0; index1 < this.Rows; ++index1) { for (int index2 = 0; index2 < this.Cols; ++index2) matrix[index1, index2] = this[index1, index2]; } eigenValues.ResizeTo(this.Rows); Vector e = new Vector(this.Rows); this.MakeTridiagonal(matrix, eigenValues, e); this.MakeEigenVectors(eigenValues, e, matrix); this.EigenSort(matrix, eigenValues); return matrix; }
public void EigenSort(Matrix eigenVectors, Vector eigenValues) { int rows = eigenVectors.Rows; double[] numArray = new double[rows * rows]; for (int index = 0; index < rows * rows; ++index) numArray[index] = eigenVectors.Elements[index / rows, index % rows]; double[] elements = eigenValues.Elements; for (int index1 = 0; index1 < rows; ++index1) { int index2 = index1; double num1 = elements[index1]; for (int index3 = index1 + 1; index3 < rows; ++index3) { if (elements[index3] >= num1) { index2 = index3; num1 = elements[index3]; } } if (index2 != index1) { elements[index2] = elements[index1]; elements[index1] = num1; for (int index3 = 0; index3 < rows; ++index3) { double num2 = numArray[index3 + index1 * rows]; numArray[index3 + index1 * rows] = numArray[index3 + index2 * rows]; numArray[index3 + index2 * rows] = num2; } } } for (int index = 0; index < rows * rows; ++index) eigenVectors.Elements[index / rows, index % rows] = numArray[index]; }
public void MakeEigenVectors(Vector d, Vector e, Matrix z) { int rows = z.Rows; double[] elements1 = d.Elements; double[] elements2 = e.Elements; double[] numArray = new double[rows * rows]; for (int index = 0; index < rows * rows; ++index) numArray[index] = z.Elements[index / rows, index % rows]; for (int index = 1; index < rows; ++index) elements2[index - 1] = elements2[index]; elements2[rows - 1] = 0.0; for (int index1 = 0; index1 < rows; ++index1) { int num1 = 0; int index2; do { for (index2 = index1; index2 < rows - 1; ++index2) { double num2 = Math.Abs(elements1[index2]) + Math.Abs(elements1[index2 + 1]); if (Math.Abs(elements2[index2]) + num2 == num2) break; } if (index2 != index1) { if (num1++ == 30) { this.Error("MakeEigenVectors", "too many iterationsn"); return; } else { double num2 = (elements1[index1 + 1] - elements1[index1]) / (2.0 * elements2[index1]); double num3 = Math.Sqrt(num2 * num2 + 1.0); double num4 = elements1[index2] - elements1[index1] + elements2[index1] / (num2 + (num2 >= 0.0 ? Math.Abs(num3) : -Math.Abs(num3))); double num5 = 1.0; double num6 = 1.0; double num7 = 0.0; int index3; for (index3 = index2 - 1; index3 >= index1; --index3) { double num8 = num5 * elements2[index3]; double num9 = num6 * elements2[index3]; num3 = Math.Sqrt(num8 * num8 + num4 * num4); elements2[index3 + 1] = num3; if (num3 == 0.0) { elements1[index3 + 1] -= num7; elements2[index2] = 0.0; break; } else { num5 = num8 / num3; num6 = num4 / num3; double num10 = elements1[index3 + 1] - num7; num3 = (elements1[index3] - num10) * num5 + 2.0 * num6 * num9; num7 = num5 * num3; elements1[index3 + 1] = num10 + num7; num4 = num6 * num3 - num9; for (int index4 = 0; index4 < rows; ++index4) { double num11 = numArray[index4 + (index3 + 1) * rows]; numArray[index4 + (index3 + 1) * rows] = num5 * numArray[index4 + index3 * rows] + num6 * num11; numArray[index4 + index3 * rows] = num6 * numArray[index4 + index3 * rows] - num5 * num11; } } } if (num3 != 0.0 || index3 < index1) { elements1[index1] -= num7; elements2[index1] = num4; elements2[index2] = 0.0; } } } } while (index2 != index1); } for (int index = 0; index < rows * rows; ++index) z.Elements[index / rows, index % rows] = numArray[index]; }
public static Vector operator +(Vector target, Vector source) { if (!source.IsValid()) throw new ApplicationException("Source vector is not initialized"); if (!target.IsValid()) throw new ApplicationException("Target vector is not initialized"); if (!Vector.AreCompatible(target, source)) throw new ApplicationException("Vectors are not compatible"); Vector vector = new Vector(target.nrows); for (int index = 0; index < target.nrows; ++index) vector[index] = target[index] + source[index]; return vector; }
public Vector Sqrt() { if (!this.IsValid()) throw new ApplicationException("Vector is not initialized"); Vector vector = new Vector(this.nrows); for (int index = 0; index < this.nrows; ++index) vector[index] = Math.Sqrt(this.elements[index]); return vector; }
public void MakeTridiagonal(Matrix a, Vector d, Vector e) { int num = a.fRows; if (a.fRows != a.fCols) { throw new ApplicationException("Matrix to tridiagonalize must be square"); } if (!a.IsSymmetric) { throw new ApplicationException("Can only tridiagonalise symmetric matrix"); } double[] array = new double[this.M * this.N]; for (int i = 0; i < this.M * this.N; i++) { array[i] = a.Elements[i / this.M, i % this.N]; } double[] elements = d.Elements; double[] elements2 = e.Elements; for (int j = num - 1; j > 0; j--) { int num2 = j - 1; double num3 = 0.0; double num4 = 0.0; if (num2 > 0) { for (int k = 0; k <= num2; k++) { num4 += Math.Abs(array[j + k * num]); } if (num4 == 0.0) { elements2[j] = array[j + num2 * num]; } else { for (int l = 0; l <= num2; l++) { array[j + l * num] /= num4; num3 += array[j + l * num] * array[j + l * num]; } double num5 = array[j + num2 * num]; double num6; if (num5 >= 0.0) { num6 = -Math.Sqrt(num3); } else { num6 = Math.Sqrt(num3); } elements2[j] = num4 * num6; num3 -= num5 * num6; array[j + num2 * num] = num5 - num6; num5 = 0.0; for (int m = 0; m <= num2; m++) { array[m + j * num] = array[j + m * num] / num3; num6 = 0.0; for (int l = 0; l <= m; l++) { num6 += array[m + l * num] * array[j + l * num]; } for (int l = m + 1; l <= num2; l++) { num6 += array[l + m * num] * array[j + l * num]; } elements2[m] = num6 / num3; num5 += elements2[m] * array[j + m * num]; } double num7 = num5 / (num3 + num3); for (int m = 0; m <= num2; m++) { num5 = array[j + m * num]; num6 = (elements2[m] -= num7 * num5); for (int l = 0; l <= m; l++) { array[m + l * num] -= num5 * elements2[l] + num6 * array[j + l * num]; } } } } else { elements2[j] = array[j + num2 * num]; } elements[j] = num3; } elements[0] = 0.0; elements2[0] = 0.0; for (int j = 0; j < num; j++) { int num8 = j - 1; if (elements[j] != 0.0) { for (int n = 0; n <= num8; n++) { double num9 = 0.0; for (int num10 = 0; num10 <= num8; num10++) { num9 += array[j + num10 * num] * array[num10 + n * num]; } for (int num10 = 0; num10 <= num8; num10++) { array[num10 + n * num] -= num9 * array[num10 + j * num]; } } } elements[j] = array[j + j * num]; array[j + j * num] = 1.0; for (int num11 = 0; num11 <= num8; num11++) { array[num11 + j * num] = (array[j + num11 * num] = 0.0); } } for (int num12 = 0; num12 < this.M * this.N; num12++) { a.Elements[num12 / this.M, num12 % this.N] = array[num12]; } }
public Matrix EigenVectors(Vector eigenValues) { if (this.IsSymmetric) { Matrix matrix = new Matrix(this.Rows, this.Cols); for (int i = 0; i < this.Rows; i++) { for (int j = 0; j < this.Cols; j++) { matrix[i, j] = this[i, j]; } } eigenValues.ResizeTo(this.Rows); Vector e = new Vector(this.Rows); this.MakeTridiagonal(matrix, eigenValues, e); this.MakeEigenVectors(eigenValues, e, matrix); this.EigenSort(matrix, eigenValues); return matrix; } throw new ApplicationException("Not yet implemented for non-symmetric matrix"); }
public void EigenSort(Matrix eigenVectors, Vector eigenValues) { int rows = eigenVectors.Rows; double[] array = new double[rows * rows]; for (int i = 0; i < rows * rows; i++) { array[i] = eigenVectors.Elements[i / rows, i % rows]; } double[] elements = eigenValues.Elements; for (int j = 0; j < rows; j++) { int num = j; double num2 = elements[j]; for (int k = j + 1; k < rows; k++) { if (elements[k] >= num2) { num = k; num2 = elements[k]; } } if (num != j) { elements[num] = elements[j]; elements[j] = num2; for (int k = 0; k < rows; k++) { num2 = array[k + j * rows]; array[k + j * rows] = array[k + num * rows]; array[k + num * rows] = num2; } } } for (int l = 0; l < rows * rows; l++) { eigenVectors.Elements[l / rows, l % rows] = array[l]; } }
public void MakeEigenVectors(Vector d, Vector e, Matrix z) { int rows = z.Rows; double[] elements = d.Elements; double[] elements2 = e.Elements; double[] array = new double[rows * rows]; for (int i = 0; i < rows * rows; i++) { array[i] = z.Elements[i / rows, i % rows]; } int j; for (j = 1; j < rows; j++) { elements2[j - 1] = elements2[j]; } elements2[rows - 1] = 0.0; j = 0; while (j < rows) { int num = 0; int k; do { for (k = j; k < rows - 1; k++) { double num2 = Math.Abs(elements[k]) + Math.Abs(elements[k + 1]); if (Math.Abs(elements2[k]) + num2 == num2) { break; } } if (k != j) { if (num++ == 30) { goto Block_5; } double num3 = (elements[j + 1] - elements[j]) / (2.0 * elements2[j]); double num4 = Math.Sqrt(num3 * num3 + 1.0); num3 = elements[k] - elements[j] + elements2[j] / (num3 + ((num3 >= 0.0) ? Math.Abs(num4) : (-Math.Abs(num4)))); double num5 = 1.0; double num6 = 1.0; double num7 = 0.0; int l; for (l = k - 1; l >= j; l--) { double num8 = num5 * elements2[l]; double num9 = num6 * elements2[l]; num4 = Math.Sqrt(num8 * num8 + num3 * num3); elements2[l + 1] = num4; if (num4 == 0.0) { elements[l + 1] -= num7; elements2[k] = 0.0; break; } num5 = num8 / num4; num6 = num3 / num4; num3 = elements[l + 1] - num7; num4 = (elements[l] - num3) * num5 + 2.0 * num6 * num9; num7 = num5 * num4; elements[l + 1] = num3 + num7; num3 = num6 * num4 - num9; for (int m = 0; m < rows; m++) { num8 = array[m + (l + 1) * rows]; array[m + (l + 1) * rows] = num5 * array[m + l * rows] + num6 * num8; array[m + l * rows] = num6 * array[m + l * rows] - num5 * num8; } } if (num4 != 0.0 || l < j) { elements[j] -= num7; elements2[j] = num3; elements2[k] = 0.0; } } } while (k != j); j++; continue; Block_5: this.Error("MakeEigenVectors", "too many iterationsn"); return; } for (int n = 0; n < rows * rows; n++) { z.Elements[n / rows, n % rows] = array[n]; } }
public Vector ElementDiv(Vector target, Vector source) { if (!source.IsValid()) { throw new ApplicationException("Source vector is not initialized"); } if (!target.IsValid()) { throw new ApplicationException("Target vector is not initialized"); } if (!Vector.AreCompatible(target, source)) { throw new ApplicationException("Vectors are not compatible"); } Vector vector = new Vector(target.fNRows); for (int i = 0; i < this.fNRows; i++) { vector[i] = target[i] / source[i]; } return vector; }
public Vector Sqrt() { if (!this.IsValid()) { throw new ApplicationException("Vector is not initialized"); } Vector vector = new Vector(this.fNRows); for (int i = 0; i < this.fNRows; i++) { vector[i] = Math.Sqrt(this.fElements[i]); } return vector; }
public static Vector operator -(Vector vector, double val) { if (!vector.IsValid()) { throw new ApplicationException("Vector is not initialized"); } Vector vector2 = new Vector(vector.fNRows); for (int i = 0; i < vector.fNRows; i++) { vector2[i] = vector[i] - val; } return vector2; }