高斯-牛顿求解器:矩形空矩阵分配不当
Gauss-Newton Solver: Improper assignment with rectangular empty matrix
我不明白为什么会收到此错误消息。我已经实现了高斯-牛顿求解器来求解线性方程组。
一直说"for i=1:m"
行的矩形空矩阵赋值不正确
function [x, l] = GS(A, b, x0, TOL)
[m n] = size(A);
l = 1;
x = [0;0;0];
while (true)
for i=1:m
sum1 = 0; sum2 = 0;
for j=1:i-1
sum1 = sum1 + A(i,j)*x(j);
for j=i+1:n
sum2 = sum2 + A(i,j)*x(j);
end
end
x(i) = (-sum1-sum2+b(i))./A(i,j);
end
if abs(norm(x) - norm(x0)) < TOL
break
end
x0 = x;
l = l + 1;
end
您的代码存在三处错误。
- 您的
for
循环语句未对齐。具体来说,您忘记在 i
循环(即 for j = 1 : i-1
) 中第一个 for
循环的末尾放置一个 end
关键字
- 您需要使用从
j = 1, 2
到 i-1
的 当前 解计算高斯-牛顿值。第一个for
循环需要使用x
,第二个for
循环从j = i+1
到n
需要使用x0
.
- 求解
x
的每个值时,需要除以正确的对角线系数。
因此:
function [x, l] = GS(A, b, x0, TOL)
[m n] = size(A);
l = 1;
x = [0;0;0];
while (true)
for i=1:m
sum1 = 0; sum2 = 0;
for j=1:i-1 %// CHANGE
sum1 = sum1 + A(i,j)*x(j); %// CHANGE
end
for j=i+1:n %// CHANGE
sum2 = sum2 + A(i,j)*x0(j);
end
x(i) = (-sum1-sum2+b(i))./A(i,i); %// CHANGE
end
if abs(norm(x) - norm(x0)) < TOL
break
end
x0 = x;
l = l + 1;
end
使用示例:
format long;
A = [6 1 1; 1 5 3; 0 2 4]
b = [1 2 3].';
[x,i] = GS(A, b, [0;0;0], 1e-10)
x =
0.048780487792648
-0.085365853612062
0.792682926806031
i =
21
这意味着需要 21 次迭代才能获得具有公差 1e-10
的解决方案。将其与 MATLAB 的内置逆函数进行比较:
x2 = A \ b
x2 =
0.048780487804878
-0.085365853658537
0.792682926829268
如您所见,我指定了 1e-10
的公差,这意味着我们保证有 10 位小数的准确性。我们当然可以看到 Gauss-Newton 给我们的和 MATLAB 给我们内置的之间有 10 位小数的精度。
我不明白为什么会收到此错误消息。我已经实现了高斯-牛顿求解器来求解线性方程组。
一直说"for i=1:m"
function [x, l] = GS(A, b, x0, TOL)
[m n] = size(A);
l = 1;
x = [0;0;0];
while (true)
for i=1:m
sum1 = 0; sum2 = 0;
for j=1:i-1
sum1 = sum1 + A(i,j)*x(j);
for j=i+1:n
sum2 = sum2 + A(i,j)*x(j);
end
end
x(i) = (-sum1-sum2+b(i))./A(i,j);
end
if abs(norm(x) - norm(x0)) < TOL
break
end
x0 = x;
l = l + 1;
end
您的代码存在三处错误。
- 您的
for
循环语句未对齐。具体来说,您忘记在i
循环(即for j = 1 : i-1
) 中第一个 - 您需要使用从
j = 1, 2
到i-1
的 当前 解计算高斯-牛顿值。第一个for
循环需要使用x
,第二个for
循环从j = i+1
到n
需要使用x0
. - 求解
x
的每个值时,需要除以正确的对角线系数。
for
循环的末尾放置一个 end
关键字
因此:
function [x, l] = GS(A, b, x0, TOL)
[m n] = size(A);
l = 1;
x = [0;0;0];
while (true)
for i=1:m
sum1 = 0; sum2 = 0;
for j=1:i-1 %// CHANGE
sum1 = sum1 + A(i,j)*x(j); %// CHANGE
end
for j=i+1:n %// CHANGE
sum2 = sum2 + A(i,j)*x0(j);
end
x(i) = (-sum1-sum2+b(i))./A(i,i); %// CHANGE
end
if abs(norm(x) - norm(x0)) < TOL
break
end
x0 = x;
l = l + 1;
end
使用示例:
format long;
A = [6 1 1; 1 5 3; 0 2 4]
b = [1 2 3].';
[x,i] = GS(A, b, [0;0;0], 1e-10)
x =
0.048780487792648
-0.085365853612062
0.792682926806031
i =
21
这意味着需要 21 次迭代才能获得具有公差 1e-10
的解决方案。将其与 MATLAB 的内置逆函数进行比较:
x2 = A \ b
x2 =
0.048780487804878
-0.085365853658537
0.792682926829268
如您所见,我指定了 1e-10
的公差,这意味着我们保证有 10 位小数的准确性。我们当然可以看到 Gauss-Newton 给我们的和 MATLAB 给我们内置的之间有 10 位小数的精度。