コード例 #1
0
 // 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)
     }));
 }
コード例 #2
0
 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;
             }
         }
     }));
 }
コード例 #3
0
 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);
 }
コード例 #4
0
        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);
        }
コード例 #5
0
        /// <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)));
        }
コード例 #6
0
 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);
 }
コード例 #7
0
 /// <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);
     });
 }
コード例 #8
0
 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;
         }
     }));
 }
コード例 #9
0
 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;
         }
     }));
 }
コード例 #10
0
 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);
 }
コード例 #11
0
 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;
         }
     }));
 }
コード例 #12
0
 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);
 }
コード例 #13
0
        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);
        }
コード例 #14
0
        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);
        }
コード例 #15
0
 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);
 }
コード例 #16
0
        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);
        }
コード例 #17
0
 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);
 }
コード例 #18
0
 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);
 }
コード例 #19
0
        // 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;
                }
            }));
        }
コード例 #20
0
        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);
        }
コード例 #21
0
        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);
        }
コード例 #22
0
        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));
        }
コード例 #23
0
 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;
             }
         }
     }));
 }