Apache Commons Mathの紹介

Apache Commons Mathの概要

1. 概要

数学ツールの使用が頻繁に必要になり、java.lang.Mathだけでは不十分な場合もあります。 幸い、Apache Commonsには、標準ライブラリのリークをApache Commons Mathで埋めることが目標です。

Apache Commons Mathは、Java用の数学関数とユーティリティの最大のオープンソースライブラリです。 この記事は単なる紹介であるため、ライブラリの概要を示し、最も説得力のあるユースケースを紹介します。

2. Apache CommonsMathから始める

2.1. Apache CommonsMathの使用法

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 –機械学習(クラスタリングおよびニューラルネットワーク)

  • java.lang.Mathを拡張するorg.apache.commons.math3.util –の一般的な数学/統計関数

  • 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には、いくつかの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);

最初に、関数を定義することから始め、次にソルバーを定義し、目的の精度を設定します。 最後に、solve()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);

関数を定義することから始め、既存のavailable integration solutionsの中から積分器を選択し、必要な精度を設定し、最後に積分します。

5. 線形代数

AX = Bの形式の線形連立方程式があり、Aは実数の行列で、Bは実数のベクトルである場合– Commons Mathは、行列とベクトルの両方を表す構造を提供し、求めるソルバーも提供します。 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);

ケースは非常に単純です。doubleの配列の配列から行列aを定義し、ベクトルの配列からベクトルbを定義します。

次に、AX = Bの形式で方程式のソルバーを提供するLUDecompositionを作成します。 その名前が示すように、LUDecompositionLU 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球面幾何学

最も有用なクラスは、おそらくVector2DVector3DLine、およびSegmentです。 それらは、それぞれ2Dベクトル(またはポイント)、3Dベクトル、線、およびセグメントを表すために使用されます。

上記のクラスを使用する場合、いくつかの計算を実行できます。 たとえば、次のコードは2つの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.optimorg.apache.commons.math3.optimimizationにあります。 線形および非線形の最適化アルゴリズムが含まれています。

optimパッケージとoptimizationパッケージに重複するクラスがあることに注意してください。optimizationパッケージはほとんど非推奨であり、Commons Math4で削除されます。

7.2. 遺伝的アルゴリズム

遺伝的アルゴリズムは一種のメタヒューリスティックです。それらは、決定論的アルゴリズムが遅すぎる場合に問題の許容可能な解決策を見つけるための解決策です。 遺伝的アルゴリズムの概要はhereにあります。

パッケージorg.apache.commons.math3.geneticsは、遺伝的アルゴリズムを使用して計算を実行するためのフレームワークを提供します。 これには、母集団と染色体を表すために使用できる構造と、突然変異、交叉、および選択操作を実行する標準アルゴリズムが含まれています。

次のクラスが出発点として適切です。

  • GeneticAlgorithm遺伝的アルゴリズムフレームワーク

  • Population母集団を表すインターフェース

  • Chromosome染色体を表すインターフェース

7.3. 機械学習

Commons-Mathの機械学習は、クラスタリングとニューラルネットワークの2つの部分に分かれています。

クラスタリング部分は、距離メトリックに関するベクトルの類似性に従ってベクトルにラベルを付けることで構成されます。 提供されるクラスタリングアルゴリズムは、K-meansアルゴリズムに基づいています。

ニューラルネットワーク部分は、ネットワーク(Network)とニューロン(Neuron)を表すクラスを提供します。 提供されている機能は、最も一般的なニューラルネットワークフレームワークと比較して制限されていますが、要件の低い小規模なアプリケーションには依然として有用であることに注意してください。

8. 公益事業

8.1. FastMath

FastMathは、org.apache.commons.math3.utilにある静的クラスであり、java.lang.Mathとまったく同じように機能します。

その目的は、少なくともjava.lang.Mathにあるのと同じ関数を提供することですが、実装はより高速です。 したがって、プログラムが数学的計算に大きく依存している場合は、アプリケーションのパフォーマンスを向上させるために、(たとえば)Math.sin()の呼び出しをFastMath.sin()の呼び出しに置き換えることをお勧めします。 一方、FastMathjava.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);

算術関連の関数(gcdlcmなど)はArithmeticUtilsにあり、組み合わせ論に関連する関数はCombinatorialUtilsにあります。 erfのような他のいくつかの特別な関数は、org.apache.commons.math3.specialでアクセスできます。

8.3. 分数と複素数

commons-mathを使用して、より複雑な型(分数と複素数)を処理することもできます。 これらの構造により、この種の数値に対して特定の計算を実行できます。

次に、2つの分数の合計を計算し、結果を分数の文字列表現として表示できます(つまり、 「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を使用して実行できる興味深いことをいくつか紹介しました。

残念ながら、この記事では分析や線形代数の分野全体を網羅することはできないため、最も一般的な状況の例のみを提供します。

ただし、詳細については、適切に記述されたdocumentationを読むことができます。これは、ライブラリのすべての側面に関する多くの詳細を提供します。

そして、いつものように、コードサンプルはhere on GitHubで見つけることができます。