/** * <p> * Solves for x in the following equation:<br> * <br> * A*x = b * </p> * * <p> * If the system could not be solved then false is returned. If it returns true * that just means the algorithm finished operating, but the results could still be bad * because 'A' is singular or nearly singular. * </p> * * <p> * If repeat calls to solve are being made then one should consider using {@link LinearSolverFactory_DSCC} * instead. * </p> * * <p> * It is ok for 'b' and 'x' to be the same matrix. * </p> * * @param a (Input) A matrix that is m by n. Not modified. * @param b (Input) A matrix that is n by k. Not modified. * @param x (Output) A matrix that is m by k. Modified. * * @return true if it could invert the matrix false if it could not. */ public static bool solve(DMatrixSparseCSC a, DMatrixRMaj b, DMatrixRMaj x) { LinearSolverSparse <DMatrixSparseCSC, DMatrixRMaj> solver; if (a.numRows > a.numCols) { solver = LinearSolverFactory_DSCC.qr(FillReducing.NONE); // todo specify a filling that makes sense } else { solver = LinearSolverFactory_DSCC.lu(FillReducing.NONE); } // Ensure that the input isn't modified if (solver.modifiesA()) { a = (DMatrixSparseCSC)a.copy(); } if (solver.modifiesB()) { b = (DMatrixRMaj)b.copy(); } // decompose then solve the matrix if (!solver.setA(a)) { return(false); } solver.solve(b, x); return(true); }
/** * <p> * Checks to see if the matrix is positive semidefinite: * </p> * <p> * x<sup>T</sup> A x ≥ 0<br> * for all x where x is a non-zero vector and A is a symmetric matrix. * </p> * * @param A square symmetric matrix. Not modified. * * @return True if it is positive semidefinite and false if it is not. */ public static bool isPositiveSemidefinite(DMatrixRMaj A) { if (!isSquare(A)) { return(false); } EigenDecomposition_F64 <DMatrixRMaj> eig = DecompositionFactory_DDRM.eig(A.numCols, false); if (eig.inputModified()) { A = (DMatrixRMaj)A.copy(); } eig.decompose(A); for (int i = 0; i < A.numRows; i++) { Complex_F64 v = eig.getEigenvalue(i); if (v.getReal() < 0) { return(false); } } return(true); }
/** * Computes the QR decomposition of the provided matrix. * * @param A Matrix which is to be decomposed. Not modified. */ public void decompose(DMatrixRMaj A) { Equation.Equation eq = new Equation.Equation(); this.QR = (DMatrixRMaj)A.copy(); int N = Math.Min(A.numCols, A.numRows); gammas = new double[A.numCols]; for (int i = 0; i < N; i++) { // update temporary variables eq.alias(QR.numRows - i, "Ni", QR, "QR", i, "i"); // Place the column that should be zeroed into v eq.process("v=QR(i:,i)"); eq.process("maxV=max(abs(v))"); // Note that v is lazily created above. Need direct access to it, which is done below. DMatrixRMaj v = eq.lookupMatrix("v"); double maxV = eq.lookupDouble("maxV"); if (maxV > 0 && v.getNumElements() > 1) { // normalize to reduce overflow issues eq.process("v=v/maxV"); // compute the magnitude of the vector double tau = NormOps_DDRM.normF(v); if (v.get(0) < 0) { tau *= -1.0; } eq.alias(tau, "tau"); eq.process("u_0 = v(0,0)+tau"); eq.process("gamma = u_0/tau"); eq.process("v=v/u_0"); eq.process("v(0,0)=1"); eq.process("QR(i:,i:) = (eye(Ni) - gamma*v*v')*QR(i:,i:)"); eq.process("QR(i:,i) = v"); eq.process("QR(i,i) = -1*tau*maxV"); // save gamma for recomputing Q later on gammas[i] = eq.lookupDouble("gamma"); } } }
/** * <p> * Checks to see if the matrix is positive definite. * </p> * <p> * x<sup>T</sup> A x > 0<br> * for all x where x is a non-zero vector and A is a symmetric matrix. * </p> * * @param A square symmetric matrix. Not modified. * @return True if it is positive definite and false if it is not. */ public static bool isPositiveDefinite(DMatrixRMaj A) { if (!isSquare(A)) { return(false); } CholeskyDecompositionInner_DDRM chol = new CholeskyDecompositionInner_DDRM(true); if (chol.inputModified()) { A = A.copy(); } return(chol.decompose(A)); }
/** * Creates a random distribution with the specified mean and covariance. The references * to the variables are not saved, their value are copied. * * @param rand Used to create the random numbers for the draw. Reference is saved. * @param cov The covariance of the distribution. Not modified. */ public CovarianceRandomDraw_DDRM(IMersenneTwister rand, DMatrixRMaj cov) { r = new DMatrixRMaj(cov.numRows, 1); CholeskyDecompositionInner_DDRM cholesky = new CholeskyDecompositionInner_DDRM(true); if (cholesky.inputModified()) { cov = (DMatrixRMaj)cov.copy(); } if (!cholesky.decompose(cov)) { throw new InvalidOperationException("Decomposition failed!"); } A = cholesky.getT(); this.rand = rand; }
/** * Computes the nullity of a matrix using the specified tolerance. * * @param A Matrix whose rank is to be calculated. Not modified. * @param threshold The numerical threshold used to determine a singular value. * @return The matrix's nullity. */ public static int nullity(DMatrixRMaj A, double threshold) { SingularValueDecomposition_F64 <DMatrixRMaj> svd = DecompositionFactory_DDRM.svd(A.numRows, A.numCols, false, false, true); if (svd.inputModified()) { A = (DMatrixRMaj)A.copy(); } if (!svd.decompose(A)) { throw new InvalidOperationException("Decomposition failed"); } return(SingularOps_DDRM.nullity(svd, threshold)); }
/** * Checks to see if the rows of the provided matrix are linearly independent. * * @param A Matrix whose rows are being tested for linear independence. * @return true if linearly independent and false otherwise. */ public static bool isRowsLinearIndependent(DMatrixRMaj A) { // LU decomposition LUDecomposition <DMatrixRMaj> lu = DecompositionFactory_DDRM.lu(A.numRows, A.numCols); if (lu.inputModified()) { A = A.copy(); } if (!lu.decompose(A)) { throw new SystemException("Decompositon failed?"); } // if they are linearly independent it should not be singular return(!lu.isSingular()); }
/** * Creates a random distribution with the specified mean and covariance. The references * to the variables are not saved, their value are copied. * * @param rand Used to create the random numbers for the draw. Reference is saved. * @param cov The covariance of the distribution. Not modified. */ public CovarianceRandomDraw_DDRM(Random rand, DMatrixRMaj cov) { r = new DMatrixRMaj(cov.numRows, 1); CholeskyDecompositionInner_DDRM cholesky = new CholeskyDecompositionInner_DDRM(true); if (cholesky.inputModified()) { cov = cov.copy(); } if (!cholesky.decompose(cov)) { throw new SystemException("Decomposition failed!"); } A = cholesky.getT(); //this.rand = rand; this.rand = new Java.Util.Random(); }
public override object Clone() { CMAESSpecies myobj = (CMAESSpecies)(base.Clone()); // clone the distribution and other variables here myobj.c = c.copy(); myobj.b = b.copy(); myobj.d = d.copy(); myobj.bd = (DMatrixRMaj)bd.copy(); myobj.sbd = (DMatrixRMaj)sbd.copy(); myobj.invsqrtC = invsqrtC.copy(); myobj.xmean = xmean.copy(); myobj.ps = ps.copy(); myobj.pc = pc.copy(); return(myobj); }
public void setup(DMatrixRMaj A) { if (A.numRows != A.numCols) { throw new InvalidOperationException("Must be square"); } if (N != A.numRows) { N = A.numRows; this.A = (DMatrixRMaj)A.copy(); u = new DMatrixRMaj(A.numRows, 1); _temp = new DMatrixRMaj(A.numRows, 1); numStepsFind = new int[A.numRows]; } else { this.A.set(A); UtilEjml.memset(numStepsFind, 0, numStepsFind.Length); } // zero all the off numbers that should be zero for a hessenberg matrix for (int i = 2; i < N; i++) { for (int j = 0; j < i - 1; j++) { this.A.set(i, j, 0); } } eigenvalues = new Complex_F64[A.numRows]; for (int i = 0; i < eigenvalues.Length; i++) { eigenvalues[i] = new Complex_F64(); } numEigen = 0; lastExceptional = 0; numExceptional = 0; steps = 0; }
private List <DMatrixRMaj> createSimulatedMeas(DMatrixRMaj x) { List <DMatrixRMaj> ret = new List <DMatrixRMaj>(); DMatrixRMaj F = createF(T); DMatrixRMaj H = createH(); // UtilEjml.print(F); // UtilEjml.print(H); DMatrixRMaj x_next = new DMatrixRMaj(x); DMatrixRMaj z = new DMatrixRMaj(H.numRows, 1); for (int i = 0; i < MAX_STEPS; i++) { CommonOps_DDRM.mult(F, x, x_next); CommonOps_DDRM.mult(H, x_next, z); ret.Add((DMatrixRMaj)z.copy()); x.set(x_next); } return(ret); }
/** * Computes the QR decomposition of the provided matrix. * * @param A Matrix which is to be decomposed. Not modified. */ public void decompose(DMatrixRMaj A) { this.QR = (DMatrixRMaj)A.copy(); int N = Math.Min(A.numCols, A.numRows); gammas = new double[A.numCols]; DMatrixRMaj A_small = new DMatrixRMaj(A.numRows, A.numCols); DMatrixRMaj A_mod = new DMatrixRMaj(A.numRows, A.numCols); DMatrixRMaj v = new DMatrixRMaj(A.numRows, 1); DMatrixRMaj Q_k = new DMatrixRMaj(A.numRows, A.numRows); for (int i = 0; i < N; i++) { // reshape temporary variables A_small.reshape(QR.numRows - i, QR.numCols - i, false); A_mod.reshape(A_small.numRows, A_small.numCols, false); v.reshape(A_small.numRows, 1, false); Q_k.reshape(v.getNumElements(), v.getNumElements(), false); // use extract matrix to get the column that is to be zeroed CommonOps_DDRM.extract(QR, i, QR.numRows, i, i + 1, v, 0, 0); double max = CommonOps_DDRM.elementMaxAbs(v); if (max > 0 && v.getNumElements() > 1) { // normalize to reduce overflow issues CommonOps_DDRM.divide(v, max); // compute the magnitude of the vector double tau = NormOps_DDRM.normF(v); if (v.get(0) < 0) { tau *= -1.0; } double u_0 = v.get(0) + tau; double gamma = u_0 / tau; CommonOps_DDRM.divide(v, u_0); v.set(0, 1.0); // extract the submatrix of A which is being operated on CommonOps_DDRM.extract(QR, i, QR.numRows, i, QR.numCols, A_small, 0, 0); // A = (I - γ*u*u<sup>T</sup>)A CommonOps_DDRM.setIdentity(Q_k); CommonOps_DDRM.multAddTransB(-gamma, v, v, Q_k); CommonOps_DDRM.mult(Q_k, A_small, A_mod); // save the results CommonOps_DDRM.insert(A_mod, QR, i, i); CommonOps_DDRM.insert(v, QR, i, i); QR.unsafe_set(i, i, -tau * max); // save gamma for recomputing Q later on gammas[i] = gamma; } } }