コード例 #1
0
        /// <summary>
        /// See <see cref="IMatrixView.Axpy(IMatrixView, double)"/>.
        /// </summary>
        public IMatrix Axpy(IMatrixView otherMatrix, double otherCoefficient)
        {
            if (otherMatrix is CsrMatrix otherCSR) // In case both matrices have the exact same index arrays
            {
                if (HasSameIndexer(otherCSR))
                {
                    // Do not copy the index arrays, since they are already spread around. TODO: is this a good idea?
                    double[] resultValues = new double[values.Length];
                    Array.Copy(this.values, resultValues, values.Length);
                    Blas.Daxpy(values.Length, otherCoefficient, otherCSR.values, 0, 1, resultValues, 0, 1);
                    return(new CsrMatrix(NumRows, NumColumns, resultValues, this.colIndices, this.rowOffsets));
                }
            }

            // All entries must be processed. TODO: optimizations may be possible (e.g. only access the nnz in this matrix)
            return(DenseStrategies.LinearCombination(this, 1.0, otherMatrix, otherCoefficient));
        }
コード例 #2
0
        /// <summary>
        /// The basic Combine version
        /// result = alpha * (T . x) . y + beta * result
        /// </summary>
        public static Array <Real> Combine21(this Array <Real> t, Array <Real> x, Array <Real> y, Array <Real> result = null, Real alpha = 1, Real beta = 0)
        {
            if (t.Shape[2] != x.Shape[0] && t.Shape[1] != y.Shape[0])
            {
                throw new ArgumentException();
            }
            if (t.Stride[2] != 1)
            {
                throw new NotImplementedException();
            }

            int offsetT = t.Offset;

            if (result == null)
            {
                result = new Array <Real>(t.Shape[0]);
            }
            else
            {
                result.Scale(beta, result: result);
            }

            int offsetRes = result.Offset;
            int strideRes = result.Stride[0];

            int offsetX = x.Offset;
            int strideX = x.Stride[0];

            int strideJ = y.Stride[0];
            int J       = y.Shape[0] * strideJ + y.Offset;

            for (int j = y.Offset; j < J; j += strideJ)
            {
                // result += alpha * y[j] * (t[:, j, :] . x)
                Blas.gemv(Order.RowMajor, Transpose.NoTrans,
                          t.Shape[0], t.Shape[2],
                          alpha * y.Values[j],
                          t.Values, offsetT, t.Stride[0],
                          x.Values, offsetX, strideX,
                          1,
                          result.Values, offsetRes, strideRes
                          );
                offsetT += t.Stride[1];
            }
            return(result);
        }
コード例 #3
0
ファイル: frmTSE.cs プロジェクト: MikeG621/TieSoundEditor
        private void vocToWav(Stream s)
        {
            BinaryWriter bw   = new BinaryWriter(s);
            Blas         blas = _currentBlas;

            // WAV_HEADER
            bw.Write("RIFF".ToCharArray());
            s.Position += 4;                                            // skip over, come back to later, P = 4  (file.length-8)
            bw.Write("WAVE".ToCharArray());
            // WAV_DATA_BLOCK
            // fmt_HEADER
            bw.Write("fmt ".ToCharArray());
            bw.Write((uint)16);                                         // fmt block length
            // fmt_DATA_BLOCK
            bw.Write((short)1);                                         // uncompressed PCM
            bw.Write((short)1);                                         // NumChannels (Mono)
            bw.Write((uint)blas.Frequency);                             // SampleRate
            bw.Write((uint)blas.Frequency);                             // ByteRate (SampleRate * NumChannels * BitsPerSample/8) [SR * 1 * 8/8]
            bw.Write((short)1);                                         // BlockAlign (NumChannels * BitsPerSample/8) [1 * 8/8]
            bw.Write((short)8);                                         // BitsPerSample
            // data_HEADER
            bw.Write("data".ToCharArray());
            s.Position += 4;                                            // skip over, come back to later, P = 40 (file.length-44);
            foreach (Blas.SoundDataBlock sdb in blas.SoundBlocks)
            {
                if (sdb.Data != null)
                {
                    if (sdb.DoesRepeat)
                    {
                        for (int i = 0; i < (sdb.NumberOfRepeats != -1 ? sdb.NumberOfRepeats + 1 : 4); i++)                             // repeat 4 times for infinite repeats
                        {
                            bw.Write(sdb.Data);
                        }
                    }
                    else
                    {
                        bw.Write(sdb.Data);
                    }
                }
            }
            s.SetLength(s.Position);
            s.Position = 4;
            bw.Write((uint)(s.Length - 8));
            s.Position = 40;
            bw.Write((uint)(s.Length - 44));
        }
コード例 #4
0
ファイル: CPHDist.cs プロジェクト: parkclub/SRATS2017
        public CPHDist(int ndim, GetParamVec alphaFunc, GetParamVec rateFunc,
                       GetParam lambdaFunc, GetParamVec scaledRateFunc, double epsi)
        {
            this.ndim       = ndim;
            this.alphaFunc  = alphaFunc;
            this.rateFunc   = rateFunc;
            this.lambdaFunc = lambdaFunc;
            this.epsi       = epsi;

            cache_x = new double[ndim];
            cache_t = 0.0;
            Blas.Dcopy(ndim, Alpha, cache_x);

            max_right = 10;
            prob      = new double[max_right + 1];
            unif      = new CPHUniformization(ndim, lambdaFunc, scaledRateFunc);
        }
