public static Array <T> Fill <T>(Func <T> f, Array <T> result) { return(Array_.ElementwiseOp(result, (n, r, offR, strideR) => { for (int i = 0; i < n; ++i) { r[offR] = f(); offR += strideR; } })); }
public static Real Norm2(Array <Real> a) { Real result = 0; Array_.ElementwiseOp(0, a, 0, (n, x, offsetx, incx) => { result += Blas.dot(n, x, offsetx, incx, x, offsetx, incx); }); return(result); }
/// <summary> /// Fills the result array using the value from a, and the indexes from selected. /// </summary> /// <typeparam name="T">The type of a content</typeparam> /// <param name="thiz"></param> /// <param name="selected">the result of a ArgMax/ArgMin operation</param> /// <param name="axis"></param> /// <param name="axisSize"></param> /// <param name="keepDims"></param> /// <param name="result"></param> /// <returns></returns> public static Array <T> UnArgmax <T>(this Array <T> thiz, Array <int> selected, int axis, int axisSize, bool keepDims = false, Array <T> result = null) { thiz.AssertOfShape(selected); var dim = thiz.NDim + (keepDims ? 0 : 1); var shape = new int[dim]; if (keepDims) { System.Array.Copy(thiz.Shape, shape, dim); } else { System.Array.Copy(thiz.Shape, 0, shape, 0, axis); System.Array.Copy(thiz.Shape, axis, shape, axis + 1, thiz.NDim - axis); } shape[axis] = axisSize; result = result ?? NN.Zeros <T>(shape); result.AssertOfShape(shape); var resultInc = result.Stride[axis]; // HACK // as result have one more shape than thiz and selected, we have to lie about the number of shapes var resultSlices = new Slice[dim]; for (int i = 0; i < dim; ++i) { resultSlices[i] = Slicer._; } if (!keepDims) { resultSlices[axis] = 0; } else { resultSlices[axis] = Slicer.Upto(1); } var res = result[resultSlices]; Array_.ElementwiseOp(thiz, selected, res, (n, x, offsetx, incx, s, offsetS, incS, r, offsetR, incR) => { for (int i = 0; i < n; ++i) { r[offsetR + resultInc * s[offsetS]] = x[offsetx]; offsetR += incR; offsetS += incS; offsetx += incx; } }); return(result); }
public static Array <R> Apply <T1, T2, T3, T4, R>(this Array <T1> a, Array <T2> b, Array <T3> c, Array <T4> d, Func <T1, T2, T3, T4, R> fn, Array <R> result = null) { return(Array_.ElementwiseOp(a, b, c, d, result, (n, x0, offset0, inc0, x1, offset1, inc1, x2, offset2, inc2, x3, offset3, inc3, x4, offset4, inc4) => { if (n < MIN_SIZE_FOR_PARELLELISM) { for (int i = 0; i < n; i++) { x4[offset4] = fn(x0[offset0], x1[offset1], x2[offset2], x3[offset3]); offset0 += inc0; offset1 += inc1; offset2 += inc2; offset3 += inc3; offset4 += inc4; } } else { var threads = Blas.NThreads; Parallel.For(0, threads, t => { var end = (n - 1) / threads + 1; var off0 = offset0 + t * end * inc0; var off1 = offset1 + t * end * inc1; var off2 = offset2 + t * end * inc2; var off3 = offset3 + t * end * inc3; var off4 = offset4 + t * end * inc4; if (t == threads - 1) { end = n - t * end; } for (int i = 0; i < end; i++) { x4[off4] = fn(x0[off0], x1[off1], x2[off2], x3[off3]); off0 += inc0; off1 += inc1; off2 += inc2; off3 += inc3; off4 += inc4; } }); } })); }
/// <summary> /// Implementations of squared Euclidean distance that doesn't create intermediary array (unlike NN.Norm(a - b)). /// Faster for small arrays, longer for really big arrays /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static Real EuclideanDistance2(Array <Real> a, Array <Real> b) { Real result = 0; Array_.ElementwiseOp(a, b, (n, x, offx, incx, y, offy, incy) => { for (int _ = 0; _ < n; ++_) { var d = x[offx] - y[offy]; result += d * d; offx += incx; offy += incy; } }); return(result); }
public static Array <R> Apply <T1, R>(this Array <T1> a, Func <T1, R> fn, Array <R> result = null) { if (result == null) { result = new Array <R>(a.Shape); } Array_.ElementwiseOp(a, result, (n, x0, offset0, inc0, x1, offset1, inc1) => { if (n < MIN_SIZE_FOR_PARELLELISM) { for (int i = 0; i < n; i++) { x1[offset1] = fn(x0[offset0]); offset0 += inc0; offset1 += inc1; } } else { var threads = Blas.NThreads; Parallel.For(0, threads, t => { var end = (n - 1) / threads + 1; var off0 = offset0 + t * end * inc0; var off1 = offset1 + t * end * inc0; if (t == threads - 1) { end = n - t * end; } for (int i = 0; i < end; i++) { x1[off1] = fn(x0[off0]); off0 += inc0; off1 += inc1; } }); } }); return(result); }
public static Array <R> Apply <T1, T2, R>(Array <T1> a, Array <T2> b, Func <T1, T2, R> fn, Array <R> result = null) { return(Array_.ElementwiseOp(a, b, result, (n, x0, offset0, inc0, x1, offset1, inc1, x2, offset2, inc2) => { if (n < MIN_SIZE_FOR_PARELLELISM) { for (int i = 0; i < n; i++) { x2[offset2] = fn(x0[offset0], x1[offset1]); offset0 += inc0; offset1 += inc1; offset2 += inc2; } } else { var threads = Blas.NThreads; Parallel.For(0, threads, t => { var end = (n - 1) / threads + 1; var off0 = offset0 + t * end * inc0; var off1 = offset1 + t * end * inc1; var off2 = offset2 + t * end * inc2; if (t == threads - 1) { end = n - t * end; } for (int i = 0; i < end; i++) { x2[off2] = fn(x0[off0], x1[off1]); off0 += inc0; off1 += inc1; off2 += inc2; } }); } })); }
public static Array <Real> Norm2(Array <Real> a, int axis, Array <Real> result = null) { if (axis < 0) { axis = a.Shape.Length + axis; } if (result == null) { result = Zeros <Real>(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) => { y[offy] = Blas.dot(n, x, offx, incx, x, offx, incx); }, axis); return(result); }