/// <summary> /// See <see cref="IMatrixView.LinearCombination(double, IMatrixView, double)"/>. /// </summary> public IMatrix LinearCombination(double thisCoefficient, IMatrixView otherMatrix, double otherCoefficient) { if (otherMatrix is CscMatrix otherCSC) // In case both matrices have the exact same index arrays { if (HasSameIndexer(otherCSC)) { // Do not copy the index arrays, since they are already spread around. TODO: is this a good idea? double[] resultValues = new double[values.Length]; if (thisCoefficient == 1.0) { Array.Copy(this.values, resultValues, values.Length); Blas.Daxpy(values.Length, otherCoefficient, otherCSC.values, 0, 1, this.values, 0, 1); } else if (otherCoefficient == 1.0) { Array.Copy(otherCSC.values, resultValues, values.Length); Blas.Daxpy(values.Length, thisCoefficient, this.values, 0, 1, resultValues, 0, 1); } else { Array.Copy(this.values, resultValues, values.Length); BlasExtensions.Daxpby(values.Length, otherCoefficient, otherCSC.values, 0, 1, thisCoefficient, resultValues, 0, 1); } return(new CscMatrix(NumRows, NumColumns, resultValues, this.rowIndices, this.colOffsets)); } } // All entries must be processed. TODO: optimizations may be possible (e.g. only access the nnz in this matrix) return(DenseStrategies.LinearCombination(this, thisCoefficient, otherMatrix, otherCoefficient)); }
/// <summary> /// See <see cref="IVectorView.LinearCombination(double, IVectorView, double)"/>. /// </summary> public IVector LinearCombination(double thisCoefficient, 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]; if (thisCoefficient == 1.0) { Array.Copy(this.values, result, this.values.Length); Blas.Daxpy(values.Length, otherCoefficient, otherSparse.values, 0, 1, result, 0, 1); } else if (otherCoefficient == 1.0) { Array.Copy(otherSparse.values, result, values.Length); Blas.Daxpy(values.Length, thisCoefficient, this.values, 0, 1, result, 0, 1); } else { Array.Copy(this.values, result, this.values.Length); BlasExtensions.Daxpby(values.Length, otherCoefficient, otherSparse.values, 0, 1, thisCoefficient, result, 0, 1); } return(new SparseVector(Length, result, indices)); } } // All entries must be processed. TODO: optimizations may be possible (e.g. only access the nnz in this vector) return(DenseStrategies.LinearCombination(this, thisCoefficient, otherVector, otherCoefficient)); }
/// <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)); }
public IMatrix LinearCombination(double thisCoefficient, IMatrixView otherMatrix, double otherCoefficient) => DenseStrategies.LinearCombination(this, thisCoefficient, otherMatrix, otherCoefficient);