Перейти к основному содержимому

Введение в математику Apache Commons

· 8 мин. чтения

1. Обзор

Нам часто нужно использовать математические инструменты, и иногда java.lang.Math просто недостаточно. К счастью, у Apache Commons есть цель восполнить утечки стандартной библиотеки с помощью Apache Commons Math .

Apache Commons Math — крупнейшая библиотека математических функций и утилит для Java с открытым исходным кодом. Учитывая, что эта статья является лишь введением, мы просто дадим обзор библиотеки и представим наиболее убедительные варианты использования.

2. Начиная с Apache Commons Math

2.1. Использование математики Apache Commons

Apache Commons Math состоит из математических функций ( например, erf ), структур, представляющих математические понятия (например, комплексные числа, многочлены, векторы и т. д.), и алгоритмов, которые мы можем применять к этим структурам (нахождение корней, оптимизация, подгонка кривой, вычисление пересечения геометрических фигур и др.).

2.2. Конфигурация Maven

Если вы используете Maven, просто добавьте эту зависимость :

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>

2.3. Обзор пакета

Apache Commons Math разделен на несколько пакетов:

  • org.apache.commons.math3.stat — статистика и статистические тесты
  • org.apache.commons.math3.distribution — распределения вероятностей
  • org.apache.commons.math3.random — случайные числа, строки и генерация данных
  • org.apache.commons.math3.analysis — поиск корней, интегрирование, интерполяция, полиномы и т. д.
  • org.apache.commons.math3.linear — матрицы, решение линейных систем
  • org.apache.commons.math3.geometry — геометрия (евклидовы пространства и разбиение бинарного пространства)
  • org.apache.commons.math3.transform — методы преобразования (быстрый Фурье)
  • org.apache.commons.math3.ode — интеграция обыкновенных дифференциальных уравнений
  • org.apache.commons.math3.fitting — подбор кривой
  • org.apache.commons.math3.optim — функция максимизации или минимизации
  • org.apache.commons.math3.genetics — генетические алгоритмы
  • org.apache.commons.math3.ml — машинное обучение (кластеризация и нейронные сети)
  • org.apache.commons.math3.util — общие математические/статистические функции, расширяющие java.lang.Math
  • org.apache.commons.math3.special — специальные функции (гамма, бета)
  • org.apache.commons.math3.complex — комплексные числа
  • org.apache.commons.math3.fraction — рациональные числа

3. Статистика, вероятности и случайность

3.1. Статистика

Пакет org.apache.commons.math3.stat предоставляет несколько инструментов для статистических вычислений. Например, чтобы вычислить среднее значение, стандартное отклонение и многое другое, мы можем использовать 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();

В этом пакете мы можем найти инструменты для вычисления ковариации, корреляции или выполнения статистических тестов (используя TestUtils ).

3.2. Вероятности и распределения

В базовой версии Java Math.random() можно использовать для генерации случайных значений, но эти значения равномерно распределяются между 0 и 1.

Иногда мы хотим создать случайное значение, используя более сложное распределение. Для этого мы можем использовать фреймворк, предоставляемый org.apache.commons.math3.distribution .

Вот как генерировать случайные значения в соответствии с нормальным распределением со средним значением 10 и стандартным отклонением 3:

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

Или мы можем получить вероятность P(X = x) получения значения для дискретных распределений или кумулятивную вероятность P(X <= x) для непрерывных распределений.

4. Анализ

Функции и алгоритмы, связанные с анализом, можно найти на странице org.apache.commons.math3.analysis .

4.1. Поиск корня

Корень — это значение, при котором функция имеет значение 0. Commons-Math включает реализацию нескольких алгоритмов поиска корня .

Здесь мы пытаемся найти корень 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);

Сначала мы начинаем с определения функции, затем определяем решатель и устанавливаем желаемую точность. Наконец, мы вызываем API решения() .

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

4.2. Вычисление интегралов

Интеграция работает почти как поиск корня:

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

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

5. Линейная алгебра

Если у нас есть линейная система уравнений в форме AX = B, где A — матрица действительных чисел, а B — вектор действительных чисел, Commons Math предоставляет структуры для представления как матрицы, так и вектора, а также предоставляет решатели для нахождения значение Х:

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

Случай довольно прост: мы определяем матрицу a из массива массивов двойников и вектор b из массива векторов.

Затем мы создаем LUDecomposition , который предоставляет решатель уравнений в форме AX = B. Как следует из названия, LUDecomposition опирается на LU-разложение и поэтому работает только с квадратными матрицами.

Для других матриц существуют разные решатели, обычно решающие уравнение с использованием метода наименьших квадратов.

6. Геометрия

Пакет org.apache.commons.math3.geometry предоставляет несколько классов для представления геометрических объектов и несколько инструментов для управления ими. Важно отметить, что этот пакет разделен на различные подпакеты в зависимости от того, какую геометрию мы хотим использовать:

