我真的很难在MATLAB上优化微积分代码。
获得非线性材料的材料属性需要进行大量计算。
此计算需要超过2.4亿步。
它本身相当简单,因为它包含大量的sum
。
唯一的问题是数字存储在各种数组和列表中,这有点令人困惑。
以下是原始代码:
Tensor=zeros(3,3,3,3);
for m=1:3
for n=1:3
for o=1:3
for p=1:3
for x=1:16
for y=1:16
for z=1:16
for i=1:3
for j=1:3
for k=1:3
for l=1:3
for r=1:3
for s=1:3
sum=sum+(1/(8*(pi()^2))*P{x,y,z}(i,m)*P{x,y,z}(j,n)*P{x,y,z}(k,o)*P{x,y,z}(l,p)*(TensorC(i,j,k,l)-TensorC0(i,j,r,s))*TensorA(r,s,k,l)*sin(omega(x))*p_omega(x)*p_phi(y)*p_beta(z);
end
end
end
end
end
end
end
end
end
Tensor(m,n,o,p)=sum;
end
end
end
end
P{x,y,z}(i,m)
是对基础公式的更改(对其他公式相同):i and m
确定公式的类型,结果使用x
,y
和z
个变量。
求和中的所有其他数字都是在数组和张量中拾取的实数。
我试图从最后一个for循环中提取尽可能多的变量,以便尽快计算它们减少操作次数:
Tensor=zeros(3,3,3,3);
CO1=1/(8*(pi()^2));
for m=1:3
for n=1:3
for o=1:3
for p=1:3
sum=C0_tensor(m,n,o,p);
for x=1:16
CO7=sin(omega(x));
CO8=p_omega(x);
for y=1:16
CO9=p_phi(y);
for z=1:16
CO10=p_beta(z);
for i=1:3
CO2=P{x,y,z}(i,m);
for j=1:3
CO3=P{x,y,z}(j,n);
for k=1:3
CO4=P{x,y,z}(k,o);
for l=1:3
CO5=P{x,y,z}(l,p);
CO6=TensorC(i,j,k,l);
for r=1:3
for s=1:3
CO11=TensorC0(i,j,r,s);
CO12=TensorA(r,s,k,l);
sum=sum+CO1*CO2*CO3*CO4*CO5*(CO6-CO11)*CO12*CO7*CO8*CO9*CO10;
end
end
end
end
end
end
end
end
end
Tensor(m,n,o,p)=sum;
end
end
end
end
但是,计算太长了。
我没有看到任何平行化或矢量化计算的方法......
从一个数组或一个矩阵中检索一个特定值的操作似乎非常慢......
你认为我应该构建一个包含所有值的巨大张量而不是使用倍数吗?
答案 0 :(得分:1)
你不应该使用sum
作为变量名,因为你用相同的名称覆盖了有用的函数。
在此处仅使用内部循环,您计算每个r
和s
的单个值,该值将添加到您的输出值中:
for r=1:3
for s=1:3
CO11=TensorC0(i,j,r,s);
CO12=TensorA(r,s,k,l);
sum=sum+CO1*CO2*CO3*CO4*CO5*(CO6-CO11)*CO12*CO7*CO8*CO9*CO10;
end
end
然而,您可以立即将C011 / C012作为3 x 3矩阵,做一个总和,然后将其添加到您的输出:
(在此处将sum
更改为out
,请注意。*而不是*在适当的位置):
C011 = squeeze(TensorCO(i,j,:,:));
C012 = squeeze(TensorCO(:,:,k,l));
s = CO1*CO2*CO3*CO4*CO5*(CO6-CO11).*CO12*CO7*CO8*CO9*CO10;
out = out + sum(s(:));
此外,当你这样做时:
CO7=sin(omega(x));
CO8=p_omega(x);
(在后面的等式中就是C07 * C08) - 你不需要为每个n,m,p.
重新计算sin(omega(x)),这样就可以完全取出循环。
预先计算sin
并乘以p_omega
(外部循环):
omega78 = sin(omega).*p_omega;
然后只需检索x循环中的值C78 = omega78(x)
,然后使用它而不是C07*C08
。