-
Notifications
You must be signed in to change notification settings - Fork 6
/
CSLAU.cs
129 lines (117 loc) · 4.49 KB
/
CSLAU.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
using System;
using static МатКлассы.Number;
namespace МатКлассы
{
/// <summary>
/// Класс комплексных СЛАУ
/// Отличие от действительного случая в том, что реализация происходит через матрицы и векторы, а не через массивы
/// Из-за комплексных чисел все методы надо переписывать
/// </summary>
public class CSLAU
{
private CSqMatrix A;
private CVectors x, b;
/// <summary>
/// Размерность системы
/// </summary>
public int Dim => x.Degree;
/// <summary>
/// Конструктор по матрице и свободному вектору
/// </summary>
/// <param name="M"></param>
/// <param name="v"></param>
public CSLAU(CSqMatrix M, CVectors v)
{
x = new CVectors(v.Degree);
b = new CVectors(v);
A = new CSqMatrix(M);
}
private void GetDet(out Complex det)
{
det = A.Det;
if (det == 0) throw new Exception("Матрица системы вырождена!");
}
/// <summary>
/// Решение системы методом Крамера
/// </summary>
public void KramerSolve()
{
GetDet(out Complex det);
for (int i = 0; i < this.Dim; i++)
x[i] = A.ColumnSwap(i + 1, b).Det / det;
}
/// <summary>
/// Метод Гаусса, годный и при нулевых коэффициентах в системе
/// </summary>
public void GaussSelection()
{
CMatrix S = new CMatrix(this.Dim, this.Dim + 1);
for (int j = 0; j < this.Dim; j++)
{
for (int i = 0; i < this.Dim; i++) S[i, j] = this.A[i, j];
S[j, this.Dim] = this.b[j];
}
for (int j = 0; j < this.Dim; j++)
{
int k = j;
if (S[k, j] == 0)//если ведущий элемент равен нулю, поменять эту строку местами с ненулевой
{
int h = k;
while (S[h, j] == 0) h++;
S.LinesSwap(k, h);
}
while (S[k, j] == 0 && k < this.Dim - 1) k++;//найти ненулевой элемент
int l = k + 1;
if (k != this.Dim - 1) while (l != this.Dim) { S.LinesDiff(l, k, S[l, j] / S[k, j]); l++; } //отнимать от строк снизу
//S.PrintMatrix();Console.WriteLine();
l = k - 1;
if (k != 0) while (l != -1) { S.LinesDiff(l, k, S[l, j] / S[k, j]); l--; }//отнимать от строк сверху
}
for (int i = 0; i < this.Dim; i++) this.x[i] = S[i, this.Dim] / S[i, i];
}
private class CMatrix
{
private Matrix R, I;
public Complex this[int i, int j]
{
get
{
return R[i, j] + Complex.I * I[i, j];
}
set
{
R[i, j] = value.Re;
I[i, j] = value.Im;
}
}
public CMatrix(int n, int m)
{
R = new Matrix(n, m);
I = new Matrix(n, m);
}
public void LinesSwap(int a, int b)
{
R.LinesSwap(a, b);
I.LinesSwap(a, b);
}
public void LinesDiff(int a, int b, Complex coef)
{
for (int k = 0; k < R.m; k++) this[a, k] -= coef * this[b, k];
}
}
/// <summary>
/// Вывести систему на консоль
/// </summary>
public void Show()
{
for (int i = 0; i < this.Dim; i++)
{
string s = "||";
for (int j = 0; j < this.Dim - 1; j++)
s += "\t" + A[i, j].ToString() + " ";
s += "\t" + A[i, this.Dim - 1].ToString() + "|| \t" + x[i].ToString() + " \t||" + b[i].ToString() + "||";
s.Show();
}
}
}
}