Table Of Contents

Source code for dolo.compiler.compiler_global

"""
symbolic model -> compiled model

"""


from dolo.compiler.compiler_functions import model_to_fg
from dolo.misc.caching import memoized

import numpy


[docs]class CModel: """ something to document """ model_type = 'fg' def __init__(self,model, keep_auxiliary=True, solve_systems=True, compiler='numpy'): "something to document" from dolo.compiler.compiler_python import GModel if isinstance(model, CModel): return model elif isinstance(model, GModel): model = model.model self.model = model self.states = [str(v) for v in model.symbols_s['states']] self.controls = [str(v) for v in model.symbols_s['controls']] self.shocks = [str(v) for v in model.symbols_s['shocks']] self.parameters = [str(v) for v in model.symbols_s['parameters']] self.__compiler__ = compiler if not keep_auxiliary: [f,g] = model_to_fg(model,solve_systems=solve_systems, compiler=compiler) self.__f__ = f self.__g__ = g else: [f,g,a] = model_to_fg(model,solve_systems=solve_systems, compiler=compiler) self.__f__ = f self.__g__ = g self.__a__ = a self.auxiliaries = [str(v) for v in model.symbols_s['auxiliary']] self.__f_h__ = [] self.__g_h__ = [] def g(self,s,x,e,p,derivs=False): if self.__compiler__ == 'numpy': return self.__g__(s,x,e,p,derivs=derivs) elif derivs is False: return self.__g__(s,x,e,p) else: g_0 = self.__g__(s,x,e,p) g_s = numdiff( lambda l: self.__g__(l,x,e,p), s, g_0) g_x = numdiff( lambda l: self.__g__(s,l,e,p), x, g_0) g_e = numdiff( lambda l: self.__g__(s,x,l,p), e, g_0) return [g_0, g_s, g_x, g_e] def f(self,s,x,S,X,E,p,derivs=False): if self.__compiler__ == 'numpy': return self.__f__(s,x,S,X,E,p,derivs=derivs) elif derivs is False: return self.__f__(s,x,S,X,E,p) else: f_0 = self.__f__(s,x,S,X,E,p) f_s = numdiff(lambda l: self.__f__(l,x,S,X,E,p), s, f_0) f_x = numdiff(lambda l: self.__f__(s,l,S,X,E,p), x, f_0) f_S = numdiff(lambda l: self.__f__(s,x,l,X,E,p), S, f_0) f_X = numdiff(lambda l: self.__f__(s,x,S,l,E,p), X, f_0) f_E = numdiff(lambda l: self.__f__(s,x,S,X,l,p), X, f_0) return [f_0, f_s, f_x, f_S, f_X, f_E] def a(self,s,x,p,derivs=False): if self.__compiler__ == 'numpy': return self.__a__(s,x,p,derivs=derivs) elif derivs is False: return self.__a__(s,x,p) else: a_0 = self.__a__(s,x,p) a_s = numdiff(lambda l: self.__f__(l,x,p), s, f_0) a_x = numdiff(lambda l: self.__f__(s,l,p), x, f_0) return [a_0, a_s, a_x] @property @memoized def x_bounds(self): # TODO : bounds should be compiled in __init__ (after sgm cleanup) model = self.model complementarities_tags = [eq.tags.get('complementarity') for eq in model.equations_groups['arbitrage']] import re regex = re.compile('(.*)<=(.*)<=(.*)') parsed = [ [model.eval_string(e) for e in regex.match(s).groups()] for s in complementarities_tags] lower_bounds_symbolic = [p[0] for p in parsed] controls = [p[1] for p in parsed] upper_bounds_symbolic = [p[2] for p in parsed] try: controls == model.symbols_s['controls'] except: raise Exception("Order of complementarities does not match order of declaration of controls.") states = model.symbols_s['states'] parameters = model.parameters from dolo.compiler.function_compiler import compile_multiargument_function lb = compile_multiargument_function( lower_bounds_symbolic, [states], ['s'], parameters, fname='lb') ub = compile_multiargument_function( upper_bounds_symbolic, [states], ['s'], parameters, fname='ub' ) return [lb,ub] def as_type(self,model_type): if model_type == 'fg': return self else: raise Exception('Model of type {0} cannot be cast to model of type {1}'.format(self.model_type, model_type)) def f_h(self, v, p, order=1): # if self.__f_h__.get(order) is None: if len(self.__f_h__) == 0: functions = model_to_fg(self.model, order=order) self.__f_h__[order] = functions return self.__f_h__[order](v,p) def g_h(self, v, p, order=1): # if self.__g_h__.get(order) is None: if len(self.__g_h__) == 0: functions = model_to_fg(self.model, order=order) for i,f in enumerate(functions): self.__g_h__[i] = f return self.__g_h__[order](v,p)
def numdiff(f,x0,f0=None): eps = 1E-6 if f0 == None: f0 = f(x0) p = f0.shape[0] q = x0.shape[0] N = x0.shape[1] df = numpy.zeros( (p,q,N) ) for i in range(q): x = x0.copy() x[i,:] += eps ff = f(x) df[:,i,:] = (ff - f0)/eps return df