gpt4 book ai didi

matlab - 返回行列式向量 - Matlab

转载 作者:太空宇宙 更新时间:2023-11-03 19:39:39 25 4
gpt4 key购买 nike

我有一个包含 3 个维度 Y(i,j,w) 的矩阵。我想得到一个行列式向量 d(w),其中每个数字都是矩阵的行列式Y(:,:,w).

是否有一个优雅的语法,或者我只需要使用一个循环?

谢谢

最佳答案

好吧,首先,您几乎从来没有真正想要计算行列式,您只是认为自己这样做。事实上,这几乎从来都不是一件好事,因为行列式的尺度太差了。它们经常被用来推断矩阵的奇点状态,这在数值分析方面是一件很糟糕的事情。

说完我对一般行列式的反对...

选项 1:

将 3 维数组转换为方阵元胞数组,数组的每个平面作为一个元胞。 mat2cell 将轻松高效地完成这项工作。

接下来,对元胞数组使用 cellfun。 cellfun 可以将一个函数 (@det) 应用于每个单元格,然后返回一个行列式向量。这是非常有效的吗?与在循环中应用 det 相比,这可能不会有太大的好处,只要您在编写循环时预先分配向量即可。

选项 2:

如果矩阵很小,比如 2x2 或 3x3 矩阵,则将行列式的乘法展开为显式向量乘法。我认为这在我写的时候还不清楚,所以对于 2x2 的情况,其中 Y 是 2x2xn:

d = Y(1,1,:).*Y(2,2,:) - Y(1,2,:).*Y(2,1,:);

您肯定会看到,对于矩阵 Y 的每个平面,这形成了一个由 2x2 行列式组成的向量。3x3 的情况也很简单,可以写为项的六个三向乘积。我没有仔细检查下面的 3x3 情况,但应该很接近。

d = Y(1,1,:).*Y(2,2,:).*Y(3,3,:) + ...
Y(2,1,:).*Y(3,2,:).*Y(1,3,:) + ...
Y(3,1,:).*Y(1,2,:).*Y(2,3,:) - ...
Y(3,1,:).*Y(2,2,:).*Y(1,3,:) - ...
Y(2,1,:).*Y(1,2,:).*Y(3,3,:) - ...
Y(1,1,:).*Y(3,2,:).*Y(2,3,:);

如您所见,选项 2 会非常快,并且它是矢量化的。

编辑:作为对 Chris 的回应,所需时间存在显着差异。考虑一组 1e5 矩阵所需的时间。

p = 2;
n = 1e5;
Y = rand(p,p,n);

tic,
d0 = squeeze(Y(1,1,:).*Y(2,2,:) - Y(2,1,:).*Y(1,2,:));
toc

Elapsed time is 0.002141 seconds.

tic,
X = squeeze(mat2cell(Y,p,p,ones(1,n)));
d1= cellfun(@det,X);
toc

Elapsed time is 12.041883 seconds.

这两个调用在浮点垃圾中返回相同的值。

std(d0-d1)
ans =
3.8312e-17

循环不会更好,事实上,肯定更糟。因此,如果我要编写一段代码来处理为数组中的许多此类矩阵生成行列式的任务,我将对 2x2 和 3x3 矩阵的代码进行特殊处理。我什至可以为 4x4 矩阵写出来。是的,写出来是乱七八糟的,但是所需要的时间却有很大的不同。

一个原因是 MATLAB 的 det 使用对 LU 的调用,分解矩阵。这在理论上比中型大矩阵的乘法更好,但对于 2x2 或 3x3,额外的开销是致命的。 (我不会猜测收支平衡点在哪里,但可以很容易地测试它。)

关于matlab - 返回行列式向量 - Matlab,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10861142/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com