1. Información general
Con frecuencia necesitamos utilizar herramientas matemáticas y, a veces, java.lang.Math simplemente no es suficiente. Afortunadamente, Apache Commons tiene el objetivo de completar las filtraciones de la biblioteca estándar con Apache Commons Math.
Apache Commons Math es la biblioteca de código abierto más grande de funciones y utilidades matemáticas para Java. Dado que este artículo es solo una introducción, solo brindaremos una descripción general de la biblioteca y presentaremos los casos de uso más atractivos.
2. Comenzando con Apache Commons Math
2.1. Los usos de Apache Commons Math
Apache Commons Math consta de funciones matemáticas ( erf, por ejemplo), estructuras que representan conceptos matemáticos (como números complejos, polinomios, vectores, etc.) y algoritmos que podemos aplicar a estas estructuras (búsqueda de raíces, optimización, ajuste de curvas, cálculo de intersecciones de figuras geométricas, etc.).
2.2. Configuración de Maven
Si está usando Maven, simplemente agregue esta dependencia:
org.apache.commons commons-math3 3.6.1
2.3. Descripción general del paquete
Apache Commons Math se divide en varios paquetes:
- org.apache.commons.math3.stat - estadísticas y pruebas estadísticas
- org.apache.commons.math3.distribution - distribuciones de probabilidad
- org.apache.commons.math3.random: números aleatorios, cadenas y generación de datos
- org.apache.commons.math3.analysis - búsqueda de raíces, integración, interpolación, polinomios, etc.
- org.apache.commons.math3.linear - matrices, resolución de sistemas lineales
- org.apache.commons.math3.geometry - geometría (espacios euclidianos y partición de espacios binarios)
- org.apache.commons.math3.transform - métodos de transformación (Fourier rápido)
- org.apache.commons.math3.ode - integración de ecuaciones diferenciales ordinarias
- org.apache.commons.math3.fitting - ajuste de curvas
- org.apache.commons.math3.optim - maximización o minimización de funciones
- org.apache.commons.math3.genetics - algoritmos genéticos
- org.apache.commons.math3.ml: aprendizaje automático (agrupación en clústeres y redes neuronales)
- org.apache.commons.math3.util: funciones matemáticas / estadísticas comunes que amplían java.lang.Math
- org.apache.commons.math3.special - funciones especiales (Gamma, Beta)
- org.apache.commons.math3.complex - números complejos
- org.apache.commons.math3.fraction - números racionales
3. Estadísticas, probabilidades y aleatoriedad
3.1. Estadísticas
El paquete org.apache.commons.math3.stat proporciona varias herramientas para cálculos estadísticos. Por ejemplo, para calcular la media, la desviación estándar y muchos más, podemos usar DescriptiveStatistics :
double[] values = new double[] {65, 51 , 16, 11 , 6519, 191 ,0 , 98, 19854, 1, 32}; DescriptiveStatistics descriptiveStatistics = new DescriptiveStatistics(); for (double v : values) { descriptiveStatistics.addValue(v); } double mean = descriptiveStatistics.getMean(); double median = descriptiveStatistics.getPercentile(50); double standardDeviation = descriptiveStatistics.getStandardDeviation();
En este paquete podemos encontrar herramientas para calcular la covarianza, correlación o realizar pruebas estadísticas (usando TestUtils ).
3.2. Probabilidades y distribuciones
En el núcleo de Java, Math.random () se puede utilizar para generar valores aleatorios, pero estos valores se distribuyen uniformemente entre 0 y 1.
A veces, queremos producir un valor aleatorio utilizando una distribución más compleja. Para ello, podemos utilizar el marco proporcionado por org.apache.commons.math3.distribution .
A continuación se explica cómo generar valores aleatorios de acuerdo con la distribución normal con la media de 10 y la desviación estándar de 3:
NormalDistribution normalDistribution = new NormalDistribution(10, 3); double randomValue = normalDistribution.sample();
O podemos obtener la probabilidad P (X = x) de obtener un valor para distribuciones discretas, o la probabilidad acumulada P (X <= x) para distribuciones continuas.
4. Análisis
Las funciones y algoritmos relacionados con el análisis se pueden encontrar en org.apache.commons.math3.analysis .
4.1. Hallazgo de raíz
Una raíz es un valor donde una función tiene el valor 0. Commons-Math incluye la implementación de varios algoritmos de búsqueda de raíces.
Aquí, intentamos encontrar la raíz de v -> (v * v) - 2 :
UnivariateFunction function = v -> Math.pow(v, 2) - 2; UnivariateSolver solver = new BracketingNthOrderBrentSolver(1.0e-12, 1.0e-8, 5); double c = solver.solve(100, function, -10.0, 10.0, 0);
Primero, comenzamos definiendo la función, luego definimos el solucionador y establecemos la precisión deseada. Finalmente, llamamos a la API solve () .
La operación de búsqueda de raíz se realizará mediante varias iteraciones, por lo que es cuestión de encontrar un compromiso entre el tiempo de ejecución y la precisión.
4.2. Calcular integrales
La integración funciona casi como la búsqueda de raíces:
UnivariateFunction function = v -> v; UnivariateIntegrator integrator = new SimpsonIntegrator(1.0e-12, 1.0e-8, 1, 32); double i = integrator.integrate(100, function, 0, 10);
Comenzamos por definir una función, elegimos un integrador entre las soluciones de integración disponibles existentes, establecemos la precisión deseada, y finalmente, integramos.
5. Álgebra lineal
Si tenemos un sistema lineal de ecuaciones bajo la forma AX = B donde A es una matriz de números reales y B un vector de números reales, Commons Math proporciona estructuras para representar tanto la matriz como el vector, y también proporciona solucionadores para encontrar el valor de X:
RealMatrix a = new Array2DRowRealMatrix( new double[][] { { 2, 3, -2 }, { -1, 7, 6 }, { 4, -3, -5 } }, false); RealVector b = new ArrayRealVector(n ew double[] { 1, -2, 1 }, false); DecompositionSolver solver = new LUDecomposition(a).getSolver(); RealVector solution = solver.solve(b);
El caso es bastante sencillo: definimos una matriz a de una matriz de matrices de dobles y un vector b de una matriz de un vector.
Luego, creamos una LUDecomposition que proporciona un solucionador de ecuaciones bajo la forma AX = B. Como su nombre lo indica, LUDecomposition se basa en la descomposición LU y, por lo tanto, solo funciona con matrices cuadradas.
Para otras matrices, existen diferentes solucionadores, generalmente resolviendo la ecuación utilizando el método de mínimos cuadrados.
6. Geometría
El paquete org.apache.commons.math3.geometry proporciona varias clases para representar objetos geométricos y varias herramientas para manipularlos. Es importante tener en cuenta que este paquete se divide en diferentes subpaquetes, en función del tipo de geometría que queramos utilizar:
Es importante tener en cuenta que este paquete se divide en diferentes subpaquetes, en función del tipo de geometría que queramos utilizar:
- org.apache.commons.math3.geometry.euclidean.oned - geometría euclidiana 1D
- org.apache.commons.math3.geometry.euclidean.twod - Geometría euclidiana 2D
- org.apache.commons.math3.geometry.euclidean.threed - geometría euclidiana 3D
- org.apache.commons.math3.geometry.spherical.oned - geometría esférica 1D
- org.apache.commons.math3.geometry.spherical.twod – 2D spherical geometry
The most useful classes are probably Vector2D, Vector3D, Line, and Segment. They are used for representing 2D vectors (or points), 3D vectors, lines, and segments respectively.
When using classes mentioned above, it is possible to perform some computation. For instance, the following code performs the calculation of the intersection of two 2D lines:
Line l1 = new Line(new Vector2D(0, 0), new Vector2D(1, 1), 0); Line l2 = new Line(new Vector2D(0, 1), new Vector2D(1, 1.5), 0); Vector2D intersection = l1.intersection(l2);
It is also feasible to use these structures to get the distance of a point to a line, or the closest point of a line to another line (in 3D).
7. Optimization, Genetic Algorithms, and Machine Learning
Commons-Math also provides some tools and algorithms for more complex tasks related to optimization and machine learning.
7.1. Optimization
Optimization usually consists of minimizing or maximizing cost functions. Algorithms for optimization can be found in org.apache.commons.math3.optim and org.apache.commons.math3.optimimization. It includes linear and nonlinear optimization algorithms.
We can note that there are duplicate classes in the optim and optimization packages: the optimization package is mostly deprecated and will be removed in the Commons Math 4.
7.2. Genetic Algorithms
Genetic algorithms are a kind of meta-heuristics: they are a solution to finding an acceptable solution to a problem when deterministic algorithms are too slow. An overview of genetic algorithms can be found here.
The package org.apache.commons.math3.genetics provides a framework to perform computations using genetic algorithms. It contains structure that can be used to represent a population and a chromosome, and standard algorithms to perform mutation, crossover, and selection operations.
The following classes give a good start point:
- GeneticAlgorithm – the genetic algorithm framework
- Population – the interface representing a population
- Chromosome – the interface representing a chromosome
7.3. Machine Learning
Machine learning in Commons-Math is divided into two parts: clustering and neural networks.
The clustering part consists of putting a label on vectors according to their similarity regarding a distance metric. The clustering algorithms provided are based on the K-means algorithm.
The neural network part gives classes to represent networks (Network) and neurons (Neuron). One may note that the provided functions are limited compared to the most common neural network frameworks, but it can still be useful for small applications with low requirements.
8. Utilities
8.1. FastMath
FastMath is a static class located in org.apache.commons.math3.util and working exactly like java.lang.Math.
Its purpose is to provide, at least the same functions that we can found in java.lang.Math, but with faster implementations. So, when a program is heavily relying on mathematical computations, it is a good idea to replace calls to Math.sin() (for instance) to calls to FastMath.sin() to improve the performance of the application. On the other hand please note that FastMath is less accurate than java.lang.Math.
8.2. Common and Special Functions
Commons-Math provides standard mathematical functions that are not implemented in java.lang.Math (like factorial). Most of these functions can be found in the packages org.apache.commons.math3.special and org.apache.commons.math3.util.
For instance, if we want to compute the factorial of 10 we can simply do:
long factorial = CombinatorialUtils.factorial(10);
Functions related to arithmetic (gcd, lcm, etc.) can be found in ArithmeticUtils, and functions related to combinatorial can be found in CombinatorialUtils. Some other special functions, like erf, can be accessed in org.apache.commons.math3.special.
8.3. Fraction and Complex Numbers
También es posible manejar tipos más complejos usando commons-math: fracción y números complejos. Estas estructuras nos permiten realizar cálculos específicos sobre este tipo de números.
Luego, podemos calcular la suma de dos fracciones y mostrar el resultado como una representación de cadena de una fracción (es decir, bajo la forma "a / b"):
Fraction lhs = new Fraction(1, 3); Fraction rhs = new Fraction(2, 5); Fraction sum = lhs.add(rhs); String str = new FractionFormat().format(sum);
O podemos calcular rápidamente la potencia de números complejos:
Complex first = new Complex(1.0, 3.0); Complex second = new Complex(2.0, 5.0); Complex power = first.pow(second);
9. Conclusión
En este tutorial, presentamos algunas de las cosas interesantes que puede hacer con Apache Commons Math.
Desafortunadamente, este artículo no puede cubrir todo el campo del análisis o el álgebra lineal y, por lo tanto, solo proporciona ejemplos para las situaciones más comunes.
Sin embargo, para obtener más información, podemos leer la documentación bien redactada, que proporciona muchos detalles sobre todos los aspectos de la biblioteca.
Y, como siempre, los ejemplos de código se pueden encontrar aquí en GitHub.