def __init__(self, nddistr=None, d=None): super(TwoVarsModel, self).__init__(nddistr, [d]) self.eliminate_other([d]) self.d = d self.vars = [] self.symvars = [] for var in nddistr.Vars: #self.free_rvs: self.vars.append(var) self.symvars.append(var.getSymname()) #print "=====", self.vars #print self.symvars #print self.dep_rvs #print self.rv_to_equation self.symop = self.rv_to_equation[d] if len(self.vars) != 2: raise Exception("use it with two variables") x = self.symvars[0] y = self.symvars[1] z = sympy.Symbol("z") self.fun_alongx = eq_solve(self.symop, z, y)[0] self.fun_alongy = eq_solve(self.symop, z, x)[0] self.lfun_alongx = my_lambdify([x, z], self.fun_alongx, "numpy") self.lfun_alongy = my_lambdify([y, z], self.fun_alongy, "numpy") self.Jx = 1 * sympy.diff(self.fun_alongx, z) #print "Jx=", self.Jx #print "fun_alongx=", self.fun_alongx self.Jy = 1 * sympy.diff(self.fun_alongy, z) self.lJx = my_lambdify([x, z], self.Jx, "numpy") self.lJy = my_lambdify([y, z], self.Jy, "numpy") self.z = z
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 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 convmodel(self): """Probabilistic operation defined by model """ op = self.symop#d.getSym() x = self.symvars[0] y = self.symvars[1] lop = my_lambdify([x, y], op, "numpy") F = self.vars[0] G = self.vars[1] #self.nddistr.setMarginals(F, G) f = self.vars[0].get_piecewise_pdf() g = self.vars[1].get_piecewise_pdf() bf = f.getBreaks() bg = g.getBreaks() bi = zeros(len(bf) * len(bg)) k = 0; for xi in bf: for yi in bg: if not isnan(lop(xi, yi)): bi[k] = lop(xi, yi) else: pass #print "not a number, xi=", xi, "yi=", yi, "result=", lop(xi,yi) k += 1 ub = array(unique(bi)) fun = lambda x : self.convmodelx(segList, x) fg = PiecewiseDistribution([]); if isinf(ub[0]): segList = _findSegList(f, g, ub[1] -1, lop) seg = MInfSegment(ub[1], fun) segint = seg.toInterpolatedSegment() fg.addSegment(segint) ub=ub[1:] if isinf(ub[-1]): segList = _findSegList(f, g, ub[-2] + 1, lop) seg = PInfSegment(ub[-2], fun) segint = seg.toInterpolatedSegment() fg.addSegment(segint) ub=ub[0:-1] for i in range(len(ub) - 1) : segList = _findSegList(f, g, (ub[i] + ub[i + 1]) / 2, lop) seg = Segment(ub[i], ub[i + 1], partial(self.convmodelx, segList)) #seg = Segment(ub[i],ub[i+1], fun) segint = seg.toInterpolatedSegment() fg.addSegment(segint) # Discrete parts of distributions #fg_discr = convdiracs(f, g, fun = lambda x,y : x * p + y * q) #for seg in fg_discr.getDiracs(): # fg.addSegment(seg) return fg
def convmodel(self): """Probabilistic operation defined by model """ op = self.symop #d.getSym() x = self.symvars[0] y = self.symvars[1] lop = my_lambdify([x, y], op, "numpy") F = self.vars[0] G = self.vars[1] #self.nddistr.setMarginals(F, G) f = self.vars[0].get_piecewise_pdf() g = self.vars[1].get_piecewise_pdf() bf = f.getBreaks() bg = g.getBreaks() bi = zeros(len(bf) * len(bg)) k = 0 for xi in bf: for yi in bg: if not isnan(lop(xi, yi)): bi[k] = lop(xi, yi) else: pass #print "not a number, xi=", xi, "yi=", yi, "result=", lop(xi,yi) k += 1 ub = array(unique(bi)) fun = lambda x: self.convmodelx(segList, x) fg = PiecewiseDistribution([]) if isinf(ub[0]): segList = _findSegList(f, g, ub[1] - 1, lop) seg = MInfSegment(ub[1], fun) segint = seg.toInterpolatedSegment() fg.addSegment(segint) ub = ub[1:] if isinf(ub[-1]): segList = _findSegList(f, g, ub[-2] + 1, lop) seg = PInfSegment(ub[-2], fun) segint = seg.toInterpolatedSegment() fg.addSegment(segint) ub = ub[0:-1] for i in range(len(ub) - 1): segList = _findSegList(f, g, (ub[i] + ub[i + 1]) / 2, lop) seg = Segment(ub[i], ub[i + 1], partial(self.convmodelx, segList)) #seg = Segment(ub[i],ub[i+1], fun) segint = seg.toInterpolatedSegment() fg.addSegment(segint) # Discrete parts of distributions #fg_discr = convdiracs(f, g, fun = lambda x,y : x * p + y * q) #for seg in fg_discr.getDiracs(): # fg.addSegment(seg) return fg
def plot(self, **kwargs): if len(self.all_vars) == 1 and len(self.free_rvs) == 1: pfun = FunDistr(self.nddistr, breakPoints = self.nddistr.Vars[0].range()) pfun.plot(label = str(self.nddistr.Vars[0].getSymname()), **kwargs) legend() elif len(self.all_vars) == 2 and len(self.free_rvs) == 2: plot_2d_distr(self.nddistr, **kwargs) elif len(self.all_vars) == 2 and len(self.free_rvs) == 1: a, b = self.free_rvs[0].range() freesym = self.free_rvs[0].getSym() fun = my_lambdify(freesym, self.rv_to_equation[self.dep_rvs[0]], "numpy") ax = plot_1d1d_distr(self.nddistr, a, b, fun) ax.set_xlabel(self.free_rvs[0].getSymname()) ax.set_ylabel(self.dep_rvs[0].getSymname()) else: raise RuntimeError("Too many variables.")
def plotFrame(self, ax, bx, ay, by): figure() h = 0.1 axis((ax - h, bx + h, ay - h, by + h)) #print self.symvars #print self.d.getSym() #print self.symop x = self.symvars[0] y = self.symvars[1] lop = my_lambdify([x, y], self.symop, "numpy") tmp = [lop(ax, ay), lop(ax, by), lop(bx, ay), lop(bx, by)] i0, i1 = min(tmp), max(tmp) for i in linspace(i0, i1, 20): #y = self.lfun_alongx(t, i) #plot(t, y) try: L, U = self.getUL(ax, bx, ay, by, i) tt = linspace(L, U, 100) y = self.lfun_alongx(tt, array([i])) plot(tt, y, "k", linewidth=2.0) #axcz, bxcz = self.solveCutsX(self.fun_alongx , ay,by) ##print "==", self.fun_alongx, "|", axcz, "|", bxcz #axc = axcz.subs(self.z, i) #bxc = bxcz.subs(self.z, i) ##print "==", axc,bxc #plot(axc,ay, 'k.') #plot(bxc,by, 'b.') #aycz, bycz = self.solveCutsY(self.fun_alongx, ax,bx) ##print "====", axcz,bxcz #ayc = aycz.subs(self.z, i) #byc = bycz.subs(self.z, i) ##print "====", ayc,byc #plot(ax, ayc, 'r.') #plot(bx, byc, 'g.') except: traceback.print_exc() plot([ax, ax], [ay, by], "k:") plot([bx, bx], [ay, by], "k:") plot([ax, bx], [ay, ay], "k:") plot([ax, bx], [by, by], "k:") plot() pass
def plot(self, **kwargs): if len(self.all_vars) == 1 and len(self.free_rvs) == 1: pfun = FunDistr(self.nddistr, breakPoints=self.nddistr.Vars[0].range()) pfun.plot(label=str(self.nddistr.Vars[0].getSymname()), **kwargs) legend() elif len(self.all_vars) == 2 and len(self.free_rvs) == 2: plot_2d_distr(self.nddistr, **kwargs) elif len(self.all_vars) == 2 and len(self.free_rvs) == 1: a, b = self.free_rvs[0].range() freesym = self.free_rvs[0].getSymname() fun = my_lambdify([freesym], self.rv_to_equation[self.dep_rvs[0]], "numpy") ax = plot_1d1d_distr(self.nddistr, a, b, fun) ax.set_xlabel(self.free_rvs[0].getSymname()) ax.set_ylabel(self.dep_rvs[0].getSymname()) elif len(self.all_vars) == 1 and len(self.free_rvs) == 0: DiracSegment(self.as_const(), 1).plot(**kwargs) else: raise RuntimeError("Too many variables.")