• Stars
    star
    104
  • Rank 330,604 (Top 7 %)
  • Language
    C++
  • License
    Other
  • Created about 12 years ago
  • Updated about 8 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Java wrapper for Eigen C++ fast matrix library

Table of Contents generated with DocToc

Jeigen

Jeigen provides a wrapper around the high-performance C++ matrix library "Eigen".

Jeigen provides matrix multiplication, for dense-dense, sparse-dense, and sparse-sparse pairs of matrices, using Eigen, and other mathematical operators, such as add, sub, sum, using native Java.

The matrix classes are :

DenseMatrix // for dense matrices
SparseMatrixLil // for sparse matrices

You can import statically Shortcuts.*, in order to have easy access to commands such as 'zeros', 'ones', 'eye' and 'diag'.

Example usage, to multiply two matrices:

DenseMatrix A = new DenseMatrix("1 2; 3 5; 7 9"); // matrix with 3 rows and 2 columns with values
                                                  // {{1,2},{3,5},{7,9}}
DenseMatrix B = new DenseMatrix(new double[][]{{4,3},{3,7}}); // matrix with 2 rows and 2 columns
DenseMatrix C = A.mmul(B); // mmul is matrix multiplication
System.out.println(C); // displays C formatted appropriately

Getting Jeigen

Download

You will need:

These were built and tested on:

  • Ubuntu 14.04 32-bit, using openjdk-7-jdk 32-bit
  • Ubuntu 14.04 64-bit, using openjdk-7-jdk 64-bit
  • Windows Server 2012 R2 64-bit, using Visual Studio 2010 Express, and 32-bit Sun jvm 1.7
  • Windows Server 2012 R2 64-bit, using Visual Studio 2010 Express, and 64-bit Sun jvm 1.7
  • Mac OS X 10.11 64-bit, via https://travis-ci.org/hughperkins/jeigen , and as per .travis.yml

Linking to Jeigen

You will need to add the following jars to the classpath:

  • Jeigen-onefat.jar
  • jna-4.1.0.jar

Jeigen-onefat.jar contains the native .dylib, .dlls and .so, for: win32, win64, linux32, linux64, and Mac OS X 64-bit platforms, which will be decompressed into the '.jeigen' folder, in your home-directory, at runtime.

Jeigen API

Commands to create new matrices

import static jeigen.Shortcuts.*;

DenseMatrix dm1;
DenseMatrix dm2;
dm1 = new DenseMatrix( "1 2; 3 4" ); // create new matrix
                   // with rows {1,2} and {3,4}
dm1 = new DenseMatrix( new double[][]{{1,2},{3,4}} ); // create new matrix
                   // with rows {1,2} and {3,4}
dm1 = zeros(5,3);  // creates a dense matrix with 5 rows, and 3 columns
dm1 = rand( 5,3); // create a 5*3 dense matrix filled with random numbers
dm1 = ones(5,3);  // 5*3 matrix filled with '1's
dm1 = diag(rand(5,1)); // creates a 5*5 diagonal matrix of random numbers
dm1 = eye(5); // creates a 5*5 identity matrix

SparseMatrixLil sm1;
sm1 = spzeros(5,3); // creates an empty 5*3 sparse matrix
sm1 = spdiag(rand(5,1)); // creates a sparse 5*5 diagonal matrix of random 
                         // numbers
sm1 = speye(5); // creates a 5*5 identity matrix, sparse

Update matrices

dm1.set( 3,4,5.0); // sets element at row 3, column 4 to 5.0
dm1.get( 3,4 ); // gets element at row 3, column 4

sm1.append( 2, 3, 5.0 ); // adds value 5.0 at row 2, column 3

Matrix Operators

dm1.mmul(dm1);  // matrix multiply, dense by dense
dm1.mmul(sm1);  // matrix multiply, dense by sparse
sm1.mmul(sm1); // matrix multiply, sparse by sparse
sm1.mmul(dm1); // matrix multiply, sparse by dense

