英語版
このページの英語版を見る

std.numeric

このモジュールは、Alexander Stepanovの数値ヘッダーの断片を移植したものである。 ヘッダーの断片を移植したものである。
Authors:
Andrei Alexandrescu, Don Clugston, Robert Jacques, Ilya Yaroshenko

ソース std/numeric.d

enum CustomFloatFlags: int;
CustomFloatのフォーマットフラグ。
signed
符号ビットを追加し、符号付き数値を使用できるようにした。
storeNormalized
デフォルトで正規化された形で値を格納する。実際の シグニフィカンドの実際の精度は、暗黙の先頭ビットを0ではなく1と仮定することで1ビット拡張される。 すなわち、0.nnnn ではなく1.nnnn となる。 すべてのIEEE754型に対して真。
allowDenorm
指数が0のとき、シグニフィカンドをIEEE754の非正規化形式で格納する。
infinity
IEEE754無限大の値を格納できる。
nan
IEEE754 Not a Number値の格納を許可する。
probability
設定されている場合、max_exp = 1となるような指数バイアスを選択する。 すなわち、最大値が1.0以上2.0未満になるようにする。 指数バイアスが手動で指定されている場合は無視される。
negativeUnsigned
設定されている場合、符号なしカスタム浮動小数点は負であると仮定される。
allowDenormZeroOnly
設定されている場合、0はIEEE754非正規化数として唯一許される。 allowDenorm と storeNormalized が必要である。
ieee
IEEE754オプションをすべて含む。
none
上記のオプションのいずれも含まない。
template CustomFloat(uint bits) if (bits == 8 || bits == 16 || bits == 32 || bits == 64 || bits == 80)

template CustomFloat(uint precision, uint exponentWidth, CustomFloatFlags flags = CustomFloatFlags.ieee) if (((flags & flags.signed) + precision + exponentWidth) % 8 == 0 && (precision + exponentWidth > 0))

struct CustomFloat(uint precision, uint exponentWidth, CustomFloatFlags flags, uint bias) if (isCorrectCustomFloat(precision, exponentWidth, flags));
ユーザー・コードでカスタム浮動小数点フォーマットを定義できるようにする。これらのフォーマットは これらのフォーマットは保存専用である。 real に展開される。演算終了後 演算終了後、代入によってカスタム浮動小数点値に格納することができる。
Examples:
import std.math.trigonometry : sin, cos;

// 16ビット浮動小数点値を定義する
CustomFloat!16                                x;     // ビット数を使う
CustomFloat!(10, 5)                           y;     // 精度と指数幅を使う
CustomFloat!(10, 5,CustomFloatFlags.ieee)     z;     // 精度、指数幅、フォーマットフラグを使う
CustomFloat!(10, 5,CustomFloatFlags.ieee, 15) w;     // 精度、指数幅、フォーマットフラグ、指数オフセットバイアスを使う

// 16ビット浮動小数点は、ほとんど通常の数値と同じように使用する
w = x*y - 1;

// 関数の呼び出しには変換が必要である
z = sin(+x)           + cos(+y);                     // 単項プラスを使用して、簡潔に実数に変換する
z = sin(x.get!float)  + cos(y.get!float);            // またはget!Tを使う
z = sin(cast(float) x) + cos(cast(float) y);           // またはcast(T)を使って明示的に変換する

// 確率を格納するために8ビットのカスタムfloatを定義する
alias Probability = CustomFloat!(4, 4, CustomFloatFlags.ieee^CustomFloatFlags.probability^CustomFloatFlags.signed );
auto p = Probability(0.5);
template FPTemporary(F) if (isFloatingPoint!F)
を一時的に格納する際に使用する、最も高速な型を定義する。 最終的に "型"の結果を得るための計算のテンポラリを格納するときに使用する最速の型を定義する。F (Ffloat,double,real のいずれかでなければならない)。多段階の計算を行う場合、中間結果を 中間結果を FPTemporary!F.
が必要なのは FPTemporaryの必要性は 浮動小数点演算とレジスタが最適化されているためである。 の必要性に起因する。上記の例で数値を加算する場合、加算は内部的に 精度で行われている可能性がある。 の加算は、実際には内部的にreal 精度で行われているかもしれない。その場合 中間値resultdouble format に格納することは、精度が低いだけでなく、(驚くことに)処理速度も遅くなる。 精度が低いだけでなく、(驚くことに)処理速度も遅くなる。 ループを通過するたびにreal からdouble への変換が行われるためである。 ループを通過するたびに、 から への変換が実行されるからだ。これは損な状況である、 FPTemporary!Fは 精度の計算に使用する最も速い型として定義されている。 F.最も正確な計算のための型を定義する必要はない。 これは常にreal
最後に FPTemporary!Fが常に最速であるという保証はない。 浮動小数点演算の速度は非常に多くの要因に左右されるからだ。 浮動小数点演算の速度は非常に多くの要因に左右されるからだ。
Examples:
import std.math.operations : isClose;

