Saturday, July 20, 2013

JavaDoc for la4j

Great news everyone!

I've pushed initial version of la4's javadoc at offisial site: http://la4j.org/apidocs/.

I'm planning to keep the docs updated as much as possible.

Friday, July 12, 2013

Six bugs per person

I was thinking about the way how can I pay back to the la4j's contributors. And the first thing that comes into y mind was just posting a short blog message about their work in the project. It is not a big deal for me, but I believe that it might be pleased for the contributors.

So, I've already wrote two posts about two valuable contributors (here and here). Now, I'm going to tell you about the third la4j's contributor who spent loads of his time trying to make la4j more stable and predictable. I'm talking about Ewald Grusk. Ewald fixed 3 bugs by himself (one, two, three), reported about 3 bugs (one, two, three) and proposed a pull-request with minor improvements.

I'm really appreciate what everyone does for la4j. And Ewald did just a fantastic job. He is definitely the most active contributor in the history of the project. Ewald, if I had a chance, I would buy you a beer :)

Wednesday, July 3, 2013

New matrix operations: shuffle and rotate

The la4j (Linear Algebra for Java) has recently got two pull-requests (#48, #50) by Jakob Moellers, who implemented two new methods in Matrix interface. Jakob added support for shuffle() (also works for vectors) and rotate() methods. Here is the brief introduction into these methods.
The Matrix.rotate() method is pretty simple. It rotates the matrix by 90 degrees. Here is the example:
Matrix a = new Basic1DMatrix(new double[][] {
  { 1.0, 2.0 },
  { 3.0, 4.0 }
});

/*
Matrix {
 3.0, 1.0
 4.0, 2.0
}
*/
Matrix b = a.rotate();

The shuffle() method can be used with matrices as well as with vector. It shuffles the element of matrix or vector by using Fisher-Yates algorithm. Here is the example.
Matrix a = new Basic1DMatrix(new double[][] {
  { 1.0, 2.0, 3.0 },
  { 4.0, 5.0, 6.0 }
});

/*
Matrix {
 3.0, 5.0, 4.0
 6.0, 1.0, 2.0
}
*/
Matrix b = a.shuffle();

Vector c = new CompressedVector(new double[] { 1.0, 2.0, 3.0 });

// Vector { 2.0, 3.0, 1.0 }
Vector d = c.shuffle();
Thanks Jakob for the great job!

Thursday, June 27, 2013

Vector Algebra in la4j

All Vector Algebra methods in la4j were completely messed up. That was my fault. I've spent loads of time improving core la4j's primitive - it's matrices. But, good news here, that Daniel Renshaw caught all this mess and proposed a pull-request with changes. Thanks Daniel! This is such a great example of how do the open source world live. So, I'll try to introduce you new features of la4j's Vector class.

The la4j now supports Inner Product (Dot Product). It was previously implemented by Vector.product(Vector) method:
Vector a = new BasicVector(new double[]{ 1.0, 2.0, 3.0 });
Vector b = new BasicVector(new double[]{ 4.0, 5.0, 6.0 });

double d = a.innerProduct(b); // 1.0*4.0 + 2.0*5.0 + 3.0*6.0 = 32

There is also a Hadamard Product (element-wise product), which was implemented in Vector.multiply(Vector).
Vector a = new BasicVector(new double[]{ 1.0, 2.0, 3.0 });
Vector b = new BasicVector(new double[]{ 4.0, 5.0, 6.0 });

Vector c = a.hadamardProduct(b); // Vector { 4.0, 10.0, 18.0 }

The la4j also supports Outer Product, which produces a matrix as result (was not supported previously).
Vector a = new BasicVector(new double[]{ 1.0, 2.0, 3.0 });
Vector b = new BasicVector(new double[]{ 4.0, 5.0, 6.0 });

/* 
Matrix {
  4.0,  5.0,  6.0
  8.0, 10.0, 12.0
 12.0, 15.0, 18.0
}
*/
Matrix c = a.outerProduct(b);

So, all these things allow do not care about vector's orientation (row-vector/column-vector). Just use vector class when you need it. The la4j does all the work for you. It automatically determine by context whether the vector is a row-vector or a column-vector.

Saturday, June 1, 2013

la4j-0.4.0 is here!

I'm proud to announce that la4j is perfectly ready for releasing version 0.4.0. This is another huge step for such a small project like la4j. It took me 6 month to prepare la4j for new version. I've done loads of work: rewrote 50% of sources and added ~5k loc of new functionality.

So, I've decided to tell you about how many interesting things are happed to me in this period of development. I've got several positive feedbacks from people about la4j. I'm so glad that pople enjoy it. I've got several awesome pull-request to la4j from Russia, Italy, USA. Thank you guys for a wonderful job!

I've bumped in the fact that people from business use la4j as competitor for their products. They used version 0.3.0 and it was realy slow. So, I did some optimizations and new version realy flies!

And the last thing. Recently, I've read awesome book about genius physicist Richard Feynman. One of its chapter describes scientific laboratory of Los-Alamos, where he worked on Manhattan project. So, I was so excited about this laboratory and pople working there. You can imagine now, what I was feeling when I've found the line "los alamos national laboratory" in www.la4j.org's visitors log.

The changelog for new version (the huges changelog in the history of la4j):
  •  Up to 2x performance improvement of sparse entries (binary search power)
  •  Performance improvement for matrix-by-matrix multiply algorithm (3x for dense, 11x for sparse)
  •  New matrix method `rank()` (contributed by Evgenia Krivova)
  •  New fast implementation of `determinant()` method
  •  New method `update()` (as compound operator replacement)
  •  Matrices are unsafe by default (new corresponding methods `safe()` and `unsafe()`)
  •  New method `slice()`
  •  New method for `kronecker()` product
  •  Support map-reduce approach by method pair `transform()` and `fold()`
  •  New matrices and vectors sources that handles IO streams
  •  Support of building a constant matrix in factories
  •  Matrices and vectors are immutable in terms of dimension
  •  Sparse entities are self-clearing (no memory leaks)
  •  Support vector-by-matrix multiplication
  •  Bug fix in `MatrixDecFunction`
  •  Bug fix in `MatrixMatketStream` (contributed by Alessio Placitelli)
  •  Bug fix in matrix-to-vector multiplication (contributed by Pavel Kalaidin)
  •  Bug fix in `align()` method (contributed by Chandler May)
  •  But fix in `QRDecompositor`
References:

Thursday, April 25, 2013

la4j's performance


Recently, I've bumped into this web-site. I was quite surprised that they used la4j for benchmarking (see demo video). It is always pleasure to see when people use your 'just-for-fun' library. Anyway, I didn't except that la4j is so slow. I wrote an email to the guys who was testing la4j and ask them to provide me benchmark sources. So, the sources was looking good and there is nothing I can do there to improve la4j's performance. But something, I already did.

They was testing la4j-0.3.0 and it is much slower than a current 0.4.0 version. I've done several significant improvements, that speeded up whole the library.

First of all, I've rewrote sparse matrices to use binary search instead of linear one. Binary search works for logarithmic time O(log n) and if gives me up to 2.2x speed up for get/set operations.

The other good thing that I did - is improvement matrix-by-matrix multiply algorithm. I've speeded it up to 3x for dense matrices and up to 11x for sparse ones.

Here is some numbers that I got today. Performnace of matrix-by-matrix multiply:

la4j-0.3.0 Basic1DMatrix(1000x1000) - 3784ms
la4j-0.3.0 Basic2DMatrix(1000x1000) - 3946ms

la4j-0.3.0 CRSMatrix(500x500) - 45897ms
la4j-0.3.0 CCSMatrix(500x500) - 219312ms

la4j-0.4.0 Basic2DMatrix(1000x1000) - 1476ms
la4j-0.4.0 Basic1DMatrix(1000x1000) - 1489ms

la4j-0.4.0 CRSMatrix(500x500) - 20245ms
la4j-0.4.0 CCSMatrix(500x500) - 12413ms

The new version of la4j - version 0.4.0 will be avaliable this summer. It is currently avaliable at it's GitHub page: https://github.com/vkostyukov/la4j

Monday, March 18, 2013

Safe and unsafe matrices/vectors

There are was an ugly methods in la4j that started with "unsafe_". So, I've added these methods to provide to the client more effective and raw mechanisms on matrices and vectors. Anyway, I've decided to replace with method by new matrix type - SafeMatrix. The thing is all matrices in la4j are unsafe by default, but if client wants to get safe matrix, he can use special matrix wrapper that wraps unsafe methods with additional checks. Actually, there is another way to do that - introduce new matrix classes (use inheritance) but everybody knows that it prefer to use composition instead of inheritance.

So, the la4j looks more strict and clear now and I feel this is the right way to develop the library.

Just brief exaple of using safe and unsafe matrices:

Matrix a = new Basic1DMatrix(..); // unsafe
Matrix b = a.safe(); // safe
Matrix c = a.multyply(b, Matrices.SAFE_BASIC1D_FACTORY); // safe

And friendly reminder: if someone want to participate - there are loads of opened issues at GitHub.

http://la4j.org