controls type of output
algorithm for calculating sums (default: Summation.appropriate)
controls the type of weights
The weighted sum of all the elements in the input
import mir.complex; import mir.math.common: approxEqual; import mir.ndslice.slice: sliced; import mir.test: should; alias C = Complex!double; wsum([1, 2, 3], [1, 2, 3]).should == (1 + 4 + 9); wsum([C(1, 3), C(2), C(3)], [1, 2, 3]).should == C((1 + 4 + 9), 3); wsum!float([0, 1, 2, 3, 4, 5].sliced(3, 2), [1, 2, 3, 4, 5, 6].sliced(3, 2)).should == 70; static assert(is(typeof(wmean!float([1, 2, 3], [1, 2, 3])) == float));
If weights are not provided, then behaves like sum
import mir.complex; import mir.ndslice.slice: sliced; import mir.test: should; alias C = Complex!double; wsum([1.0, 2, 3]).should == 6; wsum([C(1, 3), C(2), C(3)]).should == C(6, 3); wsum!float([0, 1, 2, 3, 4, 5].sliced(3, 2)).should == 15; static assert(is(typeof(wsum!float([1, 2, 3])) == float));
Weighted sum of vector
import mir.ndslice.slice: sliced; import mir.ndslice.topology: iota, map; import mir.test: should; 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 w = iota([12], 1); x.wsum.should == 29.25; x.wsum(w).should == 203;
Weighted sum of matrix
import mir.ndslice.fuse: fuse; import mir.ndslice.topology: iota; import mir.test: should; 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] ].fuse; auto w = iota([2, 6], 1); x.wsum.should == 29.25; x.wsum(w).should == 203;
Column sum of matrix
import mir.algorithm.iteration: all; import mir.math.common: approxEqual; import mir.ndslice.fuse: fuse; import mir.ndslice.topology: alongDim, byDim, iota, map, universal; 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] ].fuse; auto w = iota([2], 1).universal; auto result = [4, 16, 11.5, 4, 6.5, 4.25]; // Use byDim or alongDim with map to compute sum of row/column. assert(x.byDim!1.map!(a => a.wsum(w)).all!approxEqual(result)); assert(x.alongDim!0.map!(a => a.wsum(w)).all!approxEqual(result)); // FIXME // Without using map, computes the sum of the whole slice // assert(x.byDim!1.wsum(w) == x.sliced.wsum); // assert(x.alongDim!0.wsum(w) == x.sliced.wsum);
Can also set algorithm or output type
import mir.ndslice.slice: sliced; import mir.ndslice.topology: repeat, universal; import mir.test: should; //Set sum algorithm (also for weights) or output type auto a = [1, 1e100, 1, -1e100].sliced; auto x = a * 10_000; auto w1 = [1, 1, 1, 1].sliced; auto w2 = [0.25, 0.25, 0.25, 0.25].sliced; x.wsum!"kbn"(w1).should == 20_000; x.wsum!"kbn"(w2).should == 20_000 / 4; x.wsum!"kb2"(w1).should == 20_000; x.wsum!"precise"(w1).should == 20_000; x.wsum!(double, "precise")(w1).should == 20_000; auto y = uint.max.repeat(3); y.wsum!ulong([1, 1, 1].sliced.universal).should == 12884901885;
wsum works for complex numbers and other user-defined types
import mir.complex; import mir.ndslice.slice: sliced; import mir.test: should; alias C = Complex!double; auto x = [C(1.0, 2), C(2, 3), C(3, 4), C(4, 5)].sliced; auto w = [1, 2, 3, 4].sliced; x.wsum(w).should == C(30, 40);
Compute weighted sum tensors along specified dimention of tensors
import mir.ndslice.fuse: fuse; import mir.ndslice.slice: sliced; import mir.ndslice.topology: alongDim, as, iota, map, universal; /++ [[0,1,2], [3,4,5]] +/ auto x = [ [0, 1, 2], [3, 4, 5] ].fuse.as!double; auto w = [ [1, 2, 3], [4, 5, 6] ].fuse; auto w1 = [1, 2].sliced.universal; auto w2 = [1, 2, 3].sliced; assert(x.wsum(w) == 70); auto m0 = [(0 + 6), (1 + 8), (2 + 10)]; assert(x.alongDim!0.map!(a => a.wsum(w1)) == m0); assert(x.alongDim!(-2).map!(a => a.wsum(w1)) == m0); auto m1 = [(0 + 2 + 6), (3 + 8 + 15)]; assert(x.alongDim!1.map!(a => a.wsum(w2)) == m1); assert(x.alongDim!(-1).map!(a => a.wsum(w2)) == m1);
$(MATHREF sum, Summation)
Computes the weighted sum of the input.