// 配列内の数値を平均する
double avg(in double[] a)
{
    if (a.length == 0) return 0;
    FPTemporary!double result = 0;
    foreach (e; a) result += e;
    return result / a.length;
}

auto a = [1.0, 2.0, 3.0];
assert(isClose(avg(a), 2));
template secantMethod(alias fun)
関数の根を求めるセカント法を実装している。 fun 関数の根を求めるためのセカント法を実装する。[xn_1, x_n] (理想的には根に近い)。Numfloat,double 、 またはreal である。
Examples:
import std.math.operations : isClose;
import std.math.trigonometry : cos;

float f(float x)
{
    return cos(x) - x*x*x;
}
auto x = secantMethod!(f)(0f, 1f);
assert(isClose(x, 0.865474));
T findRoot(T, DF, DT)(scope DF f, const T a, const T b, scope DT tolerance)
if (isFloatingPoint!T && is(typeof(tolerance(T.init, T.init)) : bool) && is(typeof(f(T.init)) == R, R) && isFloatingPoint!R);

T findRoot(T, DF)(scope DF f, const T a, const T b);
実関数 f(x) の実根を括弧で囲んで求めよ。
関数 fと範囲 [a .. b]が与えられる。 f(a)f(b)が反対の符号を持つか、少なくとも一方が±0に等しいような関数と範囲を与える、 の根に最も近いx の値を返す。 の根に最も近い値を返す。 f(x). もし f(x) の根に最も近い値を返す。 が任意に選ばれる。 もし f(x)がNaNを返す場合、NaNが返される; そうでなければ、このアルゴリズムは成功することが保証されている。
TOMS748に基づくアルゴリズムを使用する。 補間を使用し、そうでない場合は放物線補間またはセカント補間を使用する。 またはsecant 補間に戻る。TOMS748と比較すると、この実装は以下のようになる。 ワーストケースの性能は100倍以上、標準的な性能は2倍向上する。 典型的な性能は2倍向上する。 を8~15回呼び出す必要がある。 f(x)を8~15回呼び出す必要がある。 の精度を達成するために8~15回の呼び出しを必要とする。最悪の場合(病的な場合)の性能は、ビット数の約2倍である。 ビット数の約2倍である。

参考文献 「非線形方程式の簡単な根を囲むことについて"、 G. Alefeld, F.A. Potra, Yixun Shi, Mathematics of Computation 61、 pp733-744 (1993). Fortranコードは www.netlib.orgTOMS478アルゴリズムとして利用できる。

Tuple!(T, T, R, R) findRoot(T, R, DF, DT)(scope DF f, const T ax, const T bx, const R fax, const R fbx, scope DT tolerance)
if (isFloatingPoint!T && is(typeof(tolerance(T.init, T.init)) : bool) && is(typeof(f(T.init)) == R) && isFloatingPoint!R);

Tuple!(T, T, R, R) findRoot(T, R, DF)(scope DF f, const T ax, const T bx, const R fax, const R fbx);

T findRoot(T, R)(scope R delegate(T) f, const T a, const T b, scope bool delegate(T lo, T hi) tolerance = (T a, T b) => false);
実関数f(x)の根を括弧で囲んで求める。 終了条件を指定できる。
Parameters:
DF f 解析する関数
T ax の初期範囲の左境界 fを含むことがわかっている ルートを含むことが知られている。
T bx の初期範囲の右端 fを含むことが知られている の右側境界。
R fax の値。 f(ax).
R fbx の値。 f(bx). faxfbxは反対の符号を持つべきである。 (f(ax)f(bx)は一般的に事前に知られている)。
DT tolerance 早期終了条件を定義する。ルートの現在の上界と下界を受け取る。 ルートの現在の上限値と下限値を受け取る。デリゲートは デリゲートはtrue を返さなければならない。 を返さなければならない。この関数が常にfalse を返す場合、完全な機械精度が達成される、 完全な機械精度が達成される。
Returns:
2つの範囲からなるタプル。最初の2つの要素は の範囲(x )である。 はそれらの点における対応する関数値である。正確な ルートが見つかった場合、最初の2つの要素には両方ともルートが含まれる。 を含み、2番目の要素の組は0になる。
Tuple!(T, "x", Unqual!(ReturnType!DF), "y", T, "error") findLocalMin(T, DF)(scope DF f, const T ax, const T bx, const T relTolerance = sqrt(T.epsilon), const T absTolerance = sqrt(T.epsilon))
if (isFloatingPoint!T && __traits(compiles, () { T _ = DF.init(T.init); } ));
実関数の実小を求める f(x)を求める。 関数 fと範囲 (ax .. bx), の最小値に最も近いx の値を返す。 f(x). fの端点で評価されることはない。 axbx. の端点で評価されることはない。 f(x)が範囲内に複数の最小値を持つ場合、任意に1つが選ばれる。 もし f(x)はNaNまたは-無限大を返す、 (x, f(x), NaN)が返される; そうでなければ、このアルゴリズムは成功することが保証されている。
Parameters:
DF f 解析される関数
T ax 最小値を含むことが分かっているfの初期範囲の左境界。
T bx 最小値を含むことが分かっているfの初期範囲の右境界。
T relTolerance 相対公差。
T absTolerance 絶対公差。

事前条件 axbxは有限の実数とする。
relToleranceは通常の正の実数とする。
absToleranceは、T.epsilon*2 以下の正規の正の実数でなければならない。

Returns:
x からなるタプルである、 y = f(x)error = 3 * (absTolerance * fabs(x) + relTolerance).
使用される方法は、黄金分割探索と逐次放物線補間の組み合わせである。 を組み合わせたものである。収束はフィボナッチ探索の場合よりはるかに遅いことはない。 フィボナッチ探索の場合よりもはるかに遅くなることはない。

参考文献 「微分なし最小化のアルゴリズム」リチャード・ブレント、プレンティスホール社 (1973)

Examples:
import std.math.operations : isClose;

auto ret = findLocalMin((double x) => (x-4)^^2, -1e7, 1e7);
assert(ret.x.isClose(4.0));
assert(ret.y.isClose(0.0, 0.0, 1e-10));
CommonType!(ElementType!Range1, ElementType!Range2) euclideanDistance(Range1, Range2)(Range1 a, Range2 b)
if (isInputRange!Range1 && isInputRange!Range2);

