MATLAB代码需要太多的编译时间
我正在计算这个 但是代码需要大约8小时来编译。尤其是MATLAB代码需要太多的编译时间,matlab,optimization,Matlab,Optimization,我正在计算这个 但是代码需要大约8小时来编译。尤其是e,Ft=[h(t);q(t)]和Omega是2x1矩阵(e'是1x2),Gamma是2x2矩阵,n=30。有人能帮我优化这个代码吗 我试着这样做: aux=[0;0]; for k=0:29 for j=1:k-1 aux=[aux Gamma^j*Omega]; end E(t,k+1)= e'*(sum(aux,2)+Gamma^k*[h(t);q(t)]); end Vix=1/30*sum(E,2);
e
,Ft=[h(t);q(t)]
和Omega
是2x1矩阵(e'
是1x2),Gamma
是2x2矩阵,n=30
。有人能帮我优化这个代码吗
我试着这样做:
aux=[0;0];
for k=0:29
for j=1:k-1
aux=[aux Gamma^j*Omega];
end
E(t,k+1)= e'*(sum(aux,2)+Gamma^k*[h(t);q(t)]);
end
Vix=1/30*sum(E,2);
编辑
现在我换成这个,速度更快,但我不确定我是否正确应用了图片中的公式
for t=2:T
% 1. compute today's volatility
csi(t) = log(SP500(t)/SP500(t-1))-r(t)+0.5*h(t);
q(t+1) = omega+rho*q(t)+phi*((csi(t)-lambda*sqrt(h(t)))^2-h(t));
h(t+1) = q(t)+alpha*((csi(t)-lambda*sqrt(h(t)))^2-q(t))+beta*(h(t)-q(t));
for k=1:30
aux=zeros(2,k);
for j=0:k-1
aux(:,j+1)=Gamma^j*Omega;
end
E(t,k)= e'*(sum(aux,2)+Gamma^k*[h(t);q(t)]);
end
end
Vix(2:end)=1/30*sum(E(2:end,:),2);
(我不需要Vix(1))以下是我可以想到的一些原因: 重复复制(无预分配)长时间运行的主要原因是行
aux=[aux Gamma^j*Omega]
行,在该行中,数组
在每次循环迭代中串联。MATLAB的调试器应该在其编辑器中为您标记这一点,并且应该使用零实现“memorypreallocation”
本质上,当一个人以这种方式连接数组时,MATLAB在每次循环迭代时都会在内部复制数组,因此,除了数学运算外,还会进行复制。随着阵列的增长,复制操作变得越来越昂贵。这可以通过预分配来避免,预分配包括预定义存储阵列的大小(在本例中为变量aux
),这样MATLAB就不必在运行中不断分配空间。尝试:
aux = zeros(2, 406); %Creates a 2 by 406 array. I explain how I get 406 below:
p = 0; %A variable that indexes the columns of aux
for k=0:29
for j=1:k-1
p = p+1; %Update column counter
aux(:,p) = Gamma^j*Omega; % A 2x2 matrix multiplied by a 2x1 matrix yields a 2x1.
end
E(t,k+1)= e'*(sum(aux,2)+Gamma^k*[h(t);q(t)]);
end
Vix=1/30*sum(E,2);
现在,MATLAB只是覆盖aux
的各个元素,而不是复制aux
,并将其与Gamma^j*Omega
连接,然后覆盖aux
。从本质上讲,上述情况使MATLAB将空间分配给aux
一次,而不是406次。通过运行以下代码,我发现aux
最终是n=30
情况下的一个2×406数组:
p = 0;
for k = 0:29
for j = 1:k-1
p = p + 1;
end
end
要知道其他n
值的aux
的最终大小,您应该查看是否有可用的公式(或推导您自己的公式)
常数的循环换位?
接下来,e'
。您可能知道,“
是转置操作。从示例代码中,变量e
未在for
循环中编辑,但在for
循环的外部中有'
运算符。如果在外部for
循环之外执行一次转置操作,可以节省每次循环迭代转置的费用
运行总数
最后,我建议将sum(aux,2)
替换为一个保持运行总数的变量。这是因为目前,这使得MATLAB在每次循环迭代时对整个aux
求和
希望这对mate有所帮助。以下是我能想到的一些原因:
重复复制(无预分配)长时间运行的主要原因是行aux=[aux Gamma^j*Omega]
行,在该行中,数组
在每次循环迭代中串联。MATLAB的调试器应该在其编辑器中为您标记这一点,并且应该使用零实现“memorypreallocation”
本质上,当一个人以这种方式连接数组时,MATLAB在每次循环迭代时都会在内部复制数组,因此,除了数学运算外,还会进行复制。随着阵列的增长,复制操作变得越来越昂贵。这可以通过预分配来避免,预分配包括预定义存储阵列的大小(在本例中为变量aux
),这样MATLAB就不必在运行中不断分配空间。尝试:
aux = zeros(2, 406); %Creates a 2 by 406 array. I explain how I get 406 below:
p = 0; %A variable that indexes the columns of aux
for k=0:29
for j=1:k-1
p = p+1; %Update column counter
aux(:,p) = Gamma^j*Omega; % A 2x2 matrix multiplied by a 2x1 matrix yields a 2x1.
end
E(t,k+1)= e'*(sum(aux,2)+Gamma^k*[h(t);q(t)]);
end
Vix=1/30*sum(E,2);
现在,MATLAB只是覆盖aux
的各个元素,而不是复制aux
,并将其与Gamma^j*Omega
连接,然后覆盖aux
。从本质上讲,上述情况使MATLAB将空间分配给aux
一次,而不是406次。通过运行以下代码,我发现aux
最终是n=30
情况下的一个2×406数组:
p = 0;
for k = 0:29
for j = 1:k-1
p = p + 1;
end
end
要知道其他n
值的aux
的最终大小,您应该查看是否有可用的公式(或推导您自己的公式)
常数的循环换位?
接下来,e'
。您可能知道,“
是转置操作。从示例代码中,变量e
未在for
循环中编辑,但在for
循环的外部中有'
运算符。如果在外部for
循环之外执行一次转置操作,可以节省每次循环迭代转置的费用
运行总数
最后,我建议将sum(aux,2)
替换为一个保持运行总数的变量。这是因为目前,这使得MATLAB在每次循环迭代时对整个aux
求和
希望这对mate有所帮助。“编译”是指将代码翻译成机器指令。这需要几分之一秒的时间。运行代码需要8个小时。如果需要帮助,您必须包含完整的代码(请参阅)。您确定要将k
的每次迭代添加到aux
?在我看来,这并不正确,因为您在该循环中使用了sum(aux)
。我也不明白,如果你要做的只是取它的和,为什么要构建数组aux
。为什么不直接添加这些值呢aux=aux+Gamma^j*ω
?另外,您确定Gamma ^j是您当前计算的矩阵幂吗?我认为这是不可能的,符号的意思是不同的。并且在代码中也跳过了j=0