dm1 = dm1.t(); // matrix transpose, dense
sm1 = sm1.t(); // matrix transpose, sparse

Per-element operators:

dm1 = dm1.neg();  // element = - element
dm1 = dm1.recpr();   // element = 1 / element 
dm1 = dm1.ceil();   // element = Math.ceil( element )
dm1 = dm1.floor();   // element = Math.floor( element )
dm1 = dm1.round();   // element = Math.round( element )

dm1 = dm1.add( dm2 );    // by-element addition
dm1 = dm1.add( 3 );    // by-element addition, of 3
dm1 = dm1.sub( 3 );    // by-element subtraction, of 3
dm1 = dm1.mul( 3 );    // by-element multiplication, by 3
dm1 = dm1.div( 3 );    // by-element division, by 3
dm1 = dm1.sub( dm2 );    // by-element subtraction
dm1 = dm1.mul( dm2 );    // by-element multiplication
dm1 = dm1.div( dm2 );    // by-element division

dm1 = dm1.le(dm2); // element1 <= element2
dm1 = dm1.ge(dm2); // element1 >= element2
dm1 = dm1.eq(dm2); // element1 == element2
dm1 = dm1.ne(dm2); // element1 != element2
dm1 = dm1.lt(dm2); // element1 &lt; element2
dm1 = dm1.gt(dm2); // element1 &gt; element2

Aggregation operators

These work for both sparse and dense matrices.

dm1 = dm1.sumOverRows(); // sum over all rows
dm1 = dm1.sumOverCols(); // sum over all columns
dm1 = dm1.sum(); // sum over rows, unless 1 row, in which case
                 // sum over columns
dm1 = dm1.minOverRows();
dm1 = dm1.maxOverRows();
dm1 = dm1.minOverCols();
dm1 = dm1.maxOverCols();

Scalar operators

Work for both dense and sparse.

double value = dm1.s();  // returns dm1.get(0,0);

Slicing

Slices are by-value. They work for both dense and sparse matrices.

dm1 = dm1.slice(startrow, endrowexclusive, startcol, endcolexclusive);
dm1 = dm1.row(row);
dm1 = dm1.col(col);
dm1 = dm1.rows(startrow, endrowexclusive);
dm1 = dm1.cols(startcol, endcolexclusive);

dm1 = dm1.concatRight(dm2); // concatenate [ dm1 dm2 ]
dm1 = dm1.concatDown(dm2); // concatenate [ dm1; dm2 ]

Operators in Shortcuts:

import static jeigen.Shortcuts.*;

DenseMatrix dm1;
dm1 = abs(dm1);  // element = abs(element)

Solvers

DenseMatrix dm1;
DenseMatrix dm2;

// to solve dm1.mmul(result) = dm2:
DenseMatrix result = dm1.ldltSolve(dm2); // using ldlt, dm1 must be positive or
                                         // negative semi-definite; fast
DenseMatrix result = dm1.fullPivHouseholderQRSolve(dm2); // no conditions on 
                                                     // dm1, but slower

Eigenvalues

// Added on Dec 2014, new, so let me know if any issues.
// Since it might return complex results, created DenseMatrixComplex 
// to handle this
DenseMatrix dm1; // should be square
EigenResult eig = dm1.eig();
DenseMatrixComplex values = eig.values; // single column, with each value
                                        // per row
                                        // might be complex
DenseMatrixComplex vectors = eig.vectors; // one column per vector, maybe
                                          // complex
// if you want to avoid complexes, you can use the pseudo-eigenvector
// decomposition
// but the eigenvalues are now returned as a square matrix, which
// might not be diagonal
PseudoEigenResult res = dm1.peig();
DenseMatrix values = res.values;
DenseMatrix vectors = res.vectors;

DenseMatrixComplex

