1using System.Collections;
2using System.Globalization;
18public class Matrix<T> : IEnumerable<T>
23 if (typeof(T) != typeof(
int) &&
24 typeof(T) != typeof(uint) &&
25 typeof(T) != typeof(
float))
44 public Matrix(uint rows, uint columns)
48 Values =
new T[rows, columns];
64 public Matrix(uint rows, uint columns, T[,] data)
72 if (data.Length != rows * columns)
74 throw new IcvMismatchException(
"Data length does not match matrix dimensions.");
93 public Matrix(uint rows, uint columns, T[] data)
101 if (data.Length != rows * columns)
103 throw new IcvMismatchException(
"Data length does not match matrix dimensions.");
106 for (uint r = 0; r < rows; r++)
107 for (uint c = 0; c < columns; c++)
109 Values[r, c] = data[r * columns + c];
113 internal T[,] Values {
get;
set; }
131 public T
this[uint row, uint col]
140 return Values[row, col];
149 Values[row, col] = value;
157 public static IEqualityComparer<Matrix<T>>
Comparer {
get; } =
new MatrixEqualityComparer();
162 return Flatten().AsEnumerable().GetEnumerator();
166 IEnumerator IEnumerable.GetEnumerator()
182 hash = hash * prime +
Rows.GetHashCode();
183 hash = hash * prime +
Columns.GetHashCode();
185 for (uint r = 0; r <
Rows; r++)
187 for (uint c = 0; c <
Columns; c++)
189 T value = Values[r, c];
190 hash = hash * prime + (value?.GetHashCode() ?? 0);
206 for (uint i = 0; i < size; i++)
208 result[i, i] = value;
220 return Diagonal(size, (T) Convert.ChangeType(1, typeof(T)));
227 internal T[] Flatten()
229 return Values.Cast<T>().ToArray();
232 internal static T[,] To2DArray(T[] input, uint height, uint width)
234 var output =
new T[height, width];
235 for (uint i = 0; i < height; i++)
237 for (uint j = 0; j < width; j++)
239 output[i, j] = input[i * width + j];
252 var sb =
new StringBuilder();
254 for (uint i = 0; i <
Rows; i++)
256 for (uint j = 0; j <
Columns; j++)
258 T value =
this[i, j];
260 if (value is IFormattable f)
262 sb.Append(f.ToString(
"F2", CultureInfo.InvariantCulture));
277 return sb.ToString();
287 protected sealed class MatrixEqualityComparer : IEqualityComparer<Matrix<T>>
301 if (ReferenceEquals(x, y))
306 if (x is
null || y is
null)
312 T[] xFlat = x.Flatten();
313 T[] yFlat = y.Flatten();
315 if (xFlat.Length != yFlat.Length)
320 for (var i = 0; i < xFlat.Length; ++i)
322 if (IsEqual(xFlat[i], yFlat[i], 1e-6f))
346 foreach (T value
in obj)
348 hash = hash * 31 + (value?.GetHashCode() ?? 0);
362 private static bool IsEqual(T x, T y,
double tolerance)
366 float fX => Math.Abs(fX - (
float) (
object) y!) > tolerance,
367 int iX => iX == (int) (
object) y!,
368 uint uX => uX == (uint) (
object) y!,
369 _ =>
throw new IcvNotSupportedException(
"Unsupported generic type for matrix class.")
Occurs when a requested operation is not implemented or supported (e.g., exporting to an unsupported ...
Occurs when attempting to access an object or value via an uninitialized or null pointer.
Occurs when a provided value falls outside the allowed valid range.
Represents a generic 2D matrix of elements with a specified number of rows and columns.
uint Columns
Number of columns in the matrix.
Matrix(uint rows, uint columns, T[] data)
Initializes a new instance of the Matrix<T> class with given values.
IEnumerator< T > GetEnumerator()
override int GetHashCode()
Computes a hash code based on all elements in the matrix.
uint Rows
Number of rows in the matrix.
Matrix(uint rows, uint columns)
Initializes a new instance of the Matrix<T> class with the specified dimensions.
override string ToString()
Returns a string representation of the matrix.
Matrix(uint rows, uint columns, T[,] data)
Initializes a new instance of the Matrix<T> class with given values.
static IEqualityComparer< Matrix< T > > Comparer
Gets a default equality comparer for comparing Matrix<T> data values.
static Matrix< T > Diagonal(uint size, T value)
Creates a diagonal matrix with the given value on the diagonal.
static Matrix< T > Identity(uint size)
Creates an identity matrix of given size.