def simulate( self, source=None, mask=None, pars=None, resid=None, init=None, operation=np.multiply, linear=False, debug=False, verbose=False, **args ): """Simulate time series given a series of exogenous innovations. Parameters ---------- source : dict Dict of `extract` results mask : array Mask for eps. Each non-None element will be replaced. """ pars = pars if pars is not None else source["pars"] resi = resid if resid is not None else source["resid"] init = init if init is not None else source["init"] sample = pars, resi, init if verbose: st = time.time() self.debug |= debug if hasattr(self, "pool"): from .estimation import create_pool create_pool(self) pickled_self = dill.dumps(self, recurse=True) def runner(arg): pelf = dill.loads(pickled_self) superflag = False par, eps, state = arg if mask is not None: eps = np.where(np.isnan(mask), eps, operation(np.array(mask), eps)) if pelf.set_par is not None: _, vv = pelf.set_par(par, return_vv=True, **args) if not np.all(vv == pelf.vv): raise Exception( "The ordering of variables has changed given different parameters." ) X = [state] L, K = [], [] for eps_t in eps: state, (l, k), flag = pelf.t_func( state, eps_t, return_k=True, linear=linear ) superflag |= flag X.append(state) L.append(l) K.append(k) X = np.array(X) LK = np.array((L, K)) K = np.array(K) return X, LK, superflag wrap = tqdm.tqdm if verbose else (lambda x, **kwarg: x) res = wrap( self.mapper(runner, zip(*sample)), unit=" sample(s)", total=len(source["pars"]), dynamic_ncols=True, ) X, LK, flags = map2arr(res) if verbose > 1: print( "[simulate:]".ljust(15, " ") + "Simulation took ", time.time() - st, " seconds.", ) if np.any(flags) and verbose: print("[simulate:]".ljust(15, " ") + "No OBC solution found (at least once).") return X, (LK[..., 0, :], LK[..., 1, :]), flags
def prior_draw(self, nsample, seed=None, ncores=None, verbose=False): """Draw parameters from prior. Drawn parameters have a finite likelihood. Parameters ---------- nsample : int Size of the prior sample ncores : int Number of cores used for prior sampling. Defaults to the number of available processors Returns ------- array Numpy array of parameters """ import pathos import warnings import tqdm import cloudpickle as cpickle from grgrlib import map2arr if seed is None: seed = 0 if verbose: print('[get_par:]'.ljust(15, ' ') + 'Drawing from the pior and checking likelihood.') if not hasattr(self, 'ndim'): self.prep_estim(load_R=True, verbose=verbose) if ncores > 1: lprob_dump = cpickle.dumps(self.lprob) lprob = cpickle.loads(lprob_dump) else: lprob = self.lprob frozen_prior = self.fdict['frozen_prior'] def runner(locseed): np.random.seed(seed + locseed) draw_prob = -np.inf while np.isinf(draw_prob): with warnings.catch_warnings(record=False): try: np.warnings.filterwarnings('error') rst = np.random.randint(2**16) pdraw = [pl.rvs(random_state=rst) for pl in frozen_prior] draw_prob = lprob(pdraw, None, verbose) except: pass return pdraw if ncores is None: ncores = pathos.multiprocessing.cpu_count() mapper = map if ncores > 1: loc_pool = pathos.pools.ProcessPool(ncores) loc_pool.clear() mapper = loc_pool.imap print('[get_cand:]'.ljust(15, ' ') + 'Sampling parameters from prior...') pmap_sim = tqdm.tqdm(mapper(runner, range(nsample)), total=nsample) ## to circumvent mem overflow if ncores > 1: loc_pool.close() loc_pool.join() return map2arr(pmap_sim)
def prior_sampler(self, nsamples, seed=0, test_lprob=False, lks=None, verbose=True, debug=False, **args): """Draw parameters from prior. Parameters ---------- nsamples : int Size of the prior sample seed : int, optional Set the random seed (0 by default) test_lprob : bool, optional Whether to ensure that drawn parameters have a finite likelihood (False by default) verbose : bool, optional debug : bool, optional Returns ------- array Numpy array of parameters """ import tqdm from grgrlib import map2arr, serializer from .stats import get_prior store_reduce_sys = np.copy(self.fdict['reduce_sys']) l_max, k_max = lks or (None, None) # if not store_reduce_sys: # self.get_sys(reduce_sys=True, verbose=verbose > 1, **args) if test_lprob and not hasattr(self, 'ndim'): self.prep_estim(load_R=True, verbose=verbose > 2) frozen_prior = get_prior(self.prior, verbose=verbose)[0] self.debug |= debug if hasattr(self, 'pool'): from .estimation import create_pool create_pool(self) set_par = serializer(self.set_par) get_par = serializer(self.get_par) lprob = serializer(self.lprob) if test_lprob else None def runner(locseed): np.random.seed(seed + locseed) done = False no = 0 while not done: no += 1 with np.warnings.catch_warnings(record=False): try: np.warnings.filterwarnings('error') rst = np.random.randint(2**31) # win explodes with 2**32 pdraw = [ pl.rvs(random_state=rst + sn) for sn, pl in enumerate(frozen_prior) ] if test_lprob: draw_prob = lprob(pdraw, linear=None, verbose=verbose > 1) done = not np.isinf(draw_prob) else: set_par(pdraw) done = True except Exception as e: if verbose > 1: print(str(e) + '(%s) ' % no) return pdraw, no if verbose > 1: print('[prior_sample:]'.ljust(15, ' ') + ' Sampling from the pior...') wrapper = tqdm.tqdm if verbose < 2 else (lambda x, **kwarg: x) pmap_sim = wrapper(self.mapper(runner, range(nsamples)), total=nsamples) draws, nos = map2arr(pmap_sim) # if not store_reduce_sys: # self.get_sys(reduce_sys=False, verbose=verbose > 1, **args) if verbose: smess = '' if test_lprob: smess = 'of zero likelihood, ' print( '[prior_sample:]'.ljust(15, ' ') + ' Sampling done. %2.2f%% of the prior is either %sindetermined or explosive.' % (100 * (sum(nos) - nsamples) / sum(nos), smess)) return draws
def irfs( self, shocklist, pars=None, state=None, T=30, linear=False, set_k=False, force_init_equil=None, verbose=True, debug=False, **args ): """Simulate impulse responses Parameters ---------- shocklist : tuple or list of tuples Tuple of (shockname, size, period) T : int, optional Simulation horizon. (default: 30) linear : bool, optional Simulate linear model (default: False) set_k: int, optional Enforce a `k` (defaults to False) force_init_equil: If set to `False`, the equilibrium will be recalculated every iteration. This may be problematic if there is multiplicity because the algoritm selects the equilibrium with the lowest (l,k) (defaults to True) verbose : bool or int, optional Level of verbosity (default: 1) Returns ------- DataFrame, tuple(int,int) The simulated series as a pandas.DataFrame object and the expected durations at the constraint """ self.debug |= debug if force_init_equil is None: force_init_equil = not bool(np.any(set_k)) if not isinstance(shocklist, list): shocklist = [ shocklist, ] if hasattr(self, "pool"): from .estimation import create_pool create_pool(self) st = time.time() nstates = self.dimx l_max, k_max = self.lks # accept all sorts of inputs new_shocklist = [] for vec in shocklist: if isinstance(vec, str): vec = (vec, 1, 0) elif len(vec) == 2: vec += (0,) new_shocklist.append(vec) pickled_self = dill.dumps(self, recurse=True) def runner(par): pelf = dill.loads(pickled_self) X = np.empty((T, nstates)) K = np.empty(T) L = np.empty(T) if np.any(par): try: pelf.set_par(par, **args) except ValueError: X[:] = np.nan K[:] = np.nan L[:] = np.nan return X, K, L, 4 st_vec = state if state is not None else np.zeros(nstates) supererrflag = False supermultflag = False l, k = 0, 0 for t in range(T): shk_vec = np.zeros(len(pelf.shocks)) for vec in new_shocklist: if vec[2] == t: shock = vec[0] shocksize = vec[1] shock_arg = pelf.shocks.index(shock) shk_vec[shock_arg] = shocksize # force_init_equil will force recalculation of l,k only if the shock vec is not empty # but loop must be skipped if no shock is provided at all (e.g. if samplinf from a state distribution) if force_init_equil and not np.any(shk_vec) and np.any([s[2] for s in new_shocklist]): set_k_eff = (l - 1, k) if l else (l, max(k - 1, 0)) _, (l_endo, k_endo), flag = pelf.t_func( st_vec[-(pelf.dimq - pelf.dimeps) :], shk_vec, set_k=None, linear=linear, return_k=True, ) multflag = l_endo != set_k_eff[0] or k_endo != set_k_eff[1] supermultflag |= multflag if verbose > 1 and multflag: print( "[irfs:]".ljust(15, " ") + "Multiplicity found in period %s: new eql. %s coexits with old eql. %s." % (t, (l_endo, k_endo), set_k_eff) ) elif set_k is None: set_k_eff = None elif isinstance(set_k, tuple): set_l_eff, set_k_eff = set_k if set_l_eff - t >= 0: set_k_eff = set_l_eff - t, set_k_eff else: set_k_eff = 0, max(set_k_eff + set_l_eff - t, 0) elif set_k: set_k_eff = 0, max(set_k - t, 0) else: set_k_eff = set_k if set_k_eff: if set_k_eff[0] > l_max or set_k_eff[1] > k_max: raise IndexError( "set_k exceeds l_max (%s vs. %s)." % (set_k_eff, (l_max, k_max)) ) st_vec, (l, k), flag = pelf.t_func( st_vec[-(pelf.dimq - pelf.dimeps) :], shk_vec, set_k=set_k_eff, linear=linear, return_k=True, ) if flag and verbose > 1: print( "[irfs:]".ljust(15, " ") + "No OBC solution found in period %s (error flag %s)." % (t, flag) ) supererrflag |= flag X[t, :] = st_vec L[t] = l K[t] = k return X, L, K, supererrflag, supermultflag if pars is not None and np.ndim(pars) > 1: res = self.mapper(runner, pars) X, L, K, flag, multflag = map2arr(res) else: X, L, K, flag, multflag = runner(pars) X = pd.DataFrame(X, columns=self.vv) if verbose == 1: if np.any(flag): print("[irfs:]".ljust(14, " ") + " No OBC solution(s) found.") elif np.any(multflag): print("[irfs:]".ljust(14, " ") + " Multiplicity/Multiplicities found.") if verbose > 2: print( "[irfs:]".ljust(15, " ") + "Simulation took ", np.round((time.time() - st), 5), " seconds.", ) return X, np.vstack((L, K)), flag
def irfs(self, shocklist, pars=None, T=30, linear=False, verbose=False): """Simulate impulse responses Parameters ---------- shocklist : tuple or list of tuples Tuple of (shockname, size, period) T : int Simulation horizon. (default: 30) Returns ------- DataFrame, tuple(int,int) The simulated series as a pandas.DataFrame object and the expected durations at the constraint """ if isinstance(shocklist, tuple): shocklist = [shocklist,] st = time.time() def irfs_runner(par): if np.any(par): self.set_par(par, autocompile=False) st_vec = np.zeros(len(self.vv)) X = np.empty((T, len(self.vv))) K = np.empty(T) L = np.empty(T) superflag = False for t in range(T): shk_vec = np.zeros(len(self.shocks)) for vec in shocklist: if vec[2] == t: shock = vec[0] shocksize = vec[1] shock_arg = self.shocks.index(shock) shk_vec[shock_arg] = shocksize st_vec, (l, k), flag = self.t_func( st_vec, shk_vec, linear=linear, return_k=True) superflag |= flag X[t,:] = st_vec L[t] = l K[t] = k return X, K, L, superflag if np.any(pars): res = self.mapper(irfs_runner, pars) X, K, L, flag = map2arr(res) else: X, K, L, flag = irfs_runner(pars) X = pd.DataFrame(X, columns=self.vv) if np.any(flag) and verbose: print('[irfs:]'.ljust(15, ' ') + 'No rational expectations solution found at least once.') if verbose: print('[irfs:]'.ljust(15, ' ') + 'Simulation took ', np.round((time.time() - st), 5), ' seconds.') return X, (K, L)
def simulate(self, source=None, mask=None, pars=None, resid=None, init=None, operation=np.multiply, linear=False, debug=False, verbose=False, **args): """Simulate time series given a series of exogenous innovations. Parameters ---------- source : dict Dict of `extract` results mask : array Mask for eps. Each non-None element will be replaced. """ from grgrlib.core import serializer pars = pars if pars is not None else source['pars'] resi = resid if resid is not None else source['resid'] init = init if init is not None else source['init'] sample = pars, resi, init if verbose: st = time.time() self.debug |= debug if hasattr(self, 'pool'): from .estimation import create_pool create_pool(self) if self.set_par is not None: set_par = serializer(self.set_par) else: set_par = None t_func = serializer(self.t_func) obs = serializer(self.obs) vv_orig = self.vv.copy() def runner(arg): superflag = False par, eps, state = arg if mask is not None: eps = np.where(np.isnan(mask), eps, operation(np.array(mask), eps)) if set_par is not None: _, vv = set_par(par, return_vv=True, **args) if not np.all(vv == vv_orig): raise Exception( 'The ordering of variables has changed given different parameters.' ) X = [state] L, K = [], [] for eps_t in eps: state, (l, k), flag = t_func(state, eps_t, return_k=True, linear=linear) superflag |= flag X.append(state) L.append(l) K.append(k) X = np.array(X) LK = np.array((L, K)) K = np.array(K) return X, LK, superflag wrap = tqdm.tqdm if verbose else (lambda x, **kwarg: x) res = wrap(self.mapper(runner, zip(*sample)), unit=' sample(s)', total=len(source['pars']), dynamic_ncols=True) X, LK, flags = map2arr(res) if verbose > 1: print('[simulate:]'.ljust(15, ' ') + 'Simulation took ', time.time() - st, ' seconds.') if np.any(flags) and verbose: print('[simulate:]'.ljust(15, ' ') + 'No rational expectations solution found (at least once).') return X, (LK[..., 0, :], LK[..., 1, :]), flags
def extract(self, sample=None, nsamples=1, init_cov=None, precalc=True, seed=0, nattemps=4, accept_failure=False, verbose=True, debug=False, l_max=None, k_max=None, **npasargs): """Extract the timeseries of (smoothed) shocks. Parameters ---------- sample : array, optional Provide one or several parameter vectors used for which the smoothed shocks are calculated (default is the current `self.par`) nsamples : int, optional Number of `npas`-draws for each element in `sample`. Defaults to 1 nattemps : int, optional Number of attemps per sample to crunch the sample with a different seed. Defaults to 4 Returns ------- tuple The result(s) """ import tqdm import os from grgrlib import map2arr if sample is None: if type(self).__name__ == "DSGE_DUMMY": sample = None else: sample = self.par if np.ndim(sample) <= 1: sample = [sample] np.random.seed(seed) fname = self.filter.name verbose = max(verbose, debug) if hasattr(self, "pool"): from .estimation import create_pool create_pool(self) run_filter = serializer(self.run_filter) if fname == "ParticleFilter": raise NotImplementedError elif fname == "KalmanFilter": if nsamples > 1: print( "[extract:]".ljust(15, " ") + " Setting `nsamples` to 1 as the linear filter does not rely on sampling." ) nsamples = 1 debug = not hasattr(self, "debug") or self.debug self.debug = True else: if self.filter.reduced_form: self.create_filter(R=self.filter.R, N=self.filter.N, reduced_form=False) print( "[extract:]".ljust(15, " ") + " Extraction requires filter in non-reduced form. Recreating filter instance." ) run_filter, npas = serializer(self.run_filter, self.filter.npas) self.debug |= debug if sample[0] is not None: set_par = serializer(self.set_par) t_func = serializer(self.t_func) edim = len(self.shocks) xdim = len(self.vv) odim = len(self.observables) obs_func = serializer(self.obs) filter_get_eps = serializer(self.get_eps_lin) dimeps = self.dimeps dimp = self.dimp # win explodes with 2**32 seeds = np.random.randint(2**31, size=nsamples) sample = [(x, y) for x in sample for y in seeds] def runner(arg): par, seed_loc = arg if par is not None: set_par(par, l_max=l_max, k_max=k_max) res = run_filter(verbose=verbose > 2, seed=seed_loc, init_cov=init_cov) if fname == "KalmanFilter": means, covs = res res = means.copy() resid = np.empty((means.shape[0] - 1, dimeps)) for t, x in enumerate(means[1:]): resid[t] = filter_get_eps(x, res[t]) res[t + 1] = t_func(res[t], resid[t], linear=True)[0] return par, res[0], resid, 0 np.random.shuffle(res) sample = np.dstack((obs_func(res), res[..., dimp:])) inits = res[:, 0, :] def t_func_loc(states, eps): (q, pobs), flag = t_func(states, eps, get_obs=True) return np.hstack((pobs, q)), flag for natt in range(nattemps): try: init, resid, flags = npas(func=t_func_loc, X=sample, init_states=inits, verbose=max( len(sample) == 1, verbose - 1), seed=seed_loc, nsamples=1, **npasargs) return par, init, resid[0], flags except Exception as e: raised_error = e if accept_failure: print("[extract:]".ljust(15, " ") + "got an error: '%s' (after %s unsuccessful attemps)." % (raised_error, natt + 1)) return None else: import sys raise type(raised_error)(str(raised_error) + " (after %s unsuccessful attemps)." % (natt + 1)).with_traceback( sys.exc_info()[2]) wrap = tqdm.tqdm if (verbose and len(sample) > 1) else (lambda x, **kwarg: x) res = wrap( self.mapper(runner, sample), unit=" sample(s)", total=len(sample), dynamic_ncols=True, ) pars, init, resid, flags = map2arr(res) if hasattr(self, "pool") and self.pool: self.pool.close() if fname == "KalmanFilter": self.debug = debug if resid.shape[0] == 1: resid[0] = pd.DataFrame(resid[0], index=self.data.index[:-1], columns=self.shocks) edict = {"pars": pars, "init": init, "resid": resid, "flags": flags} return edict
def run(self): """update the evolution paths and the distribution parameters m, sigma, and C within CMA-ES. """ par = self.params self.eigenvalues, self.eigenbasis = np.linalg.eigh(self.C) self.condition_number = np.linalg.cond(self.C) self.invsqrt = np.linalg.inv(np.linalg.cholesky(self.C)) z = self.sigma * self.eigenvalues**0.5 * self.randn() y = self.eigenbasis @ z.T xs = self.xmean + y.T res = self.map(self.objective_fct, xs) fs = map2arr(res) # interrupt if things don't go nicely if np.isinf(fs).all(): raise ValueError("Sample returns infs only.") self.counteval += len(fs) N = len(self.xmean) xold = self.xmean.copy() # sort by fitness xs = xs[fs.argsort()] self.fs = np.sort(fs) self.xs = xs self.best.update(xs[0], self.fs[0], self.counteval) # compute new weighted mean value via recombination self.xmean = xs[0:par.mu_mean].T @ par.weights_mean[:par.mu_mean] # update evolution paths via cumulation: y = self.xmean - xold z = self.invsqrt @ y csn = (par.cs * (2 - par.cs) * par.mueff)**0.5 / self.sigma # update evolution path self.ps = (1 - par.cs) * self.ps + csn * z ccn = (par.cc * (2 - par.cc) * par.mueff)**0.5 / self.sigma # turn off rank-one accumulation when sigma increases quickly hsig = par.cs and (np.sum(self.ps**2) / N # account for initial value of ps / (1 - (1 - par.cs)**(2 * self.counteval / par.lam)) < 2 + 4 / (N + 1)) self.pc = (1 - par.cc) * self.pc + ccn * hsig * y # covariance matrix adaption: # minor adjustment for the variance loss from hsig c1a = par.c1 * (1 - (1 - hsig**2) * par.cc * (2 - par.cc)) self.C *= 1 - c1a - par.cmu * np.sum(par.weights) # rank-one update self.C += par.c1 * np.outer(self.pc, self.pc) # rank-mu update for k, wk in enumerate(par.weights): # guaranty positive definiteness if wk < 0: mahalano = np.sum((self.invsqrt @ (xs[k] - xold))**2) wk *= N * self.sigma**2 / mahalano self.C += (wk * par.cmu / self.sigma**2 * np.outer(xs[k] - xold, xs[k] - xold)) # adapt step-size cn, sum_square_ps = par.cs / par.damps, np.sum(self.ps**2) self.sigma *= np.exp(np.minimum(1, cn * (sum_square_ps / N - 1) / 2))
def prior_sampler(self, nsample, seed=None, test_lprob=False, verbose=True): """Draw parameters from prior. Drawn parameters have a finite likelihood. Parameters ---------- nsample : int Size of the prior sample Returns ------- array Numpy array of parameters """ import tqdm from grgrlib import map2arr, serializer if seed is None: seed = 0 reduce_sys = np.copy(self.fdict['reduce_sys']) if not reduce_sys: self.get_sys(reduce_sys=True, verbose=verbose > 1) if test_lprob and not hasattr(self, 'ndim'): self.prep_estim(load_R=True, verbose=verbose > 2) if not 'frozen_prior' in self.fdict.keys(): from .stats import get_prior self.fdict['frozen_prior'] = get_prior(self.prior)[0] frozen_prior = self.fdict['frozen_prior'] if not hasattr(self, 'mapper'): self.mapper = map if hasattr(self, 'pool'): self.pool.clear() get_par = serializer(self.get_par) get_sys = serializer(self.get_sys) def runner(locseed): np.random.seed(seed + locseed) done = False no = 0 while not done: no += 1 with np.warnings.catch_warnings(record=False): try: np.warnings.filterwarnings('error') rst = np.random.randint(32**2 - 2) pdraw = [ pl.rvs(random_state=rst + sn) for sn, pl in enumerate(frozen_prior) ] if test_lprob: draw_prob = lprob(pdraw, None, verbose > 1) done = not np.isinf(draw_prob) else: pdraw_full = get_par(pdraw, asdict=False, full=True) get_sys(par=pdraw_full, reduce_sys=True) done = True except Exception as e: if verbose > 1: print(str(e) + '(%s) ' % no) return pdraw, no if verbose > 1: print('[prior_sample:]'.ljust(15, ' ') + ' sampling from the pior...') wrapper = tqdm.tqdm if verbose < 2 else (lambda x, **kwarg: x) pmap_sim = wrapper(self.mapper(runner, range(nsample)), total=nsample) draws, nos = map2arr(pmap_sim) if not reduce_sys: self.get_sys(reduce_sys=False, verbose=verbose > 1) if verbose: print( '[prior_sample:]'.ljust(15, ' ') + ' sampling done. %2.2f%% of the prior are either indetermined or explosive.' % (100 * (sum(nos) - nsample) / nsample)) return draws
def irfs(self, shocklist, pars=None, state=None, T=30, linear=False, verbose=True): """Simulate impulse responses Parameters ---------- shocklist : tuple or list of tuples Tuple of (shockname, size, period) T : int Simulation horizon. (default: 30) Returns ------- DataFrame, tuple(int,int) The simulated series as a pandas.DataFrame object and the expected durations at the constraint """ from grgrlib.core import serializer if isinstance(shocklist, tuple): shocklist = [ shocklist, ] if hasattr(self, 'pool'): from .estimation import create_pool create_pool(self) st = time.time() set_par = serializer(self.set_par) t_func = serializer(self.t_func) shocks = self.shocks nstates = len(self.vv) def runner(par): X = np.empty((T, nstates)) K = np.empty(T) L = np.empty(T) if np.any(par): try: set_par(par) except ValueError: X[:] = np.nan K[:] = np.nan L[:] = np.nan return X, K, L, 4 st_vec = state if state is not None else np.zeros(nstates) superflag = False for t in range(T): shk_vec = np.zeros(len(shocks)) for vec in shocklist: if vec[2] == t: shock = vec[0] shocksize = vec[1] shock_arg = shocks.index(shock) shk_vec[shock_arg] = shocksize st_vec, (l, k), flag = t_func(st_vec, shk_vec, linear=linear, return_k=True) superflag |= flag X[t, :] = st_vec L[t] = l K[t] = k return X, K, L, superflag if pars is not None and np.ndim(pars) > 1: res = self.mapper(runner, pars) X, K, L, flag = map2arr(res) else: X, K, L, flag = runner(pars) X = pd.DataFrame(X, columns=self.vv) if np.any(flag) and verbose: print('[irfs:]'.ljust(15, ' ') + 'No rational expectations solution found at least once.') if verbose > 1: print('[irfs:]'.ljust(15, ' ') + 'Simulation took ', np.round((time.time() - st), 5), ' seconds.') return X, (K, L)
def simulate(self, source, mask=None, linear=False, debug=False, verbose=False): """Simulate time series given a series of exogenous innovations. Parameters ---------- source : dict Dict of `extract` results mask : array Mask for eps. Each non-None element will be replaced. """ from grgrlib.core import serializer sample = zip(source['pars'], source['resid'], [s[0] for s in source['means']]) if verbose: st = time.time() self.debug |= debug if hasattr(self, 'pool'): from .estimation import create_pool create_pool(self) set_par = serializer(self.set_par) t_func = serializer(self.t_func) def runner(arg): superflag = False par, eps, state = arg if mask is not None: eps = np.where(np.isnan(mask), eps, np.array(mask) * eps) set_par(par) X = [state] K = [] L = [] for eps_t in eps: state, (l, k), flag = t_func(state, noise=eps_t, return_k=True, linear=linear) superflag |= flag X.append(state) L.append(l) K.append(k) X = np.array(X) L = np.array(L) K = np.array(K) return X, (L, K), superflag wrap = tqdm.tqdm if verbose else (lambda x, **kwarg: x) res = wrap(self.mapper(runner, sample), unit=' sample(s)', total=len(source['pars']), dynamic_ncols=True) res = map2arr(res) superflag = res[-1].any() if verbose: print('[simulate:]'.ljust(15, ' ') + 'Simulation took ', time.time() - st, ' seconds.') if superflag and verbose: print('[simulate:]'.ljust(15, ' ') + 'No rational expectations solution found.') X, LK, flags = res return X, (LK[:, 0, :], LK[:, 1, :]), flags