/// <summary> /// Performs matrix addition or subtraction. /// </summary> /// <typeparam name="A">The type of entry values to add or subtract.</typeparam> /// <typeparam name="R">The type of result.</typeparam> /// <param name="cvs1">The CVS instance.</param> /// <param name="cvs2">The CVS instance to add or subtract.</param> /// <param name="mdas">The operation to perform.</param> /// <returns>The new CVS instance.</returns> private static CVS <R> MatrixAddOrSubtract <A, R>(CVS <T> cvs1, CVS <A> cvs2, MDAS mdas) { if (!cvs1.Size.Equals(cvs2.Size)) { throw new InvalidOperationException("Matrices must have the same size."); } var r = new LinearIndexKeyedSparseMatrix <R>(cvs1.Size, cvs1.LinearIndexMode); dynamic value; Parallel.For(0, cvs1.Value.Count, (i) => { value = cvs1.Value[i]; Parallel.ForEach(cvs1.LinearIndex[i], (li) => { r.SetEntry(li, value); }); }); Parallel.For(0, cvs2.Value.Count, (i) => { value = cvs2.Value[i]; Parallel.ForEach(cvs2.LinearIndex[i], (li) => { if (r.ContainsKey(li)) { if (mdas == MDAS.Subtract) { value = r.GetEntry(li) - value; } else { value = r.GetEntry(li) + value; } } if (value == default(R)) { r.TryRemove(li, out R v); } else { r.SetEntry(li, value); } }); }); return(r.ToCVS(r.LinearIndexMode)); }
/// <summary> /// Performs matrix addition or subtraction and saves the results to a new sparse matrix. /// </summary> /// <typeparam name="A">The type of input entry values.</typeparam> /// <typeparam name="R">The type of result values.</typeparam> /// <param name="sparseMatrix1">The sparse matrix.</param> /// <param name="sparseMatrix2">Tha input sparse matrix.</param> /// <param name="result">The new sparse matrix.</param> /// <param name="mdas">The type of operation, whether to Add or Subtract.</param> private static void MatrixAddOrSubtract <A, R>(DOKSparseMatrixBase <K, T> sparseMatrix1, DOKSparseMatrixBase <K, A> sparseMatrix2, DOKSparseMatrixBase <K, R> result, MDAS mdas) { if (!sparseMatrix1.Size.Equals(sparseMatrix2.Size)) { throw new InvalidOperationException("Matrices must have the same size."); } if (!result.Size.Equals(sparseMatrix1.Size) || !result.Size.Equals(sparseMatrix2.Size)) { throw new InvalidOperationException("Result matrix size must match matrices size."); } Parallel.ForEach(sparseMatrix1, (entry) => { result.SetEntry(entry.Key, (dynamic)entry.Value); }); Parallel.ForEach(sparseMatrix2, (entry) => { var key = entry.Key; dynamic value; if (result.ContainsKey(key)) { value = result.GetEntry(key); if (mdas == MDAS.Subtract) { value -= entry.Value; } else { value += entry.Value; } if (value == default(R)) { result.TryRemove(key, out R v); } else { result.SetEntry(key, value); } } else { value = entry.Value; result.SetEntry(key, value); } }); }