Report a bug
If you spot a problem with this page, click here to create a GitHub 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
a local clone.
mir.stat.descriptive.multivariate
This module contains algorithms for multivariate descriptive statistics.
License:
Authors:
John Michael Hall
- enum
CovarianceAlgo
: int; - Covariance algorithms.See Also: Algorithms for calculating variance.
online
- Performs Welford's online algorithm for updating covariance. While it only iterates each input once, it can be slower for smaller inputs. However, it is also more accurate. Can also put another CovarianceAccumulator of the same type, which uses the parallel algorithm from Chan et al.
naive
- Calculates covariance using E(x*y) - E(x)*E(y) (alowing for adjustments for population/sample variance). This algorithm can be numerically unstable.
twoPass
- Calculates covariance using a two-pass algorithm whereby the inputs are first centered and then the sum of products is calculated from that. May be faster than online and generally more accurate than the naive algorithm.
assumeZeroMean
- Calculates covariance assuming the mean of the inputs is zero.
hybrid
- When slices, slice-like objects, or ranges are the inputs, uses the two-pass algorithm. When an individual data-point is added, uses the online algorithm.
- struct
CovarianceAccumulator
(T, CovarianceAlgo covarianceAlgo, Summation summation) if (isMutable!T && (covarianceAlgo == CovarianceAlgo.naive)); - Examples:
import mir.math.sum: Summation; import mir.ndslice.slice: sliced; import mir.test: shouldApprox; auto x = [ 0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0].sliced; auto y = [-0.75, 6.0, -0.25, 8.25, 5.75, 3.5, 9.25, -0.75, 2.5, 1.25, -1, 2.25].sliced; CovarianceAccumulator!(double, CovarianceAlgo.naive, Summation.naive) v; v.put(x, y); v.covariance(true).shouldApprox == 82.25 / 12 - (29.25 * 36) / (12 * 12); v.covariance(false).shouldApprox == 82.25 / 11 - (29.25 * 36) / (12 * 12) * (12.0 / 11); v.put(4.0, 3.0); v.covariance(true).shouldApprox == 94.25 / 13 - (33.25 * 39) / (13 * 13); v.covariance(false).shouldApprox == 94.25 / 12 - (33.25 * 39) / (13 * 13) * (13.0 / 12);
- alias
S
= Summator!(T, summation); - S
summatorLeft
; - S
summatorRight
; - S
summatorOfProducts
; - this(RangeX, RangeY)(RangeX
x
, RangeYy
)
if (isInputRange!RangeX && isInputRange!RangeY); - void
put
(IteratorX, IteratorY, SliceKind kindX, SliceKind kindY)(Slice!(IteratorX, 1, kindX)x
, Slice!(IteratorY, 1, kindY)y
); - void
put
(SliceLikeX, SliceLikeY)(SliceLikeXx
, SliceLikeYy
)
if (isConvertibleToSlice!SliceLikeX && !isSlice!SliceLikeX && isConvertibleToSlice!SliceLikeY && !isSlice!SliceLikeY); - void
put
(RangeX, RangeY)(RangeXx
, RangeYy
)
if (isInputRange!RangeX && !isConvertibleToSlice!RangeX && is(elementType!RangeX : T) && isInputRange!RangeY && !isConvertibleToSlice!RangeY && is(elementType!RangeY : T)); - void
put
()(Tx
, Ty
); - void
put
(U, Summation sumAlgo)(CovarianceAccumulator!(U, covarianceAlgo, sumAlgo)v
); - @property size_t
count
(); - @property F
sumLeft
(F = T)(); - @property F
sumRight
(F = T)(); - @property F
meanLeft
(F = T)(); - @property F
meanRight
(F = T)(); - @property F
sumOfProducts
(F = T)(); - @property F
centeredSumOfProducts
(F = T)(); - @property F
covariance
(F = T)(boolisPopulation
);
- struct
CovarianceAccumulator
(T, CovarianceAlgo covarianceAlgo, Summation summation) if (isFloatingPoint!T && isMutable!T && (covarianceAlgo == CovarianceAlgo.online)); - Examples:
import mir.math.sum: Summation; import mir.ndslice.slice: sliced; import mir.test: shouldApprox; auto x = [ 0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0].sliced; auto y = [-0.75, 6.0, -0.25, 8.25, 5.75, 3.5, 9.25, -0.75, 2.5, 1.25, -1, 2.25].sliced; CovarianceAccumulator!(double, CovarianceAlgo.online, Summation.naive) v; v.put(x, y); v.covariance(true).shouldApprox == -5.5 / 12; v.covariance(false).shouldApprox == -5.5 / 11; v.put(4.0, 3.0); v.covariance(true).shouldApprox == -5.5 / 13; v.covariance(false).shouldApprox == -5.5 / 12;
- alias
S
= Summator!(T, summation); - S
summatorLeft
; - S
summatorRight
; - S
centeredSummatorOfProducts
; - this(RangeX, RangeY)(RangeX
x
, RangeYy
)
if (isInputRange!RangeX && isInputRange!RangeY); - this()(T
x
, Ty
); - void
put
(IteratorX, IteratorY, SliceKind kindX, SliceKind kindY)(Slice!(IteratorX, 1, kindX)x
, Slice!(IteratorY, 1, kindY)y
); - void
put
(SliceLikeX, SliceLikeY)(SliceLikeXx
, SliceLikeYy
)
if (isConvertibleToSlice!SliceLikeX && !isSlice!SliceLikeX && isConvertibleToSlice!SliceLikeY && !isSlice!SliceLikeY); - void
put
(RangeX, RangeY)(RangeXx
, RangeYy
)
if (isInputRange!RangeX && !isConvertibleToSlice!RangeX && isInputRange!RangeY && !isConvertibleToSlice!RangeY); - void
put
()(Tx
, Ty
); - void
put
(U, CovarianceAlgo covAlgo, Summation sumAlgo)(CovarianceAccumulator!(U, covAlgo, sumAlgo)v
)
if (covAlgo != CovarianceAlgo.assumeZeroMean); - @property size_t
count
(); - @property F
sumLeft
(F = T)(); - @property F
sumRight
(F = T)(); - @property F
meanLeft
(F = T)(); - @property F
meanRight
(F = T)(); - @property F
centeredSumOfProducts
(F = T)(); - @property F
covariance
(F = T)(boolisPopulation
);
- struct
CovarianceAccumulator
(T, CovarianceAlgo covarianceAlgo, Summation summation) if (isMutable!T && (covarianceAlgo == CovarianceAlgo.twoPass)); - Examples:
import mir.math.sum: Summation; import mir.ndslice.slice: sliced; import mir.test: shouldApprox; auto x = [ 0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0].sliced; auto y = [-0.75, 6.0, -0.25, 8.25, 5.75, 3.5, 9.25, -0.75, 2.5, 1.25, -1, 2.25].sliced; auto v = CovarianceAccumulator!(double, CovarianceAlgo.twoPass, Summation.naive)(x, y); v.covariance(true).shouldApprox == -5.5 / 12; v.covariance(false).shouldApprox == -5.5 / 11;
- alias
S
= Summator!(T, summation); - this(IteratorX, IteratorY, SliceKind kindX, SliceKind kindY)(Slice!(IteratorX, 1, kindX)
x
, Slice!(IteratorY, 1, kindY)y
); - this(SliceLikeX, SliceLikeY)(SliceLikeX
x
, SliceLikeYy
)
if (isConvertibleToSlice!SliceLikeX && !isSlice!SliceLikeX && isConvertibleToSlice!SliceLikeY && !isSlice!SliceLikeY); - this(RangeX, RangeY)(RangeX
x
, RangeYy
)
if (isInputRange!RangeX && !isConvertibleToSlice!RangeX && is(elementType!RangeX : T) && isInputRange!RangeY && !isConvertibleToSlice!RangeY && is(elementType!RangeY : T)); - this()(T
x
, Ty
); - @property size_t
count
(); - @property F
sumLeft
(F = T)(); - @property F
sumRight
(F = T)(); - @property F
meanLeft
(F = T)(); - @property F
meanRight
(F = T)(); - @property F
centeredSumOfProducts
(F = T)(); - @property F
covariance
(F = T)(boolisPopulation
);
- struct
CovarianceAccumulator
(T, CovarianceAlgo covarianceAlgo, Summation summation) if (isMutable!T && (covarianceAlgo == CovarianceAlgo.assumeZeroMean)); - Examples:
import mir.stat.transform: center; import mir.math.sum: Summation; import mir.ndslice.slice: sliced; import mir.test: shouldApprox; auto a = [ 0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0].sliced; auto b = [-0.75, 6.0, -0.25, 8.25, 5.75, 3.5, 9.25, -0.75, 2.5, 1.25, -1, 2.25].sliced; auto x = a.center; auto y = b.center; CovarianceAccumulator!(double, CovarianceAlgo.assumeZeroMean, Summation.naive) v; v.put(x, y); v.covariance(true).shouldApprox == -5.5 / 12; v.covariance(false).shouldApprox == -5.5 / 11; v.put(4.0, 3.0); v.covariance(true).shouldApprox == 6.5 / 13; v.covariance(false).shouldApprox == 6.5 / 12;
- Summator!(T, summation)
centeredSummatorOfProducts
; - this(RangeX, RangeY)(RangeX
x
, RangeYy
)
if (isInputRange!RangeX && isInputRange!RangeY); - this()(T
x
, Ty
); - void
put
(IteratorX, IteratorY, SliceKind kindX, SliceKind kindY)(Slice!(IteratorX, 1, kindX)x
, Slice!(IteratorY, 1, kindY)y
); - void
put
(SliceLikeX, SliceLikeY)(SliceLikeXx
, SliceLikeYy
)
if (isConvertibleToSlice!SliceLikeX && !isSlice!SliceLikeX && isConvertibleToSlice!SliceLikeY && !isSlice!SliceLikeY); - void
put
(RangeX, RangeY)(RangeXx
, RangeYy
)
if (isInputRange!RangeX && !isConvertibleToSlice!RangeX && is(elementType!RangeX : T) && isInputRange!RangeY && !isConvertibleToSlice!RangeY && is(elementType!RangeY : T)); - void
put
()(Tx
, Ty
); - void
put
(U, Summation sumAlgo)(CovarianceAccumulator!(U, covarianceAlgo, sumAlgo)v
); - @property size_t
count
(); - @property F
sumLeft
(F = T)(); - @property F
sumRight
(F = T)(); - @property F
meanLeft
(F = T)(); - @property F
meanRight
(F = T)(); - @property F
centeredSumOfProducts
(F = T)(); - @property F
covariance
(F = T)(boolisPopulation
);
- struct
CovarianceAccumulator
(T, CovarianceAlgo covarianceAlgo, Summation summation) if (isFloatingPoint!T && isMutable!T && (covarianceAlgo == CovarianceAlgo.hybrid)); - Examples:
import mir.math.sum: Summation; import mir.ndslice.slice: sliced; import mir.test: shouldApprox; auto x = [ 0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0].sliced; auto y = [-0.75, 6.0, -0.25, 8.25, 5.75, 3.5, 9.25, -0.75, 2.5, 1.25, -1, 2.25].sliced; CovarianceAccumulator!(double, CovarianceAlgo.hybrid, Summation.naive) v; v.put(x, y); v.covariance(true).shouldApprox == -5.5 / 12; v.covariance(false).shouldApprox == -5.5 / 11; v.put(4.0, 3.0); v.covariance(true).shouldApprox == -5.5 / 13; v.covariance(false).shouldApprox == -5.5 / 12;
- alias
S
= Summator!(T, summation); - S
summatorLeft
; - S
summatorRight
; - S
centeredSummatorOfProducts
; - this()(T
x
, Ty
); - this(IteratorX, IteratorY, SliceKind kindX, SliceKind kindY)(Slice!(IteratorX, 1, kindX)
x
, Slice!(IteratorY, 1, kindY)y
); - this(SliceLikeX, SliceLikeY)(SliceLikeX
x
, SliceLikeYy
)
if (isConvertibleToSlice!SliceLikeX && !isSlice!SliceLikeX && isConvertibleToSlice!SliceLikeY && !isSlice!SliceLikeY); - this(RangeX, RangeY)(RangeX
x
, RangeYy
)
if (isInputRange!RangeX && !isConvertibleToSlice!RangeX && isInputRange!RangeY && !isConvertibleToSlice!RangeY); - void
put
(RangeX, RangeY)(RangeXx
, RangeYy
)
if (isInputRange!RangeX && isInputRange!RangeY); - void
put
()(Tx
, Ty
); - void
put
(U, CovarianceAlgo covAlgo, Summation sumAlgo)(CovarianceAccumulator!(U, covAlgo, sumAlgo)v
); - @property size_t
count
(); - @property F
sumLeft
(F = T)(); - @property F
sumRight
(F = T)(); - @property F
meanLeft
(F = T)(); - @property F
meanRight
(F = T)(); - @property F
centeredSumOfProducts
(F = T)(); - @property F
covariance
(F = T)(boolisPopulation
);
- template
covariance
(F, CovarianceAlgo covarianceAlgo = CovarianceAlgo.hybrid, Summation summation = Summation.appropriate) if (isFloatingPoint!F)
templatecovariance
(CovarianceAlgo covarianceAlgo = CovarianceAlgo.hybrid, Summation summation = Summation.appropriate)
templatecovariance
(F, string covarianceAlgo, string summation = "appropriate")
templatecovariance
(string covarianceAlgo, string summation = "appropriate") - Calculates the covariance of the inputs.If x and y are both slices or convertible to slices, then they must be one-dimensional. By default, if F is not floating point type, then the result will have a double type if F is implicitly convertible to a floating point type.Parameters:
F controls type of output covarianceAlgo algorithm for calculating covariance (default: CovarianceAlgo.hybrid) summation algorithm for calculating sums (default: Summation.appropriate) Returns:The covariance of the inputsExamples:Covariance of vectorsimport mir.ndslice.slice: sliced; import mir.test: shouldApprox; auto x = [ 0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0].sliced; auto y = [-0.75, 6.0, -0.25, 8.25, 5.75, 3.5, 9.25, -0.75, 2.5, 1.25, -1, 2.25].sliced; x.covariance(y, true).shouldApprox == -5.5 / 12; x.covariance(y).shouldApprox == -5.5 / 11;
Examples:Can also set algorithm typeimport mir.math.common: approxEqual; import mir.ndslice.slice: sliced; import mir.test: shouldApprox; auto a = [0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0].sliced; auto b = [-0.75, 6.0, -0.25, 8.25, 5.75, 3.5, 9.25, -0.75, 2.5, 1.25, -1, 2.25].sliced; auto x = a + 10.0 ^^ 9; auto y = b + 10.0 ^^ 9; x.covariance(y).shouldApprox == -5.5 / 11; // The naive algorithm is numerically unstable in this case assert(!x.covariance!"naive"(y).approxEqual(-5.5 / 11)); // The two-pass algorithm provides the same answer as hybrid x.covariance!"twoPass"(y).shouldApprox == -5.5 / 11; // And the assumeZeroMean algorithm is way off assert(!x.covariance!"assumeZeroMean"(y).approxEqual(-5.5 / 11));
Examples:Can also set algorithm or output typeimport mir.ndslice.slice: sliced; import mir.ndslice.topology: repeat; import mir.test: shouldApprox; //Set population covariance, covariance algorithm, sum algorithm or output type auto a = [1.0, 1e100, 1, -1e100].sliced; auto b = [1.0e100, 1, 1, -1e100].sliced; auto x = a * 10_000; auto y = b * 10_000; /++ Due to Floating Point precision, when centering `x`, subtracting the mean from the second and fourth numbers has no effect (for `y` the same is true for the first and fourth). Further, after centering and multiplying `x` and `y`, the third numbers in the slice has precision too low to be included in the centered sum of the products. +/ x.covariance(y).shouldApprox == 1.0e208 / 3; x.covariance(y, true).shouldApprox == 1.0e208 / 4; x.covariance!("online")(y).shouldApprox == 1.0e208 / 3; x.covariance!("online", "kbn")(y).shouldApprox == 1.0e208 / 3; x.covariance!("online", "kb2")(y).shouldApprox == 1.0e208 / 3; x.covariance!("online", "precise")(y).shouldApprox == 1.0e208 / 3; x.covariance!(double, "online", "precise")(y).shouldApprox == 1.0e208 / 3; auto z = uint.max.repeat(3); z.covariance!float(z).shouldApprox == 0.0; static assert(is(typeof(z.covariance!float(z)) == float));
Examples:For integral slices, pass output type as template parameter to ensure output type is correct.import mir.ndslice.slice: sliced; import mir.test: shouldApprox; auto x = [0, 1, 1, 2, 4, 4, 2, 7, 5, 1, 2, 0].sliced; auto y = [6, 3, 7, 1, 1, 1, 9, 5, 3, 1, 3, 7].sliced; x.covariance(y).shouldApprox == -18.583333 / 11; static assert(is(typeof(x.covariance(y)) == double)); x.covariance!float(y).shouldApprox == -18.583333 / 11; static assert(is(typeof(x.covariance!float(y)) == float));
Examples:Works with @nogcimport mir.ndslice.allocation: mininitRcslice; import mir.test: shouldApprox; static immutable a = [ 0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0]; static immutable b = [-0.75, 6.0, -0.25, 8.25, 5.75, 3.5, 9.25, -0.75, 2.5, 1.25, -1, 2.25]; auto x = mininitRcslice!double(12); auto y = mininitRcslice!double(12); x[] = a; y[] = b; x.covariance(y, true).shouldApprox == -5.5 / 12; x.covariance(y).shouldApprox == -5.5 / 11;
- F
covariance
(RangeX, RangeY)(RangeXx
, RangeYy
, boolisPopulation
= false)
if (isInputRange!RangeX && isInputRange!RangeY); - Parameters:
RangeX x
range, must be finite iterable RangeY y
range, must be finite iterable bool isPopulation
true if population covariance, false if sample covariance (default)
- enum
CorrelationAlgo
: int; - Correlation algorithms.
online
- Performs Welford's online algorithm for updating correlation. While it only iterates each input once, it can be slower for smaller inputs. However, it is also more accurate. Can also put another CorrelationAccumulator of the same type, which uses the parallel algorithm from Chan et al.
naive
- Calculates correlation using (E(x*y) - E(x)*E(y))/(sqrt(E(x^2)-E(x)^2)*sqrt(E(y^2)-E(y)^2)) (alowing for adjustments for population/sample variance). This algorithm can be numerically unstable.
twoPass
- Calculates correlation using a two-pass algorithm whereby the inputs are first centered and then the sum of products is calculated from that. May be faster than online and generally more accurate than the naive algorithm.
assumeZeroMean
- Calculates correlation assuming the mean of the inputs is zero.
assumeStandardized
- Calculates correlation assuming the mean of the inputs is zero and standard deviation is one.
hybrid
- When slices, slice-like objects, or ranges are the inputs, uses the two-pass algorithm. When an individual data-point is added, uses the online algorithm.
- struct
CorrelationAccumulator
(T, CorrelationAlgo correlationAlgo, Summation summation) if (isMutable!T && (correlationAlgo == CorrelationAlgo.naive)); - Examples:
import mir.math.sum: Summation; import mir.ndslice.slice: sliced; import mir.test: shouldApprox; auto x = [ 0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0].sliced; auto y = [-0.75, 6.0, -0.25, 8.25, 5.75, 3.5, 9.25, -0.75, 2.5, 1.25, -1, 2.25].sliced; CorrelationAccumulator!(double, CorrelationAlgo.naive, Summation.naive) v; v.put(x, y); v.covariance(true).shouldApprox == 82.25 / 12 - (29.25 * 36) / (12 * 12); v.covariance(false).shouldApprox == 82.25 / 11 - (29.25 * 36) / (12 * 12) * (12.0 / 11); v.correlation.shouldApprox == -0.0623684; v.put(4.0, 3.0); v.covariance(true).shouldApprox == 94.25 / 13 - (33.25 * 39) / (13 * 13); v.covariance(false).shouldApprox == 94.25 / 12 - (33.25 * 39) / (13 * 13) * (13.0 / 12); v.correlation.shouldApprox == -0.0611234;
- alias
S
= Summator!(T, summation); - S
summatorLeft
; - S
summatorRight
; - S
summatorOfProducts
; - S
summatorOfSquaresLeft
; - S
summatorOfSquaresRight
; - this(RangeX, RangeY)(RangeX
x
, RangeYy
)
if (isInputRange!RangeX && isInputRange!RangeY); - void
put
(IteratorX, IteratorY, SliceKind kindX, SliceKind kindY)(Slice!(IteratorX, 1, kindX)x
, Slice!(IteratorY, 1, kindY)y
); - void
put
(SliceLikeX, SliceLikeY)(SliceLikeXx
, SliceLikeYy
)
if (isConvertibleToSlice!SliceLikeX && !isSlice!SliceLikeX && isConvertibleToSlice!SliceLikeY && !isSlice!SliceLikeY); - void
put
(RangeX, RangeY)(RangeXx
, RangeYy
)
if (isInputRange!RangeX && !isConvertibleToSlice!RangeX && is(elementType!RangeX : T) && isInputRange!RangeY && !isConvertibleToSlice!RangeY && is(elementType!RangeY : T)); - void
put
()(Tx
, Ty
); - void
put
(U, Summation sumAlgo)(CorrelationAccumulator!(U, correlationAlgo, sumAlgo)v
); - @property size_t
count
(); - @property F
sumLeft
(F = T)(); - @property F
sumRight
(F = T)(); - @property F
meanLeft
(F = T)(); - @property F
meanRight
(F = T)(); - @property F
sumOfProducts
(F = T)(); - @property F
sumOfSquaresLeft
(F = T)(); - @property F
sumOfSquaresRight
(F = T)(); - @property F
centeredSumOfProducts
(F = T)(); - @property F
centeredSumOfSquaresLeft
(F = T)(); - @property F
centeredSumOfSquaresRight
(F = T)(); - @property F
covariance
(F = T)(boolisPopulation
); - @property F
correlation
(F = T)();
- struct
CorrelationAccumulator
(T, CorrelationAlgo correlationAlgo, Summation summation) if (isFloatingPoint!T && isMutable!T && (correlationAlgo == CorrelationAlgo.online)); - Examples:
import mir.math.sum: Summation; import mir.ndslice.slice: sliced; import mir.test: shouldApprox; auto x = [ 0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0].sliced; auto y = [-0.75, 6.0, -0.25, 8.25, 5.75, 3.5, 9.25, -0.75, 2.5, 1.25, -1, 2.25].sliced; CorrelationAccumulator!(double, CorrelationAlgo.online, Summation.naive) v; v.put(x, y); v.covariance(true).shouldApprox == -5.5 / 12; v.covariance(false).shouldApprox == -5.5 / 11; v.correlation.shouldApprox == -0.0623684; v.put(4.0, 3.0); v.covariance(true).shouldApprox == -5.5 / 13; v.covariance(false).shouldApprox == -5.5 / 12; v.correlation.shouldApprox == -0.0611234;
- alias
S
= Summator!(T, summation); - S
summatorLeft
; - S
summatorRight
; - S
centeredSummatorOfProducts
; - S
centeredSummatorOfSquaresLeft
; - S
centeredSummatorOfSquaresRight
; - this(RangeX, RangeY)(RangeX
x
, RangeYy
)
if (isInputRange!RangeX && isInputRange!RangeY); - this()(T
x
, Ty
); - void
put
(IteratorX, IteratorY, SliceKind kindX, SliceKind kindY)(Slice!(IteratorX, 1, kindX)x
, Slice!(IteratorY, 1, kindY)y
); - void
put
(SliceLikeX, SliceLikeY)(SliceLikeXx
, SliceLikeYy
)
if (isConvertibleToSlice!SliceLikeX && !isSlice!SliceLikeX && isConvertibleToSlice!SliceLikeY && !isSlice!SliceLikeY); - void
put
(RangeX, RangeY)(RangeXx
, RangeYy
)
if (isInputRange!RangeX && !isConvertibleToSlice!RangeX && isInputRange!RangeY && !isConvertibleToSlice!RangeY); - void
put
()(Tx
, Ty
); - void
put
(U, CorrelationAlgo covAlgo, Summation sumAlgo)(CorrelationAccumulator!(U, covAlgo, sumAlgo)v
)
if (!is(covAlgo == CorrelationAlgo.assumeZeroMean)); - @property size_t
count
(); - @property F
sumLeft
(F = T)(); - @property F
sumRight
(F = T)(); - @property F
meanLeft
(F = T)(); - @property F
meanRight
(F = T)(); - @property F
centeredSumOfProducts
(F = T)(); - @property F
centeredSumOfSquaresLeft
(F = T)(); - @property F
centeredSumOfSquaresRight
(F = T)(); - @property F
covariance
(F = T)(boolisPopulation
); - @property F
correlation
(F = T)();
- struct
CorrelationAccumulator
(T, CorrelationAlgo correlationAlgo, Summation summation) if (isMutable!T && (correlationAlgo == CorrelationAlgo.twoPass)); - Examples:
import mir.math.sum: Summation; import mir.ndslice.slice: sliced; import mir.test: shouldApprox; auto x = [ 0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0].sliced; auto y = [-0.75, 6.0, -0.25, 8.25, 5.75, 3.5, 9.25, -0.75, 2.5, 1.25, -1, 2.25].sliced; auto v = CorrelationAccumulator!(double, CorrelationAlgo.twoPass, Summation.naive)(x, y); v.covariance(true).shouldApprox == -5.5 / 12; v.covariance(false).shouldApprox == -5.5 / 11; v.correlation.shouldApprox == -0.0623684;
- alias
S
= Summator!(T, summation); - this(IteratorX, IteratorY, SliceKind kindX, SliceKind kindY)(Slice!(IteratorX, 1, kindX)
x
, Slice!(IteratorY, 1, kindY)y
); - this(SliceLikeX, SliceLikeY)(SliceLikeX
x
, SliceLikeYy
)
if (isConvertibleToSlice!SliceLikeX && !isSlice!SliceLikeX && isConvertibleToSlice!SliceLikeY && !isSlice!SliceLikeY); - this(RangeX, RangeY)(RangeX
x
, RangeYy
)
if (isInputRange!RangeX && !isConvertibleToSlice!RangeX && is(elementType!RangeX : T) && isInputRange!RangeY && !isConvertibleToSlice!RangeY && is(elementType!RangeY : T)); - this()(T
x
, Ty
); - @property size_t
count
(); - @property F
sumLeft
(F = T)(); - @property F
sumRight
(F = T)(); - @property F
meanLeft
(F = T)(); - @property F
meanRight
(F = T)(); - @property F
centeredSumOfProducts
(F = T)(); - @property F
centeredSumOfSquaresLeft
(F = T)(); - @property F
centeredSumOfSquaresRight
(F = T)(); - @property F
covariance
(F = T)(boolisPopulation
); - @property F
correlation
(F = T)();
- struct
CorrelationAccumulator
(T, CorrelationAlgo correlationAlgo, Summation summation) if (isMutable!T && (correlationAlgo == CorrelationAlgo.assumeZeroMean)); - Examples:
import mir.stat.transform: center; import mir.math.sum: Summation; import mir.ndslice.slice: sliced; import mir.test: shouldApprox; auto a = [ 0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0].sliced; auto b = [-0.75, 6.0, -0.25, 8.25, 5.75, 3.5, 9.25, -0.75, 2.5, 1.25, -1, 2.25].sliced; auto x = a.center; auto y = b.center; CorrelationAccumulator!(double, CorrelationAlgo.assumeZeroMean, Summation.naive) v; v.put(x, y); v.covariance(true).shouldApprox == -5.5 / 12; v.covariance(false).shouldApprox == -5.5 / 11; v.correlation.shouldApprox == -0.0623684; v.put(4.0, 3.0); v.covariance(true).shouldApprox == 6.5 / 13; v.covariance(false).shouldApprox == 6.5 / 12; v.correlation.shouldApprox == 0.0628802;
- alias
S
= Summator!(T, summation); - S
centeredSummatorOfProducts
; - S
centeredSummatorOfSquaresLeft
; - S
centeredSummatorOfSquaresRight
; - this(RangeX, RangeY)(RangeX
x
, RangeYy
)
if (isInputRange!RangeX && isInputRange!RangeY); - this()(T
x
, Ty
); - void
put
(IteratorX, IteratorY, SliceKind kindX, SliceKind kindY)(Slice!(IteratorX, 1, kindX)x
, Slice!(IteratorY, 1, kindY)y
); - void
put
(SliceLikeX, SliceLikeY)(SliceLikeXx
, SliceLikeYy
)
if (isConvertibleToSlice!SliceLikeX && !isSlice!SliceLikeX && isConvertibleToSlice!SliceLikeY && !isSlice!SliceLikeY); - void
put
(RangeX, RangeY)(RangeXx
, RangeYy
)
if (isInputRange!RangeX && !isConvertibleToSlice!RangeX && is(elementType!RangeX : T) && isInputRange!RangeY && !isConvertibleToSlice!RangeY && is(elementType!RangeY : T)); - void
put
()(Tx
, Ty
); - void
put
(U, Summation sumAlgo)(CorrelationAccumulator!(U, correlationAlgo, sumAlgo)v
); - @property size_t
count
(); - @property F
sumLeft
(F = T)(); - @property F
sumRight
(F = T)(); - @property F
meanLeft
(F = T)(); - @property F
meanRight
(F = T)(); - @property F
centeredSumOfProducts
(F = T)(); - @property F
centeredSumOfSquaresLeft
(F = T)(); - @property F
centeredSumOfSquaresRight
(F = T)(); - @property F
covariance
(F = T)(boolisPopulation
); - @property F
correlation
(F = T)();
- struct
CorrelationAccumulator
(T, CorrelationAlgo correlationAlgo, Summation summation) if (isFloatingPoint!T && isMutable!T && (correlationAlgo == CorrelationAlgo.hybrid)); - Examples:
import mir.math.sum: Summation; import mir.ndslice.slice: sliced; import mir.test: shouldApprox; auto x = [ 0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0].sliced; auto y = [-0.75, 6.0, -0.25, 8.25, 5.75, 3.5, 9.25, -0.75, 2.5, 1.25, -1, 2.25].sliced; CorrelationAccumulator!(double, CorrelationAlgo.hybrid, Summation.naive) v; v.put(x, y); v.covariance(true).shouldApprox == -5.5 / 12; v.covariance(false).shouldApprox == -5.5 / 11; v.correlation.shouldApprox == -0.0623684; v.put(4.0, 3.0); v.covariance(true).shouldApprox == -5.5 / 13; v.covariance(false).shouldApprox == -5.5 / 12; v.correlation.shouldApprox == -0.0611234;
- alias
S
= Summator!(T, summation); - S
summatorLeft
; - S
summatorRight
; - S
centeredSummatorOfProducts
; - S
centeredSummatorOfSquaresLeft
; - S
centeredSummatorOfSquaresRight
; - this()(T
x
, Ty
); - this(IteratorX, IteratorY, SliceKind kindX, SliceKind kindY)(Slice!(IteratorX, 1, kindX)
x
, Slice!(IteratorY, 1, kindY)y
); - this(SliceLikeX, SliceLikeY)(SliceLikeX
x
, SliceLikeYy
)
if (isConvertibleToSlice!SliceLikeX && !isSlice!SliceLikeX && isConvertibleToSlice!SliceLikeY && !isSlice!SliceLikeY); - this(RangeX, RangeY)(RangeX
x
, RangeYy
)
if (isInputRange!RangeX && !isConvertibleToSlice!RangeX && isInputRange!RangeY && !isConvertibleToSlice!RangeY); - void
put
(RangeX, RangeY)(RangeXx
, RangeYy
)
if (isInputRange!RangeX && isInputRange!RangeY); - void
put
()(Tx
, Ty
); - void
put
(U, CorrelationAlgo covAlgo, Summation sumAlgo)(CorrelationAccumulator!(U, covAlgo, sumAlgo)v
); - @property size_t
count
(); - @property F
sumLeft
(F = T)(); - @property F
sumRight
(F = T)(); - @property F
meanLeft
(F = T)(); - @property F
meanRight
(F = T)(); - @property F
centeredSumOfProducts
(F = T)(); - @property F
centeredSumOfSquaresLeft
(F = T)(); - @property F
centeredSumOfSquaresRight
(F = T)(); - @property F
covariance
(F = T)(boolisPopulation
); - @property F
correlation
(F = T)();
- template
correlation
(F, CorrelationAlgo correlationAlgo = CorrelationAlgo.hybrid, Summation summation = Summation.appropriate) if (isFloatingPoint!F)
templatecorrelation
(CorrelationAlgo correlationAlgo = CorrelationAlgo.hybrid, Summation summation = Summation.appropriate)
templatecorrelation
(F, string correlationAlgo, string summation = "appropriate")
templatecorrelation
(string correlationAlgo, string summation = "appropriate") - Calculates the correlation of the inputs.If x and y are both slices or convertible to slices, then they must be one-dimensional.Parameters:
F controls type of output correlationAlgo algorithm for calculating correlation (default: CorrelationAlgo.hybrid) summation algorithm for calculating sums (default: Summation.appropriate) Returns:The correlation of the inputsExamples:Correlation of vectorsimport mir.ndslice.slice: sliced; import mir.test: shouldApprox; auto x = [ 0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0].sliced; auto y = [-0.75, 6.0, -0.25, 8.25, 5.75, 3.5, 9.25, -0.75, 2.5, 1.25, -1, 2.25].sliced; x.correlation(y).shouldApprox == -0.0623684;
Examples:Can also set algorithm typeimport mir.math.common: approxEqual; import mir.ndslice.slice: sliced; import mir.test: shouldApprox; auto a = [0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0].sliced; auto b = [-0.75, 6.0, -0.25, 8.25, 5.75, 3.5, 9.25, -0.75, 2.5, 1.25, -1, 2.25].sliced; auto x = a + 10.0 ^^ 9; auto y = b + 10.0 ^^ 9; x.correlation(y).shouldApprox == -0.0623684; // The naive algorithm is numerically unstable in this case //assert(!x.correlation!"naive"(y).approxEqual(-0.0623684)); // The two-pass algorithm provides the same answer as hybrid x.correlation!"twoPass"(y).shouldApprox == -0.0623684; // And the assumeZeroMean algorithm is way off assert(!x.correlation!"assumeZeroMean"(y).approxEqual(-0.0623684));
Examples:Can also set algorithm or output typeimport mir.ndslice.slice: sliced; import mir.ndslice.topology: repeat; import mir.test: shouldApprox; //Set population covariance, covariance algorithm, sum algorithm or output type auto a = [1.0, 1e100, 1, -1e100].sliced; auto b = [1.0e100, 1, 1, -1e100].sliced; auto x = a * 10_000; auto y = b * 10_000; /++ Due to Floating Point precision, when centering `x`, subtracting the mean from the second and fourth numbers has no effect (for `y` the same is true for the first and fourth). Further, after centering and multiplying `x` and `y`, the third numbers in the slice has precision too low to be included in the centered sum of the products. For the calculations below, the "true" correlation should be a tiny amount above 0.5, but it is as if the calculation happens between [0, 1, 0, -1] and [1, 0, 0, -1]. +/ x.correlation(y).shouldApprox == 0.5; x.correlation!("online")(y).shouldApprox == 0.5; x.correlation!("online", "kbn")(y).shouldApprox == 0.5; x.correlation!("online", "kb2")(y).shouldApprox == 0.5; x.correlation!("online", "precise")(y).shouldApprox == 0.5; x.correlation!(double, "online", "precise")(y).shouldApprox == 0.5; auto z1 = [uint.max - 2, uint.max - 1, uint.max].sliced; auto z2 = [uint.max - 3, uint.max - 2, uint.max - 1].sliced; z1.correlation(z2).shouldApprox == 1.0; static assert(is(typeof(z1.correlation!float(z2)) == float));
Examples:For integral slices, pass output type as template parameter to ensure output type is correct.import mir.ndslice.slice: sliced; import mir.test: shouldApprox; auto x = [0, 1, 1, 2, 4, 4, 2, 7, 5, 1, 2, 0].sliced; auto y = [6, 3, 7, 1, 1, 1, 9, 5, 3, 1, 3, 7].sliced; x.correlation(y).shouldApprox == -0.27934577; static assert(is(typeof(x.correlation(y)) == double)); x.correlation!float(y).shouldApprox == -0.27934577; static assert(is(typeof(x.correlation!float(y)) == float));
Examples:Works with @nogcimport mir.ndslice.allocation: mininitRcslice; import mir.test: shouldApprox; static immutable a = [ 0.0, 1.0, 1.5, 2.0, 3.5, 4.25, 2.0, 7.5, 5.0, 1.0, 1.5, 0.0]; static immutable b = [-0.75, 6.0, -0.25, 8.25, 5.75, 3.5, 9.25, -0.75, 2.5, 1.25, -1, 2.25]; auto x = mininitRcslice!double(12); auto y = mininitRcslice!double(12); x[] = a; y[] = b; x.correlation(y).shouldApprox == -0.0623684;
- F
correlation
(RangeX, RangeY)(RangeXx
, RangeYy
)
if (isInputRange!RangeX && isInputRange!RangeY); - Parameters:
RangeX x
range, must be finite iterable RangeY y
range, must be finite iterable
Copyright © 2016-2023 by Ilya Yaroshenko | Page generated by
Ddoc on Wed Oct 18 12:23:04 2023