Report a bug If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page Quickly fork, edit online, and submit a pull request for this page.
Requires a signed-in GitHub account. This works well for small changes.
If you'd like to make larger changes you may want to consider using
local clone.

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.

Store values in normalized form by default. The actual precision of the
significand is extended by 1 bit by assuming an implicit leading bit of 1
instead of 0. i.e. 1.nnnn instead of 0.nnnn.
True for all IEE754 types

allowDenorm

Stores the significand in IEEE754 denormalized form when the
exponent is 0. Required to express the value 0.

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.

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.

Given a function f and a range [a..b] such that f(a)
and f(b) have opposite signs or at least one of them equals ±0,
returns the value of x in
the range which is closest to a root of f(x). If f(x)
has more than one root in the range, one will be chosen
arbitrarily. If f(x) returns NaN, NaN will be returned;
otherwise, this algorithm is guaranteed to succeed.

Uses an algorithm based on TOMS748, which uses inverse cubic
interpolation whenever possible, otherwise reverting to parabolic
or secant interpolation. Compared to TOMS748, this implementation
improves worst-case performance by a factor of more than 100, and
typical performance by a factor of 2. For 80-bit reals, most
problems require 8 to 15 calls to f(x) to achieve full machine
precision. The worst-case performance (pathological cases) is
approximately twice the number of bits.

Find root of a real function f(x) by bracketing, allowing the
termination condition to be specified.

Parameters:

DF f

Function to be analyzed

T ax

Left bound of initial range of f known to contain the
root.

T bx

Right bound of initial range of f known to contain the
root.

R fax

Value of f(ax).

R fbx

Value of f(bx). fax and fbx should have opposite signs.
(f(ax) and f(bx) are commonly known in advance.)

DT tolerance

Defines an early termination condition. Receives the
current upper and lower bounds on the root. The
delegate must return true when these bounds are
acceptable. If this function always returns false,
full machine precision will be achieved.

Returns:

A tuple consisting of two ranges. The first two elements are the
range (in x) of the root, while the second pair of elements
are the corresponding function values at those points. If an exact
root was found, both of the first two elements will contain the
root, and the second pair of elements will be 0.

Computes 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 distance is greater than or
equal to limit (this is useful to save computation if a small
distance is sought).

Computes the 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 is done at each
iteration. If either range has all-zero elements, return 0.

Normalizes values in range by multiplying each element with a
number chosen such that values sum up to sum. If elements in rangesum to zero, assigns sum / range.length to
all. Normalization makes sense only if all elements in range are
positive. normalize assumes that is the case without checking it.

Returns:

true if normalization completed normally, false if
all elements in range were zero or if range is empty.

Computes entropy of input range r in bits. This
function assumes (without checking) that the values in r are all
in [0, 1]. For the entropy to be meaningful, often r should
be normalized too (i.e., its values should sum to 1). The
two-parameter version stops evaluating as soon as the intermediate
result is greater than or equal to max.

Computes the Kullback-Leibler divergence between input ranges
a and b, which is the sum ai * log(ai / bi). The base
of logarithm is 2. The ranges are assumed to contain elements in [0, 1]. Usually the ranges are normalized probability distributions,
but this is not required or checked by kullbackLeiblerDivergence. If any element bi is zero and the
corresponding element ai nonzero, returns infinity. (Otherwise,
if ai == 0 && bi == 0, the term ai * log(ai / bi) is
considered zero.) If the inputs are normalized, the result is
positive.

Computes the Jensen-Shannon 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 is 2. The ranges are
assumed to contain elements in [0, 1]. Usually the ranges are
normalized probability distributions, but this is not required or
checked by jensenShannonDivergence. If the inputs are normalized,
the result is bounded within [0, 1]. The three-parameter version
stops evaluations as soon as the intermediate result is greater than
or equal to limit.

Note how the gaps in matching are simply ignored, for example ("Hello", "new") is deemed as good a match as ("new",
"world"). This may be too permissive for some applications. To
eliminate gapped matches entirely, use lambda = 0:

The call above eliminated the gapped matches ("Hello", "new"),
("Hello", "world"), and ("Hello", "new", "world") from the
tally. That leaves only 4 matches.

The most interesting case is when gapped matches still participate in
the result, but not as strongly as ungapped matches. The result will
be a smooth, fine-grained similarity measure between the input
strings. This is where values of lambda between 0 and 1 enter
into play: gapped matches are exponentially penalized with the
number of gaps with base lambda. This means that an ungapped
match adds 1 to the return value; a match with one gap in either
string adds lambda to the return value; ...; a match with a total
of n gaps in both strings adds pow(lambda, n) to the return
value. In the example above, we have 4 matches without gaps, 2 matches
with one gap, and 1 match with three gaps. The latter match is ("Hello", "world"), which has two gaps in the first string and one gap
in the second string, totaling to three gaps. Summing these up we get
4 + 2 * lambda + pow(lambda, 3).

gapWeightedSimilarity is useful wherever a smooth similarity
measure between sequences allowing for approximate matches is
needed. The examples above are given with words, but any sequences
with elements comparable for equality are allowed, e.g. characters or
numbers. gapWeightedSimilarity uses a highly optimized dynamic
programming implementation that needs 16 * min(s.length,
t.length) extra bytes of memory and Ο(s.length * t.length) time
to complete.

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",
"world"] is increasingly similar with the range ["Hello",
"world", "world", "world",...] as more instances of "world" are
appended. To prevent that, gapWeightedSimilarityNormalized
computes a normalized version of the similarity that is computed as
gapWeightedSimilarity(s, t, lambda) /
sqrt(gapWeightedSimilarity(s, t, lambda) * gapWeightedSimilarity(s, t,
lambda)). The function gapWeightedSimilarityNormalized (a
so-called normalized kernel) is bounded in [0, 1], reaches 0
only for ranges that don't match in any position, and 1 only for
identical ranges.

The optional parameters sSelfSim and tSelfSim are meant for
avoiding duplicate computation. Many applications may have already
computed gapWeightedSimilarity(s, s, lambda) and/or gapWeightedSimilarity(t, t, lambda). In that case, they can be passed
as sSelfSim and tSelfSim, respectively.

Similar 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:

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.

Compute 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
this object. The contents of range can be either numeric types,
which will be interpreted as pure real values, or complex types with
properties or members .re and .im that can be read.

Note:
Pure real FFTs are automatically detected and the relevant
optimizations are performed.

Returns:

An array of complex numbers representing the transformed data in
the frequency domain.

Same 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 contain elements that are
complex-like. This means that they must have a .re and a .im member or
property that can be both read and written and are floating point numbers.

Computes 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 elements that are
either of type std.complex.Complex or have essentially
the same compile-time interface.

Convenience functions that create an Fft object, run the FFT or inverse
FFT and return the result. Useful for one-off FFTs.

Note:
In addition to convenience, these functions are slightly more
efficient than manually creating an Fft object for a single use,
as the Fft object is deterministically destroyed before these
functions return.