Introdução ao Apache Commons Math

Introdução ao Apache Commons Math

1. Visão geral

Freqüentemente, precisamos usar ferramentas matemáticas e às vezesjava.lang.Math simplesmente não é suficiente. Felizmente, o Apache Commons tem o objetivo de preencher os vazamentos da biblioteca padrão, comApache Commons Math.

O Apache Commons Math é a maior biblioteca de código aberto de funções e utilitários matemáticos para Java. Como este artigo é apenas uma introdução, forneceremos apenas uma visão geral da biblioteca e apresentaremos os casos de uso mais atraentes.

2. Começando com Apache Commons Math

2.1. Os usos do Apache Commons Math

O Apache Commons Math consiste em funções matemáticas (erf, por exemplo), estruturas que representam conceitos matemáticos (como números complexos, polinômios, vetores, etc.) e algoritmos que podemos aplicar a essas estruturas (localização de raiz, otimização, curva ajuste, cálculo de interseções de figuras geométricas, etc.).

2.2. Configuração do Maven

Se você estiver usando o Maven, basta adicionarthis dependency:


  org.apache.commons
  commons-math3
  3.6.1

2.3. Visão geral do pacote

O Apache Commons Math está dividido em vários pacotes:

  • org.apache.commons.math3.stat – estatísticas e testes estatísticos

  • org.apache.commons.math3.distribution – distribuições de probabilidade

  • org.apache.commons.math3.random – números aleatórios, strings e geração de dados

  • org.apache.commons.math3.analysis – descoberta de raiz, integração, interpolação, polinômios, etc.

  • Matrizesorg.apache.commons.math3.linear –, resolvendo sistemas lineares

  • Geometriaorg.apache.commons.math3.geometry – (espaços euclidianos e partição de espaço binário)

  • Métodos de transformaçãoorg.apache.commons.math3.transform – (Fourier rápido)

  • org.apache.commons.math3.ode – integração de equações diferenciais ordinárias

  • org.apache.commons.math3.fitting – ajuste da curva

  • org.apache.commons.math3.optim – maximização ou minimização da função

  • org.apache.commons.math3.genetics – algoritmos genéticos

  • org.apache.commons.math3.ml – aprendizado de máquina (cluster e redes neurais)

  • org.apache.commons.math3.util – funções matemáticas / estatísticas comuns estendendo java.lang.Math

  • org.apache.commons.math3.special – funções especiais (Gama, Beta)

  • org.apache.commons.math3.complex – números complexos

  • org.apache.commons.math3.fraction – números racionais

3. Estatísticas, probabilidades e aleatoriedade

3.1. Estatisticas

O pacoteorg.apache.commons.math3.stat fornece várias ferramentas para cálculos estatísticos. Por exemplo, para calcular a média, o desvio padrão e muitos mais, podemos usarDescriptiveStatistics:

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

Neste pacote, podemos encontrar ferramentas para calcular a covariância, correlação ou para realizar testes estatísticos (usandoTestUtils).

3.2. Probabilidades e Distribuições

No núcleo do Java,Math.random() pode ser usado para gerar valores aleatórios, mas esses valores são distribuídos uniformemente entre 0 e 1.

Às vezes, queremos produzir um valor aleatório usando uma distribuição mais complexa. Para isso, podemos usar a estrutura fornecida pororg.apache.commons.math3.distribution.

Aqui está como gerar valores aleatórios de acordo com a distribuição normal com a média de 10 e o desvio padrão de 3:

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

Ou podemos obter a probabilidadeP(X = x) de obter um valor para distribuições discretas ou a probabilidade cumulativaP(X ⇐ x) para distribuições contínuas.

4. Análise

Funções e algoritmos relacionados à análise podem ser encontrados emorg.apache.commons.math3.analysis.

4.1. Root Finding

Uma raiz é um valor em que uma função tem o valor 0. Commons-Math inclui a implementação de váriosroot-finding algorithms.

Aqui, tentamos encontrar a raiz dev → (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);

Primeiro, começamos definindo a função, depois definimos o solucionador e configuramos a precisão desejada. Finalmente, chamamos a APIsolve().

A operação de localização de raiz será realizada usando várias iterações, então é uma questão de encontrar um meio-termo entre o tempo de execução e a precisão.

4.2. Calculando Integrais

A integração funciona quase como descoberta de raiz:

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

Começamos definindo uma função, escolhemos um integrador entre osavailable integration solutions existentes, definimos a precisão desejada e, por fim, integramos.

5. Álgebra Linear

Se tivermos um sistema linear de equações sob a forma AX = B, em que A é uma matriz de números reais e B um vetor de números reais - o Commons Math fornece estruturas para representar a matriz e o vetor e também fornece soluções para encontrar o valor de X:

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

O caso é bastante simples: definimos uma matriza de uma matriz de matriz de duplas e um vetorb de uma matriz de um vetor.

Em seguida, criamos umLUDecomposition que fornece um solucionador para equações na forma AX = B. Como o próprio nome indica,LUDecomposition depende doLU decomposition e, portanto, funciona apenas com matrizes quadradas.

Para outras matrizes, existem diferentes solucionadores, geralmente resolvendo a equação usando o método dos mínimos quadrados.

6. Geometria

O pacoteorg.apache.commons.math3.geometry fornece várias classes para representar objetos geométricos e várias ferramentas para manipulá-los. É importante notar que este pacote é dividido em subpacotes diferentes, em relação ao tipo de geometria que queremos usar:

É importante notar que este pacote é dividido em subpacotes diferentes, em relação ao tipo de geometria que queremos usar:

  • org.apache.commons.math3.geometry.euclidean.oned – 1D geometria euclidiana

  • org.apache.commons.math3.geometry.euclidean.twod – geometria euclidiana 2D

  • org.apache.commons.math3.geometry.euclidean.threed – geometria euclidiana 3D

  • org.apache.commons.math3.geometry.spherical.oned – geometria esférica 1D

  • org.apache.commons.math3.geometry.spherical.twod – geometria esférica 2D

As classes mais úteis são provavelmenteVector2D,Vector3D,Line eSegment. Eles são usados ​​para representar vetores 2D (ou pontos), vetores 3D, linhas e segmentos, respectivamente.

Ao usar as classes mencionadas acima, é possível realizar alguns cálculos. Por exemplo, o código a seguir executa o cálculo da interseção de duas linhas 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);

Também é possível usar essas estruturas para obter a distância de um ponto a uma linha ou o ponto mais próximo de uma linha a outra linha (em 3D).

7. Otimização, Algoritmos Genéticos e Aprendizado de Máquina

O Commons-Math também fornece algumas ferramentas e algoritmos para tarefas mais complexas relacionadas à otimização e aprendizado de máquina.

7.1. Otimização

A otimização geralmente consiste em minimizar ou maximizar as funções de custo. Algoritmos para otimização podem ser encontrados emorg.apache.commons.math3.optimeorg.apache.commons.math3.optimimization. Inclui algoritmos de otimização linear e não linear.

Podemos notar que existem classes duplicadas nos pacotesoptimeoptimization: o pacoteoptimization está em sua maioria obsoleto e será removido do Commons Math 4.

7.2. Algorítmos genéticos

Os algoritmos genéticos são um tipo de meta-heurística: eles são uma solução para encontrar uma solução aceitável para um problema quando os algoritmos determinísticos são muito lentos. Uma visão geral dos algoritmos genéticos pode ser encontradahere.

O pacoteorg.apache.commons.math3.genetics fornece uma estrutura para realizar cálculos usando algoritmos genéticos. Ele contém uma estrutura que pode ser usada para representar uma população e um cromossomo e algoritmos padrão para executar operações de mutação, cruzamento e seleção.

As seguintes classes fornecem um bom ponto de partida:

7.3. Machine Learning

O aprendizado de máquina no Commons-Math é dividido em duas partes: agrupamento e redes neurais.

A parte de agrupamento consiste em colocar um rótulo nos vetores de acordo com sua similaridade em relação à métrica de distância. Os algoritmos de armazenamento em cluster fornecidos são baseados no algoritmo K-means.

A parte da rede neural fornece classes para representar redes (Network) e neurônios (Neuron). Pode-se observar que as funções fornecidas são limitadas em comparação com as estruturas de redes neurais mais comuns, mas ainda podem ser úteis para pequenas aplicações com baixos requisitos.

8. Serviços de utilidade pública

8.1. FastMath

FastMath é uma classe estática localizada emorg.apache.commons.math3.utile funcionando exatamente comojava.lang.Math.

Seu objetivo é fornecer, pelo menos as mesmas funções que encontramos emjava.lang.Math, mas com implementações mais rápidas. Portanto, quando um programa depende muito de cálculos matemáticos, é uma boa ideia substituir as chamadas paraMath.sin() (por exemplo) para as chamadasFastMath.sin() para melhorar o desempenho do aplicativo. Por outro lado, observe queFastMath é menos preciso do quejava.lang.Math.

8.2. Funções Comuns e Especiais

Commons-Math fornece funções matemáticas padrão que não são implementadas emjava.lang.Math (como o fatorial). Muitas dessas funções podem ser encontradas nos pacotesorg.apache.commons.math3.specialeorg.apache.commons.math3.util.

Por exemplo, se queremos calcular o fatorial de 10, podemos simplesmente fazer:

long factorial = CombinatorialUtils.factorial(10);

As funções relacionadas à aritmética (gcd,lcm, etc.) podem ser encontradas emArithmeticUtils, e as funções relacionadas à combinatória podem ser encontradas emCombinatorialUtils. Algumas outras funções especiais, comoerf, podem ser acessadas emorg.apache.commons.math3.special.

8.3. Fração e números complexos

Também é possível manipular tipos mais complexos usando commons-math: fração e números complexos. Essas estruturas nos permitem realizar cálculos específicos sobre esse tipo de números.

Em seguida, podemos calcular a soma de duas frações e exibir o resultado como uma representação de string de uma fração (ou seja, sob a forma "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);

Ou podemos calcular rapidamente o poder de números complexos:

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

Complex power = first.pow(second);

9. Conclusão

Neste tutorial, apresentamos algumas das coisas interessantes que você pode fazer usando o Apache Commons Math.

Infelizmente, este artigo não pode cobrir todo o campo de análise ou álgebra linear e, portanto, apenas fornece exemplos para as situações mais comuns.

No entanto, para obter mais informações, podemos ler o bem escritodocumentation, que fornece muitos detalhes para todos os aspectos da biblioteca.

E, como sempre, as amostras de código podem ser encontradashere on GitHub.