In [1]:
import sys
sys.path.append('../..')
import PyMB
In [2]:
m = PyMB.model(name='linreg')
See the TMB tutorial for more information on writing custom models
In [3]:
linreg_code = '''
#include <TMB.hpp>
template<class Type>
Type objective_function<Type>::operator() (){
// DATA
DATA_VECTOR(Y);
DATA_VECTOR(x);
// PARAMETERS
PARAMETER(alpha);
PARAMETER(Beta);
PARAMETER(logSigma);
// MODEL
vector<Type> Y_hat = alpha + Beta*x;
REPORT(Y_hat);
Type nll = -sum(dnorm(Y, Y_hat, exp(logSigma), true));
return nll;
}
'''
See additional compiler options such as setting the R and TMB library directories via help(PyMB.model.compile)
In [4]:
m.compile(codestr=linreg_code)
In [5]:
import numpy as np
m.data['x'] = np.arange(10)
m.data['Y'] = m.data['x'] + 0.5 + np.random.rand(10)
In [6]:
m.init['alpha'] = 0.
m.init['Beta'] = 0.
m.init['logSigma'] = 0.
The model likelihood will be integrated wrt the random parameters. See here for more information.
In [7]:
m.random = ['alpha', 'Beta']
In [8]:
m.optimize()
In [9]:
import scipy.sparse.linalg
import scikits.sparse.cholmod
from scipy.sparse import csc_matrix
import numpy as np
from PyMB import get_R_attr
r = m.R.r
In [10]:
R_mu = get_R_attr(m.sdreport, 'par.random')
py_mu = np.array(R_mu)
In [11]:
joint_prec_full = get_R_attr(m.sdreport, 'jointPrecision')
R_joint_prec = r('function(mat, ran) { ii <- rownames(mat) %in% ran; return(mat[ii,ii]) }')(joint_prec_full, m.random)
py_joint_prec = np.array(r['as.matrix'](R_joint_prec))
In [12]:
R_z = r['matrix'](r['rnorm'](100*py_mu.shape[0]), ncol=100)
py_z = np.array(R_z)
In [14]:
R_chol = r['Cholesky'](R_joint_prec)
py_chol = scikits.sparse.cholmod.cholesky(csc_matrix(py_joint_prec))
In [16]:
R_Lz = r['solve'](r['t'](r['as'](R_chol, 'Matrix')), R_z)
py_Lz = scipy.sparse.linalg.spsolve(py_chol.L().T, py_z)
In [17]:
R_PLz = r['solve'](r['as'](R_chol, 'pMatrix'), R_Lz)
py_PLz = py_chol.apply_Pt(py_Lz)
In [18]:
R_draws = r('function(mu,PLz) { return(mu + PLz) }')(R_mu, R_PLz)
py_draws = py_mu.reshape([py_mu.shape[0],1]) + py_PLz
In [21]:
np.allclose(np.array(r['as.matrix'](R_draws)), py_draws)
Out[21]: