The Universal Java Matrix Package (UJMP) is an open source library for dense and sparse matrix computations and linear algebra in Java. In addition to the basic operations like matrix multiplication, matrix inverse or matrix decomposition, it also supports visualization, JDBC import/export and many other useful functions such as mean, correlation, standard deviation, mutual information, or the replacement of missing values.
It's a swiss army knife for data processing in Java, tailored to machine learning applications.
In a Nutshell
- Dense and sparse matrices in multiple dimensions
- Matrix inverse, pseudo inverse, determinant, SVD, LU, QR, Cholesky, Eigenvalue decomposition
- Multi-threaded and lighting fast
- Handle terabyte-sized matrices on disk
- Visualize and edit as heatmap, graph, plot
- Treat every type of data as a matrix
- TXT, CSV, PNG, JPG, HTML, XLS, XLSX, PDF, LaTeX, Matlab, MDB
- Free and open source (LGPL)
Features
The Universal Java Matrix Package provides various visualization methods, import and export filters for various file formats, and the possibility to link to JDBC databases. Multi-dimensional dense and sparse matrices as well as generic matrices with a specified object type are supported and very large matrices can be handled even when they do not fit into main memory.
For UJMP, everything is a matrix: an array of bytes or numbers in main memory,
a CSV
file on disk, a Java ArrayList
or HashMap
, a PNG/JPG/GIF image, an
Excel spreadsheet, a
database table in an SQL database, the database itself with its list of tables, a directory on
disk, a ZIP file with
the compressed files, and so on.
The central concept to achieve this flexibility is the strict separation of interfaces, abstract classes and their implementations, which makes it very easy to exchange the underlying data storage. In fact, the actual storage implementation becomes secondary and UJMP can even integrate other matrix libraries such as Jama and Colt, which enables UJMP's visualization methods and import/export filters for these libraries.
UJMP uses multiple threads, which results in much better performance compared to JAMA or Colt. To speed up processing even more, calculations can be redirected to other matrix libraries such as jblas, EJML or Ojalgo, depending on matrix size and computer hardware.
There are also interfaces to Matlab, Octave and R, which makes it easy to perform functions not available in Java.
This is the feature list:
-
Matrix classes for different data types
BigDecimalMatrix
,BigIntegerMatrix
,BooleanMatrix
,ByteMatrix
,DoubleMatrix
,FloatMatrix
,IntMatrix
,LongMatrix
,ObjectMatrix
,ShortMatrix
andStringMatrix
-
Generic Matrix class
UseGenericMatrix<T>
to specify the object type that is stored. -
n-dimensional matrices
You can create matrices with any number of dimensions withMatrix.Factory.sparse(rows, columns, zAxis, ...)
-
Storage of more data than fits into memory
Matrices can be mapped to hard disk or databases. -
Store up to 263-1 elements along one axis in a matrix
UJMP useslong
values for indices instead ofint
. -
Link to JDBC data sources
Work directly with your database:Matrix.Factory.linkToJDBC(host, port, db, table, user, password)
-
Store meta-data for all matrices
It is easy to label rows and columns or give a name to the matrix. -
Interact with other matrix libraries
Use Colt or Jama inside UJMP. In fact, you can tell UJMP to prefer a specific matrix implementation over its own classes. -
Interfaces to other mathematical software
Execute complex computations in Matlab, Octave, R or GnuPlot. You can use these software packages as computing or visualization engines in UJMP. -
Import and export filters for many different file types
TXT, CSV, PNG, JPG, GIF, BMP, XLS, XLSX, HTML, XML, JSON, PDF, LaTex, MAT (Matlab), MDB (MS Access), and many more. -
Link to huge CSV files without loading them into memory
This is useful when your CSV file does not fit into your machine's memory. UseMatrix.Factory.linkTo().file("hugeCSVFile").asDenseCSV(columnSeparator)
-
Additional collection classes
e.g.CachedMap
,RingBufferList
orSoftHashMap
which can be very helpful. -
Store more objects than fit into memory
SerializedObjectMapThis
stores all objects on disk and can be used like a normalHashMap
. -
Mapping of collection classes
Java collection classes likeMap
,List
orSet
can be used as UJMP matrices, which makes it easy to perform calculations. E.g. you can calculate sum, average or standard deviation of a list of values in anArrayList
. Use this to convert it to a UJMP matrix:Matrix.Factory.linkToCollection(myArrayList)
-
Visualization
Heatmap, line plot, scatter plot, histogram and many more. Just usemyMatrix.showGUI()
to bring it on the screen. Take a look at the screenshots for examples. -
Licensed under LGPL
you can use it in commercial applications.
Too good to be true?
Well, to be perfectly honest with you, there are some things you will not like about UJMP, so here is the list why you may not want to use it:
The Universal Java Matrix Package is...
-
...not finished
While some parts are already pretty stable, a lot of development is still going on in other areas. There is no guarantee that everything will be working as expected. Be prepared for renamed methods and interfaces from one version to the next. -
...not well documented
Since many things are going to change anyway, we didn't bother to write much documentation. -
...not a lightweight matrix library
If you just need linear algebra for double matrices, there are probably better choices, such as EJML or Ojalgo.
Wanna help?
Developers are welcome to contribute new features, test cases or documentation.
If you like this library and it does something useful for you, a small donation will be very much appreciated to help cover server costs and ensure the coffee supply for further development.
Thank you very much for supporting open source software!
Download
Include via Maven
The easiest way to add UJMP to your projects is to include it via Maven. You will need at least
the ujmp-core
package which contains the basic matrix classes and linear algebra
functions. Add these lines to the <dependencies>
section in your
pom.xml
file:
<dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-core</artifactId> <version>0.3.0</version> </dependency>
The ujmp-gui
package is useful when you want to display matrix data on the screen:
<dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-gui</artifactId> <version>0.3.0</version> </dependency>
Other dependencies can be added as required using the appropriate sub-packages of ujmp. Here is the full list:
<dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-core</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-gui</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-colt</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-commonsmath</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-complete</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-ehcache</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-ejml</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-elasticsearch</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-examples</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-hadoop</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-itext</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-jackcess</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-jama</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-jblas</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-jdbc</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-jetty</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-jfreechart</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-jmatio</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-jsch</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-jsci</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-jscience</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-jung</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-la4j</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-lucene</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-mail</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-mtj</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-ojalgo</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-parallelcolt</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-pdfbox</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-poi</artifactId> <version>0.3.0</version> </dependency> <dependency> <groupId>org.ujmp</groupId> <artifactId>ujmp-vecmath</artifactId> <version>0.3.0</version> </dependency>
Download JAR Packages
If you don't have Maven, you can download a jar file containing all ujmp packages here: ujmp-complete.jar
This package contains ujmp-core
, the main part of the Universal Java Matrix Package,
as well as
all additional features such as visualization and interfaces to other libraries, SQL databases,
and
a lot more. If you are new to this library, just invoke
the main()
method in org.ujmp.gui.UJMP
:
java -jar ujmp-complete.jar
Then click on "Tools - UJMP Plugins" in the menu bar and see what third party libraries are supported. Chose the tool you want, add the necessary dependencies to the class path and restart UJMP.
Download Source Code from GitHub
The source code of UJMP is available from GitHub. You can clone the repository like this:
git clone https://github.com/ujmp/universal-java-matrix-package.git
This is the link to the repository: UJMP on GitHub
You are welcome to contribute, just send me a pull request on GitHub.
Documentation
Quick Start
// create a dense empty matrix with 4 rows and 4 columns Matrix dense = DenseMatrix.Factory.zeros(4, 4); // set entry at row 2 and column 3 to the value 5.0 dense.setAsDouble(5.0, 2, 3); // set some other values dense.setAsDouble(1.0, 0, 0); dense.setAsDouble(3.0, 1, 1); dense.setAsDouble(4.0, 2, 2); dense.setAsDouble(-2.0, 3, 3); dense.setAsDouble(-2.0, 1, 3); // print the final matrix on the console System.out.println(dense); // create a sparse empty matrix with 4 rows and 4 columns Matrix sparse = SparseMatrix.Factory.zeros(4, 4); sparse.setAsDouble(2.0, 0, 0); // basic calculations Matrix transpose = dense.transpose(); Matrix sum = dense.plus(sparse); Matrix difference = dense.minus(sparse); Matrix matrixProduct = dense.mtimes(sparse); Matrix scaled = dense.times(2.0); Matrix inverse = dense.inv(); Matrix pseudoInverse = dense.pinv(); double determinant = dense.det(); Matrix[] singularValueDecomposition = dense.svd(); Matrix[] eigenValueDecomposition = dense.eig(); Matrix[] luDecomposition = dense.lu(); Matrix[] qrDecomposition = dense.qr(); Matrix choleskyDecomposition = dense.chol();
Random Matrix
// create matrix with random values between 0 and 1 Matrix rand = Matrix.Factory.rand(100, 10); // create matrix with random values between -1 and - 1 Matrix randn = Matrix.Factory.randn(100, 10); // show on screen rand.showGUI(); randn.showGUI();
Cosine Similarity Matrix
// create matrix with 10 correlated columns, 100 rows, correlation 0.1 Matrix correlated = Matrix.Factory.correlatedColumns(100, 10, 0.1); // calculate similarity and store in new matrix, // ignore missing values if present Matrix similarity = correlated.cosineSimilarity(Ret.NEW, true); // show on screen correlated.showGUI(); similarity.showGUI();
Image Matrix
// get an image InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("org/ujmp/examples/data/bigdata.jpg"); // load image into matrix. of course, this works with files, too. Matrix imageMatrix = new ImageMatrix(is); // show on screen imageMatrix.showGUI(); is.close();
Localhost Matrix
// create a matrix representing the local computer with its services Matrix localhost = Matrix.Factory.localhostMatrix(); // show on screen localhost.showGUI(); // double click on matrix entries to navigate and see how everything is // a matrix. Have fun exploring, but be careful when you change data!
Big Sparse Matrix
// create a very large sparse matrix SparseMatrix m1 = SparseMatrix.Factory.zeros(1000000, 500000); // set some values m1.setAsDouble(MathUtil.nextGaussian(), 0, 0); m1.setAsDouble(MathUtil.nextGaussian(), 1, 1); for (int i = 0; i < 10000; i++) { m1.setAsDouble(MathUtil.nextGaussian(), MathUtil.nextInteger(0, 1000), MathUtil.nextInteger(0, 1000)); } // show on screen m1.showGUI(); // create another matrix SparseMatrix m2 = SparseMatrix.Factory.zeros(3000000, 500000); // set some values m2.setAsDouble(MathUtil.nextGaussian(), 0, 0); m2.setAsDouble(MathUtil.nextGaussian(), 1, 1); for (int i = 0; i < 10000; i++) { m2.setAsDouble(MathUtil.nextGaussian(), MathUtil.nextInteger(0, 1000), MathUtil.nextInteger(0, 1000)); } // show on screen m2.showGUI(); // do some operations Matrix m3 = m1.mtimes(m2.transpose()); // show on screen m3.showGUI();
Extract Excel Data
// find all Excel files in one directory File[] files = new File("c:/temp/").listFiles(); // create matrix to store result Matrix result = Matrix.Factory.zeros(files.length, 2); // iterate over all files for (int i = 0; i < files.length; i++) { // import file as matrix Matrix m = Matrix.Factory.importFrom().file(files[i]).asDenseCSV(); // store file name in result matrix result.setAsString(files[i].getName(), i, 0); // search for "Invoice" if (m.containsString("Invoice")) // extract value at row 10 and column 3 and store in result result.setAsDouble(m.getAsDouble(10, 3), i, 1); } // display result on screen result.showGUI();
Graph Matrix
// create a GraphMatrix with Strings as nodes and Doubles as edges GraphMatrix<String, Double> graphMatrix = new DefaultGraphMatrix<String, Double>(); graphMatrix.setLabel("Interface Inheritance Graph"); // collect all matrix interfaces from UJMP Class<?>[] classArray = new Class[] { DenseMatrix.class, DenseMatrix2D.class, Matrix.class, Matrix2D.class, SparseMatrix.class, SparseMatrix2D.class, BaseBigDecimalMatrix.class, BigDecimalMatrix2D.class, DenseBigDecimalMatrix.class, DenseBigDecimalMatrix2D.class, SparseBigDecimalMatrix.class, SparseBigDecimalMatrix2D.class, BigIntegerMatrix.class, BigIntegerMatrix2D.class, DenseBigIntegerMatrix.class, DenseBigIntegerMatrix2D.class, SparseBigIntegerMatrix.class, SparseBigIntegerMatrix2D.class, BooleanMatrix.class, BooleanMatrix2D.class, DenseBooleanMatrix.class, DenseBooleanMatrix2D.class, SparseBooleanMatrix.class, SparseBooleanMatrix2D.class, ByteArrayMatrix.class, ByteArrayMatrix2D.class, DenseByteArrayMatrix.class, DenseByteArrayMatrix2D.class, SparseByteArrayMatrix.class, SparseByteArrayMatrix2D.class, ByteMatrix.class, ByteMatrix2D.class, DenseByteMatrix.class, DenseByteMatrix2D.class, SparseByteMatrix.class, SparseByteMatrix2D.class, CharMatrix.class, CharMatrix2D.class, DenseCharMatrix.class, DenseCharMatrix2D.class, SparseCharMatrix.class, SparseCharMatrix2D.class, DoubleMatrix.class, DoubleMatrix2D.class, DenseDoubleMatrix.class, DenseDoubleMatrix2D.class, SparseDoubleMatrix.class, SparseDoubleMatrix2D.class, FloatMatrix.class, FloatMatrix2D.class, DenseFloatMatrix.class, DenseFloatMatrix2D.class, SparseFloatMatrix.class, SparseFloatMatrix2D.class, GenericMatrix.class, GenericMatrix2D.class, DenseGenericMatrix.class, DenseGenericMatrix2D.class, SparseGenericMatrix.class, SparseGenericMatrix2D.class, IntMatrix.class, IntMatrix2D.class, DenseIntMatrix.class, DenseIntMatrix2D.class, SparseIntMatrix.class, SparseIntMatrix2D.class, LongMatrix.class, LongMatrix2D.class, DenseLongMatrix.class, DenseLongMatrix2D.class, SparseLongMatrix.class, SparseLongMatrix2D.class, ObjectMatrix.class, ObjectMatrix2D.class, DenseObjectMatrix.class, DenseObjectMatrix2D.class, SparseObjectMatrix.class, SparseObjectMatrix2D.class, ShortMatrix.class, ShortMatrix2D.class, DenseShortMatrix.class, DenseShortMatrix2D.class, SparseShortMatrix.class, SparseShortMatrix2D.class, StringMatrix.class, StringMatrix2D.class, DenseStringMatrix.class, DenseStringMatrix2D.class, SparseStringMatrix.class, SparseStringMatrix2D.class }; // find out how interfaces extend one another for (Class<?> c1 : classArray) { for (Class<?> c2 : classArray) { if (c2.getSuperclass() == c1) { // add edge when class2 extends class1 graphMatrix.setEdge(1.0, c1.getSimpleName(), c2.getSimpleName()); } for (Class<?> c3 : c2.getInterfaces()) { if (c1 == c3) { // add edge when class2 implements class1 graphMatrix.setEdge(1.0, c1.getSimpleName(), c2.getSimpleName()); } } } } // show on screen graphMatrix.showGUI();
Mandelbrot Matrix
// create a matrix from the Mandelbrot set Matrix m = new MandelbrotMatrix(); // show on screen m.showGUI();
Tree Matrix
// create a TreeMatrix with Strings as elements TreeMatrix<String> treeMatrix = new DefaultTreeMatrix<String>(); // create data treeMatrix.setRoot("root"); treeMatrix.addChild("root", "child1"); treeMatrix.addChild("root", "child2"); treeMatrix.addChild("root", "child3"); treeMatrix.addChild("child1", "subChild11"); treeMatrix.addChild("child1", "subChild12"); treeMatrix.addChild("child1", "subChild13"); treeMatrix.addChild("child2", "subChild21"); treeMatrix.addChild("child3", "subChild31"); treeMatrix.addChild("child3", "subChild32"); treeMatrix.addChild("subChild12", "subSubChild121"); treeMatrix.addChild("subChild12", "subSubChild122"); treeMatrix.addChild("subSubChild122", "subSubSubChild1221"); // show on screen treeMatrix.showGUI();
List of UJMP Modules
ujmp |
Parent package with just the master .pom file without any Java code | Module Info |
ujmp-colt |
Plugin to incorporate dense and sparse matrix classes from the Colt library | Module Info API Docs |
ujmp-commonsmath |
Plugin to incorporate dense matrix classes from Apache commons math | Module Info API Docs |
ujmp-complete |
Collection of all available UJMP modules in one meta package | Module Info API Docs |
ujmp-core |
Main package of UJMP containing dense and sparse matrix implementations and functions | Module Info API Docs |
ujmp-ehcache |
Plugin to enable caching using the EhCache library | Module Info API Docs |
ujmp-ejml |
Plugin to incorporate dense matrix classes from the Efficient Java Matrix Library | Module Info API Docs |
ujmp-elasticsearch |
Plugin to enable text indexing using Elasticsearch | Module Info API Docs |
ujmp-examples |
Some simple examples how to use the Universal Java Matrix Package | Module Info API Docs |
ujmp-gui |
Plugin to enable visualization and graphics | Module Info API Docs |
ujmp-hadoop |
Plugin to interface with Hadoop | Module Info API Docs |
ujmp-itext |
Plugin to enable PDF export | Module Info API Docs |
ujmp-jackcess |
Plugin to enable import and export for .mdb files from MS Access databases | Module Info API Docs |
ujmp-jama |
Plugin to enable import and export for mdb files from MS Access databases | Module Info API Docs |
ujmp-jblas |
Plugin to incorporate dense matrix classes from the jblas library | Module Info API Docs |
ujmp-jdbc |
Plugin to enable JDBC database import and export | Module Info API Docs |
ujmp-jetty |
Plugin to incorporate Jetty web server | Module Info API Docs |
ujmp-jfreechart |
Plugin for visualization using the JFreeChart library | Module Info API Docs |
ujmp-jmatio |
Plugin to enable import and export for .mat files from Matlab | Module Info API Docs |
ujmp-jsch |
Plugin to enable SSH connections using JSch | Module Info API Docs |
ujmp-jsci |
Plugin to incorporate dense matrix classes from the JSci library | Module Info API Docs |
ujmp-jscience |
Plugin to incorporate dense matrix classes from the JScience library | Module Info API Docs |
ujmp-jung |
Plugin to incorporate graph visualizations from Jung library | Module Info API Docs |
ujmp-la4j |
Plugin to incorporate dense and sparse matrix classes from la4j | Module Info API Docs |
ujmp-lucene |
Plugin to enable text indexing using Apache Lucene | Module Info API Docs |
ujmp-mail |
Plugin to enable sending email and connections to IMAP servers | Module Info API Docs |
ujmp-mtj |
Plugin to incorporate dense and sparse matrix classes from Matrix Toolkits for Java | Module Info API Docs |
ujmp-ojalgo |
Plugin to incorporate dense matrix classes from the ojAlgo library | Module Info API Docs |
ujmp-parallelcolt |
Plugin to incorporate dense and sparse matrix classes from ParallelColt | Module Info API Docs |
ujmp-pdfbox |
Plugin to enable reading PDF files | Module Info API Docs |
ujmp-poi |
Plugin to enable import and export for Excel files using Apache POI | Module Info API Docs |
ujmp-vecmath |
Plugin to incorporate dense matrix classes from Java3D vecmath | Module Info API Docs |
Java Data Mining Package
UJMP is the computational back-end of the Java Data Mining Package (JDMP), which is our second open source Java project. While UJMP is the workhorse for matrix operations, JDMP concentrates on higher-level objects, such as DataSets and Algorithms for machine learning, like clustering or classification. JDMP continues the philosophy that everything is a matrix, which makes it easy to benefit from UJMP's features. The strict separation of interfaces and abstract classes allows JDMP to easy integrate other libraries like Weka or Mallet.
Contributors
Holger Arndt
Project manager, UJMP core package, UJMP GUI package, interfaces to other libraries
Holger’s Homepage
Markus Bundschus
Strategical consultancy, marketing
Markus’s
Homepage
Andreas Nägele
Core package, GUI package, test cases
Rand Huso
Method for generalized matrix inversion
Rand’s Homepage
Frode Carlsen
Block matrix implementation and multiplication
Frode’s LinkedIn Profile