public override RealVector ebeDivide(RealVector v) /*Todo: Supposed to be ArrayRealVector */ { if (v is ArrayRealVector) { double[] vData = ((ArrayRealVector)v).data; int dim = vData.Length; checkVectorDimensions(dim); ArrayRealVector result = new ArrayRealVector(dim); double[] resultData = result.data; for (int i = 0; i < dim; i++) { resultData[i] = data[i] / vData[i]; } return(result); } else { checkVectorDimensions(v); double[] @out = data.Clone() as double[]; for (int i = 0; i < data.Length; i++) { @out[i] /= v.getEntry(i); } return(new ArrayRealVector(@out, false)); } }
/** * Solves the linear equation A × X = B for symmetric matrices A. * <p> * This method only finds exact linear solutions, i.e. solutions for * which ||A × X - B|| is exactly 0. * </p> * * @param b Right-hand side of the equation A × X = B. * @return a Vector X that minimizes the two norm of A × X - B. * * @throws DimensionMismatchException if the matrices dimensions do not match. * @throws SingularMatrixException if the decomposed matrix is singular. */ public RealVector solve(RealVector b) { if (!isNonSingular()) { throw new Exception("SingularMatrixException"); } int m = realEigenvalues.Length; if (b.getDimension() != m) { throw new Exception("DimensionMismatchException"); } double[] bp = new double[m]; for (int i = 0; i < m; ++i) { ArrayRealVector v = eigenvectors[i]; double[] vData = v.getDataRef(); double s = v.dotProduct(b) / realEigenvalues[i]; for (int j = 0; j < m; ++j) { bp[j] += s * vData[j]; } } return(new ArrayRealVector(bp, false)); }
public override RealVector subtract(RealVector v) /*Todo: Supposed to return ArrayRealVector */ { if (v is ArrayRealVector) { double[] vData = ((ArrayRealVector)v).data; int dim = vData.Length; checkVectorDimensions(dim); ArrayRealVector result = new ArrayRealVector(dim); double[] resultData = result.data; for (int i = 0; i < dim; i++) { resultData[i] = data[i] - vData[i]; } return(result); } else { checkVectorDimensions(v); double[] @out = data.Clone() as double[]; var it = v.iterator(); while (it.MoveNext()) { Entry e = it.Current; @out[e.getIndex()] -= e.getValue(); } return(new ArrayRealVector(@out, false)); } }
/** * Construct a vector by appending one vector to another vector. * @param v1 First vector (will be put in front of the new vector). * @param v2 Second vector (will be put at back of the new vector). */ public ArrayRealVector(double[] v1, ArrayRealVector v2) { int l1 = v1.Length; int l2 = v2.getDimension(); data = new double[l1 + l2]; Array.Copy(v1, 0, data, 0, l1); Array.Copy(v2.data, 0, data, l1, l2); }
/** * Construct a vector by appending one vector to another vector. * @param v1 First vector (will be put in front of the new vector). * @param v2 Second vector (will be put at back of the new vector). */ public ArrayRealVector(RealVector v1, ArrayRealVector v2) { int l1 = v1.getDimension(); int l2 = v2.data.Length; data = new double[l1 + l2]; for (int i = 0; i < l1; ++i) { data[i] = v1.getEntry(i); } Array.Copy(v2.data, 0, data, l1, l2); }
/** * Construct a vector by appending one vector to another vector. * @param v1 First vector (will be put in front of the new vector). * @param v2 Second vector (will be put at back of the new vector). */ public ArrayRealVector(ArrayRealVector v1, RealVector v2) { int l1 = v1.data.Length; int l2 = v2.getDimension(); data = new double[l1 + l2]; Array.Copy(v1.data, 0, data, 0, l1); for (int i = 0; i < l2; ++i) { data[l1 + i] = v2.getEntry(i); } }
public override RealVector getSubVector(int index, int n) { if (n < 0) { throw new Exception("NotPositiveException"); } ArrayRealVector @out = new ArrayRealVector(n); try { Array.Copy(data, index, @out.data, 0, n); } catch (IndexOutOfRangeException e) { checkIndex(index); checkIndex(index + n - 1); } return(@out); }
/** {@inheritDoc} */ public RealMatrix solve(RealMatrix b) { if (!isNonSingular()) { throw new Exception("SingularMatrixException"); } int m = realEigenvalues.Length; if (b.getRowDimension() != m) { throw new Exception("DimensionMismatchException"); } int nColB = b.getColumnDimension(); double[][] bp = Java.CreateArray <double[][]>(m, nColB);// new double[m][nColB]; double[] tmpCol = new double[m]; for (int k = 0; k < nColB; ++k) { for (int i = 0; i < m; ++i) { tmpCol[i] = b.getEntry(i, k); bp[i][k] = 0; } for (int i = 0; i < m; ++i) { ArrayRealVector v = eigenvectors[i]; double[] vData = v.getDataRef(); double s = 0; for (int j = 0; j < m; ++j) { s += v.getEntry(j) * tmpCol[j]; } s /= realEigenvalues[i]; for (int j = 0; j < m; ++j) { bp[j][k] += s * vData[j]; } } } return(new Array2DRowRealMatrix(bp, false)); }
/** * Find eigenvectors from a matrix transformed to Schur form. * * @param schur the schur transformation of the matrix * @throws MathArithmeticException if the Schur form has a norm of zero */ private void findEigenVectorsFromSchur(SchurTransformer schur) { double[][] matrixT = schur.getT().getData(); double[][] matrixP = schur.getP().getData(); int n = matrixT.Length; // compute matrix norm double norm = 0.0; for (int i = 0; i < n; i++) { for (int j = Math.Max(i - 1, 0); j < n; j++) { norm += Math.Abs(matrixT[i][j]); } } // we can not handle a matrix with zero norm if (Precision.equals(norm, 0.0, EPSILON)) { throw new Exception("MathArithmeticException"); } // Backsubstitute to find vectors of upper triangular form double r = 0.0; double s = 0.0; double z = 0.0; for (int idx = n - 1; idx >= 0; idx--) { double p = realEigenvalues[idx]; double q = imagEigenvalues[idx]; if (Precision.equals(q, 0.0)) { // Real vector int l = idx; matrixT[idx][idx] = 1.0; for (int i = idx - 1; i >= 0; i--) { double w = matrixT[i][i] - p; r = 0.0; for (int j = l; j <= idx; j++) { r += matrixT[i][j] * matrixT[j][idx]; } if (Precision.compareTo(imagEigenvalues[i], 0.0, EPSILON) < 0) { z = w; s = r; } else { l = i; if (Precision.equals(imagEigenvalues[i], 0.0)) { if (w != 0.0) { matrixT[i][idx] = -r / w; } else { matrixT[i][idx] = -r / (Precision.EPSILON * norm); } } else { // Solve real equations double x = matrixT[i][i + 1]; double y = matrixT[i + 1][i]; q = (realEigenvalues[i] - p) * (realEigenvalues[i] - p) + imagEigenvalues[i] * imagEigenvalues[i]; double t = (x * s - z * r) / q; matrixT[i][idx] = t; if (Math.Abs(x) > Math.Abs(z)) { matrixT[i + 1][idx] = (-r - w * t) / x; } else { matrixT[i + 1][idx] = (-s - y * t) / z; } } // Overflow control double tx = Math.Abs(matrixT[i][idx]); if ((Precision.EPSILON * tx) * tx > 1) { for (int j = i; j <= idx; j++) { matrixT[j][idx] /= tx; } } } } } else if (q < 0.0) { // Complex vector int l = idx - 1; // Last vector component imaginary so matrix is triangular if (Math.Abs(matrixT[idx][idx - 1]) > Math.Abs(matrixT[idx - 1][idx])) { matrixT[idx - 1][idx - 1] = q / matrixT[idx][idx - 1]; matrixT[idx - 1][idx] = -(matrixT[idx][idx] - p) / matrixT[idx][idx - 1]; } else { Complex result = cdiv(0.0, -matrixT[idx - 1][idx], matrixT[idx - 1][idx - 1] - p, q); matrixT[idx - 1][idx - 1] = result.getReal(); matrixT[idx - 1][idx] = result.getImaginary(); } matrixT[idx][idx - 1] = 0.0; matrixT[idx][idx] = 1.0; for (int i = idx - 2; i >= 0; i--) { double ra = 0.0; double sa = 0.0; for (int j = l; j <= idx; j++) { ra += matrixT[i][j] * matrixT[j][idx - 1]; sa += matrixT[i][j] * matrixT[j][idx]; } double w = matrixT[i][i] - p; if (Precision.compareTo(imagEigenvalues[i], 0.0, EPSILON) < 0) { z = w; r = ra; s = sa; } else { l = i; if (Precision.equals(imagEigenvalues[i], 0.0)) { Complex c = cdiv(-ra, -sa, w, q); matrixT[i][idx - 1] = c.getReal(); matrixT[i][idx] = c.getImaginary(); } else { // Solve complex equations double x = matrixT[i][i + 1]; double y = matrixT[i + 1][i]; double vr = (realEigenvalues[i] - p) * (realEigenvalues[i] - p) + imagEigenvalues[i] * imagEigenvalues[i] - q * q; double vi = (realEigenvalues[i] - p) * 2.0 * q; if (Precision.equals(vr, 0.0) && Precision.equals(vi, 0.0)) { vr = Precision.EPSILON * norm * (Math.Abs(w) + Math.Abs(q) + Math.Abs(x) + Math.Abs(y) + Math.Abs(z)); } Complex c = cdiv(x * r - z * ra + q * sa, x * s - z * sa - q * ra, vr, vi); matrixT[i][idx - 1] = c.getReal(); matrixT[i][idx] = c.getImaginary(); if (Math.Abs(x) > (Math.Abs(z) + Math.Abs(q))) { matrixT[i + 1][idx - 1] = (-ra - w * matrixT[i][idx - 1] + q * matrixT[i][idx]) / x; matrixT[i + 1][idx] = (-sa - w * matrixT[i][idx] - q * matrixT[i][idx - 1]) / x; } else { Complex c2 = cdiv(-r - y * matrixT[i][idx - 1], -s - y * matrixT[i][idx], z, q); matrixT[i + 1][idx - 1] = c2.getReal(); matrixT[i + 1][idx] = c2.getImaginary(); } } // Overflow control double t = Math.Max(Math.Abs(matrixT[i][idx - 1]), Math.Abs(matrixT[i][idx])); if ((Precision.EPSILON * t) * t > 1) { for (int j = i; j <= idx; j++) { matrixT[j][idx - 1] /= t; matrixT[j][idx] /= t; } } } } } } // Back transformation to get eigenvectors of original matrix for (int j = n - 1; j >= 0; j--) { for (int i = 0; i <= n - 1; i++) { z = 0.0; for (int k = 0; k <= Math.Min(j, n - 1); k++) { z += matrixP[i][k] * matrixT[k][j]; } matrixP[i][j] = z; } } eigenvectors = new ArrayRealVector[n]; double[] tmp = new double[n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { tmp[j] = matrixP[j][i]; } eigenvectors[i] = new ArrayRealVector(tmp); } }
/** * Find eigenvalues and eigenvectors (Dubrulle et al., 1971) * * @param householderMatrix Householder matrix of the transformation * to tridiagonal form. */ private void findEigenVectors(double[][] householderMatrix) { double[][] z = householderMatrix.Clone() as double[][]; int n = main.Length; realEigenvalues = new double[n]; imagEigenvalues = new double[n]; double[] e = new double[n]; for (int i = 0; i < n - 1; i++) { realEigenvalues[i] = main[i]; e[i] = secondary[i]; } realEigenvalues[n - 1] = main[n - 1]; e[n - 1] = 0; // Determine the largest main and secondary value in absolute term. double maxAbsoluteValue = 0; for (int i = 0; i < n; i++) { if (Math.Abs(realEigenvalues[i]) > maxAbsoluteValue) { maxAbsoluteValue = Math.Abs(realEigenvalues[i]); } if (Math.Abs(e[i]) > maxAbsoluteValue) { maxAbsoluteValue = Math.Abs(e[i]); } } // Make null any main and secondary value too small to be significant if (maxAbsoluteValue != 0) { for (int i = 0; i < n; i++) { if (Math.Abs(realEigenvalues[i]) <= Precision.EPSILON * maxAbsoluteValue) { realEigenvalues[i] = 0; } if (Math.Abs(e[i]) <= Precision.EPSILON * maxAbsoluteValue) { e[i] = 0; } } } for (int j = 0; j < n; j++) { int its = 0; int m; do { for (m = j; m < n - 1; m++) { double delta = Math.Abs(realEigenvalues[m]) + Math.Abs(realEigenvalues[m + 1]); if (Math.Abs(e[m]) + delta == delta) { break; } } if (m != j) { if (its == maxIter) { throw new Exception("MaxCountExceededException"); } its++; double q = (realEigenvalues[j + 1] - realEigenvalues[j]) / (2 * e[j]); double t = Math.Sqrt(1 + q * q); if (q < 0.0) { q = realEigenvalues[m] - realEigenvalues[j] + e[j] / (q - t); } else { q = realEigenvalues[m] - realEigenvalues[j] + e[j] / (q + t); } double u = 0.0; double s = 1.0; double c = 1.0; int i; for (i = m - 1; i >= j; i--) { double p = s * e[i]; double h = c * e[i]; if (Math.Abs(p) >= Math.Abs(q)) { c = q / p; t = Math.Sqrt(c * c + 1.0); e[i + 1] = p * t; s = 1.0 / t; c *= s; } else { s = p / q; t = Math.Sqrt(s * s + 1.0); e[i + 1] = q * t; c = 1.0 / t; s *= c; } if (e[i + 1] == 0.0) { realEigenvalues[i + 1] -= u; e[m] = 0.0; break; } q = realEigenvalues[i + 1] - u; t = (realEigenvalues[i] - q) * s + 2.0 * c * h; u = s * t; realEigenvalues[i + 1] = q + u; q = c * t - h; for (int ia = 0; ia < n; ia++) { p = z[ia][i + 1]; z[ia][i + 1] = s * z[ia][i] + c * p; z[ia][i] = c * z[ia][i] - s * p; } } if (t == 0.0 && i >= j) { continue; } realEigenvalues[j] -= u; e[j] = q; e[m] = 0.0; } } while (m != j); } //Sort the eigen values (and vectors) in increase order for (int i = 0; i < n; i++) { int k = i; double p = realEigenvalues[i]; for (int j = i + 1; j < n; j++) { if (realEigenvalues[j] > p) { k = j; p = realEigenvalues[j]; } } if (k != i) { realEigenvalues[k] = realEigenvalues[i]; realEigenvalues[i] = p; for (int j = 0; j < n; j++) { p = z[j][i]; z[j][i] = z[j][k]; z[j][k] = p; } } } // Determine the largest eigen value in absolute term. maxAbsoluteValue = 0; for (int i = 0; i < n; i++) { if (Math.Abs(realEigenvalues[i]) > maxAbsoluteValue) { maxAbsoluteValue = Math.Abs(realEigenvalues[i]); } } // Make null any eigen value too small to be significant if (maxAbsoluteValue != 0.0) { for (int i = 0; i < n; i++) { if (Math.Abs(realEigenvalues[i]) < Precision.EPSILON * maxAbsoluteValue) { realEigenvalues[i] = 0; } } } eigenvectors = new ArrayRealVector[n]; double[] tmp = new double[n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { tmp[j] = z[j][i]; } eigenvectors[i] = new ArrayRealVector(tmp); } }
/** * Construct a vector by appending a vector to this vector. * * @param v Vector to append to this one. * @return a new vector. */ public ArrayRealVector append(ArrayRealVector v) { return(new ArrayRealVector(this, v)); }
/** * Construct a vector by appending one vector to another vector. * @param v1 First vector (will be put in front of the new vector). * @param v2 Second vector (will be put at back of the new vector). */ public ArrayRealVector(ArrayRealVector v1, ArrayRealVector v2) { data = new double[v1.data.Length + v2.data.Length]; Array.Copy(v1.data, 0, data, 0, v1.data.Length); Array.Copy(v2.data, 0, data, v1.data.Length, v2.data.Length); }
/** * Construct a vector from another vector. * * @param v Vector to copy. * @param deep If {@code true} perform a deep copy, otherwise perform a * shallow copy. */ public ArrayRealVector(ArrayRealVector v, bool deep) { data = (deep ? v.data.Clone() : v.data) as double[]; }
/** * Construct a vector from another vector, using a deep copy. * * @param v Vector to copy. * @throws NullArgumentException if {@code v} is {@code null}. */ public ArrayRealVector(ArrayRealVector v) : this(v, true) { }