The OpenD Programming Language

prod

Parameters

ar T[]

values

Return Value

Type: prodType!T

The prduct of all the elements in ar

Examples

Product of arbitrary inputs

assert(prod(1.0, 3, 4) == 12.0);
assert(prod!float(1, 3, 4) == 12f);

Product of arrays and ranges

import mir.math.common: approxEqual;

enum l = 2.0 ^^ (double.max_exp - 1);
enum s = 2.0 ^^ -(double.max_exp - 1);
auto r = [l, l, l, s, s, s, 0.8 * 2.0 ^^ 10];

assert(r.prod == 0.8 * 2.0 ^^ 10);

// Can get the mantissa and exponent
long e;
assert(r.prod(e).approxEqual(0.8));
assert(e == 10);

Product of vector

import mir.ndslice.slice: sliced;
import mir.algorithm.iteration: reduce;
import mir.math.common: approxEqual;

enum l = 2.0 ^^ (double.max_exp - 1);
enum s = 2.0 ^^ -(double.max_exp - 1);
auto c = 0.8;
auto u = c * 2.0 ^^ 10;
auto r = [l, l, l, s, s, s, u, u, u].sliced;

assert(r.prod == reduce!"a * b"(1.0, [u, u, u]));

long e;
assert(r.prod(e).approxEqual(reduce!"a * b"(1.0, [c, c, c])));
assert(e == 30);

Product of matrix

import mir.ndslice.fuse: fuse;
import mir.algorithm.iteration: reduce;

enum l = 2.0 ^^ (double.max_exp - 1);
enum s = 2.0 ^^ -(double.max_exp - 1);
auto c = 0.8;
auto u = c * 2.0 ^^ 10;
auto r = [
    [l, l, l],
    [s, s, s],
    [u, u, u]
].fuse;

assert(r.prod == reduce!"a * b"(1.0, [u, u, u]));

long e;
assert(r.prod(e) == reduce!"a * b"(1.0, [c, c, c]));
assert(e == 30);

Column prod of matrix

import mir.ndslice.fuse: fuse;
import mir.algorithm.iteration: all;
import mir.math.common: approxEqual;
import mir.ndslice.topology: alongDim, byDim, map;

auto x = [
    [2.0, 1.0, 1.5, 2.0, 3.5, 4.25],
    [2.0, 7.5, 5.0, 1.0, 1.5, 5.0]
].fuse;

auto result = [4.0, 7.5, 7.5, 2.0, 5.25, 21.25];

// Use byDim or alongDim with map to compute mean of row/column.
assert(x.byDim!1.map!prod.all!approxEqual(result));
assert(x.alongDim!0.map!prod.all!approxEqual(result));

// FIXME
// Without using map, computes the prod of the whole slice
// assert(x.byDim!1.prod.all!approxEqual(result));
// assert(x.alongDim!0.prod.all!approxEqual(result));

Can also set output type

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

auto x = [1, 2, 3].sliced;
assert(x.prod!float == 6f);

Product of variables whose underlying types are implicitly convertible to double also have type double

static struct Foo
{
    int x;
    alias x this;
}

auto x = prod(1, 2, 3);
assert(x == 6.0);
static assert(is(typeof(x) == double));

auto y = prod([Foo(1), Foo(2), Foo(3)]);
assert(y == 6.0);
static assert(is(typeof(y) == double));

Meta