def var_change_helper(self, free_var, dep_var): """Compute inverse transformation and Jacobian for substituting dep_var for free_var.""" free_var = self.prepare_var(free_var) dep_var = self.prepare_var(dep_var) # inverve transformation equation = self.rv_to_equation[dep_var] - dep_var.getSymname() solutions = eq_solve(self.rv_to_equation[dep_var], dep_var.getSymname(), free_var.getSymname()) var_changes = [] for uj in solutions: # remove complex valued solutions vj = uj.atoms(sympy.Symbol) hvj = {} for v in vj: #print self.sym_to_rv[v].range() hvj[v] = self.sym_to_rv[v].range()[1] if len(solutions) > 1 and not sympy.im(uj.subs(hvj)) == 0: continue uj_symbols = list(sorted(uj.atoms(sympy.Symbol), key=str)) inv_transf = my_lambdify(uj_symbols, uj, "numpy") inv_transf_vars = [self.sym_to_rv[s] for s in uj_symbols] if params.models.debug_info: #print "vars to change: ", free_var.getSymname(), " <- ", dep_var.getSymname(), "=", self.rv_to_equation[dep_var] #print "equation: ", dep_var.getSymname(), "=", self.rv_to_equation[dep_var] print("substitution: ", free_var.getSymname(), "=", uj, end=' ') #print "variables: ", uj_symbols, inv_transf_vars # Jacobian #J = sympy.Abs(sympy.diff(uj, dep_var.getSymname())) J = sympy.diff(uj, dep_var.getSymname()) print(J.atoms()) J_symbols = list(sorted(J.atoms(sympy.Symbol), key=str)) if len(J_symbols) > 0: jacobian_vars = [self.sym_to_rv[s] for s in J_symbols] jacobian = my_lambdify(J_symbols, J, "numpy") jacobian = NDFun(len(jacobian_vars), jacobian_vars, jacobian, safe=True, abs=True) else: jacobian = NDConstFactor(abs(float(J))) jacobian_vars = [] if params.models.debug_info: print("; Jacobian=", J) #print "variables: ", J_symbols, jacobian_vars var_changes.append((uj, inv_transf, inv_transf_vars, jacobian)) return var_changes, equation
def ccond(self, var): """It returns conditional copula f([var, c_vars]) = C(c_var | var) """ var, c_var = self.prepare_var(var) symvars = [self.symVars[i] for i in var] DC = self.sym_C for i in range(len(self.Vars)): if i in set(var): DC = sympy.diff(DC, self.symVars[i]) else: pass dC = sympy.lambdify(self.symVars, DC, "numpy") return NDFun(self.d, self.Vars, sympy.lambdify(self.symVars, DC, "numpy"))
def condfun(self, var): """It returns conditional cdf function f([var, c_vars]) = Pr(Y<c_var | var) """ funcond = self.ccond(var) var, c_var = self.prepare_var(var) new_cond = var def fun_(*X): j, k = 0, 0 Y = [] dF = ones_like(X[0]) for i in range(len(self.Vars)): Y.append(self.marginals[i].get_piecewise_cdf()(X[i])) if i in set(var): pass else: dF *= self.marginals[i].get_piecewise_pdf()(X[i]) return funcond(*Y) return NDFun(self.d, self.Vars, fun_)
def conditionCDF(self, var, *X): """It returns conditional cdf for given copula f(c_var) = Pr(Y<c_var | var=X) """ funcond = self.ccond(var) var, c_var = self.prepare_var(var) new_cond = var def fun_(*Y_): j, k = 0, 0 Y = [] dF = ones_like(X[0]) for i in range(len(self.Vars)): if i in set(var): Y.append(self.marginals[i].get_piecewise_cdf()(X[j])) j += 1 else: Y.append(self.marginals[i].get_piecewise_cdf()(Y_[k])) dF *= self.marginals[i].get_piecewise_pdf()(Y_[k]) k += 1 return funcond(*Y) return NDFun(len(new_cond), [self.Vars[i] for i in c_var], fun_)
def condition(self, var, *X): """It returns conditional pdf for given copula f(c_var) = Pr(c_var | var=X) """ var, c_var = self.prepare_var(var) num = self.pdf den = self.eliminate(c_var) def fun_(*Y_): j, k = 0, 0 Y, Yvar = [], [] #dF = ones_like(X[0]) for i in range(len(self.Vars)): if i in set(var): Y.append(X[j]) Yvar.append(X[j]) j += 1 else: Y.append(Y_[k]) k += 1 return num(*Y) / den.pdf(*X) return NDFun(len(c_var), [self.Vars[i] for i in c_var], fun_)