コード例 #5
0
        public void CopyTo(IModelParam p)
        {
            CPHParam v = p as CPHParam;

            if (ndim == v.ndim)
            {
                v.omega  = omega;
                v.lambda = lambda;
                Blas.Dcopy(ndim, alpha, v.alpha);
                Blas.Dcopy(ndim, rate, v.rate);
                Blas.Dcopy(ndim, scaledRate, v.scaledRate);
            }
            else
            {
                throw new InvalidCastException();
            }
        }
コード例 #6
0
 /// <summary>
 /// See <see cref="IVector.LinearCombinationIntoThis(double, IVectorView, double)"/>
 /// </summary>
 public void LinearCombinationIntoThis(double thisCoefficient, IVectorView otherVector, double otherCoefficient)
 {
     Preconditions.CheckVectorDimensions(this, otherVector);
     if ((otherVector is SparseVector otherSparse) && HasSameIndexer(otherSparse))
     {
         if (thisCoefficient == 1.0)
         {
             Blas.Daxpy(values.Length, otherCoefficient, otherSparse.values, 0, 1, this.values, 0, 1);
         }
         else
         {
             BlasExtensions.Daxpby(values.Length, otherCoefficient, otherSparse.values, 0, 1,
                                   thisCoefficient, this.values, 0, 1);
         }
     }
     throw new SparsityPatternModifiedException(
               "This operation is legal only if the other vector has the same sparsity pattern");
 }
コード例 #7
0
        /// <summary>
        /// See <see cref="IVector.CopySubvectorFrom(int, IVectorView, int, int)"/>.
        /// </summary>
        public void AxpySubvectorIntoThis(int destinationIndex, IVectorView sourceVector, double sourceCoefficient,
                                          int sourceIndex, int length)
        {
            Preconditions.CheckSubvectorDimensions(this, destinationIndex, length);
            Preconditions.CheckSubvectorDimensions(sourceVector, sourceIndex, length);

            if (sourceVector is Vector casted)
            {
                Blas.Daxpy(Length, sourceCoefficient, casted.data, sourceIndex, 1, this.data, destinationIndex, 1);
            }
            else
            {
                for (int i = 0; i < length; ++i)
                {
                    data[i + destinationIndex] += sourceCoefficient * sourceVector[i + sourceIndex];
                }
            }
        }
コード例 #8
0
ファイル: CPHDist.cs プロジェクト: parkclub/SRATS2017
        private void CalcProb(double t)
        {
            double dt;

            if (t < cache_t)
            {
                dt = t;
                Blas.Dcopy(ndim, Alpha, cache_x);
            }
            else
            {
                dt = t - cache_t;
            }
            int right = AllocProb(dt);

            unif.DoForward(dt, cache_x, right, prob);
            cache_t = t;
        }
コード例 #9
0
        /// <summary>
        /// A modified Combine version.
        /// result = alpha * z . (y . T) + beta * result
        /// </summary>
        /// <param name="t">The tensor used to combine y and z: t.Shape = [k, j, i]</param>
        /// <param name="y">A vector: y.Shape = [j]</param>
        /// <param name="z">A vector: z.Shape = [k]</param>
        /// <param name="result">A vector: result.Shape = [i], if null, will be created.</param>
        /// <returns>Returns result.</returns>
        public static Array <Real> Combine10(this Array <Real> t, Array <Real> y, Array <Real> z, Array <Real> result = null, Real alpha = 1, Real beta = 0)
        {
            if (t.Shape.Length != 3 && y.Shape.Length != 1 && z.Shape.Length != 1)
            {
                throw new ArgumentException();
            }
            if (t.Shape[1] != y.Shape[0] && t.Shape[0] != z.Shape[0])
            {
                throw new ArgumentException();
            }
            if (t.Stride[2] != 1)
            {
                throw new NotImplementedException();
            }

            if (result == null)
            {
                result = new Array <Real>(t.Shape[2]);
            }
            else
            {
                result.Scale(beta, result: result);
            }

            int strideK = z.Stride[0];
            int K       = z.Shape[0] * strideK + z.Offset;

            int strideT = t.Stride[0];
            int offsetT = t.Offset;

            for (int k = z.Offset; k < K; k += strideK)
            {
                // result += alpha * z[k] * (y . t[k, :, :])
                Blas.gemv(Order.RowMajor, Transpose.Trans, t.Shape[1], t.Shape[2],
                          alpha * z.Values[k],
                          t.Values, offsetT, t.Stride[1],
                          y.Values, y.Offset, y.Stride[0],
                          1,
                          result.Values, result.Offset, result.Stride[0]);
                offsetT += t.Stride[0];
            }

            return(result);
        }
コード例 #10
0
ファイル: SRMParams.cs プロジェクト: parkclub/SRATS2017
 public string ToString(params string[] format)
 {
     if (format.Length == 0)
     {
         return(Blas.ArrayToString(param, "G", ","));
     }
     else if (format.Length == 1)
     {
         return(Blas.ArrayToString(param, format[0], ","));
     }
     else if (format.Length == param.Length)
     {
         return(Blas.ArrayToString(param, format, ","));
     }
     else
     {
         throw new FormatException();
     }
 }
