classes/Matrix.ps1
# Need to parameterize class with "id" in order to re-load class during testing $Id = if ($Env:ProjectName -eq 'pwsh-prelude') { 'Test' } else { '' } if ("Matrix${Id}" -as [Type]) { return } Add-Type -TypeDefinition @" using System; public class Matrix${Id} { public int[] Order; public double[][] Values; public Matrix${Id}(int n) { this.Order = new int[2]; this.Order[0] = n; this.Order[1] = n; this.Values = Matrix${Id}.Create(n,n); } public Matrix${Id}(int m,int n) { this.Order = new int[2]; this.Order[0] = m; this.Order[1] = n; this.Values = Matrix${Id}.Create(m,n); } public static double[][] Create(int m,int n) { double[][] result = new double[m][]; for (var i = 0; i < m; ++i) result[i] = new Double[n]; return result; } public static Matrix${Id} Unit(int size) { var unit = new Matrix${Id}(size); var m = unit.Order[0]; var n = unit.Order[1]; for (var i = 0; i < m; ++i) for (var j = 0; j < n; ++j) unit.Values[i][j] = 1; return unit; } public static Matrix${Id} Identity(int size) { var temp = new Matrix${Id}(size,size); for (var i = 0; i < temp.Order[0]; ++i) temp.Values[i][i] = 1; return temp; } public static Matrix${Id} Transpose(Matrix${Id} a) { var clone = a.Clone(); var m = clone.Order[0]; var n = clone.Order[1]; for (var i = 0; i < m; ++i) for (var j = 0; j < n; ++j) clone.Values[i][j] = a.Values[j][i]; return clone; } public static Matrix${Id} Add(params Matrix${Id}[] addends) { var order = addends[0].Order; var m = order[0]; var n = order[1]; var sum = new Matrix${Id}(m,n); foreach (Matrix${Id} matrix in addends) for (var i = 0; i < m; ++i) for (var j = 0; j < n; ++j) sum.Values[i][j] += matrix.Values[i][j]; return sum; } public static double Det(Matrix${Id} a) { var m = a.Order[0]; if (m == 2) { return (a.Values[0][0] * a.Values[1][1]) - (a.Values[0][1] * a.Values[1][0]); } var n = m + (m - 1); var temp = new Matrix${Id}(m,n); for (var i = 0; i < m; ++i) for (var j = 0; j < n; ++j) temp.Values[i][j] = a.Values[i][j % m]; double sum = 0; for (var i = 0; i < m; ++i) { double product = 1; for (var j = 0; j < m; ++j) { product *= temp.Values[j][i + j]; } sum += product; } for (var i = 0; i < m; ++i) { double product = 1; for (var j = 0; j < m; ++j) { product *= temp.Values[j][(n - 1) - (i + j)]; } sum -= product; } return sum; } public static Matrix${Id} Dot(Matrix${Id} a,Matrix${Id} b) { var m = a.Order[0]; var p = a.Order[1]; var n = b.Order[1]; var product = new Matrix${Id}(m,n); for (var i = 0; i < m; ++i) { for (var j = 0; j < n; ++j) { Double sum = 0; for (var k = 0; k < p; ++k) { sum += (a.Values[i][k] * b.Values[k][j]); } product.Values[i][j] = sum; } } return product; } public Matrix${Id} Clone() { var original = this; var m = original.Order[0]; var n = original.Order[1]; var clone = new Matrix${Id}(m,n); for (var i = 0; i < m; ++i) for (var j = 0; j < n; ++j) clone.Values[i][j] = original.Values[i][j]; return clone; } public Matrix${Id} Multiply(double k) { var clone = this.Clone(); var m = clone.Order[0]; var n = clone.Order[1]; for (var i = 0; i < m; ++i) for (var j = 0; j < n; ++j) clone.Values[i][j] *= k; return clone; } public override string ToString() { var matrix = this; var rank = matrix.Order[0]; var rows = new string[rank]; for (var i = 0; i < rank; ++i) rows[i] = string.Join(",",matrix.Values[i]); return string.Join(";",rows); } } "@ |