🐡

Apache Commons Numbersとはなんなのか?

に公開

今回はApache Commons Numbersについて調べてみました。 今回も以下のツールを使って対象プロジェクトを決めました!

https://zenn.dev/akasan/articles/7e30ad266c02c4

※ 本企画に関する記事の目的は、それぞれのプロジェクトを本格的に深ぼるのではなく、プロジェクト名⇆どんな内容かをパッと思い出せるようにすることを目指します!
※ とはいえ深ぼってみたいプロジェクトがあればどんどん複数連載になると思います。

Apache Commons Numbersとは?

公式サイトによると、

Apache Commons Numbers provides implementations of number types and utilities. Features include:

とのことで数値型とユーティリティの実装を提供するようです。具体的には以下のような特徴があるようです。

  • angles
  • arrays
  • combinatorics
  • complex numbers
  • core arithmetic
  • fields
  • fractions
  • gamma functions
  • primes
  • quaternions
  • root finding

https://commons.apache.org/proper/commons-numbers/

それぞれについて

angles

anglesでは角度に関する単位間の変換を実現するようです。例えばラジアンとturn(回転?)の変換は以下になるようです。

Angle.Deg a = Angle.Turn.of(0.5).toDeg();
Angle.Rad b = a.toRad();
Angle.Turn c = b.toTurn();
// c.getAsDouble() == 0.5

また、例えば座標からCosineをなす角度を計算することもできるようです。

double[] v1 = {1, 0};
double[] v2 = {0, 1};
double[] v3 = {7, 7};
double cosAngle1 = CosAngle.value(v1, v1);
double cosAngle2 = CosAngle.value(v1, v2);
double cosAngle3 = CosAngle.value(v1, v3);
// cosAngle1 == 1
// cosAngle2 == 0
// cosAngle3 == 0.7071067811865476  (sqrt(2) / 2)
// Math.toDegrees(Math.acos(cosAngle3)) == 45

arrays

例えばSortInPlaceを利用すると、ソートをしつつarrayを結合できるようです。以下のサンプルはわかりにくいですが、xの値についてソートし、それに対応するようにyとzもずらしていますね。

double[] x = {3, 1, 2};
double[] y = {1, 2, 3};
double[] z = {0, 5, 7};
SortInPlace.ASCENDING.apply(x, y, z);
// x == [1, 2, 3]
// y == [2, 3, 1]
// z == [5, 7, 0]

combinatorics

組み合わせ数を計算できます。いわゆるnCkのように表される数ですね。

long   bc1 = BinomialCoefficient.value(63, 33);
double bc2 = BinomialCoefficientDouble.value(1029, 514);
double bc3 = LogBinomialCoefficient.value(152635712, 125636);
// bc1 == 7219428434016265740
// bc2 ~ 1.429820686498904e308
// bc3 ~ 1017897.199659759

complex

文字通り複素数を扱うことができます。

double x = 3;
double y = 4;
Complex c1 = Complex.ofCartesian(x, y);
// c1 == x + iy

core

coreでは他のApacheプロジェクトでも利用されるようなコアな機能を提供します。例えば以下だとユークリッド距離やマンハッタン距離を計算できるようです。

double x = Norm.EUCLIDEAN.of(3, -4);                              // 5
double y = Norm.MANHATTAN.of(3, -4, 5);                           // 12
double z = Norm.MAXIMUM.of(new double[]{3, -4, 5, -6, -7, -8});   // 8

precision

precisionでは相対、絶対、および最小精度単位(ULP)の許容差を用いた浮動小数点数の比較を提供するようです。相対許容差を用いた比較は対称的で、入力された数値ペアの最大絶対値を用いて相対差分が計算されます。

// Default allows no numbers between
Precision.equals(1000.0, 1000.0)                              // true
Precision.equals(1000.0, 1000.0 + Math.ulp(1000.0))           // true
Precision.equals(1000.0, 1000.0 + 2 * Math.ulp(1000.0))       // false

fraction

fractionでは分母分子にintを利用して有理数を表現できます。

int p = 3;
int q = 4;
Fraction f = Fraction.of(p, q);
// f == 3 / 4

continued fraction

continues fractionは無限に続く連分数を表現できるようです。この機能は結構珍しい気がします。例えば以下は1 + 1/ (1 + 1/ ...)の計算結果です。

double eps = 1e-10;
double gr1 = GeneralizedContinuedFraction.value(() -> Coefficient.of(1, 1), eps);
double gr2 = GeneralizedContinuedFraction.value(1, () -> Coefficient.of(1, 1), eps);
// gr1 ~ gr2 ~ 1.6180339887498948...

gamma

gammaは文字通りガンマ関数を計算できるようです。

double result = Erfc.value(1.23);

// Default function evaluation
double a = 1.23;
double x = 4.56;
double result1 = IncompleteGamma.Lower.value(a, x);

// Parameterize function evaluation
double epsilon = 1e-10;
int maxIterations = 1000;
double result2 = IncompleteGamma.Lower.value(a, x, epsilon, maxIterations);

primes

primeも文字通り素数について扱えるようです。おそらく事前に登録されているのかなとは思います。

int n = 51237173;
boolean prime = Primes.isPrime(n);
int     m     = Primes.nextPrime(n);
// prime == false
// m     == 51237233

quaternion

quaternionは四元数という数であり、複素数の拡張だと思ってください。四元数を扱うためのものようです。

double w = 2;
double x = 3;
double y = 4;
double z = 5;
Quaternion h1 = Quaternion.of(w, x, y, z);
Quaternion h2 = Quaternion.of(w, new double[]{x, y, z});
h1.getW();            // w
h1.getScalarPart();   // w
h1.getVectorPart();   // [x, y, z]
// h1 == h2

まとめ

ここまでみたように、Apache Commons Numbersでは数学に関する様々な計算ツールを提供してくれるようです。科学計算をする場合や数値計算をする場合にとても有益なライブラリだと思います。ぜひ機会があれば皆さんも使ってみてください。

Discussion