Une introduction à SuanShu

Une introduction à SuanShu

1. introduction

The SuanShu is a Java math library for numerical analysis, statistics, root finding, linear algebra, optimization, and lots more. Une des choses qu'il fournit est la fonctionnalité pour les nombres réels et complexes.

Il existe une version open source de la bibliothèque, ainsi qu'une version nécessitant une licence - avec différentes formes de licence: académique, commerciale et contributeur.

Notez que les exemples ci-dessous utilisent la version sous licence via lespom.xml. La version open-source n'est actuellement pas disponible dans un référentiel Maven; la version sous licence nécessite l'exécution d'un serveur de licences. Par conséquent, il n'y a aucun test pour ce package dans GitHub.

2. Configuration pour SuanShu

Commençons par ajouter la dépendance Maven auxpom.xml:


    
        com.numericalmethod
        suanshu
        4.0.0
    


    
        nm-repo
        Numerical Method's Maven Repository
        http://repo.numericalmethod.com/maven/
        default
    

3. Travailler avec des vecteurs

The SuanShu library provides classes for both dense vectors and sparse vectors. Un vecteurdense est un vecteur où la plupart des éléments ont une valeur non nulle, par opposition à un vecteursparse où la plupart des valeurs ont une valeur nulle.

L'implémentation d'un vecteurdense utilise simplement un tableau Java de nombres réels / complexes tandis que l'implémentation d'un vecteursparse utilise un tableau Java deentries, où chaqueentry a un index et une valeur réelle / complexe.

Nous pouvons voir comment cela ferait une énorme différence en matière de stockage lorsque nous avons un grand vecteur où la plupart des valeurs sont nulles. La plupart des bibliothèques mathématiques utilisent une telle approche lorsqu'elles doivent prendre en charge des vecteurs de grandes tailles.

Examinons quelques-unes des opérations vectorielles de base.

3.1. Ajout de vecteurs

L'ajout de 2 vecteurs est assez simple en utilisant la méthodeadd():

public void addingVectors() throws Exception {
    Vector v1 = new DenseVector(new double[] {1, 2, 3, 4, 5});
    Vector v2 = new DenseVector(new double[] {5, 4, 3, 2, 1});
    Vector v3 = v1.add(v2);
    log.info("Adding vectors: {}", v3);
}

Le résultat que nous verrons est:

[6.000000, 6.000000, 6.000000, 6.000000, 6.000000]

Nous pouvons également ajouter les mêmes nombres à tous les éléments en utilisant la méthodeadd(double).

3.2. Vecteurs de mise à l'échelle