// Created for use with eigenvalue decomposition, above.
// DenseMatrixComplex basically contains two DenseMatrices, one for the 
// real part, and one for the imaginary part
DenseMatrixComplex dmc1 = new DenseMatrixComplex( numrows, numcols );
// create from a string of complex pairs, each row separated by ';':
DenseMatrixComplex dmc1 = new DenseMatrixComplex( "(1,-1) (2,0); (-1,3) (4,-1)" );
DenseMatrix realPart = dmc.real();
DenseMatrix imagPart = dmc.imag();
double aRealValue = dmc1.getReal(2,3); // get real value at row 2 col 3
double anImaginaryValue = dmc1.getImag(2,3); // get imaginary value
dmc3 = dmc1.sub(dmc2) // can subtract
dm1 = dmc1.abs() // per-element abs, ie sqrt(real^2+imag^2), for each 
                  // element.  Returns a non-complex DenseMatrix

Svd

DenseMatrix dm1;
SvdResult result = dm1.svd();  // uses Jacobi, and returns thin U and V
// result contains U, S and V matrices

Matrix exponential, matrix logarithm

DenseMatrix dm1;
DenseMatrix result1 = dm1.mexp(); // matrix exponential
DenseMatrix result2 = dm1.mlog(); // matrix logarithm

Performance: overhead of using java/jna?

Dense

You can use the 'dummy_mmul' method of DenseMatrix to measure the overhead. It makes a call, with two matrices, right through to the native layer, doing everything that would be done for a real multiplication, but not actually calling the Eigen multiplication method:

DenseMatrix a = rand(2000,2000);
DenseMatrix b = rand(2000,2000);
tic(); a.mmul(b); toc();	
tic(); a.mmul(b); toc();	
tic(); a.dummy_mmul(b); toc();	
tic(); a.dummy_mmul(b); toc();	

Example results:

Elapsed time: 13786 ms
Elapsed time: 13588 ms
Elapsed time: 408 ms
Elapsed time: 407 ms

So, for 2000 by 2000 matrices, the overhead of using java/jna, instead of programming directly in C++, is about 408/13600*100 = 3%.

For N*N matrices, the empirical percent overhead is about:

N = 10: 27%
N = 100: 14%
N = 1000: 4%

Sparse

For sparse matrices, a corresponding test method is: cut SparseMatrixLil a,b; a = sprand(1000,1000); b = sprand(1000,1000); tic(); a.mmul(b); toc(); tic(); a.mmul(b); toc(); tic(); a.dummy_mmul(b,b.cols); toc(); tic(); a.dummy_mmul(b,b.cols); toc();

Approximate empirical overheads for multiplication of two sparse N*N matrices are:

N = 10: 77%
N = 100: 35%
N = 1000: 9%

Building

How to build, linux

Pre-requisites

  • git
  • jdk 1.6 or more recent
  • ant
  • cmake
  • g++

Procedure

git clone git://github.com/hughperkins/jeigen.git
cd jeigen
ant

According to whether you use a 64-bit jvm or a 32-bit jvm, the files will be created in 'build/linux-32' or 'build/linux-64'. You will need to add the following to your class-path:

  • Jeigen-linux-32.jar , or Jeigen-linux-64.jar
  • jna-4.1.0.jar

How to build, Mac OS X

Pre-requisites

  • git
  • jdk 1.6 or more recent
  • ant
  • cmake
  • xcode

Procedure

git clone git://github.com/hughperkins/jeigen.git
cd jeigen
ant

According to whether you use a 64-bit jvm or a 32-bit jvm, the files will be created in 'build/mac-32' or 'build/mac-64'. You will need to add the following to your class-path:

  • Jeigen-mac-32.jar , or Jeigen-mac-64.jar
  • jna-4.1.0.jar

How to build, Windows

Pre-requisites

  • have installed git
  • have a jdk available, at least 1.6
  • have installed ant
  • have installed cmake, version 3.x
  • have installed Visual Studio C++ Express 2010 (or later version; but tested on 2010)