CommonType!(ElementType!Range1, ElementType!Range2) euclideanDistance(Range1, Range2, F)(Range1 a, Range2 b, F limit)
if (isInputRange!Range1 && isInputRange!Range2);
入力範囲間のユークリッド距離を計算する。 ab.2つの範囲は同じ長さでなければならない。3パラメータ バージョンでは、距離が に等しくなった時点で計算を停止する。 limitになった時点で計算を停止する(これは、小さな を超えた時点で計算を停止する(これは,小さな距離を求める場合に計算を節約するのに便利である)。
CommonType!(ElementType!Range1, ElementType!Range2) dotProduct(Range1, Range2)(Range1 a, Range2 b)
if (isInputRange!Range1 && isInputRange!Range2 && !(isArray!Range1 && isArray!Range2));

CommonType!(F1, F2) dotProduct(F1, F2)(in F1[] avector, in F2[] bvector);

F dotProduct(F, uint N)(ref scope const F[N] a, ref scope const F[N] b)
if (N <= 16);
入力範囲 ab の内積を計算する。2つの範囲は同じ長さでなければならない。もし両方の範囲が 長さを定義している場合、チェックは一度だけ行われる。 の繰り返しで行われる。
CommonType!(ElementType!Range1, ElementType!Range2) cosineSimilarity(Range1, Range2)(Range1 a, Range2 b)
if (isInputRange!Range1 && isInputRange!Range2);
入力範囲 ab の余弦類似度を計算する。つの範囲は同じ長さでなければならない。もし両方の範囲が 長さを定義している場合、チェックは1度だけ行われる。 の繰り返しで行われる。もしどちらかの範囲がすべて0要素であれば、0を返す。
bool normalize(R)(R range, ElementType!R sum = 1)
if (isForwardRange!R);
の値を正規化する。 rangeの値を正規化する。 を乗じることで正規化する。 sum.range の要素の合計がゼロの場合、sum / range.length を代入する。 に割り当てる。正規化が意味を持つのは rangeの要素がすべて正である場合のみ、正規化は意味を持つ。 が正である場合にのみ意味を持つ。 normalizeの要素がすべて正である場合のみ、正規化は意味を持つ。
Returns:
true 正規化が正常に完了した場合、 のすべての要素がゼロであったかfalse rangeの要素がすべてゼロであったか rangeが空の場合である。
Examples:
double[] a = [];
assert(!normalize(a));
a = [ 1.0, 3.0 ];
assert(normalize(a));
writeln(a); // [0.25, 0.75]
assert(normalize!(typeof(a))(a, 50)); // a = [12.5, 37.5]
a = [ 0.0, 0.0 ];
assert(!normalize(a));
writeln(a); // [0.5, 0.5]
ElementType!Range sumOfLog2s(Range)(Range r)
if (isInputRange!Range && isFloatingPoint!(ElementType!Range));
入力範囲の2進対数の和を計算する。 r. この方法の誤差は、素朴なlog2の和よりもはるかに小さい。
Examples:
import std.math.traits : isNaN;

writeln(sumOfLog2s(new double[0])); // 0
writeln(sumOfLog2s([0.0L])); // -real.infinity
writeln(sumOfLog2s([-0.0L])); // -real.infinity
writeln(sumOfLog2s([2.0L])); // 1
assert(sumOfLog2s([-2.0L]).isNaN());
assert(sumOfLog2s([real.nan]).isNaN());
assert(sumOfLog2s([-real.nan]).isNaN());
writeln(sumOfLog2s([real.infinity])); // real.infinity
assert(sumOfLog2s([-real.infinity]).isNaN());
writeln(sumOfLog2s([0.25, 0.25, 0.25, 0.125])); // -9
ElementType!Range entropy(Range)(Range r)
if (isInputRange!Range);

ElementType!Range entropy(Range, F)(Range r, F max)
if (isInputRange!Range && !is(CommonType!(ElementType!Range, F) == void));
入力範囲 rをビット単位で計算する。この の値がすべてであると仮定する。 rの値はすべて [0, 1]であると仮定する。エントロピーが意味を持つためには、しばしば rも正規化されるべきである。 も正規化されていなければならない(つまり、その値の合計は1でなければならない)。つのパラメータを持つ 2パラメータ・バージョンは、中間結果が を超えた時点で評価を停止する。 max.
CommonType!(ElementType!Range1, ElementType!Range2) kullbackLeiblerDivergence(Range1, Range2)(Range1 a, Range2 b)
if (isInputRange!Range1 && isInputRange!Range2);
入力範囲間のカルバック・ライブラー発散を計算する。 abの和ai * log(ai / bi) を計算する。対数の底は2である。 範囲は[0, 1] の要素を含むと仮定する。通常、範囲は正規化された確率分布である、 であるが、これは必須ではないし、kullbackLeiblerDivergence でもチェックされない。いずれかの要素bi がゼロで 対応する要素ai がゼロでなければ,無限大を返す。(そうでなければ ai == 0 && bi == 0の場合、項ai * log(ai / bi) はゼロとみなされる)。 はゼロとみなされる)。入力が正規化されている場合、結果は正となる。 になる。
Examples:
import std.math.operations : isClose;

double[] p = [ 0.0, 0, 0, 1 ];
writeln(kullbackLeiblerDivergence(p, p)); // 0
double[] p1 = [ 0.25, 0.25, 0.25, 0.25 ];
writeln(kullbackLeiblerDivergence(p1, p1)); // 0
writeln(kullbackLeiblerDivergence(p, p1)); // 2
writeln(kullbackLeiblerDivergence(p1, p)); // double.infinity
double[] p2 = [ 0.2, 0.2, 0.2, 0.4 ];
assert(isClose(kullbackLeiblerDivergence(p1, p2), 0.0719281, 1e-5));
assert(isClose(kullbackLeiblerDivergence(p2, p1), 0.0780719, 1e-5));
CommonType!(ElementType!Range1, ElementType!Range2) jensenShannonDivergence(Range1, Range2)(Range1 a, Range2 b)
if (isInputRange!Range1 && isInputRange!Range2 && is(CommonType!(ElementType!Range1, ElementType!Range2)));

CommonType!(ElementType!Range1, ElementType!Range2) jensenShannonDivergence(Range1, Range2, F)(Range1 a, Range2 b, F limit)
if (isInputRange!Range1 && isInputRange!Range2 && is(typeof(CommonType!(ElementType!Range1, ElementType!Range2).init >= F.init) : bool));
と の間のJensen-Shannon発散を計算する。 ab の和を計算する(ai * log(2 * ai / (ai + bi)) + bi * log(2 * bi / (ai + bi))) / 2 。対数の底は2である。 [0, 1]の要素を含むと仮定する。通常、範囲は 通常,範囲は正規化された確率分布である。 によってチェックされる。 jensenShannonDivergence.入力が正規化されている場合、結果は の範囲内に収まる、 [0, 1]の範囲内に収まる。 3パラメータ版では を超えるとすぐに評価を停止する。 または limit.
Examples:
import std.math.operations : isClose;

double[] p = [ 0.0, 0, 0, 1 ];
writeln(jensenShannonDivergence(p, p)); // 0
double[] p1 = [ 0.25, 0.25, 0.25, 0.25 ];
writeln(jensenShannonDivergence(p1, p1)); // 0
assert(isClose(jensenShannonDivergence(p1, p), 0.548795, 1e-5));
double[] p2 = [ 0.2, 0.2, 0.2, 0.4 ];
assert(isClose(jensenShannonDivergence(p1, p2), 0.0186218, 1e-5));
assert(isClose(jensenShannonDivergence(p2, p1), 0.0186218, 1e-5));
assert(isClose(jensenShannonDivergence(p2, p1, 0.005), 0.00602366, 1e-5));
F gapWeightedSimilarity(alias comp = "a == b", R1, R2, F)(R1 s, R2 t, F lambda)
if (isRandomAccessRange!R1 && hasLength!R1 && isRandomAccessRange!R2 && hasLength!R2);
いわゆる「全長ギャップ重み付き文字列カーネル」は、以下のような類似性尺度を計算する。 と stの間の類似性尺度を計算する。 の間の類似度を計算する。ギャップ付き部分配列も含まれる。 も含まれる。
gapWeightedSimilarity(s, t, lambda) 、 まず、lambda = 1 の場合と、s = ["Hello", "brave", "new", "world"]t = ["Hello", "new", "world"] の文字列を考える、 gapWeightedSimilarityを数える。 を数える:
  1. 長さ1の3つのマッチ、すなわち"Hello""new" 、 および"world" である;
  2. 長さ2のマッチが3つ、すなわち("Hello", "new")、("Hello", "world")、("new", "world");
  3. 長さ3のマッチが1つ、すなわち("Hello", "new", "world")。
gapWeightedSimilarity(s, t, 1) 。 7を返す。
string[] s = ["Hello", "brave", "new", "world"];
string[] t = ["Hello", "new", "world"];
assert(gapWeightedSimilarity(s, t, 1) == 7);
例えば、("Hello", "new")は("new", "world")と同じようにマッチするとみなされる。これはアプリケーションによっては寛容すぎるかもしれない。ギャップマッチを完全に排除するには ギャップマッチを完全に排除するには、lambda = 0 を使う:
string[] s = ["Hello", "brave", "new", "world"];
string[] t = ["Hello", "new", "world"];
assert(gapWeightedSimilarity(s, t, 0) == 4);
上記の呼び出しは、ギャップマッチ("Hello", "new")を除去した、 ("Hello", "world")、("Hello", "new", "world")を集計から除外した。 を除外した。残るは4マッチのみである。
最も興味深いのは、ギャップされたマッチがまだ結果に関与している場合である。 しかし、ギャップなしのマッチほど強くはない。結果は次のようになる。 入力文字列間の滑らかできめ細かな類似性測定となる。 文字列になる。この場合 lambda0と1の間の ギャップマッチは指数関数的にペナルティを受ける。 で指数関数的にペナルティを受ける。 lambda.つまり、ギャップのない のマッチは戻り値に1が加算される。 文字列に1つのギャップがあるマッチは lambdaを返り値に加える。 両方の文字列に合計n のギャップがあるマッチは、pow(lambda, n) が返り値に追加される。 が加算される。上の例では、ギャップのないマッチが4つ、ギャップが1つあるマッチが2つ、ギャップが1つあるマッチが1つある。 と3つのギャップがある。後者のマッチは("Hello", "world")で、最初の文字列に2つのギャップがあり、2つ目の文字列に1つのギャップがある。 で、合計3つのギャップがある。これらを合計すると 4 + 2 * lambda + pow(lambda, 3).
string[] s = ["Hello", "brave", "new", "world"];
string[] t = ["Hello", "new", "world"];
assert(gapWeightedSimilarity(s, t, 0.5) == 4 + 0.5 * 2 + 0.125);
gapWeightedSimilarityは、近似的な一致を可能にする配列間の が必要な場合に有用である。 が必要な場合に有用である。上記の例では単語を用いたが、文字や文字列など、等価な要素を持つ任意の配列 が等価であればどのような配列でもよい。 数値などである。 gapWeightedSimilarityは、高度に最適化された動的プログラミング実装を使用している。 16 * min(s.length, t.length) s.length * t.length、高度に最適化されたダイナミック・プログラミングの実装を使用する。 の時間を必要とする。
Select!(isFloatingPoint!F, F, double) gapWeightedSimilarityNormalized(alias comp = "a == b", R1, R2, F)(R1 s, R2 t, F lambda, F sSelfSim = F.init, F tSelfSim = F.init)
if (isRandomAccessRange!R1 && hasLength!R1 && isRandomAccessRange!R2 && hasLength!R2);
gapWeightedSimilarity 当たりの類似度は、次のような問題がある。 の類似度は、2つの文字列の長さに応じて大きくなるという問題がある。 実際にはあまり似ていない。例えば、["Hello", "world"] の範囲は、"world" のインスタンスが増えるにつれて、["Hello", "world", "world", "world",...] の範囲との類似度が増していく。 のインスタンスが増えるにつれて、 の範囲と似てくる。これを防ぐには gapWeightedSimilarityNormalized は類似度を正規化したものを計算する。 gapWeightedSimilarity(s, t, lambda) / sqrt(gapWeightedSimilarity(s, t, lambda) * gapWeightedSimilarity(s, t, lambda)).として計算される。 gapWeightedSimilarityNormalized(a いわゆる正規化カーネル)は、[0, 1] で境界を持つ。0 1 に達する。 のみである。
オプションのパラメータ sSelfSimtSelfSimは は、重複計算を避けるためのものである。多くのアプリケーションはすでに gapWeightedSimilarity(s, s, lambda) gapWeightedSimilarity(t, t, lambda)を計算済みかもしれない。その場合、それらは として渡すことができる。 sSelfSimtSelfSimとして渡すことができる。
Examples:
import std.math.operations : isClose;
import std.math.algebraic : sqrt;

string[] s = ["Hello", "brave", "new", "world"];
string[] t = ["Hello", "new", "world"];
writeln(gapWeightedSimilarity(s, s, 1)); // 15
writeln(gapWeightedSimilarity(t, t, 1)); // 7
writeln(gapWeightedSimilarity(s, t, 1)); // 7
assert(isClose(gapWeightedSimilarityNormalized(s, t, 1),
                7.0 / sqrt(15.0 * 7), 0.01));
struct GapWeightedSimilarityIncremental(Range, F = double) if (isRandomAccessRange!Range && hasLength!Range);

GapWeightedSimilarityIncremental!(R, F) gapWeightedSimilarityIncremental(R, F)(R r1, R r2, F penalty);
gapWeightedSimilarity に似ている。 最初に長さ1のマッチを明らかにし、次に長さ2のギャップマッチを明らかにする。 長さ2のマッチ、といった具合である。必要なメモリはΟ(s.length * t.length)である。時間の複雑さはΟ(s.length * t.length)時間である。 である。前の例を続ける:
この実装は、論文 "Efficient Computation of Gapped Substring Kern"の図4の擬似コードに基づいている。 "大きなアルファベットにおけるギャップ付き部分文字列カーネルの効率的計算" Rousuらによる "Effiient Computation of Gapped Substring Kernels on Large Alphabets"の図4の擬似コードに、アルゴリズムとシステムレベルの最適化を加えたものである。 最適化を加えた。
Examples:
string[] s = ["Hello", "brave", "new", "world"];
string[] t = ["Hello", "new", "world"];
auto simIter = gapWeightedSimilarityIncremental(s, t, 1.0);
assert(simIter.front == 3); // 3つの1長マッチ
simIter.popFront();
assert(simIter.front == 3); // 3つの2長マッチ
simIter.popFront();
assert(simIter.front == 1); // 1つの3長マッチ
simIter.popFront();
assert(simIter.empty);     // もうマッチしない
this(Range s, Range t, F lambda);
2つの範囲 stとペナルティ lambda.コンストラクタはΟ(s.length * t.length) 時間で完了し、長さ1のマッチをすべて計算する。
ref GapWeightedSimilarityIncremental opSlice();
Returns:
this.
void popFront();
popFront の長さのマッチを計算する。Ο(s.length * t.length) 時間で完了する。
@property F front();
Returns:
現在のマッチ長におけるギャップ類似度(最初は 1,popFront を呼び出すたびに増加する)。
@property bool empty();
Returns:
さらにマッチがあるかどうか。
typeof(Unqual!T.init % Unqual!U.init) gcd(T, U)(T a, U b)
if (isIntegral!T && isIntegral!U);

auto gcd(T)(T a, T b)
if (!isIntegral!T && is(typeof(T.init % T.init)) && is(typeof(T.init == 0 || T.init > 0)));
の最大公約数を計算する。 abの最大公約数を計算する。 を計算するSteinのアルゴリズムのような効率的なアルゴリズムを使って計算する。
Parameters:
T a モジュロ演算子% をサポートする任意の数値型の整数値。 ビットシフト<< および>> もサポートされている場合は、Steinのアルゴリズムが使用される。 が使用され、そうでない場合はユークリッドのアルゴリズムがフォールバックとして使用される。
U b 等価な数値型の整数値。
Returns:
与えられた引数の最大公約数。
typeof(Unqual!T.init % Unqual!U.init) lcm(T, U)(T a, U b)
if (isIntegral!T && isIntegral!U);

auto lcm(T)(T a, T b)
if (!isIntegral!T && is(typeof(T.init % T.init)) && is(typeof(T.init == 0 || T.init > 0)));
の最小公倍数を計算する。 ab. 引数は gcd.
Returns:
与えられた引数の最小公倍数。
Examples:
writeln(lcm(1, 2)); // 2
writeln(lcm(3, 4)); // 12
writeln(lcm(5, 6)); // 30
class Fft;
2のべき乗の高速フーリエ変換を行うクラス。 このクラスは、次のような場合に再利用可能な大量の状態をカプセル化する。 このクラスは、コンストラクタで指定されたサイズ以下の複数のFFTを実行するときに再利用可能な、大量の状態をカプセル化する。 コンストラクタで指定されたサイズ以下の複数のFFTを実行するときに再利用可能な、大量の状態をカプセル化している。 この結果、最大値が既知の複数のFFTを実行する際に、大幅なスピードアップがもたらされる。 最大サイズが既知の複数のFFTを実行する場合、大幅なスピードアップにつながる。 しかし しかし、1回限りのFFTを実行する必要がある場合に便利なように、フリー関数APIが提供されている。 が提供されている。
this(size_t size);
の高速フーリエ変換を計算するためのFft オブジェクトを作成する。 のべき乗を計算するためのオブジェクトを作成する。 size以下である。 sizeは のべき乗でなければならない。
const Complex!F[] fft(F = double, R)(R range)
if (isFloatingPoint!F && isRandomAccessRange!R);
Ο(N log N) を使って範囲のフーリエ変換を計算する。 Cooley-Tukey アルゴリズムを使用する。 rangeのランダムアクセス範囲でなければならない。 size でなければならない。 でなければならない。 rangeの内容は、純粋な実数値として解釈される数値型か、複素数型である、 これは純粋な実数値として解釈される。 プロパティまたはメンバ.re.im を持つ複合型である。

注釈 純粋実数FFTは自動的に検出され、関連する最適化が実行される。 最適化が実行される。

Returns:
周波数領域で変換されたデータを表す複素数の配列。 を表す複素数の配列。

規約 指数は負、係数は1である、 すなわち、output[j] := sum[ exp(-2 PI i j k / N) input[k] ]である。

const void fft(Ret, R)(R range, Ret buf)
if (isRandomAccessRange!Ret && isComplexLike!(ElementType!Ret) && hasSlicing!Ret);
オーバーロードと同じであるが、結果をユーザー定義のバッファに格納することができる。 バッファに格納することができる。 バッファはrangeと同じ長さでなければならない。 バッファは、範囲と同じ長さでなければならず、ランダムアクセス範囲でなければならない。 要素を含まなければならない。 つまり、.reと.imのメンバまたはプロパティを持っていなければならない。 プロパティを持ち、浮動小数点数でなければならない。
const Complex!F[] inverseFft(F = double, R)(R range)
if (isRandomAccessRange!R && isComplexLike!(ElementType!R) && isFloatingPoint!F);
範囲の逆フーリエ変換を計算する。 範囲は ランダムアクセス範囲でなければならない。 に等しい長さを持ち、以下の要素を含んでいなければならない。 std.complex.Complex型であるか、本質的に同じコンパイル時インタフェースを持つ要素を含んでいなければならない。 を持つ要素を含んでいなければならない。
Returns:
時間領域シグナル。

慣例 指数は正で、係数は1/Nである、 output[j] := (1 / N) sum[ exp(+2 PI i j k / N) input[k] ]。

const void inverseFft(Ret, R)(R range, Ret buf)
if (isRandomAccessRange!Ret && isComplexLike!(ElementType!Ret) && hasSlicing!Ret);
逆FFTは、ユーザーがバッファを提供することができる。 バッファ バッファは、スライシングを伴うランダムアクセス範囲でなければならず、その要素は何らかの複素数のような型でなければならない。 は複素数のような型でなければならない。
Complex!F[] fft(F = double, R)(R range);

void fft(Ret, R)(R range, Ret buf);

Complex!F[] inverseFft(F = double, R)(R range);

void inverseFft(Ret, R)(R range, Ret buf);
Fft 、FFTまたは逆FFTを実行し、結果を返す。 FFTを実行し、その結果を返す。 単発のFFTに便利である。

注釈: 便利なだけでなく、これらの関数は、1回の使用のために手動でFftオブジェクトを作成するよりも若干効率的である。 Fftオブジェクトが決定論的に破棄されるためである、 これらの関数が戻る前にFftオブジェクトは決定論的に破棄されるからである。 オブジェクトは決定論的に破棄されるからである。

pure nothrow @nogc @safe size_t decimalToFactorial(ulong decimal, ref ubyte[21] fac);
この関数は、値を階乗数の値に変換する。 decimalの値を階乗数系の値に変換する。 に格納されている階乗数系の値に変換する。 fac.
階乗数は次のように構成される: fac[0] * 0! + fac[1] * 1! + ... fac[20] * 20!
Parameters:
ulong decimal 階乗数に変換する10進数値。
ubyte[21] fac 階乗数を格納する配列。この配列のサイズは21である。 ulong.max には21桁の階乗が必要だからである。
Returns:
に格納された階乗の桁数を格納する変数がある。 fac.
Examples:
ubyte[21] fac;
size_t idx = decimalToFactorial(2982, fac);

writeln(fac[0]); // 4
writeln(fac[1]); // 0
writeln(fac[2]); // 4
writeln(fac[3]); // 1
writeln(fac[4]); // 0
writeln(fac[5]); // 0
writeln(fac[6]); // 0