About IDOKSparseMatrix and DOKSparseMatrixBase
After much self-deliberation, I decided that the sparse matrix must be abstracted. The primary inspiration of the sparse matrix's design in Mendz.Graphs came from Wolfram where the SparseArray is shown as a collection of coordinates and their values ((0, 0) -> 1, (3, 1) -> 3, (7, 5) -> 5, ...).
The sparse matrix can be abstracted as: IDictionary<K, T>. Note that currently, K can either be (int row, int column) coordinates or int linear index.
The sparse matrix can be abstracted as: IDictionary<K, T>. Note that currently, K can either be (int row, int column) coordinates or int linear index.
IDOKSparseMatrix.cs
using System.Collections.Generic;
namespace Mendz.Library.Matrices
{
public interface IDOKSparseMatrix<K, T>
{
T this[int row, int column] { get; }
IDictionary<K, T> Matrix { get; }
(int rows, int columns) Size { get; }
MatrixLinearIndexMode LinearIndexMode { get; }
T Default { get; }
T Diagonal { get; }
bool IsConcurrent { get; }
T GetEntry(K key);
void SetEntry(K key, T value);
}
}
This code defines the interface of a sparse matrix. The IDOKSparseMatrix interface is implemented by DOKSparseMatrixBase.
DOKSparseMatrixBase.cs
using System.Collections.Generic;
namespace Mendz.Library.Matrices
{
public abstract class DOKSparseMatrixBase<M, K, T> : IDOKSparseMatrix<K, T>
where M : IDictionary<K, T>, new()
{
protected DOKSparseMatrixBase((int rows, int columns) size,
MatrixLinearIndexMode linearIndexMode = MatrixLinearIndexMode.RowMajorOrder,
T defaultValue = default(T), T diagonal = default(T))
{
Matrix = new M();
Size = size;
LinearIndexMode = linearIndexMode;
Default = defaultValue;
Diagonal = diagonal;
}
#region Implements
public T this[int row, int column]
{
get
{
MatrixCoordinates.CheckCoordinates(Size, row, column);
K key;
if (typeof(K) == typeof(int))
{
key = (dynamic)MatrixCoordinates.ToLinearIndex(
Size, row, column, LinearIndexMode);
}
else
{
key = (dynamic)(row, column);
}
if (Matrix.ContainsKey(key))
{
return GetEntry(key);
}
else
{
return (row == column) ? Diagonal : Default;
}
}
}
public M Matrix { get; private set; }
public (int rows, int columns) Size { get; private set; }
public MatrixLinearIndexMode LinearIndexMode { get; private set; }
public T Default { get; private set; }
public T Diagonal { get; private set; }
public virtual bool IsConcurrent { get; protected set; } = false;
public T GetEntry(K key)
{
return Matrix[key];
}
public virtual void SetEntry(K key, T value)
{
if (Matrix.ContainsKey(key))
{
Matrix[key] = value;
}
else
{
Matrix.Add(key, value);
}
}
#endregion
#region Explicit Implements
IDictionary<K, T> IDOKSparseMatrix<K, T>.Matrix => Matrix;
(int rows, int columns) IDOKSparseMatrix<K, T>.Size => Size;
MatrixLinearIndexMode IDOKSparseMatrix<K, T>.LinearIndexMode => LinearIndexMode;
T IDOKSparseMatrix<K, T>.Default => Default;
T IDOKSparseMatrix<K, T>.Diagonal => Diagonal;
bool IDOKSparseMatrix<K, T>.IsConcurrent => IsConcurrent;
T IDOKSparseMatrix<K, T>.GetEntry(K key) => GetEntry(key);
void IDOKSparseMatrix<K, T>.SetEntry(K key, T value) => SetEntry(key, value);
#endregion
}
}
DOKSparseMatrixBase provides the basic implementations of the IDOKSparseMatrix members. The indexer is implemented to simulate matrix-like access. Note that the IDOKSparseMatrix members are also explicitly implemented.
Comments
Post a Comment