Skip to content

Commit 1497ca3

Browse files
authored
Remove dispersion (#305)
1 parent da14026 commit 1497ca3

File tree

1 file changed

+0
-287
lines changed

1 file changed

+0
-287
lines changed

source/mir/math/stat.d

Lines changed: 0 additions & 287 deletions
Original file line numberDiff line numberDiff line change
@@ -3260,293 +3260,6 @@ unittest
32603260
assert(x.sliced.standardDeviation!float.approxEqual(sqrt(54.76562 / 11)));
32613261
}
32623262

3263-
/++
3264-
Calculates the dispersion of the input.
3265-
3266-
For an input `x`, this function first centers `x` by subtracting each `e` in `x`
3267-
by the result of `centralTendency`, then it transforms the centered values using
3268-
the function `transform`, and then finally summarizes that information using
3269-
the `summarize` funcion.
3270-
3271-
The default functions provided are equivalent to calculating the population
3272-
variance. The `centralTendency` default is the `mean` function, which results
3273-
in the input being centered about the mean. The default `transform` function
3274-
will square the centered values. The default `summarize` function is `mean`,
3275-
which will return the mean of the squared centered values.
3276-
3277-
Params:
3278-
centralTendency = function that will produce the value that the input is centered about, default is `mean`
3279-
transform = function to transform centered values, default squares the centered values
3280-
summarize = function to summarize the transformed centered values, default is `mean`
3281-
3282-
Returns:
3283-
The dispersion of the input
3284-
+/
3285-
template dispersion(
3286-
alias centralTendency = mean,
3287-
alias transform = "a * a",
3288-
alias summarize = mean)
3289-
{
3290-
import mir.functional: naryFun;
3291-
import mir.ndslice.slice: Slice, SliceKind, sliced, hasAsSlice;
3292-
3293-
static if (__traits(isSame, naryFun!transform, transform))
3294-
{
3295-
/++
3296-
Params:
3297-
slice = slice
3298-
+/
3299-
@fmamath auto dispersion(Iterator, size_t N, SliceKind kind)(
3300-
Slice!(Iterator, N, kind) slice)
3301-
{
3302-
import core.lifetime: move;
3303-
import mir.ndslice.topology: map;
3304-
3305-
return summarize(slice.move.center!centralTendency.map!transform);
3306-
}
3307-
3308-
/// ditto
3309-
@fmamath auto dispersion(T)(scope const T[] ar...)
3310-
{
3311-
return dispersion(ar.sliced);
3312-
}
3313-
3314-
/// ditto
3315-
@fmamath auto dispersion(T)(T withAsSlice)
3316-
if (hasAsSlice!T)
3317-
{
3318-
return dispersion(withAsSlice.asSlice);
3319-
}
3320-
}
3321-
else
3322-
alias dispersion = .dispersion!(centralTendency, naryFun!transform, summarize);
3323-
}
3324-
3325-
///
3326-
version(mir_test)
3327-
@safe pure nothrow
3328-
unittest
3329-
{
3330-
import mir.ndslice.slice: sliced;
3331-
import mir.math.common: approxEqual;
3332-
import mir.functional: naryFun;
3333-
3334-
assert(dispersion([1.0, 2, 3]).approxEqual(2.0 / 3));
3335-
3336-
assert(dispersion([1.0 + 3i, 2, 3]).approxEqual((-4.0 - 6i) / 3));
3337-
3338-
assert(dispersion!(mean!float, "a * a", mean!float)([0, 1, 2, 3, 4, 5].sliced(3, 2)).approxEqual(17.5 / 6));
3339-
3340-
static assert(is(typeof(dispersion!(mean!float, "a ^^ 2", mean!float)([1, 2, 3])) == float));
3341-
}
3342-
3343-
/// Dispersion of vector
3344-
version(mir_test)
3345-
@safe pure nothrow
3346-
unittest
3347-
{
3348-
import mir.ndslice.slice: sliced;
3349-
import mir.math.common: approxEqual;
3350-
3351-
auto x = [0.0, 1.0, 1.5, 2.0, 3.5, 4.25,
3352-
2.0, 7.5, 5.0, 1.0, 1.5, 0.0].sliced;
3353-
3354-
assert(x.dispersion.approxEqual(54.76562 / 12));
3355-
}
3356-
3357-
/// Dispersion of matrix
3358-
version(mir_test)
3359-
@safe pure
3360-
unittest
3361-
{
3362-
import mir.ndslice.fuse: fuse;
3363-
import mir.math.common: approxEqual;
3364-
3365-
auto x = [
3366-
[0.0, 1.0, 1.5, 2.0, 3.5, 4.25],
3367-
[2.0, 7.5, 5.0, 1.0, 1.5, 0.0]
3368-
].fuse;
3369-
3370-
assert(x.dispersion.approxEqual(54.76562 / 12));
3371-
}
3372-
3373-
/// Column dispersion of matrix
3374-
version(mir_test)
3375-
@safe pure
3376-
unittest
3377-
{
3378-
import mir.ndslice.fuse: fuse;
3379-
import mir.ndslice.topology: alongDim, byDim, map;
3380-
import mir.math.common: approxEqual;
3381-
import mir.algorithm.iteration: all;
3382-
3383-
auto x = [
3384-
[0.0, 1.0, 1.5, 2.0],
3385-
[3.5, 4.25, 2.0, 7.5],
3386-
[5.0, 1.0, 1.5, 0.0]
3387-
].fuse;
3388-
auto result = [13.16667 / 3, 7.041667 / 3, 0.1666667 / 3, 30.16667 / 3];
3389-
3390-
// Use byDim or alongDim with map to compute dispersion of row/column.
3391-
assert(x.byDim!1.map!dispersion.all!approxEqual(result));
3392-
assert(x.alongDim!0.map!dispersion.all!approxEqual(result));
3393-
3394-
// FIXME
3395-
// Without using map, computes the dispersion of the whole slice
3396-
// assert(x.byDim!1.dispersion == x.sliced.dispersion);
3397-
// assert(x.alongDim!0.dispersion == x.sliced.dispersion);
3398-
}
3399-
3400-
/// Can also set functions to change type of dispersion that is used
3401-
version(mir_test)
3402-
@safe
3403-
unittest
3404-
{
3405-
import mir.ndslice.slice: sliced;
3406-
import mir.math.common: approxEqual, fabs, sqrt;
3407-
import mir.functional: naryFun;
3408-
3409-
auto x = [0.0, 1.0, 1.5, 2.0, 3.5, 4.25,
3410-
2.0, 7.5, 5.0, 1.0, 1.5, 0.0].sliced;
3411-
3412-
alias square = naryFun!"a * a";
3413-
3414-
// Other population variance examples
3415-
assert(x.dispersion.approxEqual(54.76562 / 12));
3416-
assert(x.dispersion!mean.approxEqual(54.76562 / 12));
3417-
assert(x.dispersion!(mean, square).approxEqual(54.76562 / 12));
3418-
assert(x.dispersion!(mean, square, mean).approxEqual(54.76562 / 12));
3419-
3420-
// Population standard deviation
3421-
assert(x.dispersion!(mean, square, mean).sqrt.approxEqual(sqrt(54.76562 / 12)));
3422-
3423-
// Mean absolute deviation about the mean
3424-
assert(x.dispersion!(mean, fabs, mean).approxEqual(21.0 / 12));
3425-
//Mean absolute deviation about the median
3426-
assert(x.dispersion!(median, fabs, mean).approxEqual(19.25000 / 12));
3427-
//Median absolute deviation about the mean
3428-
assert(x.dispersion!(mean, fabs, median).approxEqual(1.43750));
3429-
//Median absolute deviation about the median
3430-
assert(x.dispersion!(median, fabs, median).approxEqual(1.25000));
3431-
}
3432-
3433-
/++
3434-
For integral slices, pass output type to `centralTendency`, `transform`, and
3435-
`summary` functions as template parameter to ensure output type is correct.
3436-
+/
3437-
version(mir_test)
3438-
@safe pure nothrow
3439-
unittest
3440-
{
3441-
import mir.ndslice.slice: sliced;
3442-
import mir.math.common: approxEqual;
3443-
import mir.functional: naryFun;
3444-
3445-
auto x = [0, 1, 1, 2, 4, 4,
3446-
2, 7, 5, 1, 2, 0].sliced;
3447-
3448-
alias square = naryFun!"a * a";
3449-
3450-
auto y = x.dispersion;
3451-
assert(y.approxEqual(50.91667 / 12));
3452-
static assert(is(typeof(y) == double));
3453-
3454-
assert(x.dispersion!(mean!float, square, mean!float).approxEqual(50.91667 / 12));
3455-
}
3456-
3457-
/++
3458-
Dispersion works for complex numbers and other user-defined types (provided that
3459-
the `centralTendency`, `transform`, and `summary` functions are defined for those
3460-
types)
3461-
+/
3462-
version(mir_test)
3463-
@safe pure nothrow
3464-
unittest
3465-
{
3466-
import mir.ndslice.slice: sliced;
3467-
import mir.math.common: approxEqual;
3468-
3469-
auto x = [1.0 + 2i, 2 + 3i, 3 + 4i, 4 + 5i].sliced;
3470-
assert(x.dispersion.approxEqual((0.0+10.0i)/ 4));
3471-
}
3472-
3473-
/// Compute mean tensors along specified dimention of tensors
3474-
version(mir_test)
3475-
@safe pure
3476-
unittest
3477-
{
3478-
import mir.ndslice.fuse: fuse;
3479-
import mir.algorithm.iteration: all;
3480-
import mir.math.common: approxEqual;
3481-
import mir.ndslice.topology: as, iota, alongDim, map, repeat;
3482-
3483-
auto x = [
3484-
[0.0, 1, 2],
3485-
[3.0, 4, 5]
3486-
].fuse;
3487-
3488-
assert(x.dispersion.approxEqual(17.5 / 6));
3489-
3490-
auto m0 = [2.25, 2.25, 2.25];
3491-
assert(x.alongDim!0.map!dispersion.all!approxEqual(m0));
3492-
assert(x.alongDim!(-2).map!dispersion.all!approxEqual(m0));
3493-
3494-
auto m1 = [2.0 / 3, 2.0 / 3];
3495-
assert(x.alongDim!1.map!dispersion.all!approxEqual(m1));
3496-
assert(x.alongDim!(-1).map!dispersion.all!approxEqual(m1));
3497-
3498-
assert(iota(2, 3, 4, 5).as!double.alongDim!0.map!dispersion.all!approxEqual(repeat(1800.0 / 2, 3, 4, 5)));
3499-
}
3500-
3501-
/// Arbitrary dispersion
3502-
version(mir_test)
3503-
@safe pure nothrow @nogc
3504-
unittest
3505-
{
3506-
import mir.math.common: approxEqual;
3507-
import mir.functional: naryFun;
3508-
3509-
alias square = naryFun!"a * a";
3510-
3511-
assert(dispersion(1.0, 2, 3).approxEqual(2.0 / 3));
3512-
assert(dispersion!(mean!float, square, mean!float)(1, 2, 3).approxEqual(2f / 3));
3513-
}
3514-
3515-
version(mir_test)
3516-
@safe pure nothrow
3517-
unittest
3518-
{
3519-
import mir.math.common: approxEqual;
3520-
assert([1.0, 2, 3, 4].dispersion.approxEqual(5.0 / 4));
3521-
}
3522-
3523-
version(mir_test)
3524-
@safe pure nothrow
3525-
unittest
3526-
{
3527-
import mir.ndslice.topology: iota, alongDim, map;
3528-
import mir.math.common: approxEqual;
3529-
import mir.algorithm.iteration: all;
3530-
3531-
auto x = iota([2, 2], 1);
3532-
auto y = x.alongDim!1.map!dispersion;
3533-
assert(y.all!approxEqual([0.25, 0.25]));
3534-
static assert(is(meanType!(typeof(y)) == double));
3535-
}
3536-
3537-
version(mir_test)
3538-
@safe pure @nogc nothrow
3539-
unittest
3540-
{
3541-
import mir.ndslice.slice: sliced;
3542-
import mir.math.common: approxEqual;
3543-
3544-
static immutable x = [0.0, 1.0, 1.5, 2.0, 3.5, 4.25,
3545-
2.0, 7.5, 5.0, 1.0, 1.5, 0.0];
3546-
3547-
assert(x.sliced.dispersion.approxEqual(54.76562 / 12));
3548-
}
3549-
35503263
/++
35513264
A linear regression model with a single explanatory variable.
35523265
+/

0 commit comments

Comments
 (0)