Я пытаюсь создать код, который решает линейные системы A * x = b.
Я сделал приведенный ниже код, используя процесс исключения Гаусса, и он работает каждый раз, когда в A нет нулей. Если в А есть нули, то иногда это работает, иногда нет. В основном я пробую альтернативу "A \ b" в MATLAB.
Есть ли лучший / более простой способ сделать это?
A = randn(5,5);
b = randn(5,1);
nn = size(A);
n = nn(1,1);
U = A;
u = b;
for c = 1:1:n
k = U(:,c);
for r = n:-1:c
if k(r,1) == 0
continue;
else
U(r,:) = U(r,:)/k(r,1);
u(r,1) = u(r,1)/k(r,1);
end
end
for r = n:-1:(c+1)
if k(r,1) == 0
continue;
else
U(r,:) = U(r,:) - U(r-1,:);
u(r,1) = u(r,1) - u(r-1,1);
end
end
end
x = zeros(size(b));
for r = n:-1:1
if r == n
x(r,1) = u(r,1);
else
x(r,1) = u(r,1);
x(r,1) = x(r,1) - U(r,r+1:n)*x(r+1:n,1);
end
end
error = A*x - b;
for i = 1:1:n
if abs(error(i)) > 0.001
disp('ERROR!');
break;
else
continue;
end
end
disp('x:');
disp(x);
Рабочий пример с 0:
A = [1, 3, 1, 3;
3, 4, 4, 1;
3, 0, 3, 9;
0, 4, 0, 1];
b = [3;
4;
5;
6];
Пример, который терпит неудачу (A * x-b не [0])
A = [1, 3, 1, 3;
3, 4, 4, 1;
0, 0, 3, 9;
0, 4, 0, 1];
b = [3;
4;
5;
6];
Объяснение моего алгоритма:
Допустим, у меня есть следующая матрица A:
|4, 1, 9|
|3, 4, 5|
|1, 3, 5|
Для первого столбца я делю каждую строку на первое число в строке, поэтому каждая строка начинается с 1
|1, 1/4, 9/4|
|1, 4/3, 5/3|
|1, 3, 5|
Затем я вычитаю последнюю строку с той, что над ней, и затем сделаю то же самое для строки выше и так далее.
|1, 1/4, 9/4|
|0, 4/3-1/4, 5/3-9/4|
|0, 3-4/3, 5-5/3|
|1, 0.25, 2.250|
|0, 1.083, -0.5833|
|0, 1.667, 3.333|
Затем я повторяю то же самое для остальных столбцов.
|1, 0.25, 2.250|
|0, 1, -0.5385|
|0, 1, 1.999|
|1, 0.25, 2.250|
|0, 1, -0.5385|
|0, 0, -8.7700|
|1, 0.25, 2.250|
|0, 1, -0.5385|
|0, 0, 1|
Те же самые операции, которые я выполняю в A, я делаю в b, поэтому система остается эквивалентной.
повторно UPDATE:
Я добавил это сразу после "для c = 1: 1: n"
Поэтому, прежде чем что-либо делать, он сортирует строки A (и b), чтобы в столбце «c» были элементы с уменьшением (0 будут оставлены в нижних строках A). Прямо сейчас это, кажется, работает для любой обратимой квадратной матрицы, хотя я не уверен, что это будет.
r = c;
a = r + 1;
while r <= n
if r == n
r = r + 1;
elseif a <= n
while a <= n
if abs(U(r,c)) < abs(U(a,c))
UU = U(r,:);
U(r,:) = U(a,:);
U(a,:) = UU;
uu = u(r,1);
u(r,1) = u(a,1);
u(a,1) = uu;
else
a = a+1;
end
end
else
r = r+1;
a = r+1;
end
end