All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ejml.simple.SimpleMatrix Maven / Gradle / Ivy

/*
 * Copyright (c) 2022, Peter Abeles. All Rights Reserved.
 *
 * This file is part of Efficient Java Matrix Library (EJML).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.ejml.simple;

import org.ejml.data.*;
import org.ejml.dense.row.*;
import org.ejml.ops.DConvertMatrixStruct;
import org.ejml.ops.FConvertMatrixStruct;

import java.util.Random;

/**
 * 

* {@link SimpleMatrix} is a wrapper around {@link DMatrixRMaj} that provides an * easy to use object oriented interface for performing matrix operations. It is designed to be * more accessible to novice programmers and provide a way to rapidly code up solutions by simplifying * memory management and providing easy to use functions. *

* *

* Most functions in SimpleMatrix do not modify the original matrix. Instead they * create a new SimpleMatrix instance which is modified and returned. This greatly simplifies memory * management and writing of code in general. It also allows operations to be chained, as is shown * below:
*
* SimpleMatrix K = P.mult(H.transpose().mult(S.invert())); *

* *

* Working with both {@link DMatrixRMaj} and SimpleMatrix in the same code base is easy. * To access the internal DMatrixRMaj in a SimpleMatrix simply call {@link SimpleMatrix#getMatrix()}. * To turn a DMatrixRMaj into a SimpleMatrix use {@link SimpleMatrix#wrap(org.ejml.data.Matrix)}. Not * all operations in EJML are provided for SimpleMatrix, but can be accessed by extracting the internal * DMatrixRMaj. *

* *

* EXTENDING: SimpleMatrix contains a list of narrowly focused functions for linear algebra. To harness * the functionality for another application and to the number of functions it supports it is recommended * that one extends {@link SimpleBase} instead. This way the returned matrix type's of SimpleMatrix functions * will be of the appropriate types. See StatisticsMatrix inside of the examples directory. *

* *

* PERFORMANCE: The disadvantage of using this class is that it is more resource intensive, since * it creates a new matrix each time an operation is performed. This makes the JavaVM work harder and * Java automatically initializes the matrix to be all zeros. Typically operations on small matrices * or operations that have a runtime linear with the number of elements are the most affected. More * computationally intensive operations have only a slight unnoticeable performance loss. MOST PEOPLE * SHOULD NOT WORRY ABOUT THE SLIGHT LOSS IN PERFORMANCE. *

* *

* It is hard to judge how significant the performance hit will be in general. Often the performance * hit is insignificant since other parts of the application are more processor intensive or the bottle * neck is a more computationally complex operation. The best approach is benchmark and then optimize the code. *

* *

* If SimpleMatrix is extended then the protected function {link #createMatrix} should be extended and return * the child class. The results of SimpleMatrix operations will then be of the correct matrix type. *

* *

* The object oriented approach used in SimpleMatrix was originally inspired by Jama. * http://math.nist.gov/javanumerics/jama/ *

* * @author Peter Abeles */ public class SimpleMatrix extends SimpleBase { /** * A simplified way to reference the last row or column in the matrix for some functions. */ public static final int END = Integer.MAX_VALUE; /** *

* Creates a new matrix which has the same value as the matrix encoded in the * provided array. The input matrix's format can either be row-major or * column-major. *

* *

* Note that 'data' is a variable argument type, so either 1D arrays or a set of numbers can be * passed in:
* SimpleMatrix a = new SimpleMatrix(2,2,true,new double[]{1,2,3,4});
* SimpleMatrix b = new SimpleMatrix(2,2,true,1,2,3,4);
*
* Both are equivalent. *

* * @param numRows The number of rows. * @param numCols The number of columns. * @param rowMajor If the array is encoded in a row-major or a column-major format. * @param data The formatted 1D array. Not modified. * @see DMatrixRMaj#DMatrixRMaj(int, int, boolean, double...) */ public SimpleMatrix( int numRows, int numCols, boolean rowMajor, double... data ) { setMatrix(new DMatrixRMaj(numRows, numCols, rowMajor, data)); } /** *

* Creates a new matrix which has the same value as the matrix encoded in the * provided array. The input matrix's format can either be row-major or * column-major. *

* *

* Note that 'data' is a variable argument type, so either 1D arrays or a set of numbers can be * passed in:
* SimpleMatrix a = new SimpleMatrix(2,2,true,new float[]{1,2,3,4});
* SimpleMatrix b = new SimpleMatrix(2,2,true,1,2,3,4);
*
* Both are equivalent. *

* * @param numRows The number of rows. * @param numCols The number of columns. * @param rowMajor If the array is encoded in a row-major or a column-major format. * @param data The formatted 1D array. Not modified. * @see FMatrixRMaj#FMatrixRMaj(int, int, boolean, float...) */ public SimpleMatrix( int numRows, int numCols, boolean rowMajor, float... data ) { setMatrix(new FMatrixRMaj(numRows, numCols, rowMajor, data)); } /** *

* Creates a matrix with the values and shape defined by the 2D array 'data'. * It is assumed that 'data' has a row-major formatting:
*
* data[ row ][ column ] *

* * @param data 2D array representation of the matrix. Not modified. * @see DMatrixRMaj#DMatrixRMaj(double[][]) */ public SimpleMatrix( double data[][] ) { setMatrix(new DMatrixRMaj(data)); } /** *

* Creates a matrix with the values and shape defined by the 2D array 'data'. * It is assumed that 'data' has a row-major formatting:
*
* data[ row ][ column ] *

* * @param data 2D array representation of the matrix. Not modified. * @see FMatrixRMaj#FMatrixRMaj(float[][]) */ public SimpleMatrix( float data[][] ) { setMatrix(new FMatrixRMaj(data)); } /** * Creates a column vector with the values and shape defined by the 1D array 'data'. * * @param data 1D array representation of the vector. Not modified. */ public SimpleMatrix( double data[] ) { setMatrix(new DMatrixRMaj(data.length, 1, true, data)); } /** * Creates a column vector with the values and shape defined by the 1D array 'data'. * * @param data 1D array representation of the vector. Not modified. */ public SimpleMatrix( float data[] ) { setMatrix(new FMatrixRMaj(data.length, 1, true, data)); } /** * Creates a new matrix that is initially set to zero with the specified dimensions. This will wrap a * {@link DMatrixRMaj}. * * @param numRows The number of rows in the matrix. * @param numCols The number of columns in the matrix. */ public SimpleMatrix( int numRows, int numCols ) { setMatrix(new DMatrixRMaj(numRows, numCols)); } public SimpleMatrix( int numRows, int numCols, Class type ) { this(numRows, numCols, MatrixType.lookup(type)); } /** * Create a simple matrix of the specified type * * @param numRows The number of rows in the matrix. * @param numCols The number of columns in the matrix. * @param type The matrix type */ public SimpleMatrix( int numRows, int numCols, MatrixType type ) { switch (type) { case DDRM: setMatrix(new DMatrixRMaj(numRows, numCols)); break; case FDRM: setMatrix(new FMatrixRMaj(numRows, numCols)); break; case ZDRM: setMatrix(new ZMatrixRMaj(numRows, numCols)); break; case CDRM: setMatrix(new CMatrixRMaj(numRows, numCols)); break; case DSCC: setMatrix(new DMatrixSparseCSC(numRows, numCols)); break; case FSCC: setMatrix(new FMatrixSparseCSC(numRows, numCols)); break; default: throw new RuntimeException("Unknown matrix type"); } } /** * Creates a new SimpleMatrix which is identical to the original. * * @param orig The matrix which is to be copied. Not modified. */ public SimpleMatrix( SimpleMatrix orig ) { setMatrix(orig.mat.copy()); } /** * Creates a new SimpleMatrix which is a copy of the Matrix. * * @param orig The original matrix whose value is copied. Not modified. */ public SimpleMatrix( Matrix orig ) { Matrix mat; if (orig instanceof DMatrixRBlock) { DMatrixRMaj a = new DMatrixRMaj(orig.getNumRows(), orig.getNumCols()); DConvertMatrixStruct.convert((DMatrixRBlock)orig, a); mat = a; } else if (orig instanceof FMatrixRBlock) { FMatrixRMaj a = new FMatrixRMaj(orig.getNumRows(), orig.getNumCols()); FConvertMatrixStruct.convert((FMatrixRBlock)orig, a); mat = a; } else { mat = orig.copy(); } setMatrix(mat); } /** * Constructor for internal library use only. Nothing is configured and is intended for serialization. */ protected SimpleMatrix() {} /** * Creates a new SimpleMatrix with the specified DMatrixRMaj used as its internal matrix. This means * that the reference is saved and calls made to the returned SimpleMatrix will modify the passed in DMatrixRMaj. * * @param internalMat The internal DMatrixRMaj of the returned SimpleMatrix. Will be modified. */ public static SimpleMatrix wrap( Matrix internalMat ) { SimpleMatrix ret = new SimpleMatrix(); ret.setMatrix(internalMat); return ret; } /** * Returns a filled matrix (numRows x numCols) of the value a. * @param numRows The number of numRows. * @param numCols The number of columns. * @param a The number to fill the matrix with. * @return A matrix filled with the value a. */ public static SimpleMatrix filled( int numRows, int numCols, double a ) { SimpleMatrix res = new SimpleMatrix(numRows, numCols); res.fill(a); return res; } /** * Returns a matrix of ones. * @param numRows The number of numRows. * @param numCols The number of columns. * @return A matrix of ones. */ public static SimpleMatrix ones( int numRows, int numCols ) { return filled(numRows, numCols, 1); } /** * Creates a new identity matrix with the specified size. * * @param width The width and height of the matrix. * @return An identity matrix. * @see CommonOps_DDRM#identity(int) */ public static SimpleMatrix identity( int width ) { return identity(width, DMatrixRMaj.class); } public static SimpleMatrix identity( int width, Class type ) { SimpleMatrix ret = new SimpleMatrix(width, width, type); ret.ops.setIdentity(ret.mat); return ret; } /** *

* Creates a matrix where all but the diagonal elements are zero. The values * of the diagonal elements are specified by the parameter 'vals'. *

* *

* To extract the diagonal elements from a matrix see {@link #diag()}. *

* * @param vals The values of the diagonal elements. * @return A diagonal matrix. * @see CommonOps_DDRM#diag(double...) */ public static SimpleMatrix diag( double... vals ) { DMatrixRMaj m = CommonOps_DDRM.diag(vals); SimpleMatrix ret = wrap(m); return ret; } /** * Creates a real valued diagonal matrix of the specified type */ public static SimpleMatrix diag( Class type, double... vals ) { SimpleMatrix M = new SimpleMatrix(vals.length, vals.length, type); for (int i = 0; i < vals.length; i++) { M.set(i, i, vals[i]); } return M; } /** *

* Creates a new SimpleMatrix with random elements drawn from a uniform distribution from minValue to maxValue. *

* * @param numRows The number of rows in the new matrix * @param numCols The number of columns in the new matrix * @param minValue Lower bound * @param maxValue Upper bound * @param rand The random number generator that's used to fill the matrix. @return The new random matrix. * @see RandomMatrices_DDRM#fillUniform(DMatrixRMaj, java.util.Random) */ public static SimpleMatrix random_DDRM( int numRows, int numCols, double minValue, double maxValue, Random rand ) { SimpleMatrix ret = new SimpleMatrix(numRows, numCols); RandomMatrices_DDRM.fillUniform((DMatrixRMaj)ret.mat, minValue, maxValue, rand); return ret; } public static SimpleMatrix random_FDRM( int numRows, int numCols, float minValue, float maxValue, Random rand ) { SimpleMatrix ret = new SimpleMatrix(numRows, numCols, FMatrixRMaj.class); RandomMatrices_FDRM.fillUniform((FMatrixRMaj)ret.mat, minValue, maxValue, rand); return ret; } /** *

* Creates a new vector which is drawn from a multivariate normal distribution with zero mean * and the provided covariance. *

* * @param covariance Covariance of the multivariate normal distribution * @return Vector randomly drawn from the distribution * @see CovarianceRandomDraw_DDRM */ public static SimpleMatrix randomNormal( SimpleMatrix covariance, Random random ) { SimpleMatrix found = new SimpleMatrix(covariance.numRows(), 1, covariance.getType()); switch (found.getType()) { case DDRM: { CovarianceRandomDraw_DDRM draw = new CovarianceRandomDraw_DDRM(random, (DMatrixRMaj)covariance.getMatrix()); draw.next((DMatrixRMaj)found.getMatrix()); } break; case FDRM: { CovarianceRandomDraw_FDRM draw = new CovarianceRandomDraw_FDRM(random, (FMatrixRMaj)covariance.getMatrix()); draw.next((FMatrixRMaj)found.getMatrix()); } break; default: throw new IllegalArgumentException("Matrix type is currently not supported"); } return found; } @Override protected SimpleMatrix createMatrix( int numRows, int numCols, MatrixType type ) { return new SimpleMatrix(numRows, numCols, type); } @Override protected SimpleMatrix wrapMatrix( Matrix m ) { return new SimpleMatrix(m); } // TODO should this function be added back? It makes the code hard to read when its used // /** // *

// * Performs one of the following matrix multiplication operations:
// *
// * c = a * b
// * c = aT * b
// * c = a * b T
// * c = aT * b T
// *
// * where c is the returned matrix, a is this matrix, and b is the passed in matrix. // *

// * // * @see CommonOps#mult(DMatrixRMaj, DMatrixRMaj, DMatrixRMaj) // * @see CommonOps#multTransA(DMatrixRMaj, DMatrixRMaj, DMatrixRMaj) // * @see CommonOps#multTransB(DMatrixRMaj, DMatrixRMaj, DMatrixRMaj) // * @see CommonOps#multTransAB(DMatrixRMaj, DMatrixRMaj, DMatrixRMaj) // * // * @param tranA If true matrix A is transposed. // * @param tranB If true matrix B is transposed. // * @param b A matrix that is n by bn. Not modified. // * // * @return The results of this operation. // */ // public SimpleMatrix mult( boolean tranA , boolean tranB , SimpleMatrix b) { // SimpleMatrix ret; // // if( tranA && tranB ) { // ret = createMatrix(mat.numCols,b.mat.numRows); // CommonOps.multTransAB(mat,b.mat,ret.mat); // } else if( tranA ) { // ret = createMatrix(mat.numCols,b.mat.numCols); // CommonOps.multTransA(mat,b.mat,ret.mat); // } else if( tranB ) { // ret = createMatrix(mat.numRows,b.mat.numRows); // CommonOps.multTransB(mat,b.mat,ret.mat); // } else { // ret = createMatrix(mat.numRows,b.mat.numCols); // CommonOps.mult(mat,b.mat,ret.mat); // } // // return ret; // } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy