std.numeric
This module is a port of a growing fragment of the numeric header in Alexander Stepanov's Standard Template Library, with a few additions.
Types 7
Format flags for CustomFloat.
typeof(get) opCall(F value)ditto
precision + ((flags & Flags.storeNormalized) != 0) mant_digthe number of bits in mantissaexponent_max - bias - ((flags & (Flags.infinity | Flags.nan)) != 0) + 1 max_expmaximum int value such that 2<sup>max_exp-1</sup> is representablecast(T_signed_exp) -(cast(long) bias) + 1 + ((flags & Flags.allowDenorm) != 0) min_expminimum int value such that 2<sup>min_exp-1</sup> is representable as a normalized valuevoid roundedShift(T, U)(ref T sig, U shift)void toNormalized(T, U)(ref T sig, ref U exp) constvoid fromNormalized(T, U)(ref T sig, ref U exp)int max_10_exp(){ @propertyReturns: maximum int value such that 10<sup>max10exp</sup> is representableint min_10_exp(){ @propertyReturns: minimum int value such that 10<sup>min10exp</sup> is representablevoid opAssign(F: CustomFloat)(F input)Self assignmentvoid opAssign(F)(F input) if (__traits(compiles, cast(real) input))Assigns from any `real` compatible type.F get(F)() if (staticIndexOf!(immutable F, immutable float, immutable double, immutable real) >= 0) @property constFetches the stored value either as a `float`, `double` or `real`.real opUnary(string op)() if (__traits(compiles, mixin(op ~ `(get!real)`)) || op == "++" || op == "--")Convert the CustomFloat to a real and perform the relevant operator on the resultreal opBinary(string op, T)(T b) if (__traits(compiles, mixin(`get!real` ~ op ~ `b.get!real`))) constdittoreal opBinary(string op, T)(T b) if ( __traits(compiles, mixin(`get!real` ~ op ~ `b`)) &&
!__traits(compiles, mixin(`get!real` ~ op ~ `b.get!real`))) constdittoreal opBinaryRight(string op, T)(T a) if ( __traits(compiles, mixin(`a` ~ op ~ `get!real`)) &&
!__traits(compiles, mixin(`get!real` ~ op ~ `b`)) &&
!__traits(compiles, mixin(`get!real` ~ op ~ `b.get!real`))) constdittovoid opOpAssign(string op, T)(auto ref T b) if (__traits(compiles, mixin(`get!real` ~ op ~ `cast(real) b`)))dittothis(F input)Initialize from any `real` compatible type.uType(uint bits)sType(uint bits)toString()dittoSimilar to gapWeightedSimilarity, just works in an incremental manner by first revealing the matches of length 1, then gapped matches of length 2, and so on. The memory requirement is s.length * t.length. The time complexity is s.length * t.length time for computing each step. Continuing on the previous example:
The implementation is based on the pseudocode in Fig. 4 of the paper
"Efficient Computation of Gapped Substring Kernels on Large Alphabets"by Rousu et al., with additional algorithmic and systems-level optimizations.
A class for performing fast Fourier transforms of power of two sizes. This class encapsulates a large amount of state that is reusable when performing multiple FFTs of sizes smaller than or equal to that specified in the constructor. This results in substantial speedups when performing multiple FFTs with a known maximum size. However, a free function API is provided for convenience if you need to perform a one-off FFT.
References:
en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithmlookup_t[][] negSinLookupvoid enforceSize(R)(R range) constvoid fftImplPureReal(Ret, R)(R range, Ret buf) constComplex!F[] fft(F = double, R)(R range) if (isFloatingPoint!F && isRandomAccessRange!R) constCompute the Fourier transform of range using the N log N Cooley-Tukey Algorithm. `range` must be a random-access range with slicing and a length equal to `size` as provided at the construction of ...void fft(Ret, R)(R range, Ret buf) if (isRandomAccessRange!Ret && isComplexLike!(ElementType!Ret) && hasSlicing!Ret) constSame as the overload, but allows for the results to be stored in a user- provided buffer. The buffer must be of the same length as range, must be a random-access range, must have slicing, and must...Complex!F[] inverseFft(F = double, R)(R range) if (isRandomAccessRange!R && isComplexLike!(ElementType!R) && isFloatingPoint!F) constComputes the inverse Fourier transform of a range. The range must be a random access range with slicing, have a length equal to the size provided at construction of this object, and contain elemen...void inverseFft(Ret, R)(R range, Ret buf) if (isRandomAccessRange!Ret && isComplexLike!(ElementType!Ret) && hasSlicing!Ret) constInverse FFT that allows a user-supplied buffer to be provided. The buffer must be a random access range with slicing, and its elements must be some complex-like type.Functions 39
bool isCorrectCustomFloat(uint precision, uint exponentWidth, CustomFloatFlags flags) @safe pure nothrow @nogcT 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
)Find a real root of a real function f(x) via bracketing.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
)Find root of a real function f(x) by bracketing, allowing the termination condition to be specified.Tuple!(T, T, R, R) findRoot(T, R, DF)(scope DF f,
const T ax, const T bx, const R fax, const R fbx)dittoT 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)dittoTuple!(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); }))Find a real minimum of a real function `f(x)` via bracketing. Given a function `f` and a range `(ax .. bx)`, returns the value of `x` in the range which is closest to a minimum of `f(x)`. `f` is ne...CommonType!(ElementType!(Range1), ElementType!(Range2)) euclideanDistance(Range1, Range2)(Range1 a, Range2 b) if (isInputRange!(Range1) && isInputRange!(Range2))Computes https://en.wikipedia.org/wiki/Euclidean_distance between input ranges `a` and `b`. The two ranges must have the same length. The three-parameter version stops computation as soon as the di...CommonType!(ElementType!(Range1), ElementType!(Range2)) euclideanDistance(Range1, Range2, F)(Range1 a, Range2 b, F limit) if (isInputRange!(Range1) && isInputRange!(Range2))DittoCommonType!(ElementType!(Range1), ElementType!(Range2)) dotProduct(Range1, Range2)(Range1 a, Range2 b) if (isInputRange!(Range1) && isInputRange!(Range2) &&
!(isArray!(Range1) && isArray!(Range2)))Computes the https://en.wikipedia.org/wiki/Dot_product of input ranges `a` and b. The two ranges must have the same length. If both ranges define length, the check is done once; otherwise, it is do...CommonType!(ElementType!(Range1), ElementType!(Range2)) cosineSimilarity(Range1, Range2)(Range1 a, Range2 b) if (isInputRange!(Range1) && isInputRange!(Range2))Computes the https://en.wikipedia.org/wiki/Cosine_similarity of input ranges `a` and b. The two ranges must have the same length. If both ranges define length, the check is done once; otherwise, it...bool normalize(R)(R range, ElementType!(R) sum = 1) if (isForwardRange!(R))Normalizes values in `range` by multiplying each element with a number chosen such that values sum up to `sum`. If elements in range sum to zero, assigns sum / range.length to all. Normalization ma...ElementType!Range sumOfLog2s(Range)(Range r) if (isInputRange!Range && isFloatingPoint!(ElementType!Range))Compute the sum of binary logarithms of the input range `r`. The error of this method is much smaller than with a naive sum of log2.ElementType!Range entropy(Range)(Range r) if (isInputRange!Range)Computes https://en.wikipedia.org/wiki/Entropy(informationtheory, entropy) of input range `r` in bits. This function assumes (without checking) that the values in `r` are all in [0. For the entropy...ElementType!Range entropy(Range, F)(Range r, F max) if (isInputRange!Range &&
!is(CommonType!(ElementType!Range, F) == void))DittoCommonType!(ElementType!Range1, ElementType!Range2) kullbackLeiblerDivergence(Range1, Range2)(Range1 a, Range2 b) if (isInputRange!(Range1) && isInputRange!(Range2))Computes the https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence between input ranges `a` and `b`, which is the sum ai log(ai / bi). The base of logarithm is 2. The ranges are assume...CommonType!(ElementType!Range1, ElementType!Range2) jensenShannonDivergence(Range1, Range2)(Range1 a, Range2 b) if (isInputRange!Range1 && isInputRange!Range2 &&
is(CommonType!(ElementType!Range1, ElementType!Range2)))Computes the https://en.wikipedia.org/wiki/Jensen%E2%80%93Shannon_divergence between `a` and b, which is the sum (ai log(2 ai / (ai + bi) + bi log(2 bi / (ai + bi))) / 2). The base of logarithm...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))DittoF gapWeightedSimilarity(alias comp = "a == b", R1, R2, F)(R1 s, R2 t, F lambda) if (isRandomAccessRange!(R1) && hasLength!(R1) &&
isRandomAccessRange!(R2) && hasLength!(R2))The so-called "all-lengths gap-weighted string kernel" computes a similarity measure between `s` and `t` based on all of their common subsequences of all lengths. Gapped subsequences are also inclu...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))The similarity per `gapWeightedSimilarity` has an issue in that it grows with the lengths of the two strings, even though the strings are not actually very similar. For example, the range ["Hello" ...GapWeightedSimilarityIncremental!(R, F) gapWeightedSimilarityIncremental(R, F)(R r1, R r2, F penalty)Dittotypeof(Unqual!(T).init % Unqual!(U).init) gcd(T, U)(T a, U b) if (isIntegral!T && isIntegral!U)Computes the greatest common divisor of `a` and `b` by using an efficient algorithm such as en.wikipedia.org/wiki/Euclideanalgorithm or en.wikipedia.org/wiki/BinaryGCD_algorithm algorithm.auto gcd(T)(T a, T b) if (!isIntegral!T &&
is(typeof(T.init % T.init)) &&
is(typeof(T.init == 0 || T.init > 0)))dittotypeof(Unqual!(T).init % Unqual!(U).init) lcm(T, U)(T a, U b) if (isIntegral!T && isIntegral!U)Computes the least common multiple of `a` and `b`. Arguments are the same as gcd.auto lcm(T)(T a, T b) if (!isIntegral!T &&
is(typeof(T.init % T.init)) &&
is(typeof(T.init == 0 || T.init > 0)))dittoComplex!F[] fft(F = double, R)(R range)Convenience functions that create an `Fft` object, run the FFT or inverse FFT and return the result. Useful for one-off FFTs.C swapRealImag(C)(C input)size_t decimalToFactorial(ulong decimal, ref ubyte[21] fac) @safe pure nothrow @nogcThis function transforms `decimal` value into a value in the factorial number system stored in `fac`.void slowFourier2(Ret, R)(R range, Ret buf) if (isComplexLike!(ElementType!Ret))void slowFourier4(Ret, R)(R range, Ret buf)N roundDownToPowerOf2(N)(N num) if (isScalarType!N && !isFloatingPoint!N)Variables 2
isIEEEQuadruple = floatTraits!real.realFormat == RealFormat.ieeeQuadrupleMakeLocalFft = q{
import core.stdc.stdlib;
import core.exception : onOutOfMemoryError;
auto lookupBuf = (cast(lookup_t*) malloc(range.length * 2 * lookup_t.sizeof))
[0 .. 2 * range.length];
if (!lookupBuf.ptr)
onOutOfMemoryError();
scope(exit) free(cast(void*) lookupBuf.ptr);
auto fftObj = scoped!Fft(lookupBuf);
}Templates 7
if (bits == 8 || bits == 16 || bits == 32 || bits == 64 || bits == 80)Allows user code to define custom floating-point formats. These formats are for storage only; all operations on them are performed by first implicitly extracting them to real first. After the operation is completed the result can be stored in a custom floating-point value via assignment.
if (((flags & flags.signed) + precision + exponentWidth) % 8 == 0 && precision + exponentWidth > 0)ditto
if (isFloatingPoint!F)Defines the fastest type to use when storing temporaries of a calculation intended to ultimately yield a result of type F (where F must be one of float, double, or real). When doing a multi-step computation, you may want to store intermediate results as FPTemporary!F.
The necessity of FPTemporary stems from the optimized floating-point operations and registers present in virtually all processors. When adding numbers in the example above, the addition may in fact be done in real precision internally. In that case, storing the intermediate result in double format is not only less precise, it is also (surprisingly) slower, because a conversion from real to double is performed every pass through the loop. This being a lose-lose situation, FPTemporary!F has been defined as the fastest type to use for calculations at precision F. There is no need to define a type for the most accurate calculations, as that is always real.
Finally, there is no guarantee that using FPTemporary!F will always be fastest, as the speed of floating-point calculations depends on very many factors.
Implements the secant method for finding a root of the function fun starting from points [xn_1, x_n] (ideally close to the root). Num may be float, double, or real.