RosettaCodeData/Task/Matrix-exponentiation-operator/C-sharp/matrix-exponentiation-opera...

60 lines
2.0 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using static System.Linq.Enumerable;
public static class MatrixExponentation
{
public static double[,] Identity(int size) {
double[,] matrix = new double[size, size];
for (int i = 0; i < size; i++) matrix[i, i] = 1;
return matrix;
}
public static double[,] Multiply(this double[,] left, double[,] right) {
if (left.ColumnCount() != right.RowCount()) throw new ArgumentException();
double[,] m = new double[left.RowCount(), right.ColumnCount()];
foreach (var (row, column) in from r in Range(0, m.RowCount()) from c in Range(0, m.ColumnCount()) select (r, c)) {
m[row, column] = Range(0, m.RowCount()).Sum(i => left[row, i] * right[i, column]);
}
return m;
}
public static double[,] Pow(this double[,] matrix, int exp) {
if (matrix.RowCount() != matrix.ColumnCount()) throw new ArgumentException("Matrix must be square.");
double[,] accumulator = Identity(matrix.RowCount());
for (int i = 0; i < exp; i++) {
accumulator = accumulator.Multiply(matrix);
}
return accumulator;
}
private static int RowCount(this double[,] matrix) => matrix.GetLength(0);
private static int ColumnCount(this double[,] matrix) => matrix.GetLength(1);
private static void Print(this double[,] m) {
foreach (var row in Rows()) {
Console.WriteLine("[ " + string.Join(" ", row) + " ]");
}
Console.WriteLine();
IEnumerable<IEnumerable<double>> Rows() =>
Range(0, m.RowCount()).Select(row => Range(0, m.ColumnCount()).Select(column => m[row, column]));
}
public static void Main() {
var matrix = new double[,] {
{ 3, 2 },
{ 2, 1 }
};
matrix.Pow(0).Print();
matrix.Pow(1).Print();
matrix.Pow(2).Print();
matrix.Pow(3).Print();
matrix.Pow(4).Print();
matrix.Pow(50).Print();
}
}