I am looking for a Java library that closely mirrors matlab's Matrix functions and possibly other functions in the areas of polynomial interpolation, etc.
If such a library does not exist I was toying with the idea of building my own but using an existing Matrix or scientific computing library to do the heavy lifting - if I were to do that which libraries would be candidates to serve as backends for such an effort
Eigen, one of the most used (and fastest) library for matrix computation in C++, has a java wrapper: jeigen.
It allows one to manipulate full and sparse matrices and make operations one them. It can be also worth trying.
Check out the following resources/packages
http://math.nist.gov/javanumerics/jama/
http://www.jscience.org/
Try to look at la4j (Linear Algebra for Java). It supports dense matrices as well as sparse ones. Here is just a brief example of using functional features of la4j:
// reads the dense matrix from the CSV file
Matrix a = new Basic2DMatrix(Mattrices.asSymbolSeparatedSource("matrix.csv", ","));
// calculates the sum of all elements of the matrix 'a'
double sum = a.fold(Matrices.asSumAccumulator(0));
// creates a new matrix 'b', that contains elements of matrix 'a' multiplied by '2'.
Matrix b = a.transform(Matrices.asMulFunction(2));
The best way to get the last version of la4j - visit it's GitHub page.
I use the Colt library for matrix operations.
See in: http://acs.lbl.gov/software/colt/api/index.html
I think it's really good and easy to use and is better than Apache Commons-Math and EJML that I have already tried.
I suggest you try all of the libraries mentioned and choose the one that is closer to your needs.
Related
I have a large dataset (>500.000 elements) that contains the stress values (σ_xx, σ_yy, σ_zz, τ_xy, τ_yz, τ_xz) of FEM-Elements. These stress values are given in the global xyz-coordinate space of the model. I want to calculate the main axis stress values and directions from those. If you're not that familiar with the physics behind it, this means taking the symmetric matrix
| σ_xx τ_xy τ_xz |
| τ_xy σ_yy τ_yz |
| τ_xz τ_yz σ_zz |
and calculating its eigenvalues and eigenvectors. Calculating each set of eigenvalues and -vectors on its own is too slow. I'm looking for a library, an algorithm or something in Java that would allow me to do this as array calculations. As an example, in python/numpy I could just take all my 3x3-matrices, stack them along a third dimension to get a nx3x3-array, and pass that to np.linalg.eig(arr), and it automatically gives me an nx3-array for the three eigenvalues and an nx3x3-array for the three eigenvectors.
Things I tried:
nd4j has an Eigen-module for calculating eigenvalues and -vectors, but only supports a single square array at a time.
Calculate the characteristic polynomial and use cardanos formula to get the roots/eigenvalues - possible to do for the whole array at once, but I'm stuck now on how to get the corresponding eigenvectors. Is there maybe a general simple algorithm to get from those to the eigenvectors?
Looking for an analytical form of the eigenvalues and -vectors that can be calculated directly: It does exist, but just no.
You'll need to write a little code.
I'd create or use a Matrix class as a dependency and find methods to give you eigenvalues and eigenvectors. The ones you found in nd4j sound like great candidates. You might also consider the Linear Algebra For Java (LA4J) dependency.
Load the dataset into a List<Matrix>.
Use functional Java methods to apply a map to give you a List of eigenvalues as a vector per stress matrix and a List of eigenvectors as a matrix per stress matrix.
You can optimize this calculation to the greatest extent possible by applying the map function to a stream. Java will parallelize the calculation under the covers to leverage available cores to the greatest extent possible.
Follow-up: This is the way that worked best for me, as I can do all operations without iterating over every element. As stated above, I'm using Nd4j, which seems to be limited in its possibilities compared to numpy (or maybe I just didn't read the documentation thoroughly enough). The following method uses only basic array operations:
From the given stress values, calculate the eigenvalues using Cardano's formula. Only element wise instructions are needed to do that (add, sub, mul, div, pow). The result should be three vectors of size n, each containing one eigenvalue for all elements.
Use the formula given here to calculate the matrix S for each eigenvalue. Like step 1, this can obviously also be done using only element-wise operations with the stress value- and eigenvalue-vectors, in order to avoid specifiying some complicated instructions on which array to multiply according to which axis while keeping whatever other axis.
Take one column from S and normalize it to get a normalized eigenvector for the given eigenvalue.
Note that this method only works if you have a real symmetric matrix. You also should make sure to properly deal with cases where the same eigenvalue appears multiple times.
I am searching for library implementing sparse multi-dimensional array for kotlin on jvm and js. There is Sparse Array implementation in android.utils, but can it be used with JVM / JS ?
Or there is something in core library and I a m just missing it?
How about using a spatial index, such as quadtrees, R-trees, kd-trees?
I am not aware of any Kotlin library, but if you can use Java, have a look at TinSpin index library.
Especially if the positions are integers and/or unique, I can suggest the PH-Tree which has by default unique positions but can also be used as multimap (simply insert a map/list/set into any occupied position).
Disclaimer: Self-advertisement - I am the developer of TinSpin as well as the PH-Tree.
Do you think it would be possible to implement sparse matrix operations using the new Stream interface in Java 1.8 ? If yes, how do we need to implement the matrixes and the operations. Clearly, I am looking for it for being able eventually to use the "automatic" parallelization.
It can clearly be done. How about something like below for a simple SPMV (Sparse matrix vector multiplication), with the sparse matrix represented in the coordinate COO format (the simplest sparse format out there):
class COO {
int x, y, value;
}
public static ArrayList<Integer> spmv(List<COO> values, ArrayList<Integer> v) {
final ArrayList<Integer> result = new ArrayList<>(Collections.nCopies(v.size(), 0));
values.stream().forEach(
coo -> result.set(coo.x, result.get(coo.x) + coo.value * v.get(coo.y))
);
return result;
}
But I sincerely suggest you use something pre-coded, if you don't want to spend the next 3 years of your life understanding the performance implications of sparse matrix operations.
This is quite a large research/optimisation topic and there are many factors to consider like (just off the top of my head):
scheduling / reordering of matrix values to improve cache performance
using an optimal storage format for specific problems (e.g. see this survey on netlib)
There are many implementations out there that can achieve orders of magnitude improvements in performance versus hand crafted implementation. To name a few, check out:
Intel MKL Sparse BLAS
Nvidia's cuBLAS
I would just write bindings to those if they don't exist already, although something like la4j looks quite promising.
I am using Jama API for solving a problem with Linear Algebra. But it is giving me an error: java.lang.RuntimeException: Matrix is singular.
I suppose when the matrix is singular there are multiple solutions possible. Is there a way in Jama API to get one of these solutions or is there any other API that can help me here.
Below is a code snippet I am using:
Matrix A = new Matrix(input);
Matrix B = new Matrix(startState);
Matrix X = A.solve(B);
answer = X.getArray();
return answer;
check the determinant of the matrix - if zero, it means that the matrix does not have an inverse (rows making up the matrix are not independent). In that case, you can look into SVD, Gauss-Siedel, Jacobi iteration etc. Also, as an alternate library, you could look into apache commons math if it helps.
Which is the best way to implement a sparse vector in Java?
Of course the good thing would be to have something that can be manipulated quite easily (normalization, scalar product and so on)
Thanks in advance
MTJ has a Sparse Vector class. It has norm functions (1-norm 2-norm and ∞-norm) and dot product functions.
JScience has a SparseVector implementation that is part of its linear algebra package.
You can also try to look at la4j's CompressedVector implementation. It uses pair of arrays: array of values and array of their indicies. And with binary search on top of that it just flies. So, this implementation guarantees O(log n) running time for get/set operations.
Just a brief example
Vector a = new CompressedVector(new double[]{ 1.0, 2.0, 3.0 }).
// calculates L_1 norm of the vector
double n = a.norm();
// calculates the sum of vectors elements
double s = a.fold(Vectors.asSumAccumulator(0.0));