Важно отметить, что этот пакет разделен на различные подпакеты в зависимости от того, какую геометрию мы хотим использовать:

  • org.apache.commons.math3.geometry.euclidean.oned — одномерная евклидова геометрия
  • org.apache.commons.math3.geometry.euclidean.twod — двумерная евклидова геометрия
  • org.apache.commons.math3.geometry.euclidean.threed — трехмерная евклидова геометрия
  • org.apache.commons.math3.geometry.spherical.oned — одномерная сферическая геометрия
  • org.apache.commons.math3.geometry.spherical.twod — двумерная сферическая геометрия

Вероятно, наиболее полезными классами являются Vector2D , Vector3D , Line и Segment . Они используются для представления 2D-векторов (или точек), 3D-векторов, линий и сегментов соответственно.

При использовании упомянутых выше классов можно выполнить некоторые вычисления. Например, следующий код выполняет вычисление пересечения двух 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);

Также возможно использовать эти структуры, чтобы получить расстояние от точки до линии или ближайшую точку линии к другой линии (в 3D).

7. Оптимизация, генетические алгоритмы и машинное обучение

Commons-Math также предоставляет некоторые инструменты и алгоритмы для более сложных задач, связанных с оптимизацией и машинным обучением.

7.1. Оптимизация

Оптимизация обычно состоит из минимизации или максимизации функций затрат. Алгоритмы оптимизации можно найти в org.apache.commons.math3.optim и org.apache.commons.math3.optimimization . Он включает линейные и нелинейные алгоритмы оптимизации.

Мы можем заметить, что в пакетах optim и пакетов оптимизации есть повторяющиеся классы: пакет оптимизации в основном устарел и будет удален в Commons Math 4.

7.2. Генетические алгоритмы

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

Пакет org.apache.commons.math3.genetics предоставляет платформу для выполнения вычислений с использованием генетических алгоритмов. Он содержит структуру, которую можно использовать для представления популяции и хромосомы, а также стандартные алгоритмы для выполнения операций мутации, скрещивания и отбора.

Следующие классы дают хорошую отправную точку:

  • GeneticAlgorithm - структура генетического алгоритма
  • Население — интерфейс, представляющий население
  • Хромосома - интерфейс, представляющий хромосому

7.3. Машинное обучение

Машинное обучение в Commons-Math разделено на две части: кластеризация и нейронные сети.

Часть кластеризации состоит из маркировки векторов в соответствии с их сходством относительно метрики расстояния. Предоставленные алгоритмы кластеризации основаны на алгоритме K-средних.

Часть нейронной сети дает классы для представления сетей ( Network ) и нейронов ( Neuron ). Можно отметить, что предоставляемые функции ограничены по сравнению с наиболее распространенными каркасами нейронных сетей, но все же могут быть полезны для небольших приложений с низкими требованиями.

8. Утилиты

8.1. БыстраяМатематика

FastMath — это статический класс, расположенный в org.apache.commons.math3.util и работающий точно так же, как java.lang.Math .

Его цель — предоставить, по крайней мере, те же функции, что и в java.lang.Math , но с более быстрой реализацией. Итак, когда программа сильно зависит от математических вычислений, хорошей идеей будет заменить вызовы Math.sin() (например) на вызовы FastMath.sin() , чтобы повысить производительность приложения. С другой стороны, обратите внимание, что FastMath менее точен, чем java.lang.Math.

8.2. Общие и специальные функции

Commons-Math предоставляет стандартные математические функции, которые не реализованы в java.lang.Math (например, факториал). Большинство этих функций можно найти в пакетах org.apache.commons.math3.special и org.apache.commons.math3.util .

Например, если мы хотим вычислить факториал 10, мы можем просто сделать:

long factorial = CombinatorialUtils.factorial(10);

Функции, связанные с арифметикой ( gcd , lcm и т. д .), можно найти в ArithmeticUtils , а функции, связанные с комбинаторикой, можно найти в CombinatorialUtils . Доступ к некоторым другим специальным функциям, таким как erf , можно получить в org.apache.commons.math3.special .

8.3. Дробные и комплексные числа

Также можно обрабатывать более сложные типы, используя математику общего пользования: дробные и комплексные числа. Эти структуры позволяют нам выполнять определенные вычисления с такими числами.

Затем мы можем вычислить сумму двух дробей и отобразить результат в виде строкового представления дроби (т.е. в форме «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);

Или мы можем быстро вычислить мощность комплексных чисел:

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

Complex power = first.pow(second);

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

В этом руководстве мы представили несколько интересных вещей, которые вы можете сделать с помощью Apache Commons Math.

К сожалению, эта статья не может охватить всю область анализа или линейной алгебры и, таким образом, содержит только примеры для наиболее распространенных ситуаций.

Однако для получения дополнительной информации мы можем прочитать хорошо написанную документацию , в которой приведено множество подробностей по всем аспектам работы библиотеки.

И, как всегда, образцы кода можно найти здесь, на GitHub .