«1. Обзор

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

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

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

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

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.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 – специальные функции (Gamma, Beta) 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 \u003c= x) для непрерывных распределений.

4. Анализ

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

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

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

Здесь мы пытаемся найти корень v -\u003e (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. Линейная алгебра

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

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

Случай довольно прост: мы определяем матрицу 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-векторов, линий и сегментов соответственно.

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

При использовании упомянутых выше классов можно выполнить некоторые вычисления. Например, следующий код выполняет вычисление пересечения двух 2D-линий:

Эти структуры также можно использовать для получения расстояния от точки до линии или ближайшей точки линии к другая линия (в 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 — структура генетического алгоритма Population — интерфейс, представляющий популяцию Chromosome — интерфейс, представляющий хромосому

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

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

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

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

8. Утилиты

8.1. FastMath

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 (например, factorial). Большинство этих функций можно найти в пакетах org.apache.commons.math3.special и org.apache.commons.math3.util.

long factorial = CombinatorialUtils.factorial(10);

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

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

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

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

Fraction lhs = new Fraction(1, 3);
Fraction rhs = new Fraction(2, 5);
Fraction sum = lhs.add(rhs);

String str = new FractionFormat().format(sum);

Затем мы можем вычислить сумму двух дробей и отобразить результат в виде строкового представления дроби (т.е. в форме «a / b»):

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.

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

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