コード例 #11
0
        /// <summary>
        /// See <see cref="IVectorView.DotProduct(IVectorView)"/>.
        /// </summary>
        public double DotProduct(IVectorView vector)
        {
            Preconditions.CheckVectorDimensions(this, vector);

            if (vector is Vector dense)
            {
                return(SparseBlas.Ddoti(values.Length, values, indices, 0, dense.RawData, 0));
            }
            else if ((vector is SparseVector sparse) && HasSameIndexer(sparse))
            {
                return(Blas.Ddot(values.Length, this.values, 0, 1, sparse.values, 0, 1));
            }

            double sum = 0;

            for (int i = 0; i < values.Length; ++i)
            {
                sum += values[i] * vector[indices[i]];
            }
            return(sum);
        }
コード例 #12
0
        //public void print()
        //{
        //	Console.Write(omega);
        //	Console.Write(" | ");
        //	Console.Write(Blas.intToString(shape));
        //	Console.Write(" | ");
        //	Console.Write(Blas.doubleToString(alpha));
        //	Console.Write(" | ");
        //	Console.Write(Blas.doubleToString(rate));
        //}

        public string ToString(params string[] format)
        {
            string fomega;
            string falpha;
            string fshape;
            string frate;

            if (format.Length == 0)
            {
                fomega = "G";
                falpha = "G";
                fshape = "G";
                frate  = "G";
            }
            else if (format.Length == 1)
            {
                fomega = format[0];
                falpha = format[0];
                fshape = format[0];
                frate  = format[0];
            }
            else if (format.Length == 4)
            {
                fomega = format[0];
                falpha = format[1];
                fshape = format[2];
                frate  = format[3];
            }
            else
            {
                throw new FormatException();
            }

            string[] s = new string[4];
            s[0] = omega.ToString(fomega);
            s[1] = Blas.ArrayToString(alpha, falpha, ",");
            s[2] = Blas.ArrayToString(shape, fshape, ",");
            s[3] = Blas.ArrayToString(rate, frate, ",");
            return(string.Join(" | ", s));
        }
コード例 #13
0
 /// <summary>
 /// Performs the following operation for 0 &lt;= j &lt; <see cref="Order"/>, 0 &lt;= i &lt;= j:
 /// result[i, j] = <paramref name="thisCoefficient"/> * this[i, j]
 ///     + <paramref name="otherCoefficient"/> * <paramref name="otherMatrix"/>[i, j].
 /// The resulting matrix is written to a new <see cref="TriangularUpper"/> and then returned.
 /// </summary>
 /// <param name="thisCoefficient">A scalar that multiplies each entry of this <see cref="TriangularUpper"/>.</param>
 /// <param name="otherMatrix">A matrix with the same <see cref="Order"/> as this <see cref="TriangularUpper"/>
 ///     instance.</param>
 /// <param name="otherCoefficient">A scalar that multiplies each entry of <paramref name="otherMatrix"/>.</param>
 /// <exception cref="NonMatchingDimensionsException">Thrown if <paramref name="otherMatrix"/> has different
 ///     <see cref="Order"/> than this instance.</exception>
 public TriangularUpper LinearCombination(double thisCoefficient, TriangularUpper otherMatrix, double otherCoefficient)
 {
     Preconditions.CheckSameMatrixDimensions(this, otherMatrix);
     //TODO: Perhaps this should be done using mkl_malloc and BLAS copy.
     double[] result = new double[data.Length];
     if (thisCoefficient == 1.0)
     {
         Array.Copy(this.data, result, data.Length);
         Blas.Daxpy(data.Length, otherCoefficient, otherMatrix.data, 0, 1, result, 0, 1);
     }
     else if (otherCoefficient == 1.0)
     {
         Array.Copy(otherMatrix.data, result, data.Length);
         Blas.Daxpy(data.Length, thisCoefficient, this.data, 0, 1, result, 0, 1);
     }
     else
     {
         Array.Copy(this.data, result, data.Length);
         BlasExtensions.Daxpby(data.Length, otherCoefficient, otherMatrix.data, 0, 1, thisCoefficient, result, 0, 1);
     }
     return(new TriangularUpper(result, NumColumns));
 }
コード例 #14
0
 public SymmetricMatrix LinearCombination(double thisCoefficient, SymmetricMatrix otherMatrix, double otherCoefficient)
 {
     Preconditions.CheckSameMatrixDimensions(this, otherMatrix);
     //TODO: Perhaps this should be done using mkl_malloc and BLAS copy.
     double[] result = new double[data.Length];
     if (thisCoefficient == 1.0)
     {
         Array.Copy(this.data, result, data.Length);
         Blas.Daxpy(data.Length, otherCoefficient, otherMatrix.data, 0, 1, result, 0, 1);
     }
     else if (otherCoefficient == 1.0)
     {
         Array.Copy(otherMatrix.data, result, data.Length);
         Blas.Daxpy(data.Length, thisCoefficient, this.data, 0, 1, result, 0, 1);
     }
     else
     {
         Array.Copy(this.data, result, data.Length);
         BlasExtensions.Daxpby(data.Length, otherCoefficient, otherMatrix.data, 0, 1, thisCoefficient, result, 0, 1);
     }
     return(new SymmetricMatrix(result, NumColumns, DefiniteProperty.Unknown));
 }