Procedure

  1. git clone git://github.com/hughperkins/jeigen.git
  2. cd jeigen
  3. set PATH=%PATH%;c:\apache-ant\bin
  • set to appropriate path for your ant installation
  1. ant -Dcmake_home="c:\program files (x86)\Cmake" -Dgenerator="Visual Studio 10 2010 Win64"
  • set to appropriate path for your cmake installation
  • if you're using Visual Studio 2010, please change generator name to "Visual Studio 10 2010 Win64"
  • if you're using Visual Studio 2012, please change generator name to "Visual Studio 11 2012 Win64"
  • if you're using Visual Studio 2013, please change generator name to "Visual Studio 12 2013 Win64"
  • if you're using 32-bit Java JDK, please remove " Win64" from end of generator name

According to whether you use a 64-bit jvm or a 32-bit jvm, the files will be created in 'build\win-32' or 'build\win-64'.

You will need to add the following to your class-path:

  • Jeigen-win-32.jar , or Jeigen-win-64.jar
  • jna-4.1.0.jar

Sanity testing build

linux, eg for linux-64:

java -cp build/linux-64/Jeigen-linux-64.jar:build/linux-64/jna-4.1.0.jar jeigen.TestSimple

Should display a 2x2 matrix, with 1,2,3,4; and no error messages:

DenseMatrix, 2 * 2:

 1.00000  2.00000 
 3.00000  4.00000 


If you got this far, saw a 2x2 matrix with numbers 1,2,3,4, and no error message, then everything is working ok

Similarly for Windows, eg for win-64:

java -cp build\win-64\Jeigen-win-64.jar;build\win-64\jna-4.1.0.jar TestSimple

Again, should display a 2x2 matrix, with 1,2,3,4; and no error messages.

Running unit-tests

After following the build instructions, do:

ant test

Possible issues, and possible solutions

'java.lang.UnsatisfiedLinkError: Can't obtain updateLastError method for class com.sun.jna.Native'

  • See java-native-access/jna#281
    • Adding -Djna.nosys=true to the java command-line seems to work ok
    • You can have a look at an example, by looking at the test target in build.xml

Development

Wrapping additional functions

If you want to add additional functions, here's the procedure:

  1. Find the appropriate function in Eigen, and find out how to call it.
  2. Add a method to jeigen.cpp and jeigen.h, that wraps this function
    • matrices arrives as arrays of double (double *)
    • you also need one or two integer parameters to describe the size of the array
    • result matrices also arrive as a parameter of type double *
  3. In the jeigen.cpp method, use 'Map AnEigenMatrix(doublearray, rows, cols );' to convert the matrix represented by the double array 'doublearray' into an Eigen matrix, here called 'AnEigenMatrix'.
    • do this for each of the incoming matrices, and for any results matrices
  4. Then call the Eigen method, and ... that's it for the C++ part. You don't need to do anything with the result matrix, since it's already mapped to the function results parameter
  5. Make sure this compiles ok
  6. Add a method to JeigenJna.java, with the exact same name and parameter names as the method you just added to jeigen.cpp/.h
    • any double arrays ('double *') from jeigen.cpp/.h need to be written as 'double[]' here, since this bit is java
  7. Add a method to DenseMatrix.cpp, with an appropriate, concise name (see names above for examples, and/or check with me), which:
    • creates any result DenseMatrices, using 'new DenseMatrix(desiredrows,desiredcols)';
    • calls the JeigenJna method you created just now, using '.values' on each matrix, to obtain the underlying array of doubles
    • note that after passing the result matrix as a parameter, you don't need to do any additional work to get the result of the call into this matrix
  8. And that's it... Check it compiles, ideally write a test case in TestJeigen.java, or TestUnsupported.java

Note that some methods might be better implemented in native Java, because of the time required to copy data across to the C++ side. Basically, if a method is asymptotically O(n^3), where n is the size of the matrix, then implementing it in C++/Eigen will be faster. If it's O(n^2), then implementing it in native Java might be better. For example:

  • applying the same operation to all values of a matrix is implemented in native Java
  • multiplying two matrices is implemented using wrapped C++/Eigen

