Introduction à Apache Commons Math

Introduction à Apache Commons Math

1. Vue d'ensemble

Nous avons souvent besoin d’outils mathématiques, et parfoisjava.lang.Math ne suffit tout simplement pas. Heureusement, Apache Commons a pour objectif de combler les fuites de la bibliothèque standard, avecApache Commons Math.

Apache Commons Math est la plus grande bibliothèque open-source de fonctions et utilitaires mathématiques pour Java. Étant donné que cet article n’est qu’une introduction, nous allons simplement donner un aperçu de la bibliothèque et présenter les cas d’utilisation les plus convaincants.

2. Commencer avec Apache Commons Math

2.1. Les usages d'Apache Commons Math

Apache Commons Math se compose de fonctions mathématiques (erf par exemple), de structures représentant des concepts mathématiques (comme les nombres complexes, les polynômes, les vecteurs, etc.), et d'algorithmes que nous pouvons appliquer à ces structures (recherche de racines, optimisation, courbe ajustement, calcul des intersections de figures géométriques, etc.).

2.2. Configuration Maven

Si vous utilisez Maven, ajoutez simplementthis dependency:


  org.apache.commons
  commons-math3
  3.6.1

2.3. Aperçu du package

Apache Commons Math est divisé en plusieurs packages:

  • Statistiquesorg.apache.commons.math3.stat – et tests statistiques

  • Distributions de probabilitéorg.apache.commons.math3.distribution –

  • org.apache.commons.math3.random – nombres aléatoires, chaînes et génération de données

  • Recherche de racine deorg.apache.commons.math3.analysis –, intégration, interpolation, polynômes, etc.

  • Matricesorg.apache.commons.math3.linear –, résolution de systèmes linéaires

  • Géométrieorg.apache.commons.math3.geometry – (espaces euclidiens et partitionnement d'espace binaire)

  • Méthodes de transformationorg.apache.commons.math3.transform – (Fourier rapide)

  • Intégration d'équations différentielles ordinairesorg.apache.commons.math3.ode –

  • Ajustement de la courbeorg.apache.commons.math3.fitting –

  • Maximisation ou minimisation de la fonctionorg.apache.commons.math3.optim –

  • Algorithmes génétiques deorg.apache.commons.math3.genetics –

  • Apprentissage automatique deorg.apache.commons.math3.ml – (clustering et réseaux de neurones)

  • Fonctions mathématiques / statistiques courantes deorg.apache.commons.math3.util – étendant java.lang.Math

  • Fonctions spéciales deorg.apache.commons.math3.special – (Gamma, Beta)

  • Nombres complexesorg.apache.commons.math3.complex –

  • org.apache.commons.math3.fraction – nombres rationnels

3. Statistiques, probabilités et aléa

3.1. Statistiques

Le packageorg.apache.commons.math3.stat fournit plusieurs outils pour les calculs statistiques. Par exemple, pour calculer la moyenne, l'écart type et bien d'autres, nous pouvons utiliserDescriptiveStatistics:

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();

Dans ce package, nous pouvons trouver des outils pour calculer la covariance, la corrélation ou pour effectuer des tests statistiques (en utilisantTestUtils).

3.2. Probabilités et distributions

Dans le noyau Java,Math.random() peut être utilisé pour générer des valeurs aléatoires, mais ces valeurs sont uniformément réparties entre 0 et 1.

Parfois, nous voulons produire une valeur aléatoire en utilisant une distribution plus complexe. Pour cela, nous pouvons utiliser le framework fourni parorg.apache.commons.math3.distribution.

Voici comment générer des valeurs aléatoires selon la distribution normale avec la moyenne de 10 et l'écart type de 3:

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

Ou nous pouvons obtenir la probabilitéP(X = x) d'obtenir une valeur pour les distributions discrètes, ou la probabilité cumulativeP(X ⇐ x) pour les distributions continues.

4. Une analyse

Les fonctions et algorithmes liés à l'analyse peuvent être trouvés dansorg.apache.commons.math3.analysis.

4.1. Recherche de racine

Une racine est une valeur où une fonction a la valeur 0. Commons-Math inclut l'implémentation de plusieursroot-finding algorithms.

Ici, nous essayons de trouver la racine dev → (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);

Tout d'abord, nous commençons par définir la fonction, puis nous définissons le solveur et nous définissons la précision souhaitée. Enfin, nous appelons l'APIsolve().

L’opération de recherche de racine sera effectuée en plusieurs itérations, il s’agit donc de trouver un compromis entre le temps d’exécution et la précision.

4.2. Calcul des intégrales

L'intégration fonctionne presque comme une recherche de racine:

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

Nous commençons par définir une fonction, nous choisissons un intégrateur parmi lesavailable integration solutions existants, nous fixons la précision souhaitée, et enfin, nous intégrons.

5. Algèbre linéaire

Si nous avons un système d'équations linéaire sous la forme AX = B où A est une matrice de nombres réels et B un vecteur de nombres réels - Commons Math fournit des structures pour représenter à la fois la matrice et le vecteur, ainsi que des solveurs permettant de trouver la valeur 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);

Le cas est assez simple: nous définissons une matricea à partir d'un tableau de tableaux de doubles, et un vecteurb à partir d'un tableau d'un vecteur.

Ensuite, nous créons unLUDecomposition qui fournit un solveur pour les équations sous la forme AX = B. Comme son nom l'indique,LUDecomposition s'appuie sur lesLU decomposition, et ne fonctionne donc qu'avec des matrices carrées.

Pour les autres matrices, il existe différents solveurs, résolvant généralement l'équation à l'aide de la méthode des moindres carrés.

6. Géométrie

Le packageorg.apache.commons.math3.geometry fournit plusieurs classes pour représenter des objets géométriques et plusieurs outils pour les manipuler. Il est important de noter que ce paquet est divisé en différents sous-paquets, en fonction du type de géométrie que nous voulons utiliser:

Il est important de noter que ce paquet est divisé en différents sous-paquets, en fonction du type de géométrie que nous voulons utiliser:

  • org.apache.commons.math3.geometry.euclidean.oned – Géométrie euclidienne 1D

  • org.apache.commons.math3.geometry.euclidean.twod – Géométrie euclidienne 2D

  • Géométrie euclidienne 3Dorg.apache.commons.math3.geometry.euclidean.threed –

  • org.apache.commons.math3.geometry.spherical.oned – Géométrie sphérique 1D

  • Géométrie sphérique 2Dorg.apache.commons.math3.geometry.spherical.twod –

Les classes les plus utiles sont probablementVector2D,Vector3D,Line etSegment. Ils sont utilisés pour représenter les vecteurs 2D (ou points), les vecteurs 3D, les lignes et les segments, respectivement.

Lors de l'utilisation des classes mentionnées ci-dessus, il est possible d'effectuer certains calculs. Par exemple, le code suivant effectue le calcul de l'intersection de deux lignes 2D:

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);

