为什么这个 Scilab 程序不能递归地找到行列式?
Why doesn't this Scilab program of finding the determinant recursively work?
我正在寻找 $N\timesN$ 矩阵的行列式。这是我的代码:
clc
function determinant=take_detm(A)
order=sqrt(length(A))
disp(order)
if order==2 then
determinant=A(1,1)*A(2,2)-A(1,2)*A(2,1);
else
s=0
for i=1:order
s=s+((-1)^(i+1))*A(1,i)*take_detm(A(:,i)=[]);//deleting 1st row and a column in the recursive call
end
determinant=s
end
endfunction
matr=input("Enter a matrix")
printf (string(take_detm(matr)))
这是问题所在:当我 运行 代码并输入矩阵时:[1 2 3 4;5 6 7 8;9 10 11 12;13 14 15 16] 控制台打印 4 (命令)和程序挂起。我收到 Windows 7 的滚动蓝色环,过了一段时间后,一条消息说 Scilab 6.0.1 已停止工作。是算法有问题还是其他什么?
PS-初级
问题出在 A(:,i)=[] 指令上。分配 [] 仅适用于一组完整的行或一组完整的行,因此您的指令只是删除了 A 矩阵的第 i 列(结果是矩形矩阵)
您可以通过
解决问题
Ai=A(2:order,[1:i-1 i+1:order])//deleting 1st row and column i
s=s+((-1)^(i+1))*A(1,i)*take_detm(Ai); //recursive call
但是请注意,Scilab det 函数更加精确和高效
好的,所以我有信心我明白了,因此回答我自己的问题。
当您想在 Scilab 中删除行 或 列时,您可以将其分配给 []。以下示例说明了这是如何工作的。
考虑矩阵
A=[1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16]
在控制台中打印为
A =
1. 2. 3. 4.
5. 6. 7. 8.
9. 10. 11. 12.
13. 14. 15. 16.
如果要删除第一行,命令为
A(1,:)=[]
A =
5. 6. 7. 8.
9. 10. 11. 12.
13. 14. 15. 16.
您只需将第一行分配给空矩阵。同样,如果你想删除第二列,你将它分配给空矩阵:
A(:,2)=[]
A =
5. 7. 8.
9. 11. 12.
13. 15. 16.
(请注意,该操作是在更新后的矩阵上执行的——即删除了第一行)
但是如果你想删除第一行和第二列,你不能写:
A(1,2)=[]
Scilab 说:
Submatrix incorrectly defined.
这是使用空矩阵赋值的替代解决方案:
总体思路:我们一个一个地执行 2 个操作:删除第 1 行,然后删除第 i 列。
仅发布 else 部分的代码:
else
s=0
first_row_removed=A //taking a backup of A and then...
first_row_removed(1,:)=[] //...removing the 1st row
for i=1:order
column_i_removed=first_row_removed //taking a backup of the 1st-row-removed matrix...
column_i_removed(:,i)=[] //... and then deleting column i
s=s+((-1)^(i+1))*A(1,i)*take_detm(column_i_removed); //recursive call
end
determinant=s
end //of else
需要注意的重要一点是,对空矩阵执行赋值会改变原始矩阵本身。因此,对于 for 循环的每次迭代,我们必须确保我们对第 1 行删除的矩阵执行删除第 ith 列操作,而不是对在之前的 for 循环迭代中删除第 i 列的矩阵执行。
因此线
column_i_removed=first_row_removed
必须在 for 循环内。
我正在寻找 $N\timesN$ 矩阵的行列式。这是我的代码:
clc
function determinant=take_detm(A)
order=sqrt(length(A))
disp(order)
if order==2 then
determinant=A(1,1)*A(2,2)-A(1,2)*A(2,1);
else
s=0
for i=1:order
s=s+((-1)^(i+1))*A(1,i)*take_detm(A(:,i)=[]);//deleting 1st row and a column in the recursive call
end
determinant=s
end
endfunction
matr=input("Enter a matrix")
printf (string(take_detm(matr)))
这是问题所在:当我 运行 代码并输入矩阵时:[1 2 3 4;5 6 7 8;9 10 11 12;13 14 15 16] 控制台打印 4 (命令)和程序挂起。我收到 Windows 7 的滚动蓝色环,过了一段时间后,一条消息说 Scilab 6.0.1 已停止工作。是算法有问题还是其他什么? PS-初级
问题出在 A(:,i)=[] 指令上。分配 [] 仅适用于一组完整的行或一组完整的行,因此您的指令只是删除了 A 矩阵的第 i 列(结果是矩形矩阵)
您可以通过
解决问题 Ai=A(2:order,[1:i-1 i+1:order])//deleting 1st row and column i
s=s+((-1)^(i+1))*A(1,i)*take_detm(Ai); //recursive call
但是请注意,Scilab det 函数更加精确和高效
好的,所以我有信心我明白了,因此回答我自己的问题。
当您想在 Scilab 中删除行 或 列时,您可以将其分配给 []。以下示例说明了这是如何工作的。 考虑矩阵
A=[1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16]
在控制台中打印为
A =
1. 2. 3. 4.
5. 6. 7. 8.
9. 10. 11. 12.
13. 14. 15. 16.
如果要删除第一行,命令为
A(1,:)=[]
A =
5. 6. 7. 8.
9. 10. 11. 12.
13. 14. 15. 16.
您只需将第一行分配给空矩阵。同样,如果你想删除第二列,你将它分配给空矩阵:
A(:,2)=[]
A =
5. 7. 8.
9. 11. 12.
13. 15. 16.
(请注意,该操作是在更新后的矩阵上执行的——即删除了第一行) 但是如果你想删除第一行和第二列,你不能写:
A(1,2)=[]
Scilab 说:
Submatrix incorrectly defined.
这是使用空矩阵赋值的替代解决方案: 总体思路:我们一个一个地执行 2 个操作:删除第 1 行,然后删除第 i 列。 仅发布 else 部分的代码:
else
s=0
first_row_removed=A //taking a backup of A and then...
first_row_removed(1,:)=[] //...removing the 1st row
for i=1:order
column_i_removed=first_row_removed //taking a backup of the 1st-row-removed matrix...
column_i_removed(:,i)=[] //... and then deleting column i
s=s+((-1)^(i+1))*A(1,i)*take_detm(column_i_removed); //recursive call
end
determinant=s
end //of else
需要注意的重要一点是,对空矩阵执行赋值会改变原始矩阵本身。因此,对于 for 循环的每次迭代,我们必须确保我们对第 1 行删除的矩阵执行删除第 ith 列操作,而不是对在之前的 for 循环迭代中删除第 i 列的矩阵执行。 因此线
column_i_removed=first_row_removed
必须在 for 循环内。