Third-party libraries used

License

Jeigen is available under MPL v2 license, http://mozilla.org/MPL/2.0/

News

  • 31 Jan 2016:
    • windows build process based on vs 2010 now, and adds the msvc 2010 redistributables to the jar file
    • published v1.2 jar, containing latest changes, and which should run on all of win32, win64, linux32, linux64, Mac OS X
  • 3rd Jan 2016:
  • 12th Aug 2015:
    • upgraded to Eigen 3.2.5
    • fixed QR solver to work with non-square matrices
  • 14th Feb 2015:
    • merged from Frograms branch
    • investigated and documented fix for 'can't obtain lastUpdateError' jna linking issue
  • 17th Dec 2014:
    • Added native library inside the jar, with automatic extraction, and setting of the jna.library.path variable, so dont need to set this variable oneself
    • Rebuilt on win64, win32, linux64, linux32, and uploaded to new downloads location at http://hughperkins.com/jeigen
    • Created one single jar file, containing all native shared objects
  • 14th Dec 2014 Added eigenvector decomposition, and complex matrices

More Repositories

1

DeepCL

OpenCL library to train deep convolutional neural networks
C++
849
star
2

coriander

Build NVIDIA® CUDA™ code for OpenCL™ 1.2 devices
LLVM
842
star
3

VeriGPU

OpenSource GPU, in Verilog, loosely based on RISC-V ISA
SystemVerilog
792
star
4

tf-coriander

OpenCL 1.2 implementation for Tensorflow
C++
792
star
5

pytorch

Python wrappers for torch and lua
Python
431
star
6

cltorch

An OpenCL backend for torch.
C++
287
star
7

EasyCL

Easy to run kernels using OpenCL
C++
177
star
8

Jinja2CppLight

(very) lightweight version of Jinja2 for C++
C++
140
star
9

clnn

OpenCL backend for Torch nn neural networks library
Lua
123
star
10

howto-jenkins-ssl

quick how to on activating ssl on jenkins, so I can find it easily
109
star
11

kgsgo-dataset-preprocessor

Dataset preprocessor for the KGS go dataset, eg according to Clark and Storkey input planes
Python
70
star
12

peaceful-pie

Control Unity from Python! Use for reinforcement learning.
C#
28
star
13

cpu-tutorial

Tutorial on building your own CPU, in Verilog
28
star
14

coriander-dnn

Partial implementation of NVIDIA® cuDNN API for Coriander, OpenCL 1.2
C++
22
star
15

rnn-notes

Notes on how element-research rnn works
17
star
16

luacpptemplater

Write Jinja2-style templates in C++. Uses lua as a scripting language (very lightweight)
C++
16
star
17

jfastparser

Very fast parsing of doubles and ints from a string
Java
15
star
18

UnityFluidSim-pub

UnityFluidSim-pub
C#
14
star
19

pytorch-coriander

OpenCL build of pytorch - (in-progress, not useable)
Python
14
star
20

pub-prototyping

prototyping stuff
C++
13
star
21

securewebcmd

Execute commands on a linux server through a webpage. Secured using md5 hashing
JavaScript
12
star
22

neonCl-underconstruction

experimental port of nervana neon kernels in OpenCL
Python
11
star
23

selfstudy-IBP

Self-study notes for Indian Buffet Process, from reading through "The Indian Buffet Process: An Introduction and Review", Griffiths, Ghahramani, 2011
Jupyter Notebook
11
star
24

torch-modder-notes

Notes for torch maintainers/modders
10
star
25

pycudatorch

poc for using cuda torch from python :-)
Python
7
star
26

nimbix-admin

utility scripts for start/stop/ssh to nimbix instances
Python
7
star
27

coriander-CLBlast

BLAS implementation for Coriander, using CLBlast
C++
6
star
28

ArgParseCpp

C++ version of Python's ArgParse
C++
5
star
29

passwordbookmarklet

