Введение в Apache Commons Math

Введение в Apache Commons Math

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, просто добавьтеthis dependency:


  org.apache.commons
  commons-math3
  3.6.1

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. Вероятности и распределения

В ядре JavaMath.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 включает реализацию несколькихroot-finding algorithms.

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

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

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

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

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

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 из массива массивов чисел типа double и векторb из массива вектора.

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

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

6. Геометрия

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

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

  • org.apache.commons.math3.geometry.euclidean.oned – 1D евклидова геометрия

  • org.apache.commons.math3.geometry.euclidean.twod – 2D евклидова геометрия

  • org.apache.commons.math3.geometry.euclidean.threed – 3D евклидова геометрия

  • org.apache.commons.math3.geometry.spherical.oned – 1D сферическая геометрия

  • org.apache.commons.math3.geometry.spherical.twod – 2D сферическая геометрия

Наиболее полезными классами, вероятно, являются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 иoptimization есть повторяющиеся классы: пакетoptimization в основном устарел и будет удален в Commons Math 4.

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

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

Пакет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 (например, факториал). Большинство этих функций можно найти в пакетах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. Дроби и комплексные числа

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

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

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.

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

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

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