Il est également possible d'utiliser ces structures pour obtenir la distance d'un point à une ligne ou le point le plus proche d'une ligne à une autre ligne (en 3D).

7. Optimisation, algorithmes génétiques et apprentissage automatique

Commons-Math fournit également des outils et des algorithmes pour des tâches plus complexes liées à l'optimisation et à l'apprentissage automatique.

7.1. Optimisation

L'optimisation consiste généralement à minimiser ou à maximiser les fonctions de coût. Les algorithmes d'optimisation peuvent être trouvés dansorg.apache.commons.math3.optim etorg.apache.commons.math3.optimimization. Il comprend des algorithmes d'optimisation linéaires et non linéaires.

Nous pouvons noter qu'il existe des classes en double dans les packagesoptim etoptimization: le packageoptimization est pour la plupart obsolète et sera supprimé dans Commons Math 4.

7.2. Algorithmes génétiques

Les algorithmes génétiques sont une sorte de méta-heuristique: ils permettent de trouver une solution acceptable à un problème lorsque les algorithmes déterministes sont trop lents. Un aperçu des algorithmes génétiques peut être trouvéhere.

Le packageorg.apache.commons.math3.genetics fournit un cadre pour effectuer des calculs à l'aide d'algorithmes génétiques. Il contient une structure pouvant être utilisée pour représenter une population et un chromosome, ainsi que des algorithmes standard permettant d'effectuer des opérations de mutation, de croisement et de sélection.

Les cours suivants donnent un bon point de départ:

7.3. Apprentissage machine

L'apprentissage automatique dans Commons-Math est divisé en deux parties: le regroupement et les réseaux de neurones.

La partie regroupement consiste à apposer une étiquette sur les vecteurs en fonction de leur similarité par rapport à une métrique de distance. Les algorithmes de classification fournis sont basés sur l'algorithme K-means.

La partie réseau neuronal donne des classes pour représenter les réseaux (Network) et les neurones (Neuron). On peut noter que les fonctions fournies sont limitées par rapport aux structures de réseau de neurones les plus courantes, mais cela peut néanmoins être utile pour les petites applications peu exigeantes.

8. Utilitaires

8.1. FastMath

FastMath est une classe statique située dansorg.apache.commons.math3.util et fonctionnant exactement commejava.lang.Math.

Son but est de fournir, au moins les mêmes fonctions que l'on peut trouver dansjava.lang.Math, mais avec des implémentations plus rapides. Ainsi, lorsqu'un programme repose fortement sur des calculs mathématiques, il est judicieux de remplacer les appels àMath.sin() (par exemple) par des appels àFastMath.sin() pour améliorer les performances de l'application. En revanche, notez queFastMath est moins précis quejava.lang.Math.

8.2. Fonctions communes et spéciales

Commons-Math fournit des fonctions mathématiques standard qui ne sont pas implémentées dansjava.lang.Math (comme factorielle). La plupart de ces fonctions se trouvent dans les packagesorg.apache.commons.math3.special etorg.apache.commons.math3.util.

Par exemple, si nous voulons calculer la factorielle de 10, nous pouvons simplement faire:

long factorial = CombinatorialUtils.factorial(10);

Les fonctions liées à l'arithmétique (gcd,lcm, etc.) peuvent être trouvées dansArithmeticUtils, et les fonctions liées à la combinatoire peuvent être trouvées dansCombinatorialUtils. Certaines autres fonctions spéciales, commeerf, sont accessibles dansorg.apache.commons.math3.special.

8.3. Fraction et nombres complexes

Il est également possible de gérer des types plus complexes en utilisant commons-math: nombres fractionnaires et complexes. Ces structures nous permettent d'effectuer des calculs spécifiques sur ce type de nombres.

Ensuite, nous pouvons calculer la somme de deux fractions et afficher le résultat sous la forme d’une chaîne représentant une fraction (c.-à-d. sous la forme "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);

Ou, nous pouvons rapidement calculer la puissance de nombres complexes:

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

Complex power = first.pow(second);

9. Conclusion

Dans ce tutoriel, nous avons présenté quelques-unes des choses intéressantes que vous pouvez faire avec Apache Commons Math.

Malheureusement, cet article ne peut pas couvrir tout le domaine de l’analyse ou de l’algèbre linéaire et ne fournit donc que des exemples pour les situations les plus courantes.

Cependant, pour plus d'informations, nous pouvons lire ledocumentation bien écrit, qui fournit de nombreux détails sur tous les aspects de la bibliothèque.

Et, comme toujours, les exemples de code peuvent être trouvéshere on GitHub.