bookmarklet to generate unique secure passwords for each website from a single master password
JavaScript
5
star
30

torchunit

torchunit
Shell
4
star
31

tinisles-googleauthenticator

Fork of the code at http://blog.tinisles.com/2011/10/google-authenticator-one-time-password-algorithm-in-javascript/
HTML
3
star
32

springgrid

Runs spring matches on a grid of botrunners
Python
3
star
33

osmp-cs

OSMP C# - Opensource Secondlife clone, from around 2005
C#
3
star
34

ailadder

code to create an ailadder webserver
Python
3
star
35

pycltorch

POC for Python wrappers for cltorch/clnn
Python
3
star
36

yet-another-measure-theoretic-probability-tutorial

Yet another measure theoretic probability tutorial
Jupyter Notebook
3
star
37

HughAI

HughAI Java AI for Spring
Java
3
star
38

selfstudy-LARS

least angle regression, reproducing for self-study
Jupyter Notebook
2
star
39

verigpu-cuda-frontend

Front-end for VeriGPU, providing NVIDIA® CUDA™ compatibility, for compatibility purposes
2
star
40

selfstudy-LIME

LIME
Jupyter Notebook
2
star
41

blameful-indenter

reindent code, whilst preserving git blame
Python
2
star
42

SpringRTS-CSharpAI

AI For Spring RTS game, in C#, from around 2006
C#
2
star
43

neon-benchmarks

benchmarks for neon, both cuda and OpenCL version
Python
2
star
44

FractalSpline-cpp

Provides SecondLife-like primitives , in C++/OpenGL. From around 2005
C++
2
star
45

relooper

Reloop llvm IR output, to have `for`s, `if`s, `while`s. From https://reviews.llvm.org/D12744
C++
2
star
46

osmp-cpp

OSMP C++ - opensource SecondLife clone, from around 2004
C++
2
star
47

python-graphics-numpy

Scripts for youtube video on creating graphics in python using numpy
Python
2
star
48

chat-ai-npcs-video-resources

chat-ai-npcs-video-resources
C#
2
star
49

github-stars

get an email whenever someone stars your github repo :-)
Python
2
star
50

project-ideas

Ideas for projects
2
star
51

scalable-gpt-developer

scalable-gpt-developer
Python
2
star
52

gpu-experiments

Informal experiments on various gpu kernel questions
Python
1
star
53

blender-tips

blender-tips
Python
1
star
54

peaceful-pie-video-resources

Resources for watching Peaceful Pie videos
Python
1
star
55

dockerfiles

dockerfiles
1
star
56

virtualenv-move

Moves a python virtualenv
Shell
1
star
57

privacy-policies

privacy-policies
HTML
1
star
58

openpw

Password hash generator, including console, bookmarklet, chrome extension
JavaScript
1
star
59

headlessopenglstubs

stubs for opengl, glew, sdl, whatever it takes ;-), to get spring to run without an X session
1
star
60

python-threadingx

Erlang-like threading functionality for Python
Python
1
star
61

youtube-likes

Receive a notification/email when someone 'like's one of your videos.
Python
1
star
62

youtube-rl-demos

Scripts, code used in youtube demos
Python
1
star
63

SpringMapDesigner

3d MapDesigner for Spring
1
star
64

chinese-transcriptions

Transcriptions of Chinese language videos
1
star
65

ndplot

high-dimensional viewer, by projecting onto a 3d hypercube. Use the mouse to rotate the 3d projection.
Python
1
star
66

pytorch-prettify

Prettifies exceptions coming out of pytorch
Jupyter Notebook
1
star
67

tf_cached_build

Cache tensorflow build dependencies, to accelerate repeated tf configures, or run on a plane
Python
1
star
68

cppsimpleargsparser

Simple C++ args parser. Easy to use. Automatically provides checking and usage printout.
C++
1
star
69

PortableTensor.Net

Cross-platform Tensor with transpose, slice as views over underlying data
C#
1
star