用于对数似然的 fmincon 的快速替代方案
Speedy alternatives to fmincon for log-Likelihood
我目前正在使用 fmincon 最小化关于 18*18 矩阵的对数似然函数。虽然在较小的问题上算法非常快,但在当前设置中收敛大约需要 2 小时 - 因为我正在迭代这个最小化问题,运行 通过代码可能需要长达 2 周的时间。
是否有基于 matlab 的免费替代 fmincon 来提高此类特定问题的速度? (讨论了昂贵的解决方案 here, non-matlab solutions here。)或者我需要打电话给例如来自 matlab 的 python 脚本?
我要最小化的函数:
function [L] = logL(A, U, Sigma_e, T, lags)
% A - parameters to optimize w.r.t
logL = 0;
for t = 1 : T - lags
logL(t, 1) = 0.5*(log(det(A * diag(Sigma_e(t,:)) * A' ) ) + ...
U(t,:) * (A * diag(Sigma_e(t,:)) * A' )^(-1) * U(t,:)' );
end
L = sum(logL);
并通过以下方式调用它:
Options = optimset('Algorithm', 'active-set', 'Display', 'off', 'Hessian','bfgs', ...
'DerivativeCheck','on','Diagnostics','off','GradObj','off','LargeScale','off');
A = fmincon( @(A0)logL(A0, U, Sigma_e, T, lags), A0 , [], [] , [] , [] , [] , [] , [], Options);
(我尝试了不同的 fmincon 算法,但没有太大改进)。请注意,T 非常大~3000。
A和A0是一个18*18的矩阵,
Sigma_e为T*18,
U 为 T*18
我不知道 fminconst
有任何快速替代方法,但您可以向量化 logL
函数来加速算法。这是矢量化版本:
function [L] = logL(A, U, Sigma_e, T, lags)
ia = inv(A);
iat = ia.';
N = T - lags;
UU = zeros(N,1);
for t = 1: N
UU (t) = U(t,:) * (iat .* 1./Sigma_e(t,:) * ia) * U(t,:)';
end
L = 0.5 *sum( log(det(A) ^ 2 .* prod(Sigma_e(1:N,:),2)) + UU);
end
在 Octave 的一些测试中,它几乎比您的解决方案快 10 倍。
请注意,如果 Sigma_e
的某些元素等于零,您需要将 UU
计算为:
UU (t)=U(t,:) * (A * diag(Sigma_e(t,:)) * A' )^(-1) * U(t,:)';
这些关系用于将循环解决方案转换为矢量化解决方案:
det(a * b * c) == det(a) * det(b) * det(c)
det(a) == det(a.')
det(diag(a)) == prod(a)
(a * b * c)^-1 == c^-1 * b^-1 * a^-1
a * diag(b) == a .* b
inv(diag(a)) == diag(1./a)
我目前正在使用 fmincon 最小化关于 18*18 矩阵的对数似然函数。虽然在较小的问题上算法非常快,但在当前设置中收敛大约需要 2 小时 - 因为我正在迭代这个最小化问题,运行 通过代码可能需要长达 2 周的时间。
是否有基于 matlab 的免费替代 fmincon 来提高此类特定问题的速度? (讨论了昂贵的解决方案 here, non-matlab solutions here。)或者我需要打电话给例如来自 matlab 的 python 脚本?
我要最小化的函数:
function [L] = logL(A, U, Sigma_e, T, lags)
% A - parameters to optimize w.r.t
logL = 0;
for t = 1 : T - lags
logL(t, 1) = 0.5*(log(det(A * diag(Sigma_e(t,:)) * A' ) ) + ...
U(t,:) * (A * diag(Sigma_e(t,:)) * A' )^(-1) * U(t,:)' );
end
L = sum(logL);
并通过以下方式调用它:
Options = optimset('Algorithm', 'active-set', 'Display', 'off', 'Hessian','bfgs', ...
'DerivativeCheck','on','Diagnostics','off','GradObj','off','LargeScale','off');
A = fmincon( @(A0)logL(A0, U, Sigma_e, T, lags), A0 , [], [] , [] , [] , [] , [] , [], Options);
(我尝试了不同的 fmincon 算法,但没有太大改进)。请注意,T 非常大~3000。 A和A0是一个18*18的矩阵, Sigma_e为T*18, U 为 T*18
我不知道 fminconst
有任何快速替代方法,但您可以向量化 logL
函数来加速算法。这是矢量化版本:
function [L] = logL(A, U, Sigma_e, T, lags)
ia = inv(A);
iat = ia.';
N = T - lags;
UU = zeros(N,1);
for t = 1: N
UU (t) = U(t,:) * (iat .* 1./Sigma_e(t,:) * ia) * U(t,:)';
end
L = 0.5 *sum( log(det(A) ^ 2 .* prod(Sigma_e(1:N,:),2)) + UU);
end
在 Octave 的一些测试中,它几乎比您的解决方案快 10 倍。
请注意,如果 Sigma_e
的某些元素等于零,您需要将 UU
计算为:
UU (t)=U(t,:) * (A * diag(Sigma_e(t,:)) * A' )^(-1) * U(t,:)';
这些关系用于将循环解决方案转换为矢量化解决方案:
det(a * b * c) == det(a) * det(b) * det(c)
det(a) == det(a.')
det(diag(a)) == prod(a)
(a * b * c)^-1 == c^-1 * b^-1 * a^-1
a * diag(b) == a .* b
inv(diag(a)) == diag(1./a)