/// <summary> /// Adds two matrices, C = alpha*A + beta*B, where A is current instance. /// </summary> /// <param name="alpha">Scalar factor for A, current instance.</param> /// <param name="beta">Scalar factor for B, other instance.</param> /// <param name="other">The matrix added to this instance.</param> /// <param name="result">Contains the sum.</param> /// <remarks> /// The (result) matrix has to be fully initialized and provide enough space for /// the nonzero entries of the sum. An upper bound is the sum of the nonzeros count /// of (this) and (other). /// </remarks> public override void Add(double alpha, double beta, CompressedColumnStorage <double> other, CompressedColumnStorage <double> result) { if (other == null) { throw new ArgumentNullException(nameof(other)); } if (result == null) { throw new ArgumentNullException(nameof(result)); } int p, j, nz = 0; int m = this.rowCount; int n = this.columnCount; // check inputs if (m != other.RowCount || n != other.ColumnCount) { throw new ArgumentException(Resources.MatrixDimensions); } // Workspace var w = new int[m]; var x = new double[m]; // Allocate result: (anz + bnz) is an upper bound var ci = result.ColumnPointers; var cj = result.RowIndices; var cx = result.Values; for (j = 0; j < n; j++) { ci[j] = nz; // column j of C starts here nz = this.Scatter(j, alpha, w, x, j + 1, result, nz); // alpha*A(:,j) nz = other.Scatter(j, beta, w, x, j + 1, result, nz); // beta*B(:,j) for (p = ci[j]; p < nz; p++) { cx[p] = x[cj[p]]; } } // Finalize the last column ci[n] = nz; // Remove extra space result.Resize(0); result.SortIndices(); }
/// <inheritdoc /> public override void Multiply(CompressedColumnStorage <Complex> other, CompressedColumnStorage <Complex> result) { if (other == null) { throw new ArgumentNullException(nameof(other)); } if (result == null) { throw new ArgumentNullException(nameof(result)); } int p, j, nz = 0; int[] cp, ci; Complex[] cx; int m = this.rows; int n = other.ColumnCount; int anz = this.NonZerosCount; int bnz = other.NonZerosCount; if (this.ColumnCount != other.RowCount) { throw new ArgumentException(Resources.MatrixDimensions, nameof(other)); } if ((m > 0 && this.ColumnCount == 0) || (other.RowCount == 0 && n > 0)) { throw new Exception(Resources.InvalidDimensions); } if (result.RowCount != m || result.ColumnCount != n) { throw new ArgumentException(Resources.InvalidDimensions, nameof(result)); } var bp = other.ColumnPointers; var bi = other.RowIndices; var bx = other.Values; // Workspace var w = new int[m]; var x = new Complex[m]; cp = result.ColumnPointers; for (j = 0; j < n; j++) { if (nz + m > result.Values.Length) { // Might throw out of memory exception. result.Resize(2 * (result.Values.Length) + m); } ci = result.RowIndices; cx = result.Values; // C.i and C.x may be reallocated cp[j] = nz; // column j of C starts here for (p = bp[j]; p < bp[j + 1]; p++) { nz = this.Scatter(bi[p], bx[p], w, x, j + 1, result, nz); } for (p = cp[j]; p < nz; p++) { cx[p] = x[ci[p]]; } } cp[n] = nz; // finalize the last column of C result.Resize(0); // remove extra space from C result.SortIndices(); }