197 lines
5.1 KiB
C#
197 lines
5.1 KiB
C#
using System.ComponentModel;
|
|
|
|
namespace omp
|
|
{
|
|
public static class MatrixExtensions
|
|
{
|
|
public static void Print(this double[,] a)
|
|
{
|
|
int rows = a.GetLength(0);
|
|
int columns = a.GetLength(1);
|
|
|
|
Console.WriteLine("Matrix of size {0}x{1}:", rows, columns);
|
|
for (int i = 0; i < rows; ++i)
|
|
{
|
|
for (int j = 0; j < columns; ++j)
|
|
{
|
|
Console.Write("\t{0}", a[i, j]);
|
|
}
|
|
Console.WriteLine("");
|
|
}
|
|
}
|
|
|
|
public static void SaveToFile(this double[,] a, string filePath)
|
|
{
|
|
int rows = a.GetLength(0);
|
|
int cols = a.GetLength(0);
|
|
|
|
using (var stream = new FileStream(filePath, FileMode.Create))
|
|
using (var writer = new BinaryWriter(stream))
|
|
{
|
|
unsafe
|
|
{
|
|
fixed (double* ptr = &a[0, 0])
|
|
{
|
|
byte* bytePtr = (byte*)ptr;
|
|
int byteCount = rows * cols * sizeof(double);
|
|
|
|
writer.Write(new ReadOnlySpan<byte>(bytePtr, byteCount));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static double Adj(this double[,] a, int i, int j)
|
|
{
|
|
double sgn = ((i + j) % 2 == 0) ? 1 : -1;
|
|
|
|
return sgn * Det(Minor(a, j, i));
|
|
}
|
|
|
|
public static double[,] Minor(this double[,] a, int i, int j)
|
|
{
|
|
int rows = a.GetLength(0);
|
|
int columns = a.GetLength(1);
|
|
|
|
double[,] minor = new double[rows - 1, columns - 1];
|
|
|
|
int k = 0;
|
|
int l;
|
|
|
|
for (int r = 0; r < rows; ++r)
|
|
{
|
|
if (r == i)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
l = 0;
|
|
|
|
for (int c = 0; c < columns; ++c)
|
|
{
|
|
if (c == j)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
minor[k, l] = a[r, c];
|
|
|
|
l++;
|
|
}
|
|
|
|
k++;
|
|
}
|
|
|
|
return minor;
|
|
}
|
|
|
|
public static double Det(this double[,] a)
|
|
{
|
|
int n = a.GetLength(0);
|
|
|
|
switch (n)
|
|
{
|
|
case 1:
|
|
return a[0, 0];
|
|
case 2:
|
|
return Det2(a);
|
|
case 3:
|
|
return Det3(a);
|
|
default:
|
|
double det = 0;
|
|
|
|
double sgn;
|
|
for (int j = 0; j < n; ++j)
|
|
{
|
|
sgn = (j % 2 == 0) ? 1 : -1;
|
|
det += sgn * a[0, j] * Det(Minor(a, 0, j));
|
|
}
|
|
|
|
return det;
|
|
}
|
|
}
|
|
|
|
public static double Det2(this double[,] a)
|
|
{
|
|
return a[0, 0] * a[1, 1] - a[0, 1] * a[1, 0];
|
|
}
|
|
|
|
|
|
public static double Det3(double[,] a)
|
|
{
|
|
if (a.GetLength(0) != 3 || a.GetLength(1) != 3)
|
|
throw new ArgumentException("Matrix must be 3x3");
|
|
|
|
return
|
|
a[0, 0] * a[1, 1] * a[2, 2]
|
|
+ a[0, 1] * a[1, 2] * a[2, 0]
|
|
+ a[0, 2] * a[1, 0] * a[2, 1]
|
|
- a[0, 2] * a[1, 1] * a[2, 0]
|
|
- a[0, 0] * a[1, 2] * a[2, 1]
|
|
- a[2, 2] * a[0, 1] * a[1, 0];
|
|
}
|
|
public static double[,] MultTrans(this double[,] a)
|
|
{
|
|
int rows = a.GetLength(0);
|
|
int columns = a.GetLength(1);
|
|
|
|
double[,] r = new double[rows, rows];
|
|
|
|
for (int i = 0; i < rows; ++i)
|
|
{
|
|
for (int j = 0; j < rows; ++j)
|
|
{
|
|
for (int k = 0; k < columns; ++k)
|
|
{
|
|
r[i, j] += a[i, k] * a[j, k];
|
|
}
|
|
}
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
public static (double Min, double Max) MinMax(this double[,] a)
|
|
{
|
|
double min = double.MaxValue;
|
|
double max = double.MinValue;
|
|
|
|
object MMLock = new();
|
|
|
|
Parallel.For(0, a.GetLength(0), i =>
|
|
{
|
|
double localMin = double.MaxValue;
|
|
double localMax = double.MinValue;
|
|
|
|
for (int j = 0; j < a.GetLength(1); ++j)
|
|
{
|
|
if (a[i, j] < localMin)
|
|
{
|
|
localMin = a[i, j];
|
|
}
|
|
if (a[i, j] > localMax)
|
|
{
|
|
localMax = a[i, j];
|
|
}
|
|
}
|
|
|
|
lock (MMLock)
|
|
{
|
|
if (localMin < min)
|
|
{
|
|
min = localMin;
|
|
}
|
|
|
|
if (localMax > max)
|
|
{
|
|
max = localMax;
|
|
}
|
|
|
|
}
|
|
});
|
|
|
|
return (min, max);
|
|
}
|
|
}
|
|
}
|