// result = a + alpha * b public static Array <Real> Add(this Array <Real> a, Array <Real> b, Real alpha = 1, Array <Real> result = null) { return(Array_.ElementwiseOp(a, b, result, (n, x, offsetx, incx, y, offsety, incy, z, offsetz, incz) => { if (alpha == 1 && incx == 1 && incy == 1 && incz == 1) { Blas.vadd(n, x, offsetx, y, offsety, z, offsetz); } else if (alpha == -1 && incx == 1 && incy == 1 && incz == 1) { Blas.vsub(n, x, offsetx, y, offsety, z, offsetz); } else if (z == x) { Blas.axpy(n, alpha, y, offsety, incy, x, offsetx, incx); } else if (z == y && alpha == 1) { Blas.axpy(n, alpha, x, offsetx, incx, y, offsety, incy); } // TODO: else if (incx == 0) => broadcast x ?? // TODO: else if (incy == 0) => broadcast y ?? else { for (int i = 0; i < n; i++) // TODO: Blas.copy y => x, Blas.axpy(1, x, y) { z[offsetz] = x[offsetx] + alpha * y[offsety]; offsetx += incx; offsety += incy; offsetz += incz; } } // See also: mkl_?omatadd => C := alpha*op(A) + beta*op(B) })); }
public static Array <Real> Mul(this Array <Real> a, Array <Real> b, Array <Real> result = null) { return(Array_.ElementwiseOp(a, b, result, (n, x, offsetx, incx, y, offsety, incy, z, offsetz, incz) => { if (incx == 1 && incy == 1 && incz == 1) { Blas.vmul(n, x, offsetx, y, offsety, z, offsetz); } else if (incx == 0) // x[offsetx] is broadcast: y[:] * x[offsetx] { Blas.gemv(Order.RowMajor, Transpose.NoTrans, n, 1, 1, y, offsety, incy, x, offsetx, 1, 0, z, offsetz, incz); } //else if (incy == 0) // y[offsety] is broadcast: x[:] * y[offsety] // Blas.gemv(Order.RowMajor, Transpose.NoTrans, n, 1, 1, x, offsetx, incx, y, offsety, 1, 0, z, offsetz, incz); else // when everything else fails, fallback to slow version { for (int i = 0; i < n; i++) { z[offsetz] = x[offsetx] * y[offsety]; offsetx += incx; offsety += incy; offsetz += incz; } } })); }
public static Array <Real> Add(this Array <Real> a, Real b, Real alpha = 1, Array <Real> result = null) { if (result == null) { result = new Array <Real>(a.Shape); } Array_.ElementwiseOp(a, result, (n, x, offsetx, incx, z, offsetz, incz) => { if (z == x) { Blas.axpy(n, alpha, ref b, x, offsetx, incx); } else { for (int i = 0; i < n; i++) { z[offsetz] = x[offsetx] + alpha * b; offsetx += incx; offsetz += incz; } } }); return(result); }
public static Array <Real> Sum(this Array <Real> a, int axis, Func <Real, Real> f, Array <Real> result = null, bool keepDims = false) { if (axis < 0) { axis = a.Shape.Length + axis; } result = result == null?NN.Zeros <Real>(GetAggregatorResultShape(a, axis, true)) : result.Clear(); var slice = a.Slices(); // TODO: create a new ElementwiseOp int ndim = a.Shape[axis]; for (int d = 0; d < ndim; ++d) { slice[axis] = (d, d + 1); Array_.ElementwiseOp(a[slice], result, (n, _a, off_a, step_a, _r, off_r, step_r) => { Real s = 0; for (int i = 0; i < n; i++) { s += f(_a[off_a]); off_a += step_a; off_r += step_r; } result += s; }); } if (!keepDims) { result = result.Reshape(RemoveAxis(result.Shape, axis)); } return(result); }
/// <summary><a href="http://docs.scipy.org/doc/numpy/reference/generated/numpy.argmax.html">see NumPy doc</a></summary> public static Array <int> Argmax(this Array <Real> a, int axis, bool keepDims = false, Array <int> result = null) { if (axis < 0) { axis = a.Shape.Length + axis; } if (result == null) { result = NN.Zeros <int>(GetAggregatorResultShape(a, axis, true)); } else if (result.NDim != a.NDim) { result = result.Reshape(GetAggregatorResultShape(a, axis, true)); } Array_.ElementwiseOp(a, result, (n, x, offx, incx, y, offy, incy) => { var max = x[offx]; offx += incx; var argmax = 0; for (int i = 1; i < n; ++i) { var value = x[offx]; if (value > max) { max = value; argmax = i; } offx += incx; } y[offy] = argmax; }, axis); return(keepDims ? result : result.Reshape(GetAggregatorResultShape(a, axis, false))); }
public static Array <Real> Scale(this Array <Real> a, Real alpha, Array <Real> result = null) { if (result != a) { result = a.Copy(result: result); } Array_.ElementwiseOp(0, result, 0, (n, x, offsetx, incx) => { Blas.scal(n, alpha, x, offsetx, incx); }); return(result); }
/// <summary>a += α * b </summary> public static void Acc(this Array <Real> a, Array <Real> b, Real alpha = 1) { if (alpha == 0) { return; } b.AssertOfShape(a.Shape); Array_.ElementwiseOp(b, a, (n, x, offsetx, incx, y, offsety, incy) => { // TODO: broadcasting ? Blas.axpy(n, alpha, x, offsetx, incx, y, offsety, incy); }); }
public static Array <Int> Apply(this Array <Int> a, Array <Int> b, Func <Int, Int, Int> fn, Array <Int> result = null) { return(Array_.ElementwiseOp(a, b, result, (n, x, offsetx, incx, y, offsety, incy, z, offsetz, incz) => { for (int i = 0; i < n; i++) { z[offsetz] = fn(x[offsetx], y[offsety]); offsetx += incx; offsety += incy; offsetz += incz; } })); }
public static Array <Int> Div(this Array <Int> a, Array <Int> b, Array <Int> result = null) { return(Array_.ElementwiseOp(a, b, result, (n, x, offsetx, incx, y, offsety, incy, z, offsetz, incz) => { for (int i = 0; i < n; i++) { z[offsetz] = x[offsetx] / y[offsety]; offsetx += incx; offsety += incy; offsetz += incz; } })); }
public static Array <Int> Acc(this Array <Int> a, Array <Int> b, Int alpha = 1) { Array_.ElementwiseOp(a, b, (n, x, offsetx, incx, y, offsety, incy) => { for (int i = 0; i < n; i++) { x[offsetx] += alpha * y[offsety]; offsetx += incx; offsety += incy; } }); return(a); }
public static Array <Real> NotEqual(this Array <Real> a, Array <Real> b, Array <Real> result = null) { return(Array_.ElementwiseOp(a, b, result, (n, x, offsetx, incx, y, offsety, incy, z, offsetz, incz) => { for (int i = 0; i < n; i++) { z[offsetz] = x[offsetx] != y[offsety] ? 1 : 0; offsetx += incx; offsety += incy; offsetz += incz; } })); }
public static Array <Real> Copy(this Array <Real> a, Array <Real> result = null) { if (a == result) { return(result); } if (result == null) { result = new Array <Real>(a.Shape); } Array_.ElementwiseOp(result, a, (n, x, offsetx, incx, y, offsety, incy) => { Blas.copy(n, y, offsety, incy, x, offsetx, incx); }); return(result); }
public static Int Min(this Array <Int> a) { Int result = Int.MaxValue; Array_.ElementwiseOp(0, a, 0, (n, x, offsetx, incx) => { Int s = Int.MaxValue; for (int i = 0; i < n; i++) { s = Math.Min(s, x[offsetx]); offsetx += incx; } result = Math.Min(result, s); }); return(result); }
public static Real Sum(this Array <Real> a) { Real result = 0; Array_.ElementwiseOp(0, a, 0, (n, x, offsetx, incx) => { Real s = 0; for (int i = 0; i < n; i++) { s += x[offsetx]; offsetx += incx; } result += s; }); return(result); }
public static Array <Int> Apply(this Array <Int> a, Func <Int, Int> fn, Array <Int> result = null) { if (result == null) { result = new Array <Int>(a.Shape); } Array_.ElementwiseOp(a, result, (n, x, offsetx, incx, y, offsety, incy) => { for (int i = 0; i < n; i++) { y[offsety] = fn(x[offsetx]); offsetx += incx; offsety += incy; } }); return(result); }
public static Real Min(this Array <Real> a) { Real result = Real.PositiveInfinity; Array_.ElementwiseOp(0, a, 0, (n, x, offsetx, incx) => { Real s = Real.PositiveInfinity; for (int i = 0; i < n; i++) { s = Math.Min(s, x[offsetx]); offsetx += incx; } result = Math.Min(result, s); }); return(result); }
public static Array <Real> Equal(this Array <Real> a, Real b, Array <Real> result = null) { if (result == null) { result = new Array <Real>(a.Shape); } Array_.ElementwiseOp(a, result, (n, x, offsetx, incx, z, offsetz, incz) => { for (int i = 0; i < n; i++) { z[offsetz] = x[offsetx] == b ? 1 : 0; offsetx += incx; offsetz += incz; } }); return(result); }
public static Array <Int> Copy(this Array <Int> a, Array <Int> result = null) { if (result == null) { result = new Array <Int>(a.Shape); } Array_.ElementwiseOp(result, a, (n, x, offsetx, incx, y, offsety, incy) => { //Blas.copy(n, y, offsety, incy, x, offsetx, incx); for (int i = 0; i < n; i++) { x[offsetx] = y[offsety]; offsetx += incx; offsety += incy; } }); return(result); }
// result = a + alpha * b public static Array <Int> Add(this Array <Int> a, Array <Int> b, Int alpha = 1, Array <Int> result = null) { if (result == a) { return(a.Acc(b, alpha)); } return(Array_.ElementwiseOp(a, b, result, (n, x, offsetx, incx, y, offsety, incy, z, offsetz, incz) => { for (int i = 0; i < n; i++) { z[offsetz] = x[offsetx] + alpha * y[offsety]; offsetx += incx; offsety += incy; offsetz += incz; } })); }
public static int Argmin(this Array <Real> a) { Real min = Real.PositiveInfinity; int pos = -1; Array_.ElementwiseOp(0, a, 0, (n, x, offsetx, incx) => { for (int i = 0; i < n; i++) { if (x[offsetx] < min) { min = x[offsetx]; pos = offsetx; } offsetx += incx; } }); return(pos); }
public static int Argmax(this Array <Int> a, int[] result = null) { Int min = Int.MinValue; int pos = -1; Array_.ElementwiseOp(0, a, 0, (n, x, offsetx, incx) => { for (int i = 0; i < n; i++) { if (x[offsetx] > min) { min = x[offsetx]; pos = offsetx; } offsetx += incx; } }); return(pos); }
public static int[] ArgMin(this Array <Int> a, int[] result = null) { Int min = Int.MaxValue; int pos = -1; Array_.ElementwiseOp(0, a, 0, (n, x, offsetx, incx) => { for (int i = 0; i < n; i++) { if (x[offsetx] < min) { min = x[offsetx]; pos = offsetx; } offsetx += incx; } }); return(a.UnravelIndex(pos, result)); }
public static Array <Real> Div(this Array <Real> a, Array <Real> b, Array <Real> result = null) { return(Array_.ElementwiseOp(a, b, result, (n, x, offsetx, incx, y, offsety, incy, z, offsetz, incz) => { if (incx == 1 && incy == 1 && incz == 1) { Blas.vdiv(n, x, offsetx, y, offsety, z, offsetz); } // TODO: else if (incx == 0) dgemv 1/x // TODO: else if (incy == 0) dgemv 1/y else { for (int i = 0; i < n; i++) { z[offsetz] = x[offsetx] / y[offsety]; offsetx += incx; offsety += incy; offsetz += incz; } } })); }