コード例 #15
0
 /// <summary>
 /// Performs the following operation for 0 &lt;= i &lt; this.<see cref="Length"/>:
 /// result[i] = <paramref name="thisCoefficient"/> * this[i] + <paramref name="otherCoefficient"/> *
 /// <paramref name="otherVector"/>[i]. The resulting vector is written to a new <see cref="Vector"/> and then returned.
 /// </summary>
 /// <param name="thisCoefficient">A scalar that multiplies each entry of this <see cref="Vector"/>.</param>
 /// <param name="otherVector">A vector with the same <see cref="Length"/> as this <see cref="Vector"/> instance.</param>
 /// <param name="otherCoefficient">A scalar that multiplies each entry of <paramref name="otherVector"/>.</param>
 /// <exception cref="NonMatchingDimensionsException">Thrown if <paramref name="otherVector"/> has different
 ///     <see cref="Length"/> than this.</exception>
 public Vector LinearCombination(double thisCoefficient, Vector otherVector, double otherCoefficient)
 {
     Preconditions.CheckVectorDimensions(this, otherVector);
     //TODO: Perhaps this should be done using mkl_malloc and BLAS copy.
     double[] result = new double[data.Length];
     if (thisCoefficient == 1.0)
     {
         Array.Copy(data, result, data.Length);
         Blas.Daxpy(Length, otherCoefficient, otherVector.data, 0, 1, result, 0, 1);
     }
     else if (otherCoefficient == 1.0)
     {
         Array.Copy(otherVector.data, result, data.Length);
         Blas.Daxpy(data.Length, thisCoefficient, this.data, 0, 1, result, 0, 1);
     }
     else
     {
         Array.Copy(data, result, data.Length);
         BlasExtensions.Daxpby(Length, otherCoefficient, otherVector.data, 0, 1, thisCoefficient, result, 0, 1);
     }
     return(new Vector(result));
 }
コード例 #16
0
        /// <summary>
        /// See <see cref="IVector.AxpySubvectorIntoThis(int, IVectorView, double, int, int)"/>.
        /// </summary>
        public void AxpySubvectorIntoThis(int destinationIndex, IVectorView sourceVector, double sourceCoefficient,
                                          int sourceIndex, int length)
        {
            //TODO: needs testing for off-by-1 bugs and extension to cases where source and destination indices are different.

            Preconditions.CheckSubvectorDimensions(this, destinationIndex, length);
            Preconditions.CheckSubvectorDimensions(sourceVector, sourceIndex, length);

            if ((sourceVector is SparseVector otherSparse) && HasSameIndexer(otherSparse))
            {
                if (destinationIndex != sourceIndex)
                {
                    throw new NotImplementedException();
                }
                int start        = Array.FindIndex(this.indices, x => x >= destinationIndex);
                int end          = Array.FindIndex(this.indices, x => x >= destinationIndex + length);
                int sparseLength = end - start;
                Blas.Daxpy(sparseLength, sourceCoefficient, otherSparse.values, start, 1, this.values, start, 1);
            }
            throw new SparsityPatternModifiedException(
                      "This operation is legal only if the other vector has the same sparsity pattern");
        }
コード例 #17
0
        /// <summary>
        /// Solve the linear least squares problem A * x = b => x = inv(R) * transpose(Q) * b.
        /// Warning: the columns of the original matrix A must be independent for this to work.
        /// </summary>
        /// <param name="rhsVector">The right hand side vector b. It may lie outside the column space of the original matrix. Its
        ///     <see cref="IIndexable1D.Length"/> must be equal to this.<see cref="NumRows"/>.</param>
        /// <exception cref="Exceptions.LapackException">Thrown if the call to LAPACK fails due to <paramref name="rhsVector"/>
        ///     having a different <see cref="IIndexable1D.Length"/> than this.<see cref="NumRows"/>.</exception>
        public Vector SolveLeastSquares(Vector rhsVector) //TODO: perhaps I should use the driver routines of LAPACKE
        {
            if (NumRows < NumColumns)
            {
                throw new NotImplementedException("For now, the number of rows must be >= the number of columns");
            }
            Preconditions.CheckSystemSolutionDimensions(NumRows, rhsVector.Length);

            // Least squares: x = inv(A^T * A) * A^T * b = inv(R) * Q^T * b, where b is the right hand side vector.
            // Step 1: c = Q^T * b. Q is m-by-m, b is m-by-1 => c is m-by-1
            double[] c             = rhsVector.CopyToArray();
            int      numRowsC      = rhsVector.Length;
            int      numColsC      = 1; // rhs = m-by-1
            int      numReflectors = reflectorScalars.Length;
            int      leadingDimA   = numRowsC;
            int      leadingDimC   = numRowsC;

            LapackLeastSquares.Dormqr(MultiplicationSide.Left, TransposeMatrix.Transpose, numRowsC, numColsC, numReflectors,
                                      reflectorsAndR, 0, leadingDimA, reflectorScalars, 0, c, 0, leadingDimC);

            // Step 2: R * x = c, with R being m-by-n and upper trapezoidal (because m >= n).
            // Decomposing R: [R1; 0] * x = [c1 ; c2 ] => R1 * x = c1 => R1 * x = c1, with R1 being n-by-n, upper triangular
            // and stored in the factorized col major data. c1 and x are both n-by-1. The information stored in c2 is lost due to
            // the least squares approximation.
            // TODO: I do not really need to discard the extra m-n terms of c2, but I think it is unsafe to carry them around and
            // risk some method of Vector using the length of the internal buffer, instead of its Length propert.
            if (NumRows > NumColumns)
            {
                Array.Resize <double>(ref c, NumColumns);
            }
            int n    = NumColumns; // Order of matrix R1
            int ldR  = NumRows;    // R1 is stored in the upper trapezoid of a NumRows * NumColumns col major array.
            int incC = 1;          // step in rhs array, which is the same c used for Q^T * b

            Blas.Dtrsv(StoredTriangle.Upper, TransposeMatrix.NoTranspose, DiagonalValues.NonUnit,
                       n, reflectorsAndR, 0, ldR, c, 0, incC);
            // TODO: Check output of BLAS somehow. E.g. Zero diagonal entries will result in NaN in the result vector.
            return(Vector.CreateFromArray(c, false));
        }
