On Sun, 30 Jun 2013 13:23:50 -0700 (PDT) Eric Gourgoulhon <egourgoul...@gmail.com> wrote:
> Meanwhile, I've written the following workaround in python: > basically, it scans all the sqrt's in a given symbolic expression, > send them to radcan, takes the absolute value of the output and then > calls simplify(). It is not optimal but it works: > > sage: assume(x<0) > sage: simplify_sqrt_real( sqrt(x^2) ) > -x > sage: simplify_sqrt_real( sqrt(x^2-2*x+1) ) > -x + 1 > sage: simplify_sqrt_real( sqrt(x^2) + sqrt(x^2-2*x+1) ) > -2*x + 1 > > Here is the source code: > > def simplify_sqrt_real(expr): > r""" > Simplify sqrt in symbolic expressions in the real domain. > > EXAMPLES: > > Simplifications of basic expressions:: > > sage: assume(x<0) > sage: simplify_sqrt_real( sqrt(x^2) ) > -x > sage: simplify_sqrt_real( sqrt(x^2-2*x+1) ) > -x + 1 > sage: simplify_sqrt_real( sqrt(x^2) + sqrt(x^2-2*x+1) ) > -2*x + 1 > > """ > from sage.symbolic.ring import SR > from sage.calculus.calculus import maxima > # 1/ Search for the sqrt's in expr > sexpr = str(expr) > if 'sqrt(' not in sexpr: # no sqrt to simplify > return expr > pos_sqrts = [] # positions of the sqrt's in sexpr > the_sqrts = [] # the sqrt sub-expressions in sexpr > for pos in range(len(sexpr)): > if sexpr[pos:pos+5] == 'sqrt(': > pos_sqrts.append(pos) > parenth = 1 > scan = pos+5 > while parenth != 0: > if sexpr[scan] == '(': parenth += 1 > if sexpr[scan] == ')': parenth -= 1 > scan += 1 > the_sqrts.append( sexpr[pos:scan] ) Instead of going through strings, you might want to try pattern matching: sage: t = sin(x)*sqrt(x^2)*e^(sqrt(x+1)) sage: w = SR.wild() sage: t.find(w^(1/2)) [sqrt(x + 1), sqrt(x^2)] Note that this won't catch sqrt() in the denominator. You will need to specify a negative exponent for that: sage: u = 1/sqrt(x+1) sage: u.find(w^(-1/2)) [1/sqrt(x + 1)] > # 2/ Simplifications of the sqrt's > new_expr = "" # will contain the result > pos0 = 0 > for i, pos in enumerate(pos_sqrts): > # radcan is called on each sqrt: > x = SR(the_sqrts[i]) > simpl = SR(x._maxima_().radcan()) This is x.maxima_methods().radcan(). > # the absolute value of radcan's output is taken, the call to > simplify() > # taking into account possible assumptions regarding the sign > of simpl: > new_expr += sexpr[pos0:pos] + '(' + > str(abs(simpl).simplify()) + ')' pos0 = pos + len(the_sqrts[i]) > new_expr += sexpr[pos0:] > return SR(new_expr) Putting the new values back can be done with subs(). sage: t sqrt(x^2)*e^(sqrt(x + 1))*sin(x) sage: t.subs({sqrt(x^2): x}) x*e^(sqrt(x + 1))*sin(x) Cheers, Burcin -- You received this message because you are subscribed to the Google Groups "sage-devel" group. To unsubscribe from this group and stop receiving emails from it, send an email to sage-devel+unsubscr...@googlegroups.com. To post to this group, send email to sage-devel@googlegroups.com. Visit this group at http://groups.google.com/group/sage-devel. For more options, visit https://groups.google.com/groups/opt_out.