Closed franyack closed 6 years ago
Aquí, un benchmark de referencia. Yo priorizaría tanto que sea simple de usar como performante, sin buscar el más performante necesariamente. De estos, me convence por ahora EJML aunque no he llegado a probarlo
https://github.com/optimatika/ojAlgo/wiki/Java-Matrix-Benchmark
Muy bueno Lea!!! Según la gráfica que se encuentra en ese benchmark EJML parece bancársela bastante a medida que crece el size de las matrices por lo que también creo que es una gran alternativa. La estuve probando y por lo poco que hice, anda bien, parece ser intiutiva y en la documentación se encuentran las diferentes operaciones. Además, hace comparativos sobre como se hacen en Matlab y como se hacen con SimpleMatrix (objeto que se debe crear para operar con esta libreria en Java) los diferentes métodos para trabajar con matrices y vectores.
Para realizar las pruebas he creado un proyecto en Java:
1 - Me descargué el IDE Eclipse (la instalación en Ubuntu fue super rápida e intuitiva).
2 - Hice un nuevo proyecto con gradle (similar a la utilización de este herramienta en Android), allí agregué dentro de las dependencias la siguiente línea: compile group: 'org.ejml', name: 'ejml-all', version: '0.34'
la cual descarga y compila todas las dependencias de EJML
3- Luego hice una nueva clase que se llama StatisticsMatrix (ejemplo en internet) y el código es el siguiente:
import org.ejml.data.DMatrixRMaj;
import org.ejml.data.Matrix;
import org.ejml.data.MatrixType;
import org.ejml.dense.row.RandomMatrices_DDRM;
import org.ejml.simple.SimpleBase;
import org.ejml.simple.SimpleMatrix;
import java.util.Random;
public class StatisticsMatrix extends SimpleBase<StatisticsMatrix> {
public StatisticsMatrix( int numRows , int numCols ) {
super(numRows,numCols);
}
protected StatisticsMatrix(){}
/**
* Wraps a StatisticsMatrix around 'm'. Does NOT create a copy of 'm' but saves a reference
* to it.
*/
public static StatisticsMatrix wrap( DMatrixRMaj m ) {
StatisticsMatrix ret = new StatisticsMatrix();
ret.setMatrix( m );
return ret;
}
/**
* Computes the mean or average of all the elements.
*
* @return mean
*/
public double mean() {
double total = 0;
final int N = getNumElements();
for( int i = 0; i < N; i++ ) {
total += get(i);
}
return total/N;
}
/**
* Computes the unbiased standard deviation of all the elements.
*
* @return standard deviation
*/
public double stdev() {
double m = mean();
double total = 0;
final int N = getNumElements();
if( N <= 1 )
throw new IllegalArgumentException("There must be more than one element to compute stdev");
for( int i = 0; i < N; i++ ) {
double x = get(i);
total += (x - m)*(x - m);
}
total /= (N-1);
return Math.sqrt(total);
}
/**
* Returns a matrix of StatisticsMatrix type so that SimpleMatrix functions create matrices
* of the correct type.
*/
@Override
protected StatisticsMatrix createMatrix(int numRows, int numCols, MatrixType type) {
return new StatisticsMatrix(numRows,numCols);
}
@Override
protected StatisticsMatrix wrapMatrix(Matrix m) {
StatisticsMatrix r = new StatisticsMatrix();
r.setMatrix( m );
return r;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Random rand = new Random(24234);
int N = 500;
// create two vectors whose elements are drawn from uniform distributions
StatisticsMatrix A = StatisticsMatrix.wrap(RandomMatrices_DDRM.rectangle(N,1,0,1,rand));
StatisticsMatrix B = StatisticsMatrix.wrap(RandomMatrices_DDRM.rectangle(N,1,1,2,rand));
// the mean should be about 0.5
System.out.println("Mean of A is "+A.mean());
// the mean should be about 1.5
System.out.println("Mean of B is "+B.mean());
StatisticsMatrix C = A.plus(B);
// the mean should be about 2.0
System.out.println("Mean of C = A + B is "+C.mean());
System.out.println("Standard deviation of A is "+A.stdev());
System.out.println("Standard deviation of B is "+B.stdev());
System.out.println("Standard deviation of C is "+C.stdev());
double[][] datos = {{1, 2}, {3, 4}};
SimpleMatrix F = new SimpleMatrix(datos);
F.print();
SimpleMatrix G = F.plus(F);
G.print();
}
}
Excelente Fran! Sii y lo que estuve viendo es que soporta sparse matrices y demás funcionalidades que no encuentro en JBlas por ejemplo. Así que por ahora le metemos con esa librería si te parece, ya que no encontré ninguna mejor en términos de rapido-facil de usar- completo.
Este benchmark es más completo: http://lessthanoptimal.github.io/Java-Matrix-Benchmark/runtime/2013_10_Corei7v2600/
Por ahí lo que veo es que el total de Jars pesa 2MB, suponiendo que se van a necesitar todos. Estaba viendo que la4J es mucho más liviano (al orden d cientos de KB) pero no parece ser para nada más óptimo, e incluso tiene muy poca documentación. Quise seguir un ejemplo pero no encontré las funciones para completar lo que quería, asi que por ahora resulta mejor EJML.
Por el momento, la elección sería EJML ya que muestra ser una librería apropiada y fácil de usar. Por lo tanto se puede cerrar este issue
Debemos encontrar que librería en java puede resolver problemas relacionados a la ciencia de la computación (como lo es NumPy en Python), ya sea para operar matrices, vectores, etc.