コード例 #18
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);
        }
コード例 #19
0
ファイル: CiFar.cs プロジェクト: garykhollingshead/YoloV2
        private static void test_cifar_multi(string filename, string weightfile)
        {
            Network net = Parser.parse_network_cfg(filename);

            if (string.IsNullOrEmpty(weightfile))
            {
                Parser.load_weights(net, weightfile);
            }
            Network.set_batch_network(net, 1);


            float avgAcc = 0;

            Data.Data test = Data.Data.load_cifar10_data("Data.Data/cifar/cifar-10-batches-bin/test_batch.bin");

            int i;

            for (i = 0; i < test.X.Rows; ++i)
            {
                Image im = new Image(32, 32, 3, test.X.Vals[i]);

                float[] pred = new float[10];

                float[] p = Network.network_predict(net, im.Data);
                Blas.Axpy_cpu(10, 1, p, pred);
                LoadArgs.flip_image(im);
                p = Network.network_predict(net, im.Data);
                Blas.Axpy_cpu(10, 1, p, pred);

                int index  = Utils.max_index(pred, 10);
                int sclass = Utils.max_index(test.Y.Vals[i], 10);
                if (index == sclass)
                {
                    avgAcc += 1;
                }
                Console.Write($"%4d: %.2f%%\n", i, 100f * avgAcc / (i + 1));
            }
        }
コード例 #20
0
 /// <summary>
 /// Compute the outer product of two vectors: result[i, j] = alpha * a[i] * b[j] + beta * result[i, j]
 /// </summary>
 /// <param name="a"></param>
 /// <param name="b"></param>
 /// <param name="result"></param>
 /// <param name="alpha"></param>
 /// <param name="beta"></param>
 /// <returns></returns>
 public static Array <Real> Outer(this Array <Real> a, Array <Real> b, Array <Real> result = null, Real alpha = 1, Real beta = 0)
 {
     if (a.Shape.Length != 1 && (a.Shape.Length != 2 || a.Shape[1] != 1))
     {
         a = a.Reshape(a.Size);
     }
     if (b.Shape.Length != 1 && (b.Shape.Length != 2 || b.Shape[1] != 1))
     {
         b = b.Reshape(b.Size);
     }
     if (result == null)
     {
         result = new Array <Real>(a.Shape[0], b.Shape[0]);
     }
     else
     {
         if (result.Shape.Length != 2)
         {
             throw new RankException("objects are not aligned");
         }
         if (result.Shape[0] != a.Shape[0])
         {
             throw new RankException("objects are not aligned");
         }
         if (result.Shape[1] != b.Shape[0])
         {
             throw new RankException("objects are not aligned");
         }
         // TODO: check strides ?
     }
     Blas.gemm(Order.RowMajor, Transpose.NoTrans, Transpose.Trans, result.Shape[0], result.Shape[1], 1,
               alpha,
               a.Values, a.Offset, a.Stride[0],
               b.Values, b.Offset, b.Stride[0],
               beta,
               result.Values, result.Offset, result.Stride[0]);
     return(result);
 }
コード例 #21
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;
             }
         }
     }));
 }
コード例 #22
0
 /// <summary>
 /// See <see cref="IVectorView.Axpy(IVectorView, double)"/>.
 /// </summary>
 public IVector Axpy(IVectorView otherVector, double otherCoefficient)
 {
     Preconditions.CheckVectorDimensions(this, otherVector);
     if (otherVector is SparseVector otherSparse) // In case both matrices have the exact same index arrays
     {
         if (HasSameIndexer(otherSparse))
         {
             // Do not copy the index arrays, since they are already spread around. TODO: is this a good idea?
             double[] result = new double[this.values.Length];
             Array.Copy(this.values, result, this.values.Length);
             Blas.Daxpy(values.Length, otherCoefficient, otherSparse.values, 0, 1, result, 0, 1);
             return(new SparseVector(Length, result, indices));
         }
     }
     else if (otherVector is Vector otherDense)
     {
         double[] result = otherDense.Scale(otherCoefficient).RawData;
         SparseBlas.Daxpyi(this.indices.Length, 1.0, this.values, this.indices, 0, result, 0);
         return(Vector.CreateFromArray(result, false));
     }
     // All entries must be processed. TODO: optimizations may be possible (e.g. only access the nnz in this vector)
     return(DenseStrategies.LinearCombination(this, 1.0, otherVector, otherCoefficient));
 }
