/** * Computes the d and H parameters. Where d is the average error gradient and * H is an approximation of the hessian. */ private void computeDandH(DMatrixRMaj param, DMatrixRMaj x, DMatrixRMaj y) { func.compute(param, x, tempDH); CommonOps_DDRM.subtractEquals(tempDH, y); computeNumericalJacobian(param, x, jacobian); int numParam = param.getNumElements(); int length = x.getNumElements(); // d = average{ (f(x_i;p) - y_i) * jacobian(:,i) } for (int i = 0; i < numParam; i++) { double total = 0; for (int j = 0; j < length; j++) { total += tempDH.get(j, 0) * jacobian.get(i, j); } d.set(i, 0, total / length); } // compute the approximation of the hessian CommonOps_DDRM.multTransB(jacobian, jacobian, H); CommonOps_DDRM.scale(1.0 / length, H); }
//@Override public void update(DMatrixRMaj z, DMatrixRMaj R) { // y = z - H x CommonOps_DDRM.mult(H, x, y); CommonOps_DDRM.subtract(z, y, y); // S = H P H' + R CommonOps_DDRM.mult(H, P, c); CommonOps_DDRM.multTransB(c, H, S); CommonOps_DDRM.addEquals(S, R); // K = PH'S^(-1) if (!solver.setA(S)) { throw new InvalidOperationException("Invert failed"); } solver.invert(S_inv); CommonOps_DDRM.multTransA(H, S_inv, d); CommonOps_DDRM.mult(P, d, K); // x = x + Ky CommonOps_DDRM.mult(K, y, a); CommonOps_DDRM.addEquals(x, a); // P = (I-kH)P = P - (KH)P = P-K(HP) CommonOps_DDRM.mult(H, P, c); CommonOps_DDRM.mult(K, c, b); CommonOps_DDRM.subtractEquals(P, b); }
//@Override public void predict() { // x = F x CommonOps_DDRM.mult(F, x, a); x.set(a); // P = F P F' + Q CommonOps_DDRM.mult(F, P, b); CommonOps_DDRM.multTransB(b, F, P); CommonOps_DDRM.addEquals(P, Q); }
/** * Creates a newJava.Util.Random symmetric matrix that will have the specified real eigenvalues. * * @param num Dimension of the resulting matrix. * @param randJava.Util.Random number generator. * @param eigenvalues Set of real eigenvalues that the matrix will have. * @return AJava.Util.Random matrix with the specified eigenvalues. */ public static DMatrixRMaj symmetricWithEigenvalues(int num, Java.Util.Random rand, double[] eigenvalues) { DMatrixRMaj V = RandomMatrices_DDRM.orthogonal(num, num, rand); DMatrixRMaj D = CommonOps_DDRM.diag(eigenvalues); DMatrixRMaj temp = new DMatrixRMaj(num, num); CommonOps_DDRM.mult(V, D, temp); CommonOps_DDRM.multTransB(temp, V, D); return(D); }
/** * Creates aJava.Util.Random symmetric positive definite matrix. * * @param width The width of the square matrix it returns. * @param randJava.Util.Random number generator used to make the matrix. * @return TheJava.Util.Random symmetric positive definite matrix. */ public static DMatrixRMaj symmetricPosDef(int width, Java.Util.Random rand) { // This is not formally proven to work. It just seems to work. DMatrixRMaj a = new DMatrixRMaj(width, 1); DMatrixRMaj b = new DMatrixRMaj(width, width); for (int i = 0; i < width; i++) { a.set(i, 0, rand.NextDouble()); } CommonOps_DDRM.multTransB(a, a, b); for (int i = 0; i < width; i++) { b.add(i, i, 1); } return(b); }
/** * <p> * Creates aJava.Util.Random matrix which will have the provided singular values. The Count() of sv * is assumed to be the rank of the matrix. This can be useful for testing purposes when one * needs to ensure that a matrix is not singular but randomly generated. * </p> * * @param numRows Number of rows in generated matrix. * @param numCols NUmber of columns in generated matrix. * @param randJava.Util.Random number generator. * @param sv Singular values of the matrix. * @return A new matrix with the specified singular values. */ public static DMatrixRMaj singular(int numRows, int numCols, Java.Util.Random rand, double[] sv) { DMatrixRMaj U, V, S; // speed it up in compact format if (numRows > numCols) { U = RandomMatrices_DDRM.orthogonal(numRows, numCols, rand); V = RandomMatrices_DDRM.orthogonal(numCols, numCols, rand); S = new DMatrixRMaj(numCols, numCols); } else { U = RandomMatrices_DDRM.orthogonal(numRows, numRows, rand); V = RandomMatrices_DDRM.orthogonal(numCols, numCols, rand); S = new DMatrixRMaj(numRows, numCols); } int min = Math.Min(numRows, numCols); min = Math.Min(min, sv.Count()); for (int i = 0; i < min; i++) { S.set(i, i, sv[i]); } DMatrixRMaj tmp = new DMatrixRMaj(numRows, numCols); CommonOps_DDRM.mult(U, S, tmp); S.reshape(numRows, numCols); CommonOps_DDRM.multTransB(tmp, V, S); return(S); }
/** * <p> * Creates a random matrix which will have the provided singular values. The length of sv * is assumed to be the rank of the matrix. This can be useful for testing purposes when one * needs to ensure that a matrix is not singular but randomly generated. * </p> * * @param numRows Number of rows in generated matrix. * @param numCols NUmber of columns in generated matrix. * @param rand Random number generator. * @param sv Singular values of the matrix. * @return A new matrix with the specified singular values. */ public static DMatrixRMaj singleValues(int numRows, int numCols, IMersenneTwister rand, double[] sv) { DMatrixRMaj U = RandomMatrices_DDRM.orthogonal(numRows, numRows, rand); DMatrixRMaj V = RandomMatrices_DDRM.orthogonal(numCols, numCols, rand); DMatrixRMaj S = new DMatrixRMaj(numRows, numCols); int min = Math.Min(numRows, numCols); min = Math.Min(min, sv.Length); for (int i = 0; i < min; i++) { S.set(i, i, sv[i]); } DMatrixRMaj tmp = new DMatrixRMaj(numRows, numCols); CommonOps_DDRM.mult(U, S, tmp); CommonOps_DDRM.multTransB(tmp, V, S); return(S); }
public virtual bool decompose(DMatrixRMaj orig) { if (!decompQRP.decompose(orig)) { return(false); } m = orig.numRows; n = orig.numCols; min = Math.Min(m, n); B.reshape(min, n, false); decompQRP.getR(B, true); // apply the column pivots. // TODO this is horribly inefficient DMatrixRMaj result = new DMatrixRMaj(min, n); DMatrixRMaj P = decompQRP.getColPivotMatrix(null); CommonOps_DDRM.multTransB(B, P, result); B.set(result); return(decompBi.decompose(B)); }