What about an option Numba dependency?Or, Numba emitting ahead of time compiled code.
def simulate_var(params, innovation='gaussian', nobs=None):
p = len(params)
k_endog = params[0].shape[0]
if innovation in ['g', 'gaussian']:
if nobs is None:
raise ValueError('nobs needs to be an integer if innovation is not array')
y = np.random.normal(size=(nobs + p, k_endog))
else:
y = np.asarray(innovation).copy()
if y.dtype != np.float:
import warnings
warnings.warn('dtype of innovation is not float')
n, k = y.shape
nobs = n - p
for t in range(p, n):
y[t] += sum(y[t - k].dot(A[k - 1]) for k in range(1, p+1))
return y
and a quick check with just a simple 3 variable VAR(2) with 1000 observations
VAR estimate lag 1
[[ 0.62 0.54 -0.04]
[ 0.01 0.46 0.06]
[ 0.06 -0.01 0.54]]
true lag 1
[[ 0.6 0.5 0. ]
[ 0. 0.5 0.1]
[ 0. 0. 0.5]]
VAR estimate lag 2
[[ 0.06 0.12 0.14]
[ 0.08 0.1 0.1 ]
[ 0.08 0.12 0.1 ]]
true lag 2
[[ 0.1 0.1 0.1]
[ 0.1 0.1 0.1]
[ 0.1 0.1 0.1]]
time.time for the VAR simulation loop 0.00586