def intersect(subspaces): if len(subspaces) == 0: raise ValueError("There must be subspaces to intersect.") #If parent dimension is different it should be treated vars = [var('x' + str(i)) for i in range(matrices[0].ncols() - 1)] eqs = [] for s in subspaces: eqs.append(equations(s, vars)) return solve(eqs, vars)
def solve_one_var(self, eqs, var): """ Solve the equations with respect to the given variable Returns a list of numerical values. """ liste = solve(eqs, var, explicit_solutions=True) a = [] for soluce in liste: a.append(numerical_approx(soluce.rhs())) return a
def solve_ext(list_of_conditions,*args,**kwds): # takes multiple conditions and gives them to solve. # Each condition is an input for solve, ususally a conjunct of # equations. The list of conditions is interpreted as a disjunct of conditions. solutions = [] for cond in list_of_conditions: sol=S.solve(cond,*args,**kwds) # if sol != []: # print "cons:", cond # print "sol :", sol solutions.extend(sol) return solutions
def fit_inside(self, xmin, xmax, ymin, ymax): """ return the largest segment that fits into the given bounds """ if self.is_horizontal: k = self.I.y return Segment(Point(xmin, k), Point(xmax, k)) if self.is_vertical: k = self.I.x return Segment(Point(x, ymin), Point(x, ymax)) x = var("x") f = self.phyFunction() x1 = solve([f(x) == ymax], x)[0].rhs() x2 = solve([f(x) == ymin], x)[0].rhs() x1 = QQ(x1) x2 = QQ(x2) X = [xmin, x1, x2, xmax] X.sort() A = Point(X[1], f(X[1])) B = Point(X[2], f(X[2])) return Segment(Point(X[1], f(X[1])), Point(X[2], f(X[2])))
def substitute(e1, e2): """ Examples: sage: var('x t q b y a') (x, t, q, b, y, a) sage: IeqDeduce.substitute(t-2*b>=0,x==q*y+t) [-q*y - 2*b + x >= 0] sage: IeqDeduce.substitute(t-2*b>=0,b-y*a==0) [-2*a*y + t >= 0] sage: IeqDeduce.substitute(t-2*b>=0,b-4==0) [t - 8 >= 0] sage: IeqDeduce.substitute(t-2*b>=0,b+4==0) [t + 8 >= 0] sage: IeqDeduce.substitute(t-2*b>=0,b^2+4==0) [t + 4*I >= 0, t - 4*I >= 0] sage: IeqDeduce.substitute(t-2*b>=0,b^2-4==0) [t + 4 >= 0, t - 4 >= 0] #todo: cannot do when e2 is not equation sage: IeqDeduce.substitute(2*b>=0,b>=5) dig_polynomials:Warn:substitution fails on b >= 5 2*b >= 0 sage: IeqDeduce.substitute(2*b==0,b>=5) dig_polynomials:Warn:substitution fails on b >= 5 2*b == 0 """ e1_vs = get_vars(e1) e2_vs = get_vars(e2) rs = [ solve(e2, e2_v, solution_dict=True) for e2_v in e2_vs if e2_v in e1_vs ] rs = flatten(rs) try: rs = [e1.subs(rs_) for rs_ in rs] return rs except Exception: logger.warn('substitution fails on {}'.format(e2)) return e1
def solve_more_vars(self, eqs, *vars): """ Solve the equations with respect to the given variables Returns a list like [ [1,2],[3,4] ] if the solutions are (1,2) and (3,4) """ liste = solve(eqs, vars, explicit_solutions=True) a = [] for soluce in liste: sol = [] for variable in soluce: sol.append(numerical_approx(variable.rhs())) a.append(sol) return a
def substitute(e1,e2): """ Examples: sage: var('x t q b y a') (x, t, q, b, y, a) sage: IeqDeduce.substitute(t-2*b>=0,x==q*y+t) [-q*y - 2*b + x >= 0] sage: IeqDeduce.substitute(t-2*b>=0,b-y*a==0) [-2*a*y + t >= 0] sage: IeqDeduce.substitute(t-2*b>=0,b-4==0) [t - 8 >= 0] sage: IeqDeduce.substitute(t-2*b>=0,b+4==0) [t + 8 >= 0] sage: IeqDeduce.substitute(t-2*b>=0,b^2+4==0) [t + 4*I >= 0, t - 4*I >= 0] sage: IeqDeduce.substitute(t-2*b>=0,b^2-4==0) [t + 4 >= 0, t - 4 >= 0] #todo: cannot do when e2 is not equation sage: IeqDeduce.substitute(2*b>=0,b>=5) dig_polynomials:Warn:substitution fails on b >= 5 2*b >= 0 sage: IeqDeduce.substitute(2*b==0,b>=5) dig_polynomials:Warn:substitution fails on b >= 5 2*b == 0 """ e1_vs = get_vars(e1) e2_vs = get_vars(e2) rs = [solve(e2,e2_v,solution_dict=True) for e2_v in e2_vs if e2_v in e1_vs] rs = flatten(rs) try: rs = [e1.subs(rs_) for rs_ in rs] return rs except Exception: logger.warn('substitution fails on {}'.format(e2)) return e1
# Solve for the eigenvalues and then manually # construct the right eigenvectors of A. eigenvalues = A.eigenvalues() v1 = var('v1') v2 = var('v2') evector_solutions = [] for eval in eigenvalues: characteristic_product = Matrix([v1, v2 ]) * (A - eval * Matrix([[1, 0], [0, 1]])) evector_solutions.append( solve([characteristic_product[0, 0], characteristic_product[0, 1]], [v1, v2], solution_dict=True)) # We are interested in the eigenvector corresponding to # eigenvalue 1. idx = eigenvalues.index(1) soln = evector_solutions[idx] assert len(soln) == 1 # sometimes more here? vec = Matrix([v1, v2]) vec = vec.subs(soln[0]) # There is a free variable in the solution, name begins with 'r'. free = [v for v in vec[0, 0].variables() if str(v)[0] == 'r'] assert len(free) == 1 free_var = var(free[0])
def solve_single(list_of_conditions,vars,**kwds): sol = [] for v in vars: sol += S.solve(list_of_conditions,vars,**kwds) return sol
def Intersection(f,g,a=None,b=None,numerical=False): ## # When f and g are objects with an attribute equation, return the list of points of intersections. # # - The list of point is sorted by order of `x` coordinates. # - Return only real solutions. # # Only numerical approximations are returned as there are some errors # otherwise. As an example the following #solving return points that # are not even near from the circle \f$ x^2+y^2=9 \f$ : # ``` # solve( [ -1/3*sqrt(3)*y + 1/3*sqrt(3)*(-0.19245008972987399*sqrt(3) - 3) + x == 0,x^2 + y^2 - 9 == 0 ],[x,y] ) # ``` # # ## Examples # # ``` # sage: from phystricks import * # sage: fun=phyFunction(x**2-5*x+6) # sage: droite=phyFunction(2) # sage: pts = Intersection(fun,droite) # sage: for P in pts:print P # <Point(1,2)> # <Point(4,2)> #``` # #``` # sage: f=phyFunction(sin(x)) # sage: g=phyFunction(cos(x)) # sage: pts=Intersection(f,g,-2*pi,2*pi,numerical=True) # sage: for P in pts:print P # <Point(-5.497787143782138,0.707106781186548)> # <Point(-2.3561944901923466,-0.707106781186546)> # <Point(0.7853981633974484,0.707106781186548)> # <Point(3.926990816987241,-0.707106781186547)> #``` # # If 'numerical' is True, it search for the intersection points of the functions 'f' and 'g' (it only work with functions). In this case an interval is required. from AffineVectorGraph import AffineVectorGraph if isinstance(f,AffineVectorGraph): f=f.segment if isinstance(g,AffineVectorGraph): g=g.segment if numerical and "sage" in dir(f) : import SmallComputations k=f-g xx=SmallComputations.find_roots_recursive(k.sage,a,b) pts=[ Point(x,f(x)) for x in xx ] return pts x,y=var('x,y') pts=[] if numerical : soluce=solve([f.equation(numerical=True),g.equation(numerical=True)],[x,y]) else : soluce=solve([f.equation(),g.equation()],[x,y]) for s in soluce: a=s[0].rhs() b=s[1].rhs() z=a**2+b**2 ok1,a=test_imaginary_part(a) ok2,b=test_imaginary_part(b) if ok1 and ok2 : pts.append(Point(a,b)) return pts
def points(self): vars = [var('x' + str(i)) for i in range(self.dim)] x = vector(vars) return solve(x * self.matrix * x == 0, vars)
def Intersection(f, g, a=None, b=None, numerical=False): """ Return the list of intersection point between `f` and `g`. When f and g are objects with an attribute equation, return the list of points of intersections. - The list of point is sorted by order of `x` coordinates. - Return only real solutions. Only numerical approximations are returned as there are some errors otherwise. As an example the following #solving return points that are not even near from the circle \f$ x^2+y^2=9 \f$ : ``` #pylint:disable=line-too-long solve( [ -1/3*sqrt(3)*y + 1/3*sqrt(3)*(-0.19245008972987399*sqrt(3) - 3) + x == 0,x^2 + y^2 - 9 == 0 ],[x,y] ) ``` Examples ``` sage: from yanntricks import * sage: fun=phyFunction(x**2-5*x+6) sage: droite=phyFunction(2) sage: pts = Intersection(fun,droite) sage: for P in pts:print P <Point(1,2)> <Point(4,2)> ``` ``` sage: f=phyFunction(sin(x)) sage: g=phyFunction(cos(x)) sage: pts=Intersection(f,g,-2*pi,2*pi,numerical=True) sage: for P in pts:print P <Point(-5.497787143782138,0.707106781186548)> <Point(-2.3561944901923466,-0.707106781186546)> <Point(0.7853981633974484,0.707106781186548)> <Point(3.926990816987241,-0.707106781186547)> ``` If 'numerical' is True, it searchs for the intersection points of the functions 'f' and 'g' (it only work with functions). In this case an interval is required. """ from yanntricks.src.affine_vector import AffineVector from yanntricks.src.SmallComputations import find_roots_recursive from yanntricks.src.point import Point if isinstance(f, AffineVector): f = f.segment if isinstance(g, AffineVector): g = g.segment if numerical and "sage" in dir(f): k = f - g xx = find_roots_recursive(k.sage, a, b) pts = [Point(x, f(x)) for x in xx] return pts x, y = var('x,y') pts = [] if numerical: soluce = solve( [f.equation(numerical=True), g.equation(numerical=True)], [x, y]) else: soluce = solve([f.equation(), g.equation()], [x, y]) for s in soluce: a = s[0].rhs() b = s[1].rhs() ok1, a = test_imaginary_part(a) ok2, b = test_imaginary_part(b) if ok1 and ok2: pts.append(Point(a, b)) return pts