/// <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]; } } } }
/// <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 } }
/// <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)); }
/// <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]; } } } }