コード例 #23
0
        // markov operation
        public void DoBackward(double t, double[] x, int right, double[] prob)
        {
            //int right;
            //if (t > maxt)
            //{
            //	right = setMaxT(t);
            //}
            //else
            //{
            //	right = PoiDist.getRightBound(lambda * t, epsi);
            //}
            double weight = PoiDist.CompProb(Lambda * t, 0, right, prob);

            Blas.Dcopy(ndim, x, xi);
            Blas.Fill(ndim, x, 0.0);
            Blas.Daxpy(ndim, prob[0], xi, x);
            for (int l = 1; l <= right; l++)
            {
                Blas.Dcopy(ndim, xi, tmp);
                DgemvNoTrans(1.0, tmp, 0.0, xi);
                Blas.Daxpy(ndim, prob[l], xi, x);
            }
            Blas.Dscal(ndim, 1.0 / weight, x);
        }
コード例 #24
0
        public void DoSojournForward(double t, double[] f, double[] b, double[] h, int right, double[] prob, double[][] vc)
        {
            //int right;
            //if (t > maxt)
            //{
            //	right = setMaxT(t);
            //}
            //else
            //{
            //	right = PoiDist.getRightBound(lambda * t, epsi);
            //}
            double weight = PoiDist.CompProb(Lambda * t, 0, right + 1, prob);

            // forward and backward
            Blas.Fill(ndim, vc[right + 1], 0.0);
            Blas.Daxpy(ndim, prob[right + 1], b, vc[right + 1]);
            for (int l = right; l >= 1; l--)
            {
                DgemvNoTrans(1.0, vc[l + 1], 0.0, vc[l]);
                Blas.Daxpy(ndim, prob[l], b, vc[l]);
            }
            Blas.Dcopy(ndim, f, xi);
            Blas.Fill(ndim, f, 0.0);
            Blas.Daxpy(ndim, prob[0], xi, f);
            Blas.Fill(ndim * 2, h, 0.0);
            Dger(1.0, xi, vc[1], h);
            for (int l = 1; l <= right; l++)
            {
                Blas.Dcopy(ndim, xi, tmp);
                DgemvTrans(1.0, tmp, 0.0, xi);
                Blas.Daxpy(ndim, prob[l], xi, f);
                Dger(1.0, xi, vc[l + 1], h);
            }
            Blas.Dscal(ndim, 1.0 / weight, f);
            Blas.Dscal(ndim * 2, 1.0 / Lambda / weight, h);
        }
コード例 #25
0
 /// <summary>
 /// See <see cref="IVectorView.Norm2"/>
 /// </summary>
 public double Norm2() => Blas.Dnrm2(Length, data, 0, 1);
コード例 #26
0
 public void AxpyIntoThis(SymmetricMatrix otherMatrix, double otherCoefficient)
 {
     Preconditions.CheckSameMatrixDimensions(this, otherMatrix);
     Blas.Daxpy(data.Length, otherCoefficient, otherMatrix.data, 0, 1, this.data, 0, 1);
     this.Definiteness = DefiniteProperty.Unknown;
 }
コード例 #27
0
 /// <summary>
 /// Calculates the dot (or inner/scalar) product of this vector with <paramref name="vector"/>:
 /// result = sum over all i of this[i] * <paramref name="vector"/>[i]).
 /// </summary>
 /// <param name="vector">A vector with the same <see cref="Length"/> as this.</param>
 public double DotProduct(Vector vector)
 {
     Preconditions.CheckVectorDimensions(this, vector);
     return(Blas.Ddot(Length, this.data, 0, 1, vector.data, 0, 1));
 }
