forked from TheAlgorithms/C-Sharp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
LU.cs
114 lines (96 loc) · 3.97 KB
/
LU.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
using System;
namespace Algorithms.Numeric.Decomposition
{
/// <summary>
/// LU-decomposition factors the "source" matrix as the product of lower triangular matrix
/// and upper triangular matrix.
/// </summary>
public static class Lu
{
/// <summary>
/// Performs LU-decomposition on "source" matrix.
/// Lower and upper matrices have same shapes as source matrix.
/// Note: Decomposition can be applied only to square matrices.
/// </summary>
/// <param name="source">Square matrix to decompose.</param>
/// <returns>Tuple of lower and upper matrix.</returns>
/// <exception cref="ArgumentException">Source matrix is not square shaped.</exception>
public static (double[,] L, double[,] U) Decompose(double[,] source)
{
if (source.GetLength(0) != source.GetLength(1))
{
throw new ArgumentException("Source matrix is not square shaped.");
}
var pivot = source.GetLength(0);
var lower = new double[pivot, pivot];
var upper = new double[pivot, pivot];
for (var i = 0; i < pivot; i++)
{
for (var k = i; k < pivot; k++)
{
double sum = 0;
for (var j = 0; j < i; j++)
{
sum += lower[i, j] * upper[j, k];
}
upper[i, k] = source[i, k] - sum;
}
for (var k = i; k < pivot; k++)
{
if (i == k)
{
lower[i, i] = 1;
}
else
{
double sum = 0;
for (var j = 0; j < i; j++)
{
sum += lower[k, j] * upper[j, i];
}
lower[k, i] = (source[k, i] - sum) / upper[i, i];
}
}
}
return (L: lower, U: upper);
}
/// <summary>
/// Eliminates linear equations system represented as A*x=b, using LU-decomposition,
/// where A - matrix of equation coefficients, b - vector of absolute terms of equations.
/// </summary>
/// <param name="matrix">Matrix of equation coefficients.</param>
/// <param name="coefficients">Vector of absolute terms of equations.</param>
/// <returns>Vector-solution for linear equations system.</returns>
/// <exception cref="ArgumentException">Matrix of equation coefficients is not square shaped.</exception>
public static double[] Eliminate(double[,] matrix, double[] coefficients)
{
if (matrix.GetLength(0) != matrix.GetLength(1))
{
throw new ArgumentException("Matrix of equation coefficients is not square shaped.");
}
var pivot = matrix.GetLength(0);
var upperTransform = new double[pivot, 1]; // U * upperTransform = coefficients
var solution = new double[pivot]; // L * solution = upperTransform
(double[,] l, double[,] u) = Decompose(matrix);
for (var i = 0; i < pivot; i++)
{
double pivotPointSum = 0;
for (var j = 0; j < i; j++)
{
pivotPointSum += upperTransform[j, 0] * l[i, j];
}
upperTransform[i, 0] = (coefficients[i] - pivotPointSum) / l[i, i];
}
for (var i = pivot - 1; i >= 0; i--)
{
double pivotPointSum = 0;
for (var j = i; j < pivot; j++)
{
pivotPointSum += solution[j] * u[i, j];
}
solution[i] = (upperTransform[i, 0] - pivotPointSum) / u[i, i];
}
return solution;
}
}
}