/** * Performs a matrix inversion operations that takes advantage of the special * properties of a covariance matrix. * * @param cov A covariance matrix. Not modified. * @param cov_inv The inverse of cov. Modified. * @return true if it could invert the matrix false if it could not. */ public static bool invert(DMatrixRMaj cov, DMatrixRMaj cov_inv) { if (cov.numCols <= 4) { if (cov.numCols != cov.numRows) { throw new ArgumentException("Must be a square matrix."); } if (cov.numCols >= 2) { UnrolledInverseFromMinor_DDRM.inv(cov, cov_inv); } else { cov_inv.data[0] = 1.0 / cov_inv.data[0]; } } else { LinearSolverDense <DMatrixRMaj> solver = LinearSolverFactory_DDRM.symmPosDef(cov.numRows); // wrap it to make sure the covariance is not modified. solver = new LinearSolverSafe <DMatrixRMaj>(solver); if (!solver.setA(cov)) { return(false); } solver.invert(cov_inv); } return(true); }
/** * Constructor. * * @param degree The polynomial's degree which is to be fit to the observations. */ public PolynomialFit(int degree) { coef = new DMatrixRMaj(degree + 1, 1); A = new DMatrixRMaj(1, degree + 1); y = new DMatrixRMaj(1, 1); // create a solver that allows elements to be added or removed efficiently solver = LinearSolverFactory_DDRM.adjustable(); }
/** * Computes the most dominant eigen vector of A using an inverted shifted matrix. * The inverted shifted matrix is defined as <b>B = (A - αI)<sup>-1</sup></b> and * can converge faster if α is chosen wisely. * * @param A An invertible square matrix matrix. * @param alpha Shifting factor. * @return If it converged or not. */ public bool computeShiftInvert(DMatrixRMaj A, double alpha) { initPower(A); LinearSolverDense <DMatrixRMaj> solver = LinearSolverFactory_DDRM.linear(A.numCols); SpecializedOps_DDRM.addIdentity(A, B, -alpha); solver.setA(B); bool converged = false; for (int i = 0; i < maxIterations && !converged; i++) { solver.solve(q0, q1); double s = NormOps_DDRM.normPInf(q1); CommonOps_DDRM.divide(q1, s, q2); converged = checkConverged(A); } return(converged); }
public bool process(WatchedDoubleStepQREigen_DDRM imp, DMatrixRMaj A, DMatrixRMaj Q_h) { this._implicit = imp; if (N != A.numRows) { N = A.numRows; Q = new DMatrixRMaj(N, N); splits = new int[N]; origEigenvalues = new Complex_F64[N]; eigenvectors = new DMatrixRMaj[N]; eigenvectorTemp = new DMatrixRMaj(N, 1); solver = LinearSolverFactory_DDRM.linear(0); } else { // UtilEjml.setnull(eigenvectors); eigenvectors = new DMatrixRMaj[N]; } Array.Copy(_implicit.eigenvalues, 0, origEigenvalues, 0, N); _implicit.setup(A); _implicit.setQ(Q); numSplits = 0; onscript = true; // Console.WriteLine("Orig A"); // A.print("%12.10f"); if (!findQandR()) { return(false); } return(extractVectors(Q_h)); }
//@Override public void configure(DMatrixRMaj F, DMatrixRMaj Q, DMatrixRMaj H) { this.F = F; this.Q = Q; this.H = H; int dimenX = F.numCols; int dimenZ = H.numRows; a = new DMatrixRMaj(dimenX, 1); b = new DMatrixRMaj(dimenX, dimenX); y = new DMatrixRMaj(dimenZ, 1); S = new DMatrixRMaj(dimenZ, dimenZ); S_inv = new DMatrixRMaj(dimenZ, dimenZ); c = new DMatrixRMaj(dimenZ, dimenX); d = new DMatrixRMaj(dimenX, dimenZ); K = new DMatrixRMaj(dimenX, dimenZ); x = new DMatrixRMaj(dimenX, 1); P = new DMatrixRMaj(dimenX, dimenX); // covariance matrices are symmetric positive semi-definite solver = LinearSolverFactory_DDRM.symmPosDef(dimenX); }
/** * <p> * Given an eigenvalue it computes an eigenvector using inverse iteration: * <br> * for i=1:MAX {<br> * (A - μI)z<sup>(i)</sup> = q<sup>(i-1)</sup><br> * q<sup>(i)</sup> = z<sup>(i)</sup> / ||z<sup>(i)</sup>||<br> * λ<sup>(i)</sup> = q<sup>(i)</sup><sup>T</sup> A q<sup>(i)</sup><br> * }<br> * </p> * <p> * NOTE: If there is another eigenvalue that is very similar to the provided one then there * is a chance of it converging towards that one instead. The larger a matrix is the more * likely this is to happen. * </p> * @param A Matrix whose eigenvector is being computed. Not modified. * @param eigenvalue The eigenvalue in the eigen pair. * @return The eigenvector or null if none could be found. */ public static DEigenpair computeEigenVector(DMatrixRMaj A, double eigenvalue) { if (A.numRows != A.numCols) { throw new ArgumentException("Must be a square matrix."); } DMatrixRMaj M = new DMatrixRMaj(A.numRows, A.numCols); DMatrixRMaj x = new DMatrixRMaj(A.numRows, 1); DMatrixRMaj b = new DMatrixRMaj(A.numRows, 1); CommonOps_DDRM.fill(b, 1); // perturb the eigenvalue slightly so that its not an exact solution the first time // eigenvalue -= eigenvalue*UtilEjml.EPS*10; double origEigenvalue = eigenvalue; SpecializedOps_DDRM.addIdentity(A, M, -eigenvalue); double threshold = NormOps_DDRM.normPInf(A) * UtilEjml.EPS; double prevError = double.MaxValue; bool hasWorked = false; LinearSolverDense <DMatrixRMaj> solver = LinearSolverFactory_DDRM.linear(M.numRows); double perp = 0.0001; for (int i = 0; i < 200; i++) { bool failed = false; // if the matrix is singular then the eigenvalue is within machine precision // of the true value, meaning that x must also be. if (!solver.setA(M)) { failed = true; } else { solver.solve(b, x); } // see if solve silently failed if (MatrixFeatures_DDRM.hasUncountable(x)) { failed = true; } if (failed) { if (!hasWorked) { // if it failed on the first trial try perturbing it some more double val = i % 2 == 0 ? 1.0 - perp : 1.0 + perp; // maybe this should be turn into a parameter allowing the user // to configure the wise of each step eigenvalue = origEigenvalue * Math.Pow(val, i / 2 + 1); SpecializedOps_DDRM.addIdentity(A, M, -eigenvalue); } else { // otherwise assume that it was so accurate that the matrix was singular // and return that result return(new DEigenpair(eigenvalue, b)); } } else { hasWorked = true; b.set(x); NormOps_DDRM.normalizeF(b); // compute the residual CommonOps_DDRM.mult(M, b, x); double error = NormOps_DDRM.normPInf(x); if (error - prevError > UtilEjml.EPS * 10) { // if the error increased it is probably converging towards a different // eigenvalue // CommonOps.set(b,1); prevError = double.MaxValue; hasWorked = false; double val = i % 2 == 0 ? 1.0 - perp : 1.0 + perp; eigenvalue = origEigenvalue * Math.Pow(val, 1); } else { // see if it has converged if (error <= threshold || Math.Abs(prevError - error) <= UtilEjml.EPS) { return(new DEigenpair(eigenvalue, b)); } // update everything prevError = error; eigenvalue = VectorVectorMult_DDRM.innerProdA(b, A, b); } SpecializedOps_DDRM.addIdentity(A, M, -eigenvalue); } } return(null); }