The OpenD Programming Language

rawMoment

Calculates the n-th raw moment of the input.

By default, if F is not floating point type or complex type, then the result will have a double type if F is implicitly convertible to a floating point type or a type for which isComplex!F is true.

Parameters

F

controls type of output

N

controls n-th raw moment

summation

algorithm for calculating sums (default: Summation.appropriate)

Return Value

The n-th raw moment of the input, must be floating point or complex type

Examples

Basic implementation

import mir.math.common: approxEqual;
import mir.ndslice.slice: sliced;

assert(rawMoment!2([1.0, 2, 3]).approxEqual(14.0 / 3));
assert(rawMoment!3([1.0, 2, 3]).approxEqual(36.0 / 3));

assert(rawMoment!(float, 2)([0, 1, 2, 3, 4, 5].sliced(3, 2)).approxEqual(55f / 6));
static assert(is(typeof(rawMoment!(float, 2)([1, 2, 3])) == float));

Raw Moment of vector

import mir.math.common: approxEqual;
import mir.ndslice.slice: sliced;
import mir.stat.transform: center;

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 x = a.center;

assert(x.rawMoment!2.approxEqual(54.76562 / 12));

Raw Moment of matrix

import mir.math.common: approxEqual;
import mir.ndslice.fuse: fuse;
import mir.stat.transform: center;

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]
].fuse;
auto x = a.center;

assert(x.rawMoment!2.approxEqual(54.76562 / 12));

Can also set algorithm or output type

import mir.math.common: approxEqual;
import mir.ndslice.slice: sliced;
import mir.ndslice.topology: repeat;
import mir.stat.transform: center;

//Set sum algorithm or output type

auto a = [1.0, 1e100, 1, -1e100].sliced;
auto b = a * 10_000;
auto x = b.center;

/++
Due to Floating Point precision, when centering `x`, subtracting the mean 
from the second and fourth numbers has no effect. Further, after centering 
and squaring `x`, the first and third numbers in the slice have precision 
too low to be included in the centered sum of squares. 
+/
assert(x.rawMoment!2.approxEqual(2.0e208 / 4));

assert(x.rawMoment!(2, "kbn").approxEqual(2.0e208 / 4));
assert(x.rawMoment!(2, "kb2").approxEqual(2.0e208 / 4));
assert(x.rawMoment!(2, "precise").approxEqual(2.0e208 / 4));
assert(x.rawMoment!(double, 2, "precise").approxEqual(2.0e208 / 4));

auto y = uint.max.repeat(3);
auto z = y.rawMoment!(ulong, 2);
assert(z.approxEqual(cast(double) (cast(ulong) uint.max) ^^ 2u));
static assert(is(typeof(z) == double));

rawMoment works for complex numbers and other user-defined types (that are either implicitly convertible to floating point or if isComplex is true)

import mir.ndslice.slice: sliced;
import std.complex: Complex;
import std.math.operations: isClose;

auto x = [Complex!double(1, 2), Complex!double(2, 3), Complex!double(3, 4), Complex!double(4, 5)].sliced;
assert(x.rawMoment!2.isClose(Complex!double(-24, 80)/ 4));

Arbitrary raw moment

import mir.math.common: approxEqual;

assert(rawMoment!2(1.0, 2, 3).approxEqual(14.0 / 3));
assert(rawMoment!(float, 2)(1, 2, 3).approxEqual(14f / 3));

Meta