def _geodesic_between_two_points(x1, y1, x2, y2): r""" Geodesic path between two points hyperbolic upper half-plane INPUTS: - ''(x1,y1)'' -- starting point (0<y1<=infinity) - ''(x2,y2)'' -- ending point (0<y2<=infinity) - ''z0'' -- (default I) the point in the upper corresponding to the point 0 in the disc. I.e. the transform is w -> (z-I)/(z+I) OUTPUT: - ''ca'' -- a polygonal approximation of a circular arc centered at c and radius r, starting at t0 and ending at t1 EXAMPLES:: sage: l=_geodesic_between_two_points(0.1,0.2,0.0,0.5) """ pi = RR.pi() from sage.plot.plot import line from sage.functions.trig import arcsin # logging.debug("z1=%s,%s" % (x1,y1)) # logging.debug("z2=%s,%s" % (x2,y2)) if abs(x1 - x2) < 1e-10: # The line segment [x=x1, y0<= y <= y1] return line([[x1, y1], [x2, y2]]) # [0,0,x0,infinity] c = RR(y1 ** 2 - y2 ** 2 + x1 ** 2 - x2 ** 2) / RR(2 * (x1 - x2)) r = RR(sqrt(y1 ** 2 + (x1 - c) ** 2)) r1 = RR(y1 / r) r2 = RR(y2 / r) if abs(r1 - 1) < 1e-12: r1 = RR(1.0) elif abs(r2 + 1) < 1e-12: r2 = -RR(1.0) if abs(r2 - 1) < 1e-12: r2 = RR(1.0) elif abs(r2 + 1) < 1e-12: r2 = -RR(1.0) if x1 >= c: t1 = RR(arcsin(r1)) else: t1 = RR(pi) - RR(arcsin(r1)) if x2 >= c: t2 = RR(arcsin(r2)) else: t2 = RR(pi) - arcsin(r2) # tmid = (t1 + t2) * RR(0.5) # a0 = min(t1, t2) # a1 = max(t1, t2) # logging.debug("c,r=%s,%s" % (c,r)) # logging.debug("t1,t2=%s,%s"%(t1,t2)) return _circ_arc(t1, t2, c, r)
def _geodesic_between_two_points(x1, y1, x2, y2): r""" Geodesic path between two points hyperbolic upper half-plane INPUTS: - ''(x1,y1)'' -- starting point (0<y1<=infinity) - ''(x2,y2)'' -- ending point (0<y2<=infinity) - ''z0'' -- (default I) the point in the upper corresponding to the point 0 in the disc. I.e. the transform is w -> (z-I)/(z+I) OUTPUT: - ''ca'' -- a polygonal approximation of a circular arc centered at c and radius r, starting at t0 and ending at t1 EXAMPLES:: sage: l=_geodesic_between_two_points(0.1,0.2,0.0,0.5) """ pi = RR.pi() from sage.plot.plot import line from sage.functions.trig import arcsin #print "z1=",x1,y1 #print "z2=",x2,y2 if (abs(x1 - x2) < 1E-10): # The line segment [x=x1, y0<= y <= y1] return line([[x1, y1], [x2, y2]]) #[0,0,x0,infinity] c = RR(y1**2 - y2**2 + x1**2 - x2**2) / RR(2 * (x1 - x2)) r = RR(sqrt(y1**2 + (x1 - c)**2)) r1 = RR(y1 / r) r2 = RR(y2 / r) if (abs(r1 - 1) < 1E-12): r1 = RR(1.0) elif (abs(r2 + 1) < 1E-12): r2 = -RR(1.0) if (abs(r2 - 1) < 1E-12): r2 = RR(1.0) elif (abs(r2 + 1) < 1E-12): r2 = -RR(1.0) if (x1 >= c): t1 = RR(arcsin(r1)) else: t1 = RR(pi) - RR(arcsin(r1)) if (x2 >= c): t2 = RR(arcsin(r2)) else: t2 = RR(pi) - arcsin(r2) tmid = (t1 + t2) * RR(0.5) a0 = min(t1, t2) a1 = max(t1, t2) #print "c,r=",c,r #print "t1,t2=",t1,t2 return _circ_arc(t1, t2, c, r)
def subexpressions_list(f, pars=None): """ Construct the lists with the intermediate steps on the evaluation of the function. INPUT: - ``f`` -- a symbolic function of several components. - ``pars`` -- a list of the parameters that appear in the function this should be the symbolic constants that appear in f but are not arguments. OUTPUT: - a list of the intermediate subexpressions that appear in the evaluation of f. - a list with the operations used to construct each of the subexpressions. each element of this list is a tuple, formed by a string describing the operation made, and the operands. For the trigonometric functions, some extra expressions will be added. These extra expressions will be used later to compute their derivatives. EXAMPLES:: sage: from sage.interfaces.tides import subexpressions_list sage: var('x,y') (x, y) sage: f(x,y) = [x^2+y, cos(x)/log(y)] sage: subexpressions_list(f) ([x^2, x^2 + y, sin(x), cos(x), log(y), cos(x)/log(y)], [('mul', x, x), ('add', y, x^2), ('sin', x), ('cos', x), ('log', y), ('div', log(y), cos(x))]) :: sage: f(a)=[cos(a), arctan(a)] sage: from sage.interfaces.tides import subexpressions_list sage: subexpressions_list(f) ([sin(a), cos(a), a^2, a^2 + 1, arctan(a)], [('sin', a), ('cos', a), ('mul', a, a), ('add', 1, a^2), ('atan', a)]) :: sage: from sage.interfaces.tides import subexpressions_list sage: var('s,b,r') (s, b, r) sage: f(t,x,y,z)= [s*(y-x),x*(r-z)-y,x*y-b*z] sage: subexpressions_list(f,[s,b,r]) ([-y, x - y, s*(x - y), -s*(x - y), -z, r - z, (r - z)*x, -y, (r - z)*x - y, x*y, b*z, -b*z, x*y - b*z], [('mul', -1, y), ('add', -y, x), ('mul', x - y, s), ('mul', -1, s*(x - y)), ('mul', -1, z), ('add', -z, r), ('mul', x, r - z), ('mul', -1, y), ('add', -y, (r - z)*x), ('mul', y, x), ('mul', z, b), ('mul', -1, b*z), ('add', -b*z, x*y)]) :: sage: var('x, y') (x, y) sage: f(x,y)=[exp(x^2+sin(y))] sage: from sage.interfaces.tides import * sage: subexpressions_list(f) ([x^2, sin(y), cos(y), x^2 + sin(y), e^(x^2 + sin(y))], [('mul', x, x), ('sin', y), ('cos', y), ('add', sin(y), x^2), ('exp', x^2 + sin(y))]) """ from sage.functions.trig import sin, cos, arcsin, arctan, arccos variables = f[0].arguments() if not pars: parameters = [] else: parameters = pars varpar = list(parameters) + list(variables) F = symbolic_expression([i(*variables) for i in f]).function(*varpar) lis = flatten([fast_callable(i,vars=varpar).op_list() for i in F], max_level=1) stack = [] const =[] stackcomp=[] detail=[] for i in lis: if i[0] == 'load_arg': stack.append(varpar[i[1]]) elif i[0] == 'ipow': if i[1] in NN: basis = stack[-1] for j in range(i[1]-1): a=stack.pop(-1) detail.append(('mul', a, basis)) stack.append(a*basis) stackcomp.append(stack[-1]) else: detail.append(('pow',stack[-1],i[1])) stack[-1]=stack[-1]**i[1] stackcomp.append(stack[-1]) elif i[0] == 'load_const': const.append(i[1]) stack.append(i[1]) elif i == 'mul': a=stack.pop(-1) b=stack.pop(-1) detail.append(('mul', a, b)) stack.append(a*b) stackcomp.append(stack[-1]) elif i == 'div': a=stack.pop(-1) b=stack.pop(-1) detail.append(('div', a, b)) stack.append(b/a) stackcomp.append(stack[-1]) elif i == 'add': a=stack.pop(-1) b=stack.pop(-1) detail.append(('add',a,b)) stack.append(a+b) stackcomp.append(stack[-1]) elif i == 'pow': a=stack.pop(-1) b=stack.pop(-1) detail.append(('pow', b, a)) stack.append(b**a) stackcomp.append(stack[-1]) elif i[0] == 'py_call' and str(i[1])=='log': a=stack.pop(-1) detail.append(('log', a)) stack.append(log(a)) stackcomp.append(stack[-1]) elif i[0] == 'py_call' and str(i[1])=='exp': a=stack.pop(-1) detail.append(('exp', a)) stack.append(exp(a)) stackcomp.append(stack[-1]) elif i[0] == 'py_call' and str(i[1])=='sin': a=stack.pop(-1) detail.append(('sin', a)) detail.append(('cos', a)) stackcomp.append(sin(a)) stackcomp.append(cos(a)) stack.append(sin(a)) elif i[0] == 'py_call' and str(i[1])=='cos': a=stack.pop(-1) detail.append(('sin', a)) detail.append(('cos', a)) stackcomp.append(sin(a)) stackcomp.append(cos(a)) stack.append(cos(a)) elif i[0] == 'py_call' and str(i[1])=='tan': a=stack.pop(-1) b = sin(a) c = cos(a) detail.append(('sin', a)) detail.append(('cos', a)) detail.append(('div', b, c)) stackcomp.append(b) stackcomp.append(c) stackcomp.append(b/c) stack.append(b/c) elif i[0] == 'py_call' and str(i[1])=='arctan': a=stack.pop(-1) detail.append(('mul', a, a)) detail.append(('add', 1, a*a)) detail.append(('atan', a)) stackcomp.append(a*a) stackcomp.append(1+a*a) stackcomp.append(arctan(a)) stack.append(arctan(a)) elif i[0] == 'py_call' and str(i[1])=='arcsin': a=stack.pop(-1) detail.append(('mul', a, a)) detail.append(('mul', -1, a*a)) detail.append(('add', 1, -a*a)) detail.append(('pow', 1- a*a, 0.5)) detail.append(('asin', a)) stackcomp.append(a*a) stackcomp.append(-a*a) stackcomp.append(1-a*a) stackcomp.append(sqrt(1-a*a)) stackcomp.append(arcsin(a)) stack.append(arcsin(a)) elif i[0] == 'py_call' and str(i[1])=='arccos': a=stack.pop(-1) detail.append(('mul', a, a)) detail.append(('mul', -1, a*a)) detail.append(('add', 1, -a*a)) detail.append(('pow', 1- a*a, 0.5)) detail.append(('mul', -1, sqrt(1-a*a))) detail.append(('acos', a)) stackcomp.append(a*a) stackcomp.append(-a*a) stackcomp.append(1-a*a) stackcomp.append(sqrt(1-a*a)) stackcomp.append(-sqrt(1-a*a)) stackcomp.append(arccos(a)) stack.append(arccos(a)) elif i[0] == 'py_call' and 'sqrt' in str(i[1]): a=stack.pop(-1) detail.append(('pow', a, 0.5)) stackcomp.append(sqrt(a)) stack.append(sqrt(a)) elif i == 'neg': a = stack.pop(-1) detail.append(('mul', -1, a)) stack.append(-a) stackcomp.append(-a) return stackcomp,detail
def invP(z): t = complex(z)**(-0.5) phi = arcsin(t) return invper * elliptic_f(phi, -1)