返回行列式向量-Matlab

返回行列式向量-Matlab,matlab,matrix,Matlab,Matrix,我有一个3维Y(I,j,w)的矩阵。 我想得到一个行列式向量d(w),其中每个数字都是矩阵的行列式 Y(:,:,w) 是否有一个优雅的语法,或者我只需要使用一个循环 谢谢首先,事实上,你永远不会真正想要计算行列式,你只是认为你需要。事实上,这几乎从来都不是一件好事,因为决定因素的规模太小了。它们常常被用来推断矩阵的奇异性状态,这在数值分析中是一件可怕的事情 说了我对一般行列式的小咆哮 备选案文1: 将三维阵列转换为方阵单元阵列,阵列的每个平面作为一个单元。mat2cell将轻松有效地完成此任务

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

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


谢谢

首先,事实上,你永远不会真正想要计算行列式,你只是认为你需要。事实上,这几乎从来都不是一件好事,因为决定因素的规模太小了。它们常常被用来推断矩阵的奇异性状态,这在数值分析中是一件可怕的事情

说了我对一般行列式的小咆哮

备选案文1:

将三维阵列转换为方阵单元阵列,阵列的每个平面作为一个单元。mat2cell将轻松有效地完成此任务

接下来,在cell阵列上使用cellfun。cellfun可以对每个单元格应用一个函数(@det),然后返回行列式向量。这是非常有效的吗?与在循环中应用det相比,这可能不是一个巨大的收益,只要在编写循环时预先分配向量

备选案文2:

如果矩阵很小,比如说2x2或3x3矩阵,那么将行列式的乘法扩展为显式向量乘法。我认为这在我写这篇文章时并不清楚,所以对于2x2的情况,Y是2xn:

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,额外的开销是致命的。(我猜不出盈亏平衡点落在哪里,但可以很容易地进行测试。)

我会使用arrayfun:

d = arrayfun(@(w) det(Y(:, :, w)), 1 : size(Y, 3));
编辑:速度测试:

p = 10;
n = 1e4;
Y = rand(p,p,n);
测试1:

>> tic, d1 = arrayfun(@(w) det(Y(:, :, w)), 1 : size(Y, 3)); toc
Elapsed time is 0.139030 seconds.
测试2(通过木片):

测试3(简单方法):


结论:朴素的方法是最快的。

我更喜欢选项1,甚至是循环而不是选项2。如果循环中解释器的速度损失很大,我会感到震惊,我更喜欢更灵活的代码。想象一下这样做5x5行列式way@ChrisA-12.041883/0.002141=5624.4是令人震惊的差异吗?+1是!回答很好。也许有一个更灵活的方法来做这件事。。。因为随着
p,术语的数量越来越大,所以它变得非常糟糕
@Day\u Dreamer,你应该总是用“家庭作业”标签标记属于家庭作业的帖子。实际上,这不是家庭作业,只是其中的一小部分。即使有一个循环,代码也能正常工作,但我想拓宽我的视野。你可以使用@woodchips answer中的测试用例,在这种语法和cellfun和特殊情况选项之间进行速度比较吗?@t Pearce,没问题,我添加了测试结果。结果将取决于
p
的大小:p=2,@woodchips的方式可能相当快。有趣的是,当p=10时,循环速度比arrayfun快。
>> tic, X = squeeze(mat2cell(Y,p,p,ones(1,n))); d2= cellfun(@det,X); toc
Elapsed time is 1.318396 seconds.
>> p = 10;
>> n = 1e4;
>> Y = rand(p,p,n);
>> tic; d = nan(n, 1); for w = 1 : length(d), d(w) = det(Y(:, :, w)); end; toc
Elapsed time is 0.069279 seconds.