Ejemplo n.º 1
0
 /// <summary>
 /// See <see cref="IVector.AxpyIntoThis(IVectorView, double)"/>.
 /// </summary>
 public void AxpyIntoThis(IVectorView otherVector, double otherCoefficient)
 {
     if (otherVector is Vector dense)
     {
         AxpyIntoThis(dense, otherCoefficient);
     }
     else
     {
         Preconditions.CheckVectorDimensions(this, otherVector);
         if (otherVector is SparseVector sparse)
         {
             if (sparse.RawIndices.Length != 0)
             {
                 SparseBlas.Daxpyi(sparse.RawIndices.Length, otherCoefficient, sparse.RawValues,
                                   sparse.RawIndices, 0, data, 0);
             }
         }
         else
         {
             for (int i = 0; i < Length; ++i)
             {
                 this.data[i] += otherCoefficient * otherVector[i];
             }
         }
     }
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Performs the matrix-vector multiplication: <paramref name="rhsVector"/> = oper(this) * <paramref name="vector"/>.
 /// To multiply this * columnVector, set <paramref name="transposeThis"/> to false.
 /// To multiply rowVector * this, set <paramref name="transposeThis"/> to true.
 /// The resulting vector will overwrite the entries of <paramref name="rhsVector"/>.
 /// </summary>
 /// <param name="lhsVector">
 /// The vector that will be multiplied by this matrix. It sits on the left hand side of the equation y = oper(A) * x.
 /// Constraints: <paramref name="lhsVector"/>.<see cref="IIndexable1D.Length"/>
 /// == oper(this).<see cref="IIndexable2D.NumColumns"/>.
 /// </param>
 /// <param name="rhsVector">
 /// The vector that will be overwritten by the result of the multiplication. It sits on the right hand side of the
 /// equation y = oper(A) * x. Constraints: <paramref name="lhsVector"/>.<see cref="IIndexable1D.Length"/>
 /// == oper(this).<see cref="IIndexable2D.NumRows"/>.
 /// </param>
 /// <param name="transposeThis">If true, oper(this) = transpose(this). Otherwise oper(this) = this.</param>
 /// <exception cref="NonMatchingDimensionsException">
 /// Thrown if the <see cref="IIndexable1D.Length"/> of <paramref name="lhsVector"/> or <paramref name="rhsVector"/>
 /// violate the described contraints.
 /// </exception>
 public void MultiplyIntoResult(Vector lhsVector, Vector rhsVector, bool transposeThis = false)
 {
     if (transposeThis)
     {
         Preconditions.CheckMultiplicationDimensions(NumRows, lhsVector.Length);
         Preconditions.CheckSystemSolutionDimensions(NumColumns, rhsVector.Length);
     }
     else
     {
         Preconditions.CheckMultiplicationDimensions(NumColumns, lhsVector.Length);
         Preconditions.CheckSystemSolutionDimensions(NumRows, rhsVector.Length);
     }
     SparseBlas.Dcscgemv(transposeThis, NumRows, NumColumns, values, colOffsets, rowIndices,
                         lhsVector.RawData, 0, rhsVector.RawData, 0);
 }
Ejemplo n.º 3
0
 /// <summary>
 /// See <see cref="IVectorView.Axpy(IVectorView, double)"/>.
 /// </summary>
 public IVector Axpy(IVectorView otherVector, double otherCoefficient)
 {
     if (otherVector is Vector dense)
     {
         return(Axpy(dense, otherCoefficient));
     }
     else if (otherVector is SparseVector sparse)
     {
         Preconditions.CheckVectorDimensions(this, otherVector);
         double[] result = new double[data.Length];
         Array.Copy(data, result, data.Length);
         SparseBlas.Daxpyi(sparse.RawIndices.Length, otherCoefficient, sparse.RawValues,
                           sparse.RawIndices, 0, result, 0);
         return(Vector.CreateFromArray(result, false));
     }
     else
     {
         return(otherVector.LinearCombination(otherCoefficient, this, 1.0)); // To avoid accessing zero entries
     }
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Performs the matrix-matrix multiplication: oper(this) * <paramref name="other"/>.
        /// </summary>
        /// <param name="other">
        /// A matrix such that the <see cref="IIndexable2D.NumRows"/> of <paramref name="other"/> are equal to the
        /// <see cref="IIndexable2D.NumColumns"/> of oper(this).
        /// </param>
        /// <param name="transposeThis">If true, oper(this) = transpose(this). Otherwise oper(this) = this.</param>
        /// <exception cref="Exceptions.NonMatchingDimensionsException">
        /// Thrown if <paramref name="otherMatrix"/> has different <see cref="IIndexable2D.NumRows"/> than the
        /// <see cref="IIndexable2D.NumColumns"/> of oper(this).
        /// </exception>
        public Matrix MultiplyRight(Matrix other, bool transposeThis)
        {
            int numRowsResult;

            if (transposeThis)
            {
                Preconditions.CheckMultiplicationDimensions(this.NumRows, other.NumRows);
                numRowsResult = this.NumColumns;
            }
            else
            {
                Preconditions.CheckMultiplicationDimensions(this.NumColumns, other.NumRows);
                numRowsResult = this.NumRows;
            }

            var result = Matrix.CreateZero(numRowsResult, other.NumColumns);

            SparseBlas.Dcscgemm(transposeThis, this.NumRows, other.NumColumns, this.NumColumns, values, colOffsets, rowIndices,
                                other.RawData, result.RawData);
            return(result);
        }
Ejemplo n.º 5
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);
        }
Ejemplo n.º 6
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));
 }
Ejemplo n.º 7
0
 /// <summary>
 /// See <see cref="IVector.AxpyIntoThis(IVectorView, double)"/>.
 /// </summary>
 public void AxpyIntoThis(IVectorView otherVector, double otherCoefficient)
 {
     if (otherVector is Vector dense)
     {
         AxpyIntoThis(dense, otherCoefficient);
     }
     else
     {
         Preconditions.CheckVectorDimensions(this, otherVector);
         if (otherVector is SparseVector sparse)
         {
             //TODO: should I check whether the sparse vector is all 0, in order to avoid the BLAS call?
             SparseBlas.Daxpyi(sparse.RawIndices.Length, otherCoefficient, sparse.RawValues,
                               sparse.RawIndices, 0, data, 0);
         }
         else
         {
             for (int i = 0; i < Length; ++i)
             {
                 this.data[i] += otherCoefficient * otherVector[i];
             }
         }
     }
 }