Рубрики
Без рубрики

Введение в Суаншу

Узнайте о SuanShu – математической библиотеке Java для численного анализа, статистики, поиска корней, линейной алгебры, оптимизации и многого другого.

Автор оригинала: baeldung.

1. введение

SuanShu – это математическая библиотека Java для численного анализа, статистики, поиска корней, линейной алгебры, оптимизации и многого другого. Одна из вещей, которую он предоставляет, – это функциональность как для вещественных, так и для комплексных чисел.

Существует версия библиотеки с открытым исходным кодом, а также версия, требующая лицензии-с различными формами лицензии: академической, коммерческой и авторской.

Обратите внимание, что в приведенных ниже примерах используется лицензионная версия через pom.xml . Версия с открытым исходным кодом в настоящее время недоступна в репозитории Maven; лицензионная версия требует запуска сервера лицензий. В результате в GitHub нет никаких тестов для этого пакета.

2. Настройка для SuanShu

Давайте начнем с добавления зависимости Maven в pom.xml :


    
        com.numericalmethod
        suanshu
        4.0.0
    


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

3. Работа С Векторами

Библиотека SuanShu предоставляет классы как для плотных векторов, так и для разреженных векторов. A плотный вектор-это вектор, в котором большинство элементов имеют ненулевое значение, в отличие от разреженного вектора, в котором большинство значений имеют нулевое значение.

Реализация плотного вектора просто использует массив Java вещественных/комплексных чисел , в то время как реализация разреженного вектора использует массив Java записей , где каждая запись имеет индекс и вещественное/комплексное значение.

Мы можем видеть, как это будет иметь огромное значение в хранении, когда у нас есть большой вектор, где большинство значений равно нулю. Большинство математических библиотек используют подобный подход, когда им необходимо поддерживать векторы больших размеров.

Давайте рассмотрим некоторые из основных векторных операций.

3.1. Добавление векторов

Добавление 2 векторов довольно просто с помощью метода add() :

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

Результат, который мы увидим, будет:

[6.000000, 6.000000, 6.000000, 6.000000, 6.000000]

Мы также можем добавить одинаковые числа ко всем элементам, используя метод add(double) .

3.2. Векторы масштабирования

Масштабирование вектора (т. Е. умножение на константу) также очень просто:

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

Выход:

[2.000000, 4.000000, 6.000000, 8.000000, 10.000000]

3.3. Векторное внутреннее произведение

Вычисление внутреннего произведения 2 векторов требует вызова метода inner Product(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. Работа С Ошибками

Библиотека проверяет, совместимы ли векторы, с которыми мы работаем, с выполняемой нами операцией. Например, добавление вектора размера 2 к вектору размера 3 не должно быть возможным. Таким образом, приведенный ниже код должен привести к исключению:

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

И действительно, это так – запуск этого кода приводит к:

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.baeldung.suanshu.SuanShuMath.addingIncorrectVectors(SuanShuMath.java:21)
    at com.baeldung.suanshu.SuanShuMath.main(SuanShuMath.java:8)

4. Работа С Матрицами

В дополнение к векторам библиотека также обеспечивает поддержку матричных операций. Подобно векторам, матрицы поддерживаются в плотном и разреженном формате, а также для вещественных и комплексных чисел.

4.1. Добавление матриц

Добавление матриц так же просто, как и работа с векторами:

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. Умножение матриц

Математическую библиотеку можно использовать для умножения матриц:

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

Умножение матрицы 2×3 на матрицу 3×2 приведет к матрице 2×2.

И чтобы доказать, что библиотека правильно проверяет размеры матрицы, давайте попробуем выполнить умножение, которое должно потерпеть неудачу:

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

Выполнение этого приведет к следующему результату.

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.baeldung.suanshu.SuanShuMath.multiplyIncorrectMatrices(SuanShuMath.java:98)
    at com.baeldung.suanshu.SuanShuMath.main(SuanShuMath.java:22)

4.3. Вычисление обратной матрицы

Вычисление обратной матрицы может быть длительным процессом, выполняемым вручную, но математическая библиотека SuanShu упрощает его:

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

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

Мы можем проверить это, используя библиотеку SuanShu, но умножая матрицу на ее обратную: результатом должна быть матрица идентичности. Мы можем сделать это, добавив следующее к приведенному выше методу:

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

5. Решение многочленов

Одна из других областей, в которых SuanShu оказывает поддержку, – это многочлены. Он предоставляет методы для оценки полинома, но также и для нахождения его корня (входные значения, при которых полином равен 0).

5.1. Создание полинома

Многочлен можно создать, указав его коэффициенты. Таким образом, многочлен типа 3x 2 -5x+1 можно создать с помощью:

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

Как мы видим, сначала мы начинаем с коэффициента для самой высокой степени.

5.2. Оценка многочлена

Для оценки полинома можно использовать метод evaluate () . Это может быть сделано для реальных и сложных входных данных.

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

Результат, который мы увидим, будет:

51.0
-13.000000+2.000000i

5.3. Нахождение корней многочлена

Поиск корней многочлена облегчается математической библиотекой SuanShu. Он предоставляет хорошо известные алгоритмы для определения корней многочленов различной степени и, основываясь на самой высокой степени многочлена, класс PolyRoot выбирает наилучший метод:

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

Выход:

[-2.0, 1.0]

Таким образом, для этого выборочного полинома было найдено 2 реальных корня: -2 и 1. Естественно, поддерживаются и комплексные корни.

6. Заключение

Эта статья-всего лишь краткое введение в математическую библиотеку Суаншу.

Как всегда, полный исходный код статьи доступен на GitHub .