コード例 #28
0
        /// <summary>
        /// Matrix multiplication.
        /// Returns: alpha * dot(a, b) + beta * result
        /// Ie with default value: dot(a, b)
        /// </summary>
        /// <remarks>
        /// For 2-D arrays it is equivalent to matrix multiplication,
        /// and for 1-D arrays to inner product of vectors (without complex conjugation).
        /// For N dimensions it is a sum product over the last axis of a and the second-to-last of b:
        /// dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])
        /// `TensorDot` provides more control for N-dim array multiplication.
        /// </remarks>
        public static Array <Real> Dot(this Array <Real> a, Array <Real> b, Array <Real> result = null, Real alpha = 1, Real beta = 0, bool transA = false, bool transB = false)
        {
            if (transA)
            {
                if (a.Shape.Length == 1)
                {
                    if (b.Shape.Length == 1)
                    {
                        if (transB)
                        {
                            return(a.Dot(b, result, alpha, beta));
                        }
                        else
                        {
                            return(a.VectorDot(b));
                        }
                    }
                    if (b.Shape.Length != 2)
                    {
                        throw new NotImplementedException();
                    }
                    return(b.Dot(a, result, alpha, beta, transA: !transB, transB: false));
                }
                else
                {
                    a = a.T;    // TODO: optimize => avoid creating new shape, stride, ...
                    //if (b.Shape.Length == 1 && !transB) b = b.Reshape(1, b.Shape[0]);
                }
                transA = false;
            }

            if (transB)
            {
                if (b.Shape.Length == 1)
                {
                    if (a.Shape.Length == 1)
                    {
                        if (transA)
                        {
                            throw new NotImplementedException();
                        }
                        return(a.Outer(b, result: result, alpha: alpha, beta: 0));
                    }
                    throw new NotImplementedException();
                    //if (a.Shape.Length != 2) throw new NotImplementedException();
                    //if (a.IsTransposed())
                    //{
                    //    a = a.T;
                    //    transA = !transA;
                    //}
                    //result = new Array<Real>(transA ? a.Shape[1] : a.Shape[0], b.Shape[0]);   // TODO: result != null
                    //Blas.gemm(Order.RowMajor, transA ? Transpose.Trans : Transpose.NoTrans, Transpose.NoTrans,
                    //    result.Shape[0], result.Shape[1], 1,
                    //    alpha,
                    //    a.Values, a.Offset, a.Stride[0],
                    //    b.Values, b.Offset, b.Stride[0],
                    //    beta,
                    //    result.Values, result.Offset, result.Stride[0]);
                    //return result;
                }
                else
                {
                    b = b.T;    // TODO: optimize => avoid creating new shape, stride, ...
                }
                transB = false;
            }

            // TODO: check alpha & beta
            if (a.Shape.Length == 0)
            {
                return(b.Scale(a.Values[a.Offset]));
            }
            if (b.Shape.Length == 0)
            {
                return(a.Scale(b.Values[b.Offset]));
            }
            if (a.Shape.Length == 1)     // vector x tensor
            {
                if (b.Shape.Length == 1) // vector x vector
                {
                    if (a.Shape[0] != b.Shape[0])
                    {
                        throw AssertArray.BadRank("objects are not aligned: [{0}] dot [{1}]", a.Shape[0], b.Shape[0]);
                    }
                    if (result == null)
                    {
                        result = new Array <Real>();
                    }
                    else
                    {
                        if (result.Shape.Length != 0)
                        {
                            throw AssertArray.BadRank("objects are not aligned");
                        }
                    }

                    result.Values[result.Offset] = beta * result.Values[result.Offset] + alpha * Blas.dot(a.Shape[0], a.Values, a.Offset, a.Stride[0], b.Values, b.Offset, b.Stride[0]);
                    return(result);
                }
                else if (b.Shape.Length == 2)   // vector x matrix
                {
                    if (a.Shape[0] != b.Shape[0])
                    {
                        throw new RankException("objects are not aligned");
                    }
                    if (result == null)
                    {
                        result = new Array <Real>(b.Shape[1]);
                    }
                    else
                    {
                        if (result.Shape.Length != 1)
                        {
                            throw new RankException("objects are not aligned");
                        }
                        if (result.Shape[0] != b.Shape[1])
                        {
                            throw new RankException("objects are not aligned");
                        }
                    }

                    // dgemv computes matrix x vector => result = M.T.dot(v.T).T
                    transB = !transB;
                    if (b.IsTransposed())
                    {
                        transB = !transB;
                        b      = b.T;
                    }
                    // y:= alpha * A' * x + beta * y
                    Blas.gemv(Order.RowMajor, transB ? Transpose.Trans : Transpose.NoTrans, b.Shape[0], b.Shape[1], alpha,
                              b.Values, b.Offset, b.Stride[0],
                              a.Values, a.Offset, a.Stride[0],
                              beta,
                              result.Values, result.Offset, result.Stride[0]);
                    return(result);
                }
                else if (b.Shape.Length == 3) // vector x tensor3
                {
                    // TODO: beta ?
                    if (a.Shape[0] != b.Shape[1])
                    {
                        throw new RankException("objects are not aligned");
                    }
                    if (result == null)
                    {
                        result = new Array <Real>(b.Shape[0], b.Shape[2]);
                    }
                    else
                    {
                        if (result.Shape[0] != b.Shape[0])
                        {
                            throw new RankException("objects are not aligned");
                        }
                        if (result.Shape[1] != b.Shape[2])
                        {
                            throw new RankException("objects are not aligned");
                        }
                    }

                    var offsetk = b.Offset;
                    var k_0     = result.Offset;
                    for (var k = 0; k < result.Shape[0]; k++)       // result.Shape[0] == b.Shape[0]
                    {
                        var offsetm = offsetk;
                        var k_m     = k_0;
                        for (var m = 0; m < result.Shape[1]; m++)                                                                               // result.Shape[1] == b.Shape[2]
                        {
                            result.Values[k_m] = alpha * Blas.dot(a.Shape[0], a.Values, a.Offset, a.Stride[0], b.Values, offsetm, b.Stride[1]); // a.Shape[axis] == b.Shape[1];
                            offsetm           += b.Stride[2];
                            k_m += result.Stride[1];
                        }
                        offsetk += b.Stride[0];
                        k_0     += result.Stride[0];
                    }

                    return(result);
                }
                throw new NotImplementedException();
            }
            else if (b.Shape.Length == 1)   // tensor x vector
            {
                if (a.Shape.Length == 2)    // matrix x vector
                {
                    if (a.Shape[1] != b.Shape[0])
                    {
                        throw new RankException("objects are not aligned");
                    }
                    if (result == null)
                    {
                        result = new Array <Real>(a.Shape[0]);
                    }
                    else
                    {
                        if (result.Shape.Length != b.Shape.Length)
                        {
                            throw new RankException("objects are not aligned");
                        }
                        if (result.Shape[0] != a.Shape[0])
                        {
                            throw new RankException("objects are not aligned");
                        }
                        // TODO: check strides
                    }
                    if ((a.Flags & Flags.Transposed) != 0)
                    {
                        transA = !transA;
                        a      = a.T;
                    }
                    // y:= A*x + beta*y
                    if (a.Stride[1] == 1)
                    {
                        Blas.gemv(Order.RowMajor, transA ? Transpose.Trans : Transpose.NoTrans, a.Shape[0], a.Shape[1], alpha,
                                  a.Values, a.Offset, a.Stride[0],
                                  b.Values, b.Offset, b.Stride[0],
                                  beta,
                                  result.Values, result.Offset, result.Stride[0]);
                    }
                    else
                    {
                        // y *= beta
                        if (beta != 1)
                        {
                            result.Scale(beta, result: result);
                        }

                        int offB = b.Offset;
                        int offA = a.Offset;
                        for (int j = 0; j < b.Shape[0]; ++j)
                        {
                            Blas.axpy(a.Shape[0], alpha * b.Values[offB],
                                      a.Values, offA, a.Stride[0],
                                      result.Values, result.Offset, result.Stride[0]);
                            offB += b.Stride[0];
                            offA += a.Stride[1];
                        }
                    }

                    return(result);
                }
                else if (a.Shape.Length == 3)    // tensor x vector = mat
                {
                    if (a.Shape[2] != b.Shape[0])
                    {
                        throw new RankException("objects are not aligned");
                    }
                    if (result == null)
                    {
                        result = new Array <Real>(a.Shape[0], a.Shape[1]);
                    }
                    else if (result.Shape[0] != a.Shape[0] || result.Shape[1] != a.Shape[1])
                    {
                        throw new RankException("objects are not aligned");
                    }

                    var offsetk   = a.Offset;
                    var offsetRes = result.Offset;

                    for (var k = 0; k < result.Shape[0]; k++)
                    {
                        var offsetj = offsetk;
                        for (var j = 0; j < result.Shape[1]; j++)
                        {
                            result.Values[offsetRes] = alpha * Blas.dot(a.Shape[2], a.Values, offsetj, a.Stride[2], b.Values, b.Offset, b.Stride[0]);
                            offsetj   += a.Stride[1];
                            offsetRes += result.Stride[1];
                        }
                        offsetk += a.Stride[0];
                    }
                    return(result);
                }
                throw new NotImplementedException();
            }
            else if (a.Shape.Length == 2 && b.Shape.Length == 2)    // matrix x matrix
            {
                if (a.Shape[1] != b.Shape[0])
                {
                    throw AssertArray.BadRank("objects are not aligned: [{0}, {1}] dot [{2}, {3}]", a.Shape[0], a.Shape[1], b.Shape[0], b.Shape[1]);
                }
                if (result == null)
                {
                    result = new Array <Real>(a.Shape[0], b.Shape[1]);
                }
                else
                {
                    if (result.Shape[0] != a.Shape[0] || result.Shape[1] != b.Shape[1])
                    {
                        throw AssertArray.BadRank("result target have incorrect shape: [{0}, {1}] instead of [{2}, {3}].", result.Shape[0], result.Shape[1], a.Shape[0], b.Shape[1]);
                    }
                    // TODO: check strides
                }
                var m = a.Shape[0];
                var n = b.Shape[1];
                var k = a.Shape[1];
                if ((a.Flags & Flags.Transposed) != 0)
                {
                    transA = !transA;
                    a      = a.T;
                }
                if ((b.Flags & Flags.Transposed) != 0)
                {
                    transB = !transB;
                    b      = b.T;
                }
                // C:= alpha * op(A) * op(B) + beta * C
                Blas.gemm(Order.RowMajor, transA ? Transpose.Trans : Transpose.NoTrans, transB ? Transpose.Trans : Transpose.NoTrans,
                          m, n, k,
                          alpha,
                          a.Values, a.Offset, a.Stride[0],
                          b.Values, b.Offset, b.Stride[0],
                          beta,
                          result.Values, result.Offset, result.Stride[0]);
                return(result);
            }
            // tensor x tensor
            throw new NotImplementedException();
        }
コード例 #29
0
 /// <summary>
 /// Performs the following operation for 0 &lt;= i &lt; this.<see cref="Length"/>:
 /// this[i] = <paramref name="otherCoefficient"/> * <paramref name="otherVector"/>[i] + this[i].
 /// The resulting vector overwrites the entries of this <see cref="Vector"/> instance.
 /// </summary>
 /// <param name="otherVector">A vector with the same <see cref="Length"/> as this <see cref="Vector"/> instance.</param>
 /// <param name="otherCoefficient">A scalar that multiplies each entry of <paramref name="otherVector"/>.</param>
 /// <exception cref="NonMatchingDimensionsException">Thrown if <paramref name="otherVector"/> has different
 ///     <see cref="Length"/> than this.</exception>
 public void AxpyIntoThis(Vector otherVector, double otherCoefficient)
 {
     Preconditions.CheckVectorDimensions(this, otherVector);
     Blas.Daxpy(Length, otherCoefficient, otherVector.data, 0, 1, this.data, 0, 1);
 }
コード例 #30
0
 /// <summary>
 /// See <see cref="IVector.ScaleIntoThis(double)"/>.
 /// </summary>
 public void ScaleIntoThis(double scalar) => Blas.Dscal(Length, scalar, data, 0, 1);