IDS peak ICV v1.3.0
Loading...
Searching...
No Matches
Matrix.cs
Go to the documentation of this file.
1using System.Collections;
2using System.Globalization;
3using System.Text;
4
6
18public class Matrix<T> : IEnumerable<T>
19{
20 static Matrix()
21 {
22 // Guard rail: Only allow these specific types
23 if (typeof(T) != typeof(int) &&
24 typeof(T) != typeof(uint) &&
25 typeof(T) != typeof(float))
26 {
27 throw new IcvNotSupportedException($"{typeof(T)} is not supported.");
28 }
29 }
30
44 public Matrix(uint rows, uint columns)
45 {
46 Rows = rows;
47 Columns = columns;
48 Values = new T[rows, columns];
49 }
50
64 public Matrix(uint rows, uint columns, T[,] data)
65 : this(rows, columns)
66 {
67 if (data is null)
68 {
69 throw new IcvNullPointerException("Invalid data array.");
70 }
71
72 if (data.Length != rows * columns)
73 {
74 throw new IcvMismatchException("Data length does not match matrix dimensions.");
75 }
76
77 Values = data;
78 }
79
93 public Matrix(uint rows, uint columns, T[] data)
94 : this(rows, columns)
95 {
96 if (data is null)
97 {
98 throw new IcvNullPointerException("Invalid data array.");
99 }
100
101 if (data.Length != rows * columns)
102 {
103 throw new IcvMismatchException("Data length does not match matrix dimensions.");
104 }
105
106 for (uint r = 0; r < rows; r++)
107 for (uint c = 0; c < columns; c++)
108 {
109 Values[r, c] = data[r * columns + c];
110 }
111 }
112
113 internal T[,] Values { get; set; }
114
119 public uint Rows { get; }
120
125 public uint Columns { get; }
126
131 public T this[uint row, uint col]
132 {
133 get
134 {
135 if (row >= Rows || col >= Columns)
136 {
137 throw new IcvOutOfRangeException("The given row or column index is out of range.");
138 }
139
140 return Values[row, col];
141 }
142 set
143 {
144 if (row >= Rows || col >= Columns)
145 {
146 throw new IcvOutOfRangeException("The given row or column index is out of range.");
147 }
148
149 Values[row, col] = value;
150 }
151 }
152
157 public static IEqualityComparer<Matrix<T>> Comparer { get; } = new MatrixEqualityComparer();
158
160 public IEnumerator<T> GetEnumerator()
161 {
162 return Flatten().AsEnumerable().GetEnumerator();
163 }
164
166 IEnumerator IEnumerable.GetEnumerator()
167 {
168 return GetEnumerator();
169 }
170
175 public override int GetHashCode()
176 {
177 unchecked
178 {
179 var hash = 17;
180 var prime = 31;
181
182 hash = hash * prime + Rows.GetHashCode();
183 hash = hash * prime + Columns.GetHashCode();
184
185 for (uint r = 0; r < Rows; r++)
186 {
187 for (uint c = 0; c < Columns; c++)
188 {
189 T value = Values[r, c];
190 hash = hash * prime + (value?.GetHashCode() ?? 0);
191 }
192 }
193
194 return hash;
195 }
196 }
197
198
203 public static Matrix<T> Diagonal(uint size, T value)
204 {
205 var result = new Matrix<T>(size, size);
206 for (uint i = 0; i < size; i++)
207 {
208 result[i, i] = value;
209 }
210
211 return result;
212 }
213
218 public static Matrix<T> Identity(uint size)
219 {
220 return Diagonal(size, (T) Convert.ChangeType(1, typeof(T)));
221 }
222
227 internal T[] Flatten()
228 {
229 return Values.Cast<T>().ToArray();
230 }
231
232 internal static T[,] To2DArray(T[] input, uint height, uint width)
233 {
234 var output = new T[height, width];
235 for (uint i = 0; i < height; i++)
236 {
237 for (uint j = 0; j < width; j++)
238 {
239 output[i, j] = input[i * width + j];
240 }
241 }
242
243 return output;
244 }
245
250 public override string ToString()
251 {
252 var sb = new StringBuilder();
253
254 for (uint i = 0; i < Rows; i++)
255 {
256 for (uint j = 0; j < Columns; j++)
257 {
258 T value = this[i, j];
259
260 if (value is IFormattable f)
261 {
262 sb.Append(f.ToString("F2", CultureInfo.InvariantCulture));
263 }
264
265 if (j < Columns - 1)
266 {
267 sb.Append(" ");
268 }
269 }
270
271 if (i < Rows - 1)
272 {
273 sb.Append("\n");
274 }
275 }
276
277 return sb.ToString();
278 }
279
287 protected sealed class MatrixEqualityComparer : IEqualityComparer<Matrix<T>>
288 {
299 public bool Equals(Matrix<T>? x, Matrix<T>? y)
300 {
301 if (ReferenceEquals(x, y))
302 {
303 return true;
304 }
305
306 if (x is null || y is null)
307 {
308 return false;
309 }
310
311
312 T[] xFlat = x.Flatten();
313 T[] yFlat = y.Flatten();
314
315 if (xFlat.Length != yFlat.Length)
316 {
317 return false;
318 }
319
320 for (var i = 0; i < xFlat.Length; ++i)
321 {
322 if (IsEqual(xFlat[i], yFlat[i], 1e-6f))
323 {
324 return false;
325 }
326 }
327
328 return true;
329 }
330
341 public int GetHashCode(Matrix<T> obj)
342 {
343 unchecked
344 {
345 var hash = 17;
346 foreach (T value in obj)
347 {
348 hash = hash * 31 + (value?.GetHashCode() ?? 0);
349 }
350
351 return hash;
352 }
353 }
354
362 private static bool IsEqual(T x, T y, double tolerance)
363 {
364 return x switch
365 {
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.")
370 };
371 }
372 }
373}
Occurs when a requested operation is not implemented or supported (e.g., exporting to an unsupported ...
Definition Exception.cs:62
Occurs when attempting to access an object or value via an uninitialized or null pointer.
Definition Exception.cs:115
Occurs when a provided value falls outside the allowed valid range.
Definition Exception.cs:128
Represents a generic 2D matrix of elements with a specified number of rows and columns.
Definition Matrix.cs:19
uint Columns
Number of columns in the matrix.
Definition Matrix.cs:125
Matrix(uint rows, uint columns, T[] data)
Initializes a new instance of the Matrix<T> class with given values.
Definition Matrix.cs:93
IEnumerator< T > GetEnumerator()
Definition Matrix.cs:160
override int GetHashCode()
Computes a hash code based on all elements in the matrix.
Definition Matrix.cs:175
uint Rows
Number of rows in the matrix.
Definition Matrix.cs:119
Matrix(uint rows, uint columns)
Initializes a new instance of the Matrix<T> class with the specified dimensions.
Definition Matrix.cs:44
override string ToString()
Returns a string representation of the matrix.
Definition Matrix.cs:250
Matrix(uint rows, uint columns, T[,] data)
Initializes a new instance of the Matrix<T> class with given values.
Definition Matrix.cs:64
static IEqualityComparer< Matrix< T > > Comparer
Gets a default equality comparer for comparing Matrix<T> data values.
Definition Matrix.cs:157
static Matrix< T > Diagonal(uint size, T value)
Creates a diagonal matrix with the given value on the diagonal.
Definition Matrix.cs:203
static Matrix< T > Identity(uint size)
Creates an identity matrix of given size.
Definition Matrix.cs:218