Matlab 如何从这些循环中得到矩阵的对角线?
我有一个8维经验copula的代码,它创建了一个8d矩阵,但我只需要矩阵的对角线,在这个代码中它被命名为EC。由于这段代码非常慢,我是否可以在不计算所有“ecop”的情况下得到“EC”Matlab 如何从这些循环中得到矩阵的对角线?,matlab,loops,for-loop,Matlab,Loops,For Loop,我有一个8维经验copula的代码,它创建了一个8d矩阵,但我只需要矩阵的对角线,在这个代码中它被命名为EC。由于这段代码非常慢,我是否可以在不计算所有“ecop”的情况下得到“EC” 函数EC=ecopula8d(x) [mn]=尺寸(x); y=排序(x); 对于r=1:m 对于q=1:m 对于p=1:m 对于o=1:m 对于l=1:m 对于k=1:m 对于j=1:m 对于i=1:m ecop(i,j,k,l,o,p,q,r)=和((x(:,1)我将使用的方法之一是将N-D数组转换为二维平方
函数EC=ecopula8d(x)
[mn]=尺寸(x);
y=排序(x);
对于r=1:m
对于q=1:m
对于p=1:m
对于o=1:m
对于l=1:m
对于k=1:m
对于j=1:m
对于i=1:m
ecop(i,j,k,l,o,p,q,r)=和((x(:,1)我将使用的方法之一是将N-D数组转换为二维平方(如果可能),然后简单地提取对角线项,因为在这两种情况下它们应该相等:
EC=diag(reshape(ecop,size1,size2));
我建议尝试使用Python,因为numpy有非常好和高效的线性代数包来处理N-D数组。Matlab在添加和更新其库方面非常慢。我将使用的一种方法是将N-D数组转换为二维正方形(如果可能的话)然后简单地提取对角线项,因为它们在两种情况下应该相等:
EC=diag(reshape(ecop,size1,size2));
我建议尝试使用Python,因为numpy有非常好的、高效的线性代数包来处理N-D数组。Matlab在添加和更新其库方面非常慢。我还没有检查您的初始计算是否正确(与wikipedia文章的公式相比),但您的代码应等效于:
[m n] = size(x);
y = sort(x);
for i = 1:m
EC(i,1) = sum(all(bsxfun(@le, x, y(i,:)), 2), 1)/(m+1);
end
我还没有检查您的初始计算是否正确(如将您的实现与wikipedia文章的公式进行比较),但您的代码应该相当于:
[m n] = size(x);
y = sort(x);
for i = 1:m
EC(i,1) = sum(all(bsxfun(@le, x, y(i,:)), 2), 1)/(m+1);
end
您可以使用完全矢量化的解决方案-
这里的神奇之处在于我们能够全速前进
这里有一个基准测试来比较这种方法和运行时效率-
x = rand(2000,2000);
y = sort(x);
m = size(x,1);
%// Warm up tic/toc.
for k = 1:100000
tic(); elapsed = toc();
end
disp('----------- With completely vectorized solution')
tic
EC1 = squeeze(sum(all(bsxfun(@le,x,permute(y,[3 2 1])),2),1))/(m+1);
toc, clear EC1
disp('----------- With partial vectorized solution')
tic
for i = 1:m
EC2(i,1) = sum(all(bsxfun(@le, x, y(i,:)), 2), 1)/(m+1);
end
toc
由此获得的运行时是-
----------- With completely vectorized solution
Elapsed time is 2.883594 seconds.
----------- With partial vectorized solution
Elapsed time is 4.752508 seconds.
一个可以为另一个部分矢量化方法预先分配-
EC2 = zeros(m,1);
for i = 1:m
EC2(i,1) = sum(all(bsxfun(@le, x, y(i,:)), 2), 1)/(m+1);
end
然而,由此获得的运行时并没有那么大的不同-
----------- With completely vectorized solution
Elapsed time is 2.963835 seconds.
----------- With partial vectorized solution
Elapsed time is 4.620455 seconds.
您可以使用完全矢量化的解决方案-
这里的神奇之处在于我们能够全速前进
这里有一个基准测试来比较这种方法和运行时效率-
x = rand(2000,2000);
y = sort(x);
m = size(x,1);
%// Warm up tic/toc.
for k = 1:100000
tic(); elapsed = toc();
end
disp('----------- With completely vectorized solution')
tic
EC1 = squeeze(sum(all(bsxfun(@le,x,permute(y,[3 2 1])),2),1))/(m+1);
toc, clear EC1
disp('----------- With partial vectorized solution')
tic
for i = 1:m
EC2(i,1) = sum(all(bsxfun(@le, x, y(i,:)), 2), 1)/(m+1);
end
toc
由此获得的运行时是-
----------- With completely vectorized solution
Elapsed time is 2.883594 seconds.
----------- With partial vectorized solution
Elapsed time is 4.752508 seconds.
一个可以为另一个部分矢量化方法预先分配-
EC2 = zeros(m,1);
for i = 1:m
EC2(i,1) = sum(all(bsxfun(@le, x, y(i,:)), 2), 1)/(m+1);
end
然而,由此获得的运行时并没有那么大的不同-
----------- With completely vectorized solution
Elapsed time is 2.963835 seconds.
----------- With partial vectorized solution
Elapsed time is 4.620455 seconds.
嗯。这看起来像是一个逻辑表达式,肯定可以加快速度。你能用你自己的话描述一下你在这里试图实现什么吗?在不知道这应该做什么的情况下,我会说:因为循环不依赖于它的计算:只需将所有变量j,k,l,o,p,q,r
替换为I
,摆脱它你的外循环和改变ecop(i,j,k,l,o,p,q,r)
到EC(i,1)
@knedlsepp我试图只找到ecop的对角线,它被称为EC,ecop是这里详述的经验copula:@knedlsepp你的意思是ecop计算是错误的吗?正如knedlsepp建议的那样,只使用ecop(i,i,i,i,i,i,i,i,i,i,i,i,i,i)嗯。这看起来像是一个逻辑表达式,肯定可以加快速度。你能用你自己的话描述一下你在这里试图实现什么吗?在不知道这应该做什么的情况下,我会说:因为循环不依赖于它的计算:只需将所有变量j,k,l,o,p,q,r
替换为I
,摆脱它你的外循环和改变ecop(i,j,k,l,o,p,q,r)
到EC(i,1)
@knedlsepp我试图只找到ecop的对角线,它被称为EC,ecop是这里详述的经验copula:@knedlsepp你的意思是ecop计算是错误的吗?正如knedlsepp建议的那样,只使用ecop(i,i,i,i,i,i,i,i,i,i,i,i,i,i)问题代码不是提取对角线元素,而是生成大量的N-D数组,这根本不需要!而且您建议的方法甚至不起作用!问题代码不是提取对角线元素,而是生成大量的N-D数组,这根本不需要完全正确!而且你建议的方法根本不起作用!@Fred:是的,我把它简化为两个步骤:首先,我们意识到ecop(I,j,k,l,o,p,q,r)
的每一次计算,除了ecop(I,I,I,I,I,I,I,I,I,I,I)i=1:m
是绝对无用的,因为这些值从未被使用过。因此我删除了i
循环之外的所有循环,并使用i
而不是变量名j,k,l,o,p,q,r
。然后只需替换。@弗雷德:是的,我将其简化为两个步骤:首先,我们意识到的每个计算de>ecop(i,j,k,l,o,p,q,r)
除了ecop(i,i,i,i,i,i)
和i=1:m
是绝对无用的,因为这些值从未被使用过。所以我删除了i
循环,使用i
而不是变量名j,k,l,o,p,q,r
。然后只需替换