Mise à l'échelle d'un vecteur (c'est-à-dire multiplier par une constante) est également très facile:

public void scaleVector() throws Exception {
    Vector v1 = new DenseVector(new double[]{1, 2, 3, 4, 5});
    Vector v2 = v1.scaled(2.0);
    log.info("Scaling a vector: {}", v2);
}

Le résultat:

[2.000000, 4.000000, 6.000000, 8.000000, 10.000000]

3.3. Produit intérieur vectoriel

Le calcul du produit interne de 2 vecteurs nécessite un appel à la méthodeinnerProduct(Vector):

public void innerProductVectors() throws Exception {
    Vector v1 = new DenseVector(new double[]{1, 2, 3, 4, 5});
    Vector v2 = new DenseVector(new double[]{5, 4, 3, 2, 1});
    double inner = v1.innerProduct(v2);
    log.info("Vector inner product: {}", inner);
}

3.4. Traiter les erreurs

La bibliothèque vérifie que les vecteurs sur lesquels vous travaillez sont compatibles avec l'opération que vous exécutez. Par exemple, l'ajout d'un vecteur de taille 2 à un vecteur de taille 3 ne devrait pas être possible. Le code ci-dessous devrait donc donner lieu à une exception:

public void addingIncorrectVectors() throws Exception {
    Vector v1 = new DenseVector(new double[] {1, 2, 3});
    Vector v2 = new DenseVector(new double[] {5, 4});
    Vector v3 = v1.add(v2);
}

Et en effet, si vous exécutez ce code, vous obtenez:

Exception in thread "main" com.numericalmethod.suanshu.vector.doubles.IsVector$SizeMismatch: vectors do not have the same size: 3 and 2
    at com.numericalmethod.suanshu.vector.doubles.IsVector.throwIfNotEqualSize(IsVector.java:101)
    at com.numericalmethod.suanshu.vector.doubles.dense.DenseVector.add(DenseVector.java:174)
    at com.example.suanshu.SuanShuMath.addingIncorrectVectors(SuanShuMath.java:21)
    at com.example.suanshu.SuanShuMath.main(SuanShuMath.java:8)

4. Travailler avec des matrices

In addition to vectors, the library also provides support for matrix operations. Comme pour les vecteurs, les matrices sont prises en charge au formatdense etsparse, et pour les nombres réels et complexes.

4.1. Ajout de matrices

Ajouter des matrices est aussi simple que de travailler avec des vecteurs:

public void addingMatrices() throws Exception {
    Matrix m1 = new DenseMatrix(new double[][]{
        {1, 2, 3},
        {4, 5, 6}
    });

    Matrix m2 = new DenseMatrix(new double[][]{
        {3, 2, 1},
        {6, 5, 4}
    });

    Matrix m3 = m1.add(m2);
    log.info("Adding matrices: {}", m3);
}

4.2. Multiplier les matrices

La bibliothèque mathématique peut être utilisée pour multiplier des matrices:

public void multiplyMatrices() throws Exception {
    Matrix m1 = new DenseMatrix(new double[][]{
        {1, 2, 3},
        {4, 5, 6}
    });

    Matrix m2 = new DenseMatrix(new double[][]{
        {1, 4},
        {2, 5},
        {3, 6}
    });

    Matrix m3 = m1.multiply(m2);
    log.info("Multiplying matrices: {}", m3);
}

Multiplier une matrice 2 × 3 avec une matrice 3 × 2 donnera une matrice 2 × 2.

Et pour prouver que la bibliothèque vérifie correctement les tailles de matrice, essayons de faire une multiplication qui devrait échouer:

public void multiplyIncorrectMatrices() throws Exception {
    Matrix m1 = new DenseMatrix(new double[][]{
        {1, 2, 3},
        {4, 5, 6}
    });

    Matrix m2 = new DenseMatrix(new double[][]{
        {3, 2, 1},
        {6, 5, 4}
    });

    Matrix m3 = m1.multiply(m2);
}

L'exécution qui aboutira à la sortie suivante.

Exception in thread "main" com.numericalmethod.suanshu.matrix.MatrixMismatchException:
    matrix with 3 columns and matrix with 2 rows cannot multiply due to mis-matched dimension
    at com.numericalmethod.suanshu.datastructure.DimensionCheck.throwIfIncompatible4Multiplication(DimensionCheck.java:164)
    at com.numericalmethod.suanshu.matrix.doubles.matrixtype.dense.DenseMatrix.multiply(DenseMatrix.java:374)
    at com.example.suanshu.SuanShuMath.multiplyIncorrectMatrices(SuanShuMath.java:98)
    at com.example.suanshu.SuanShuMath.main(SuanShuMath.java:22)

4.3. Calcul d'une matrice inverse

Le calcul de l'inverse d'une matrice peut être un long processus à effectuer manuellement, mais la bibliothèque de mathématiques SuanShu facilite les choses:

public void inverseMatrix() {
    Matrix m1 = new DenseMatrix(new double[][]{
        {1, 2},
        {3, 4}
    });

    Inverse m2 = new Inverse(m1);
    log.info("Inverting a matrix: {}", m2);
}

Nous pouvons le vérifier en utilisant la bibliothèque SuanShu mais en multipliant la matrice par son inverse: le résultat devrait être la matrice identité. Nous pouvons le faire en ajoutant ce qui suit à la méthode ci-dessus:

log.info("Verifying a matrix inverse: {}", m1.multiply(m2));

5. Résolution de polynômes

One of the other areas the SuanShu provides support for is polynomials. Il fournit des méthodes pour évaluer un polynôme mais aussi pour trouver sa racine (valeurs d'entrée où le polynôme est évalué à 0).

5.1. Créer un polynôme

Un polynôme peut être créé en spécifiant ses coefficients. Ainsi, un polynôme comme3x2-5x+1 peut être créé avec:

public Polynomial createPolynomial() {
    return new Polynomial(new double[]{3, -5, 1});
}

Comme nous pouvons le constater, nous commençons par le coefficient du degré le plus élevé.

5.2. Évaluation d'un polynôme

La méthodeevaluate() peut être utilisée pour évaluer le polynôme. Cela peut être fait pour des entrées réelles et complexes.

public void evaluatePolynomial(Polynomial p) {
    log.info("Evaluating a polynomial using a real number: {}", p.evaluate(5));
    log.info("Evaluating a polynomial using a complex number: {}", p.evaluate(new Complex(1, 2)));
}

Le résultat que nous verrons est:

51.0
-13.000000+2.000000i

5.3. Recherche des racines d’un polynôme

La recherche des racines d’un polynôme est facilitée par la bibliothèque de mathématiques SuanShu. Il fournit des algorithmes bien connus pour déterminer les racines des polynômes de divers degrés et basé sur le degré le plus élevé du polynôme, la classe PolyRoot choisit la meilleure méthode:

public void solvePolynomial() {
    Polynomial p = new Polynomial(new double[]{2, 2, -4});
    PolyRootSolver solver = new PolyRoot();
    List roots = solver.solve(p);
    log.info("Finding polynomial roots: {}", roots);
}

Le résultat:

[-2.0, 1.0]

Deux racines réelles ont donc été trouvées pour cet exemple de polynôme: -2 et 1. Naturellement, les racines complexes sont également prises en charge.

6. Conclusion

Cet article est juste une brève introduction à la bibliothèque de mathématiques SuanShu.

Comme toujours, le code source complet de l'article est disponibleover on GitHub.