在Matlab中缩短这个时间

在Matlab中缩短这个时间,matlab,vectorization,Matlab,Vectorization,设x=[1,…,t]为包含t分量和a和p数组的向量。我问自己是否有机会缩短这个,因为它看起来很麻烦: for n = 1:t for m = 1:n H(n,m) = A(n,m) + x(n) * P(n,m) end end 一个好的开始是 H = A + x*P 这可能不是一个有效的解决方案,您必须检查数组和向量的一致性,并确保使用正确的乘法,但这应该足以为您指明正确的方向。如果您是Matlab新手,请注意向量可以是1xn或nx1,即行向量和列向量是不

x=[1,…,t]
为包含
t
分量和
a
p
数组的向量。我问自己是否有机会缩短这个,因为它看起来很麻烦:

for n = 1:t
    for m = 1:n
        H(n,m) = A(n,m) + x(n) * P(n,m)
    end
end 
一个好的开始是

H = A + x*P
这可能不是一个有效的解决方案,您必须检查数组和向量的一致性,并确保使用正确的乘法,但这应该足以为您指明正确的方向。如果您是Matlab新手,请注意向量可以是
1xn
nx1
,即行向量和列向量是不同的种类,与许多编程语言不同。如果
x
不是您在rhs上想要的,您可能需要它的转置,即Matlab中的
x'


从一个角度来看,Matlab是一种数组语言,显式循环通常是不必要的,甚至不是一种好方法。

我的建议:
bsxfun(@times,x,p)+a

e、 g

返回

ans =  1
编辑: 阿姆罗是对的!使第二个循环取决于第一次使用
tril

H2 = tril(bsxfun(@times,x,P) + A);

顺便说一句,矩阵是正方形的,因为这也会产生其他问题,就像我在评论中指出的那样,除非是打字错误,否则第二个for循环计数器取决于第一个for循环计数器的计数器

如果是故意的,我想出了以下解决方案:

% some random data
t = 10;
x = (1:t)';
A = rand(t,t);
P = rand(t,t);

% double for-loop
H = zeros(t,t);
for n = 1:t
    for m = 1:n
        H(n,m) = A(n,m) + x(n) * P(n,m);
    end
end

% vectorized using linear-indexing
[a,b] = ndgrid(1:t,1:t);
idx = sub2ind([t t], nonzeros(tril(a)), nonzeros(tril(b)));
xidx = nonzeros(tril(a));
HH = zeros(t);
HH(tril(true(t))) = A(idx) + x(xidx).*P(idx);

% check the results are the same
assert(isequal(H,HH))

我更喜欢他的解决方案。这里唯一的优点是我不计算不必要的值(因为矩阵的上半部分是零),而另一个解决方案计算完整的矩阵,然后减少额外的内容。

tril(A+p.*repmat(x',1,t))

编辑。这适用于x为行向量时。 如果x是列向量,则使用
tril(a+P.*repmat(x,t,1))


如果您的示例代码是正确的,那么对于任何j>i,H(i,j)=0,例如X(1,2)。 例如,对于
t=3
,您可能需要

H = 

'A(1,1) + x(1) * P(1,1)'                          []                          []
'A(2,1) + x(2) * P(2,1)'    'A(2,2) + x(2) * P(2,2)'                          []
'A(3,1) + x(3) * P(3,1)'    'A(3,2) + x(3) * P(3,2)'    'A(3,3) + x(3) * P(3,3)'

由于第二个循环的范围是
1:n
,因此可以使用矩阵
A
p
的下三角部分进行计算

H = bsxfun(@times,x(:),tril(P)) + tril(A);

你确定这是正确的吗?问题中的第二个循环是m=1:n的
,而不是m=1:t的
(因此它取决于第一个循环计数器),除非这是一个输入错误。。。请仔细检查,我一直在尝试矢量化!是的,很容易修复:)+1来自我
H = bsxfun(@times,x(:),tril(P)) + tril(A);