如何在 Matlab 上减少 DDE 仿真中的计算时间

计算科学 matlab 模拟
2021-12-06 05:24:12

我需要模拟一个节点网络。边的权重在矩阵中给出。由于节点之间的非零距离,我们考虑时间延迟,它是在给定距离和任意速度的情况下计算的。延迟值已经计算过了。鉴于A是对称的,对于n经过n矩阵,我们有m=n(n1)2 不同的时延。

load('A.mat'); % A is a symmetric matrix of dimensions n by n
load('tau.mat'); % tau is the delay array vector with n(n-1)/2 components
tf = 10;
sol = dde23(@(t,y,z)(dde(t,y,z,A)),tau,@(t)(history(t,A)),[0 tf]);
t = linspace(0,tf,200);
y = deval(sol,t);
figure
plot(t,y)

网络需要以其解析形式表示为一个动态系统:

x˙=A0x+A1x(tτ1)+...+Amx(tτm)

, 在哪里A0是初始的对角矩阵A矩阵,其中考虑到由于节点与自身之间的距离为零,因此没有延迟。在没有初始化方法的情况下m不同的矩阵n经过n,我创建了一个P矩阵如下。每个对称对A矩阵将被放在其各自的位置P并乘以相应的延迟。

function dydt = dde(t,y,yd,A)
 n = length(A);
 A0 = diag(diag(A));
 m = n*(n-1)/2;
 P = zeros(n,n*m);
 k = 0;
 for i = 1:n
     for j = 1:n
         if j>i
             P(i,j+n*k) = A(i,j);
             P(j,i+n*k) = A(i,j);
             k = k+1;
         end
     end
 end
dydt = A0*y;
for c = 0:m-1 
    dydt = dydt + P(:,n*c+1:(c+1)*n)*yd(:,c+1);
end
end
function y = history(t,A)
y = rand(length(A),1);
end

如果代码在技术上是正确的,那么它就不是有效的,因为即使对于少量节点,它产生结果的时间也会成倍增加。例如,对于 7 个节点的网络,需要 2.1 秒,8 个节点需要 7.6 秒,9 个节点需要 30 秒,10 个节点几乎需要 121 秒。这使得它对大型网络的使用令人望而却步。

这种指数级增长的计算成本有意义吗?

有什么办法可以减少计算时间?

1个回答

为了让我的评论更明确:

尝试使用以下代码来消除 DDE 函数P

function dydt = dde(t,y,yd,A)
  n = length(A);
  dydt = diag(A).*y;
  k = 0;
  for i = 1:n
    for j = (i+1):n
      dydt(i) += A(i,j)*yd(j,k);
      dydt(j) += A(i,j)*yd(i,k);
      k = k+1;
    end
  end
end

这消除了O(n3)的矩阵向量乘法,P填充yd的非零条目的工作P与直接更新导数向量大致相同,最昂贵的是显式双循环。

这种变化的可疑结果是运行时间普遍减少了 2 到 10(?),并且运行时间对n.

是的,对于较大配置的实验,您应该在 matlab 中使用编译代码,或在 python 中使用 JitCDDE(将代码转换为 C 或 Fortran 并使用已编译的例程)或使用相应的 julia-lang 库。