Ejemplo n.º 1
0
        public static GenTensor <T, TWrapper> MatrixPower(GenTensor <T, TWrapper> m, int power, Threading threading)
        {
            #if ALLOW_EXCEPTIONS
            if (!m.IsSquareMatrix)
            {
                throw new InvalidShapeException("Square matrix required");
            }
            #endif
            if (power == 0)
            {
                return(Constructors <T, TWrapper> .CreateIdentityMatrix(m.Shape.shape[0]));
            }
            if (power < 0)
            {
                m = m.Forward();
                m.InvertMatrix();
                power *= -1;
            }
            if (power == 1)
            {
                return(m);
            }
            if (power == 2)
            {
                return(MatrixMultiplication <T, TWrapper> .Multiply(m, m, threading));
            }
            var half   = power / 2;
            var m1     = MatrixPower(m, half, threading);
            var dotted = MatrixMultiplication <T, TWrapper> .Multiply(m1, m1, threading);

            if (power % 2 == 0)
            {
                return(dotted);
            }
            else
            {
                return(MatrixMultiplication <T, TWrapper> .Multiply(dotted, m, threading));
            }
        }
 public static GenTensor <T, TWrapper> PiecewiseSubtract(GenTensor <T, TWrapper> a,
                                                         T b, Threading threading)
 => Constructors <T, TWrapper> .CreateTensor(a.Shape, ind =>
                                             default(TWrapper).Subtract(a[ind], b), threading);
 public static GenTensor <T, TWrapper> PiecewiseSubtract(
     T a, GenTensor <T, TWrapper> b, Threading threading)
 => Constructors <T, TWrapper> .CreateTensor(b.Shape, ind =>
                                             default(TWrapper).Subtract(a, b[ind]), threading);
Ejemplo n.º 4
0
        internal static GenTensor <T, TWrapper> Multiply(GenTensor <T, TWrapper> a,
                                                         GenTensor <T, TWrapper> b, Threading threading = Threading.Single)
        {
            #if ALLOW_EXCEPTIONS
            if (!a.IsMatrix || !b.IsMatrix)
            {
                throw new InvalidShapeException($"Both {nameof(a)} and {nameof(b)} should be matrices");
            }
            if (a.Shape[1] != b.Shape[0])
            {
                throw new InvalidShapeException($"{nameof(a)}'s height must be equal to {nameof(b)}'s width");
            }
            #endif

            var width  = a.Shape[0];
            var height = b.Shape[1];
            var row    = a.Shape[1];
            var res    = Constructors <T, TWrapper> .CreateMatrix(width, height);

            var parallel = threading == Threading.Multi || (threading == Threading.Auto && a.Volume > 125);


            var aBlocks0   = a.blocks[0];
            var aBlocks1   = a.blocks[1];
            var bBlocks0   = b.blocks[0];
            var bBlocks1   = b.blocks[1];
            var aLinoffset = a.LinOffset;
            var bLinoffset = b.LinOffset;

            if (!parallel)
            {
                for (int x = 0; x < width; x++)
                {
                    for (int y = 0; y < height; y++)
                    {
                        var s = default(TWrapper).CreateZero();
                        for (int i = 0; i < row; i++)
                        {
                            var v1 = a.data[x * aBlocks0 + i * aBlocks1 + aLinoffset];
                            var v2 = b.data[i * bBlocks0 + y * bBlocks1 + bLinoffset];
                            s = default(TWrapper).Add(s, default(TWrapper).Multiply(v1, v2));
                        }
                        res.data[x * height + y] = s;
                    }
                }
            }
            else
            {
                Parallel.For(0, width, x =>
                {
                    for (int y = 0; y < height; y++)
                    {
                        var s = default(TWrapper).CreateZero();
                        for (int i = 0; i < row; i++)
                        {
                            var v1 = a.data[x * aBlocks0 + i * aBlocks1 + aLinoffset];
                            var v2 = b.data[i * bBlocks0 + y * bBlocks1 + bLinoffset];
                            s      = default(TWrapper).Add(s, default(TWrapper).Multiply(v1, v2));
                        }
                        res.data[x * height + y] = s;
                    }
                });
            }

            return(res);
        }