/** * <p> * Creates a randomly generated set of orthonormal vectors. At most it can generate the same * number of vectors as the dimension of the vectors. * </p> * * <p> * This is done by creating random vectors then ensuring that they are orthogonal * to all the ones previously created with reflectors. * </p> * * <p> * NOTE: This employs a brute force O(N<sup>3</sup>) algorithm. * </p> * * @param dimen dimension of the space which the vectors will span. * @param numVectors How many vectors it should generate. * @param rand Used to create random vectors. * @return Array of N random orthogonal vectors of unit length. */ // is there a faster algorithm out there? This one is a bit sluggish public static DMatrixRMaj[] span(int dimen, int numVectors, IMersenneTwister rand) { if (dimen < numVectors) { throw new ArgumentException("The number of vectors must be less than or equal to the dimension"); } DMatrixRMaj[] u = new DMatrixRMaj[numVectors]; u[0] = RandomMatrices_DDRM.rectangle(dimen, 1, -1, 1, rand); NormOps_DDRM.normalizeF(u[0]); for (int i = 1; i < numVectors; i++) { // Console.WriteLine(" i = "+i); DMatrixRMaj a = new DMatrixRMaj(dimen, 1); DMatrixRMaj r = null; for (int j = 0; j < i; j++) { // Console.WriteLine("j = "+j); if (j == 0) { r = RandomMatrices_DDRM.rectangle(dimen, 1, -1, 1, rand); } // find a vector that is normal to vector j // u[i] = (1/2)*(r + Q[j]*r) a.set(r); VectorVectorMult_DDRM.householder(-2.0, u[j], r, a); CommonOps_DDRM.add(r, a, a); CommonOps_DDRM.scale(0.5, a); // UtilEjml.print(a); DMatrixRMaj t = a; a = r; r = t; // normalize it so it doesn't get too small double val = NormOps_DDRM.normF(r); if (val == 0 || double.IsNaN(val) || double.IsInfinity(val)) { throw new InvalidOperationException("Failed sanity check"); } CommonOps_DDRM.divide(r, val); } u[i] = r; } return(u); }
/** * <p> * Computes the F norm of the difference between the two Matrices:<br> * <br> * Sqrt{∑<sub>i=1:m</sub> ∑<sub>j=1:n</sub> ( a<sub>ij</sub> - b<sub>ij</sub>)<sup>2</sup>} * </p> * <p> * This is often used as a cost function. * </p> * * @see NormOps_DDRM#fastNormF * * @param a m by n matrix. Not modified. * @param b m by n matrix. Not modified. * * @return The F normal of the difference matrix. */ public static double diffNormF(DMatrixD1 a, DMatrixD1 b) { if (a.numRows != b.numRows || a.numCols != b.numCols) { throw new ArgumentException("Both matrices must have the same shape."); } int size = a.getNumElements(); DMatrixRMaj diff = new DMatrixRMaj(size, 1); for (int i = 0; i < size; i++) { diff.set(i, b.get(i) - a.get(i)); } return(NormOps_DDRM.normF(diff)); }