所以,我想知道是否使代码更容易阅读会降低Matlab的性能。
function V = example(t, I)
a = 10;
b = 20;
c = 0.5;
V = zeros(1, length(t));
V(1) = 0;
delta_t = t(2) - t(1);
for i=1:length(t)-1
V(i+1) = V(i) + delta_t*feval(@V_prime,a,b,c,t(i));
end;
所以,这个函数只是欧拉方法的一个例子。我的想法是命名常量变量a,b,c并定义导数的函数。这基本上使代码更容易阅读。我想知道的是,如果声明a,b,c会降低我的代码速度。另外,为了提高性能,最好将导数公式(V_prime)直接放在方程上而不是调用它? 遵循这种心态,代码看起来就像这样。
function V = example(t, I)
V = zeros(1, length(t));
V(1) = 0;
delta_t = t(2) - t(1);
for i=1:length(t)-1
V(i+1) = V(i) + delta_t*(((10 + t(i)*3)/20)+0.5);
同样从我读过的内容来看,当代码被矢量化时,Matlab表现得更好,我的代码就是这种情况吗?
编辑: 所以,这是我正在处理的实际代码:
function [V, u] = Izhikevich_CA1_Imp(t, I_amp, t_inj)
vr = -61.8; % resting potential (mV)
vt = -57.0; % threshold potential (mV)
c = -65.8; % reset membrane potential (mV)
vpeak = 22.6; % membrane voltage cutoff
khigh = 3.3; % nS/mV
klow = 0.1; % nS/mV
C = 115; % Membrane capacitance (pA)
a = 0.0012; % 1/ms
b = 3; % nS
d = 10; % pA
V = zeros(1, length(t));
V(1) = vr; u = 0; % initial values
span = length(t)-1;
delta_t = t(2) - t(1);
for i=1:span
if (V(i) <= vt)
k = klow;
else
k = khigh;
end;
if ((t(i) >= t_inj(1)) && (t(i) <= t_inj(2)))
I_inj = I_amp;
else I_inj = 0;
end;
V(i+1) = V(i) + delta_t*((k*(V(i)-vr)*(V(i)-vt)-u(i)+I_inj)/C);
u(i+1) = u(i) + delta_t*(a*(b*(V(i)-vr)-u(i)));
if (V(i+1) >= vpeak)
V(i+1) = c;
V(i) = vpeak;
u(i+1) = u(i+1) + d;
end;
end;
plot(t,V);
由于我没有接受任何Matlab培训(通过尝试和失败来学习),我有编程的C语言,而且根据我的理解,Matlab代码应该被矢量化。 最终我将开始使用更大的功能,因此性能将成为一个问题。现在我的目标是对这段代码进行矢量化。
答案 0 :(得分:3)
通常 更快。
特别是如果您更换循环函数调用(例如plot()
),将看到性能显着提升。
在我过去的一个项目中,我不得不优化一个程序。这个是使用常规程序规则(for,while等)制作的。使用矢量化,我的性能提高了10倍,这是非常值得注意的。
我建议大多数时候使用矢量化而不是循环。
答案 1 :(得分:1)
在matlab上,你基本上应该忘记来自低级C编程的思维方式。
根据我的经验,在matlab中实现性能的第一条规则是避免循环并尽可能使用内置的矢量化函数。通常,您应该尽量避免直接访问array(i)
等数组元素。
实现自己的ODE求解器不可避免地导致执行速度非常慢,因为在这种情况下,即使您的实现本身很好(例如在您的情况下),也无法避免上述情况。我强烈建议依靠matlab的ode求解器,它们是高度优化的编译代码块,并且比你可以编写的任何解释的matlab代码快得多。
在我看来,这也伴随着代码的可读性,至少是因为你获得更短代码的微不足道的原因......但我想这也是个人品味的问题。