Introduzione ad Apache Commons Math

1. Panoramica

Abbiamo spesso bisogno di utilizzare strumenti matematici e talvolta java.lang.Math semplicemente non è sufficiente. Fortunatamente, Apache Commons ha l'obiettivo di colmare le falle della libreria standard, con Apache Commons Math.

Apache Commons Math è la più grande libreria open source di funzioni matematiche e utilità per Java. Dato che questo articolo è solo un'introduzione, forniremo solo una panoramica della libreria e presenteremo i casi d'uso più convincenti.

2. A partire da Apache Commons Math

2.1. Gli usi di Apache Commons Math

Apache Commons Math consiste di funzioni matematiche ( erf per esempio), strutture che rappresentano concetti matematici (come numeri complessi, polinomi, vettori, ecc.) E algoritmi che possiamo applicare a queste strutture (ricerca delle radici, ottimizzazione, adattamento della curva, calcolo di intersezioni di figure geometriche, ecc.).

2.2. Configurazione Maven

Se stai usando Maven, aggiungi semplicemente questa dipendenza:

 org.apache.commons commons-math3 3.6.1  

2.3. Panoramica del pacchetto

Apache Commons Math è suddiviso in diversi pacchetti:

  • org.apache.commons.math3.stat - statistiche e test statistici
  • org.apache.commons.math3.distribution - distribuzioni di probabilità
  • org.apache.commons.math3.random: numeri casuali, stringhe e generazione di dati
  • org.apache.commons.math3.analysis - ricerca delle radici, integrazione, interpolazione, polinomi, ecc.
  • org.apache.commons.math3.linear - matrici, risoluzione di sistemi lineari
  • org.apache.commons.math3.geometry - geometria (spazi euclidei e partizionamento binario dello spazio)
  • org.apache.commons.math3.transform - metodi di trasformazione (Fast Fourier)
  • org.apache.commons.math3.ode - integrazione di equazioni differenziali ordinarie
  • org.apache.commons.math3.fitting - raccordo della curva
  • org.apache.commons.math3.optim - massimizzazione o minimizzazione delle funzioni
  • org.apache.commons.math3.genetics - algoritmi genetici
  • org.apache.commons.math3.ml - machine learning (clustering e reti neurali)
  • org.apache.commons.math3.util - funzioni matematiche / statistiche comuni che estendono java.lang.Math
  • org.apache.commons.math3.special - funzioni speciali (Gamma, Beta)
  • org.apache.commons.math3.complex - numeri complessi
  • org.apache.commons.math3.fraction - numeri razionali

3. Statistiche, probabilità e casualità

3.1. Statistiche

Il pacchetto org.apache.commons.math3.stat fornisce diversi strumenti per i calcoli statistici. Ad esempio, per calcolare la media, la deviazione standard e molti altri, possiamo usare 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(); 

In questo pacchetto, possiamo trovare strumenti per calcolare la covarianza, la correlazione o per eseguire test statistici (utilizzando TestUtils ).

3.2. Probabilità e distribuzioni

In Java core, Math.random () può essere utilizzato per generare valori casuali, ma questi valori sono distribuiti uniformemente tra 0 e 1.

A volte, vogliamo produrre un valore casuale utilizzando una distribuzione più complessa. Per questo, possiamo utilizzare il framework fornito da org.apache.commons.math3.distribution .

Ecco come generare valori casuali secondo la distribuzione normale con la media di 10 e la deviazione standard di 3:

NormalDistribution normalDistribution = new NormalDistribution(10, 3); double randomValue = normalDistribution.sample(); 

Oppure possiamo ottenere la probabilità P (X = x) di ottenere un valore per distribuzioni discrete o la probabilità cumulativa P (X <= x) per distribuzioni continue.

4. Analisi

Le funzioni e gli algoritmi relativi all'analisi possono essere trovati in org.apache.commons.math3.analysis .

4.1. Ricerca delle radici

Una radice è un valore in cui una funzione ha il valore 0. Commons-Math include l'implementazione di diversi algoritmi di ricerca delle radici.

Qui, proviamo a trovare la radice di 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); 

Per prima cosa, iniziamo definendo la funzione, quindi definiamo il risolutore e impostiamo la precisione desiderata. Infine, chiamiamo l' API resol () .

L'operazione di ricerca delle radici verrà eseguita utilizzando diverse iterazioni, quindi si tratta di trovare un compromesso tra tempo di esecuzione e precisione.

4.2. Calcolo degli integrali

L'integrazione funziona quasi come la ricerca di root:

UnivariateFunction function = v -> v; UnivariateIntegrator integrator = new SimpsonIntegrator(1.0e-12, 1.0e-8, 1, 32); double i = integrator.integrate(100, function, 0, 10); 

Iniziamo definendo una funzione, scegliamo un integratore tra le soluzioni di integrazione disponibili esistenti, impostiamo la precisione desiderata e infine integriamo.

5. Algebra lineare

Se abbiamo un sistema lineare di equazioni sotto la forma AX = B dove A è una matrice di numeri reali e B un vettore di numeri reali - Commons Math fornisce strutture per rappresentare sia la matrice che il vettore, e fornisce anche risolutori per trovare il valore di 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); 

Il caso è piuttosto semplice: definiamo una matrice a da un array di array di doppi e un vettore b da un array di un vettore.

Quindi, creiamo una decomposizione LUD che fornisce un risolutore per equazioni sotto la forma AX = B. Come dice il nome, la decomposizione LUD si basa sulla scomposizione LU e quindi funziona solo con matrici quadrate.

Per altre matrici, esistono diversi solutori, che di solito risolvono l'equazione utilizzando il metodo dei minimi quadrati.

6. Geometria

Il pacchetto org.apache.commons.math3.geometry fornisce diverse classi per rappresentare oggetti geometrici e diversi strumenti per manipolarli. È importante notare che questo pacchetto è diviso in diversi sotto-pacchetti, per quanto riguarda il tipo di geometria che vogliamo utilizzare:

È importante notare che questo pacchetto è diviso in diversi sotto-pacchetti, per quanto riguarda il tipo di geometria che vogliamo utilizzare:

  • org.apache.commons.math3.geometry.euclidean.oned - Geometria euclidea 1D
  • org.apache.commons.math3.geometry.euclidean.twod - Geometria euclidea 2D
  • org.apache.commons.math3.geometry.euclidean.threed - Geometria euclidea 3D
  • org.apache.commons.math3.geometry.spherical.oned - Geometria sferica 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

È anche possibile gestire tipi più complessi utilizzando la matematica comune: frazioni e numeri complessi. Queste strutture ci consentono di eseguire calcoli specifici su questo tipo di numeri.

Quindi, possiamo calcolare la somma di due frazioni e visualizzare il risultato come una rappresentazione di stringa di una frazione (cioè sotto 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); 

Oppure possiamo calcolare rapidamente la potenza di numeri complessi:

Complex first = new Complex(1.0, 3.0); Complex second = new Complex(2.0, 5.0); Complex power = first.pow(second); 

9. Conclusione

In questo tutorial, abbiamo presentato alcune delle cose interessanti che puoi fare usando Apache Commons Math.

Sfortunatamente, questo articolo non può coprire l'intero campo dell'analisi o dell'algebra lineare e, quindi, fornisce solo esempi per le situazioni più comuni.

Tuttavia, per maggiori informazioni, possiamo leggere la documentazione ben scritta, che fornisce molti dettagli per tutti gli aspetti della libreria.

E, come sempre, gli esempi di codice possono essere trovati qui su GitHub.