コード例 #1
0
ファイル: NN.cs プロジェクト: stuarthillary/NumNet
 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;
         }
     }));
 }
コード例 #2
0
        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);
        }
コード例 #3
0
ファイル: NN.cs プロジェクト: stuarthillary/NumNet
        /// <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);
        }
コード例 #4
0
ファイル: NN.cs プロジェクト: stuarthillary/NumNet
        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;
                        }
                    });
                }
            }));
        }
コード例 #5
0
        /// <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);
        }
コード例 #6
0
ファイル: NN.cs プロジェクト: stuarthillary/NumNet
        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);
        }
コード例 #7
0
ファイル: NN.cs プロジェクト: stuarthillary/NumNet
        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;
                        }
                    });
                }
            }));
        }
コード例 #8
0
        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);
        }