Ticket #9879: trac_9879-hold.patch

File trac_9879-hold.patch, 29.4 KB (added by Burcin Erocal, 12 years ago)
  • c_lib/include/ginac_wrap.h

    # HG changeset patch
    # User Burcin Erocal <burcin@erocal.org>
    # Date 1284022330 -7200
    # Node ID 6384a472bba2027c020cffbff63f32f3d872ed84
    # Parent  c00d0700e7ac40764acecd68ac00cc8543e370a9
    #9879: Add a hold parameter to methods of sage.symbolic.expression.Expression to prevent automatic evalution.
    
    diff --git a/c_lib/include/ginac_wrap.h b/c_lib/include/ginac_wrap.h
    a b  
    126126#define NE_WRAP(x,y)  (x)!=(y)
    127127#define GE_WRAP(x,y)  (x)>=(y)
    128128
     129#define HOLD(fn, x, hold_flag) hold_flag ? ex(fn(x).hold()) : fn(x)
     130
     131#define HOLD2(fn, x, y, hold_flag) hold_flag ? ex(fn(x,y).hold()) : fn(x,y)
     132
     133// declare the constant 1/2 so we can use it for a custom square root function
     134namespace GiNaC {
     135
     136extern const ex _ex1_2;
     137
     138}
  • sage/libs/ginac/decl.pxi

    diff --git a/sage/libs/ginac/decl.pxi b/sage/libs/ginac/decl.pxi
    a b  
    223223    GEx gdiv "DIV_WRAP" (GEx left, GEx right) except +
    224224    GEx g_pow "pow" (GEx left, GEx exp)      except +
    225225
     226    GEx g_hold_wrapper "HOLD" (GEx (GEx) except+, GEx ex, bint) except +
     227    GEx g_hold_wrapper_vec "HOLD" (GEx (GExVector) except+, GExVector vec,
     228            bint) except +
     229    GEx g_hold2_wrapper "HOLD2" (GEx (GEx, GEx) except+, GEx ex, GEx ex,
     230            bint) except +
     231
    226232    #GSymbol get_symbol(char* s)              except +
    227233    GSymbol ginac_symbol "GiNaC::symbol" (char* s, char* t, unsigned d) except +
    228234    GSymbol ginac_new_symbol "GiNaC::symbol" () except +
     
    251257
    252258
    253259    GEx g_abs "GiNaC::abs" (GEx x)           except +
    254     GEx g_step "GiNaC::step" (GEx x)         except +  # step function
    255     GEx g_csgn "GiNaC::csgn" (GEx x)         except + # complex sign
    256     GEx g_conjugate "GiNaC::conjugate" (GEx x)  except + # complex conjugation
    257     GEx g_real_part "GiNaC::real_part" (GEx x)  except + # real part
    258     GEx g_imag_part "GiNaC::imag_part" (GEx x)  except + # imaginary part
    259     GEx g_sqrt "GiNaC::sqrt" (GEx x)    except +  # square root (not a GiNaC function, rather an alias for pow(x, numeric(1, 2)))
     260    GEx g_step "GiNaC::step" (GEx x)         except +  # step function
     261    GEx g_csgn "GiNaC::csgn" (GEx x)         except + # complex sign
     262    # complex conjugation
     263    GEx g_conjugate "GiNaC::conjugate_function" (GEx x) except +
     264    # real part
     265    GEx g_real_part "GiNaC::real_part_function" (GEx x) except +
     266    # imaginary part
     267    GEx g_imag_part "GiNaC::imag_part_function" (GEx x) except +
     268    # square root (not a GiNaC function, rather an alias for
     269    # pow(x, numeric(1, 2)))
     270    GEx g_sqrt "GiNaC::sqrt" (GEx x) except + 
    260271    GEx g_sin "GiNaC::sin" (GEx x)      except + # sine
    261272    GEx g_cos "GiNaC::cos" (GEx x)      except + # cosine
    262273    GEx g_tan "GiNaC::tan" (GEx x)      except + # tangent
    263274    GEx g_asin "GiNaC::asin" (GEx x)    except + # inverse sine
    264275    GEx g_acos "GiNaC::acos" (GEx x)    except + # inverse cosine
    265276    GEx g_atan "GiNaC::atan" (GEx x)    except + # inverse tangent
    266     GEx g_atan2 "GiNaC::atan2" (GEx y, GEx x) except +  # inverse tangent with two arguments
     277    GEx g_atan2 "GiNaC::atan2" (GEx y, GEx x) except +  # inverse tangent with two arguments
    267278    GEx g_sinh "GiNaC::sinh" (GEx x)    except + # hyperbolic sine
    268279    GEx g_cosh "GiNaC::cosh" (GEx x)    except + # hyperbolic cosine
    269280    GEx g_tanh "GiNaC::tanh" (GEx x)    except + # hyperbolic tangent
     
    290301    GEx g_binomial "GiNaC::binomial" (GEx n, GEx k)     except + # binomial coefficients
    291302    GEx g_Order "GiNaC::Order" (GEx x)          except + # order term function in truncated power series
    292303
     304    # wrapper around arithmetic to allow "hold"ing results
     305    GEx g_power_construct "GiNaC::power" (GEx b, GEx p) except +
     306    GEx g_add_construct "GiNaC::add" (GExVector, bint) except +
     307    GEx g_mul_construct "GiNaC::mul" (GExVector, bint) except +
     308
     309    GEx g_ex1_2 "GiNaC::_ex1_2"
    293310
    294311    ctypedef struct GFunction "function":
    295312        unsigned get_serial()
  • sage/symbolic/expression.pyx

    diff --git a/sage/symbolic/expression.pyx b/sage/symbolic/expression.pyx
    a b  
    39413941        raise TypeError, "Must construct a function with a tuple (or list) of symbolic variables."
    39423942
    39433943    ############################################################################
     3944    # Basic arithmetic wrappers
     3945    # which allow disabling automatic evaluation with the hold parameter
     3946    ############################################################################
     3947    def power(self, exp, hold=False):
     3948        """
     3949        Returns the current expression to the power ``exp``.
     3950
     3951        To prevent automatic evaluation use the ``hold`` argument.
     3952
     3953        EXAMPLES::
     3954
     3955            sage: (x^2).power(2)
     3956            x^4
     3957            sage: (x^2).power(2, hold=True)
     3958            (x^2)^2
     3959        """
     3960        cdef Expression nexp = self.coerce_in(exp)
     3961        return new_Expression_from_GEx(self._parent,
     3962                g_hold2_wrapper(g_power_construct, self._gobj, nexp._gobj,
     3963                    hold))
     3964
     3965    def add(self, *args, hold=False):
     3966        """
     3967        Return the sum of the current expression and the given arguments.
     3968
     3969        To prevent automatic evaluation use the ``hold`` argument.
     3970
     3971        EXAMPLES::
     3972
     3973            sage: x.add(x)
     3974            2*x
     3975            sage: x.add(x, hold=True)
     3976            x + x
     3977            sage: x.add(x, (2+x), hold=True)
     3978            x + x + (x + 2)
     3979            sage: x.add(x, (2+x), x, hold=True)
     3980            x + x + (x + 2) + x
     3981            sage: x.add(x, (2+x), x, 2*x, hold=True)
     3982            x + x + (x + 2) + x + 2*x
     3983        """
     3984        nargs = [self.coerce_in(x) for x in args]
     3985        cdef GExVector vec
     3986        cdef Py_ssize_t i
     3987        vec.push_back(self._gobj)
     3988        for i in range(len(args)):
     3989            vec.push_back((<Expression>nargs[i])._gobj)
     3990        return new_Expression_from_GEx(self._parent, g_add_construct(vec, hold))
     3991
     3992    def mul(self, *args, hold=False):
     3993        """
     3994        Return the product of the current expression and the given arguments.
     3995
     3996        To prevent automatic evaluation use the ``hold`` argument.
     3997
     3998        EXAMPLES::
     3999
     4000            sage: x.mul(x)
     4001            x^2
     4002            sage: x.mul(x, hold=True)
     4003            x*x
     4004            sage: x.mul(x, (2+x), hold=True)
     4005            x*x*(x + 2)
     4006            sage: x.mul(x, (2+x), x, hold=True)
     4007            x*x*(x + 2)*x
     4008            sage: x.mul(x, (2+x), x, 2*x, hold=True)
     4009            x*x*(x + 2)*x*(2*x)
     4010        """
     4011        nargs = [self.coerce_in(x) for x in args]
     4012        cdef GExVector vec
     4013        cdef Py_ssize_t i
     4014        vec.push_back(self._gobj)
     4015        for i in range(len(args)):
     4016            vec.push_back((<Expression>nargs[i])._gobj)
     4017        return new_Expression_from_GEx(self._parent, g_mul_construct(vec, hold))
     4018
     4019    ############################################################################
    39444020    # Polynomial functions
    39454021    ############################################################################
    39464022    def coefficient(self, s, int n=1):
     
    43384414            sage: R(f)
    43394415            2.7182818284590452353602874714*x^3 + 3.1415926535897932384626433833*y^3 + 1.4142135623730950488016887242 + 1.0000000000000000000000000000*I
    43404416
     4417        Using the ``hold`` parameter it is possible to prevent automatic
     4418        evaluation::
     4419
     4420            sage: SR(I).conjugate(hold=True)
     4421            conjugate(I)
     4422
    43414423        TESTS:
    43424424
    43434425        This shows that the issue at trac #5755 is fixed (attempting to
     
    45134595            5
    45144596            sage: type(abs(SR(-5)))
    45154597            <type 'sage.symbolic.expression.Expression'>
     4598
     4599        Using the ``hold`` parameter it is possible to prevent automatic
     4600        evaluation::
     4601
     4602            sage: SR(-5).abs(hold=True)
     4603            abs(-5)
    45164604        """
    45174605        return new_Expression_from_GEx(self._parent, g_abs(self._gobj))
    45184606
    4519     def step(self):
     4607    def abs(self, hold=False):
     4608        """
     4609        Return the absolute value of this expression.
     4610
     4611        EXAMPLES::
     4612
     4613            sage: var('x, y')
     4614            (x, y)
     4615            sage: (x+y).abs()
     4616            abs(x + y)
     4617
     4618        Using the ``hold`` parameter it is possible to prevent automatic
     4619        evaluation::
     4620
     4621            sage: SR(-5).abs(hold=True)
     4622            abs(-5)
     4623        """
     4624        return new_Expression_from_GEx(self._parent,
     4625                g_hold_wrapper(g_abs, self._gobj, hold))
     4626
     4627    def step(self, hold=False):
    45204628        """
    45214629        Return the value of the Heaviside step function, which is 0 for
    45224630        negative x, 1/2 for 0, and 1 for positive x.
     
    45324640            0
    45334641            sage: SR(float(-1)).step()
    45344642            0
    4535         """
    4536         return new_Expression_from_GEx(self._parent, g_step(self._gobj))
    4537 
    4538     def csgn(self):
     4643
     4644        Using the ``hold`` parameter it is possible to prevent automatic
     4645        evaluation::
     4646
     4647            sage: SR(2).step()
     4648            1
     4649            sage: SR(2).step(hold=True)
     4650            step(2)
     4651        """
     4652        return new_Expression_from_GEx(self._parent,
     4653                g_hold_wrapper(g_step, self._gobj, hold))
     4654
     4655    def csgn(self, hold=False):
    45394656        """
    45404657        Return the sign of self, which is -1 if self < 0, 0 if self ==
    45414658        0, and 1 if self > 0, or unevaluated when self is a nonconstant
     
    45574674            1
    45584675            sage: SR(I).csgn()
    45594676            1
    4560         """
    4561         return new_Expression_from_GEx(self._parent, g_csgn(self._gobj))
    4562 
    4563     def conjugate(self):
     4677
     4678        Using the ``hold`` parameter it is possible to prevent automatic
     4679        evaluation::
     4680
     4681            sage: SR(I).csgn(hold=True)
     4682            csgn(I)
     4683        """
     4684        return new_Expression_from_GEx(self._parent,
     4685                g_hold_wrapper(g_csgn, self._gobj, hold))
     4686
     4687    def conjugate(self, hold=False):
    45644688        """
    45654689        Return the complex conjugate of this symbolic expression.
    45664690       
     
    45874711            sage: ( 1+I  + (2-3*I)*x).conjugate()
    45884712            (3*I + 2)*conjugate(x) - I + 1
    45894713        """
    4590         return new_Expression_from_GEx(self._parent, self._gobj.conjugate())
     4714        return new_Expression_from_GEx(self._parent,
     4715                g_hold_wrapper(g_conjugate, self._gobj, hold))
    45914716
    45924717    def norm(self):
    45934718        r"""
     
    46104735        """
    46114736        return (self*self.conjugate()).expand()
    46124737
    4613     def real_part(self):
     4738    def real_part(self, hold=False):
    46144739        """
    46154740        Return the real part of this symbolic expression.
    46164741
     
    46294754            sage: f = log(x)
    46304755            sage: f.real_part()
    46314756            log(abs(x))
    4632         """
    4633         return new_Expression_from_GEx(self._parent, self._gobj.real_part())
     4757
     4758        Using the ``hold`` parameter it is possible to prevent automatic
     4759        evaluation::
     4760
     4761            sage: SR(2).real_part()
     4762            2
     4763            sage: SR(2).real_part(hold=True)
     4764            real_part(2)
     4765        """
     4766        return new_Expression_from_GEx(self._parent,
     4767                g_hold_wrapper(g_real_part, self._gobj, hold))
    46344768
    46354769    real = real_part
    46364770
    4637     def imag_part(self):
     4771    def imag_part(self, hold=False):
    46384772        r"""
    46394773        Return the imaginary part of this symbolic expression.
    46404774
     
    46644798            sage: f.imag_part()
    46654799            arctan2(real_part(b) + imag_part(a), real_part(a) - imag_part(b))
    46664800
     4801        Using the ``hold`` parameter it is possible to prevent automatic
     4802        evaluation::
     4803
     4804            sage: I.imag_part()
     4805            1
     4806            sage: I.imag_part(hold=True)
     4807            imag_part(I)
     4808
    46674809        TESTS::
    46684810       
    46694811            sage: x = var('x')
     
    46764818            sage: SR(CDF(2,3)).imag_part()
    46774819            3.0
    46784820        """
    4679         return new_Expression_from_GEx(self._parent, self._gobj.imag_part())
     4821        return new_Expression_from_GEx(self._parent,
     4822                g_hold_wrapper(g_imag_part, self._gobj, hold))
    46804823
    46814824    imag = imag_part
    46824825
    4683     def sqrt(self):
     4826    def sqrt(self, hold=False):
    46844827        """
    46854828        EXAMPLES:
    46864829            sage: var('x, y')
     
    46914834            sqrt(x^2 + y^2)
    46924835            sage: (x^2).sqrt()
    46934836            sqrt(x^2)
    4694         """
    4695         return new_Expression_from_GEx(self._parent, g_sqrt(self._gobj))
    4696 
    4697     def sin(self):
     4837
     4838        Using the ``hold`` parameter it is possible to prevent automatic
     4839        evaluation::
     4840
     4841            sage: SR(4).sqrt()
     4842            2
     4843            sage: SR(4).sqrt(hold=True)
     4844            sqrt(4)
     4845        """
     4846        return new_Expression_from_GEx(self._parent,
     4847                g_hold2_wrapper(g_power_construct, self._gobj, g_ex1_2, hold))
     4848
     4849    def sin(self, hold=False):
    46984850        """
    46994851        EXAMPLES::
    47004852
     
    47094861            sage: sin(SR(RealField(150)(1)))
    47104862            0.84147098480789650665250232163029899962256306
    47114863
     4864        Using the ``hold`` parameter it is possible to prevent automatic
     4865        evaluation::
     4866
     4867            sage: SR(0).sin()
     4868            0
     4869            sage: SR(0).sin(hold=True)
     4870            sin(0)
     4871
    47124872        TESTS::
    47134873
    47144874            sage: SR(oo).sin()
     
    47244884            ...
    47254885            RuntimeError: sin_eval(): sin(infinity) encountered
    47264886        """
    4727         return new_Expression_from_GEx(self._parent, g_sin(self._gobj))
    4728 
    4729     def cos(self):
     4887        return new_Expression_from_GEx(self._parent,
     4888                g_hold_wrapper(g_sin, self._gobj, hold))
     4889
     4890    def cos(self, hold=False):
    47304891        """
    47314892        Return the cosine of self.
    47324893       
     
    47514912            sage: SR(float(1)).cos().n()
    47524913            0.540302305868140           
    47534914
     4915        To prevent automatic evaluation use the ``hold`` argument::
     4916
     4917            sage: pi.cos()
     4918            -1
     4919            sage: pi.cos(hold=True)
     4920            cos(pi)
     4921
    47544922        TESTS::
    47554923
    47564924            sage: SR(oo).cos()
     
    47664934            ...
    47674935            RuntimeError: cos_eval(): cos(infinity) encountered
    47684936        """
    4769         return new_Expression_from_GEx(self._parent, g_cos(self._gobj))
    4770 
    4771     def tan(self):
     4937        return new_Expression_from_GEx(self._parent,
     4938                g_hold_wrapper(g_cos, self._gobj, hold))
     4939
     4940    def tan(self, hold=False):
    47724941        """
    47734942        EXAMPLES::
    47744943
     
    47834952            sage: tan(SR(RealField(150)(1)))
    47844953            1.5574077246549022305069748074583601730872508
    47854954
     4955        To prevent automatic evaluation use the ``hold`` argument::
     4956
     4957            sage: (pi/12).tan()
     4958            -sqrt(3) + 2
     4959            sage: (pi/12).tan(hold=True)
     4960            tan(1/12*pi)
     4961
    47864962        TESTS::
    47874963
    47884964            sage: SR(oo).tan()
     
    47984974            ...
    47994975            RuntimeError: tan_eval(): tan(infinity) encountered
    48004976        """
    4801         return new_Expression_from_GEx(self._parent, g_tan(self._gobj))
    4802 
    4803     def arcsin(self):
     4977        return new_Expression_from_GEx(self._parent,
     4978                g_hold_wrapper(g_tan, self._gobj, hold))
     4979
     4980    def arcsin(self, hold=False):
    48044981        """
    48054982        Return the arcsin of x, i.e., the number y between -pi and pi
    48064983        such that sin(y) == x.
     
    48184995            sage: SR(-1/3).arcsin()
    48194996            -arcsin(1/3)
    48204997
     4998        To prevent automatic evaluation use the ``hold`` argument::
     4999
     5000            sage: SR(0).arcsin()
     5001            0
     5002            sage: SR(0).arcsin(hold=True)
     5003            arcsin(0)
     5004
    48215005        TESTS::
    48225006
    48235007            sage: SR(oo).arcsin()
     
    48315015            sage: SR(unsigned_infinity).arcsin()
    48325016            Infinity
    48335017        """
    4834         return new_Expression_from_GEx(self._parent, g_asin(self._gobj))
    4835 
    4836     def arccos(self):
     5018        return new_Expression_from_GEx(self._parent,
     5019                g_hold_wrapper(g_asin, self._gobj, hold))
     5020
     5021    def arccos(self, hold=False):
    48375022        """
    48385023        Return the arc cosine of self.
    48395024
     
    48495034            1.15927948072741
    48505035            sage: plot(lambda x: SR(x).arccos(), -1,1)
    48515036
     5037        To prevent automatic evaluation use the ``hold`` argument::
     5038
     5039            sage: SR(1).arccos(hold=True)
     5040            arccos(1)
     5041
    48525042        TESTS::
    48535043
    48545044            sage: SR(oo).arccos()
     
    48625052            sage: SR(unsigned_infinity).arccos()
    48635053            Infinity
    48645054        """
    4865         return new_Expression_from_GEx(self._parent, g_acos(self._gobj))
    4866 
    4867     def arctan(self):
     5055        return new_Expression_from_GEx(self._parent,
     5056                g_hold_wrapper(g_acos, self._gobj, hold))
     5057
     5058    def arctan(self, hold=False):
    48685059        """
    48695060        Return the arc tangent of self.
    48705061
     
    48815072            0.463647609000806
    48825073            sage: plot(lambda x: SR(x).arctan(), -20,20)
    48835074
     5075        To prevent automatic evaluation use the ``hold`` argument::
     5076
     5077            sage: SR(1).arctan(hold=True)
     5078            arctan(1)
     5079
    48845080        TESTS::
    48855081
    48865082            sage: SR(oo).arctan()
     
    48925088            ...
    48935089            RuntimeError: arctan_eval(): arctan(unsigned_infinity) encountered
    48945090        """
    4895         return new_Expression_from_GEx(self._parent, g_atan(self._gobj))
    4896 
    4897     def arctan2(self, x):
     5091        return new_Expression_from_GEx(self._parent,
     5092                g_hold_wrapper(g_atan, self._gobj, hold))
     5093
     5094    def arctan2(self, x, hold=False):
    48985095        """
    48995096        Return the inverse of the 2-variable tan function on self and x.
    49005097       
     
    49125109            sage: SR(-0.7).arctan2(SR(-0.6))
    49135110            -pi + 0.862170054667226
    49145111
     5112        To prevent automatic evaluation use the ``hold`` argument::
     5113
     5114            sage: SR(1/2).arctan2(1/2, hold=True)
     5115            arctan2(1/2, 1/2)
     5116
    49155117        TESTS:
    49165118
    49175119        We compare a bunch of different evaluation points between
     
    49755177            RuntimeError: arctan2_eval(): arctan2(x, unsigned_infinity) encountered
    49765178        """
    49775179        cdef Expression nexp = self.coerce_in(x)
    4978         return new_Expression_from_GEx(self._parent, g_atan2(self._gobj, nexp._gobj))
    4979 
    4980     def sinh(self):
     5180        return new_Expression_from_GEx(self._parent,
     5181                g_hold2_wrapper(g_atan2, self._gobj, nexp._gobj, hold))
     5182
     5183    def sinh(self, hold=False):
    49815184        r"""
    49825185        Return sinh of self.
    49835186
     
    50025205            sage: SR(RIF(1)).sinh()
    50035206            1.175201193643802?
    50045207
     5208        To prevent automatic evaluation use the ``hold`` argument::
     5209
     5210            sage: arccosh(x).sinh()
     5211            sqrt(x - 1)*sqrt(x + 1)
     5212            sage: arccosh(x).sinh(hold=True)
     5213            sinh(arccosh(x))
     5214
    50055215        TESTS::
    50065216
    50075217            sage: SR(oo).sinh()
     
    50135223            ...
    50145224            RuntimeError: sinh_eval(): sinh(unsigned_infinity) encountered
    50155225        """
    5016         return new_Expression_from_GEx(self._parent, g_sinh(self._gobj))
    5017 
    5018     def cosh(self):
     5226        return new_Expression_from_GEx(self._parent,
     5227                g_hold_wrapper(g_sinh, self._gobj, hold))
     5228
     5229    def cosh(self, hold=False):
    50195230        r"""
    50205231        Return cosh of self.
    50215232
     
    50385249            sage: SR(RIF(1)).cosh()
    50395250            1.543080634815244?
    50405251
     5252        To prevent automatic evaluation use the ``hold`` argument::
     5253
     5254            sage: arcsinh(x).cosh()
     5255            sqrt(x^2 + 1)
     5256            sage: arcsinh(x).cosh(hold=True)
     5257            cosh(arcsinh(x))
     5258
    50415259        TESTS::
    50425260
    50435261            sage: SR(oo).cosh()
     
    50495267            ...
    50505268            RuntimeError: cosh_eval(): cosh(unsigned_infinity) encountered
    50515269        """
    5052         return new_Expression_from_GEx(self._parent, g_cosh(self._gobj))
    5053 
    5054     def tanh(self):
     5270        return new_Expression_from_GEx(self._parent,
     5271                g_hold_wrapper(g_cosh, self._gobj, hold))
     5272
     5273    def tanh(self, hold=False):
    50555274        r"""
    50565275        Return tanh of self.
    50575276
     
    50715290            .7615941559557649
    50725291            sage: plot(lambda x: SR(x).tanh(), -1, 1)
    50735292
     5293        To prevent automatic evaluation use the ``hold`` argument::
     5294
     5295            sage: arcsinh(x).tanh()
     5296            x/sqrt(x^2 + 1)
     5297            sage: arcsinh(x).tanh(hold=True)
     5298            tanh(arcsinh(x))
     5299
    50745300        TESTS::
    50755301
    50765302            sage: SR(oo).tanh()
     
    50825308            ...
    50835309            RuntimeError: tanh_eval(): tanh(unsigned_infinity) encountered
    50845310        """
    5085         return new_Expression_from_GEx(self._parent, g_tanh(self._gobj))
    5086 
    5087     def arcsinh(self):
     5311        return new_Expression_from_GEx(self._parent,
     5312                g_hold_wrapper(g_tanh, self._gobj, hold))
     5313
     5314    def arcsinh(self, hold=False):
    50885315        """
    50895316        Return the inverse hyperbolic sine of self.
    50905317       
     
    51025329            1.44363547517881
    51035330
    51045331        Sage automatically applies certain identities::
     5332
    51055333            sage: SR(3/2).arcsinh().cosh()
    51065334            1/2*sqrt(13)
    51075335
     5336        To prevent automatic evaluation use the ``hold`` argument::
     5337
     5338            sage: SR(-2).arcsinh()
     5339            -arcsinh(2)
     5340            sage: SR(-2).arcsinh(hold=True)
     5341            arcsinh(-2)
     5342
    51085343        TESTS::
    51095344
    51105345            sage: SR(oo).arcsinh()
     
    51145349            sage: SR(unsigned_infinity).arcsinh()
    51155350            Infinity
    51165351        """
    5117         return new_Expression_from_GEx(self._parent, g_asinh(self._gobj))
    5118 
    5119     def arccosh(self):
     5352        return new_Expression_from_GEx(self._parent,
     5353                g_hold_wrapper(g_asinh, self._gobj, hold))
     5354
     5355    def arccosh(self, hold=False):
    51205356        """
    51215357        Return the inverse hyperbolic cosine of self.
    51225358
     
    51335369            sage: maxima('acosh(0.5)')
    51345370            1.047197551196598*%i
    51355371
     5372        To prevent automatic evaluation use the ``hold`` argument::
     5373
     5374            sage: SR(-1).arccosh()
     5375            I*pi
     5376            sage: SR(-1).arccosh(hold=True)
     5377            arccosh(-1)
     5378
    51365379        TESTS::
    51375380
    51385381            sage: SR(oo).arccosh()
     
    51425385            sage: SR(unsigned_infinity).arccosh()
    51435386            +Infinity
    51445387        """
    5145         return new_Expression_from_GEx(self._parent, g_acosh(self._gobj))
    5146 
    5147     def arctanh(self):
     5388        return new_Expression_from_GEx(self._parent,
     5389                g_hold_wrapper(g_acosh, self._gobj, hold))
     5390
     5391    def arctanh(self, hold=False):
    51485392        """
    51495393        Return the inverse hyperbolic tangent of self.
    51505394
     
    51635407            sage: maxima('atanh(0.5)')
    51645408            .5493061443340...
    51655409
     5410        To prevent automatic evaluation use the ``hold`` argument::
     5411
     5412            sage: SR(-1/2).arctanh()
     5413            -arctanh(1/2)
     5414            sage: SR(-1/2).arctanh(hold=True)
     5415            arctanh(-1/2)
     5416
    51665417        TESTS::
    51675418
    51685419            sage: SR(1).arctanh()
     
    51795430            ...
    51805431            RuntimeError: arctanh_eval(): arctanh(unsigned_infinity) encountered
    51815432        """
    5182         return new_Expression_from_GEx(self._parent, g_atanh(self._gobj))
    5183 
    5184     def exp(self):
     5433        return new_Expression_from_GEx(self._parent,
     5434                g_hold_wrapper(g_atanh, self._gobj, hold))
     5435
     5436    def exp(self, hold=False):
    51855437        """
    51865438        Return exponential function of self, i.e., e to the
    51875439        power of self.
     
    52045456            sage: (pi*I).exp()
    52055457            -1
    52065458
     5459        To prevent automatic evaluation use the ``hold`` argument::
     5460
     5461            sage: (pi*I).exp(hold=True)
     5462            e^(I*pi)
     5463
    52075464        TESTS:
    52085465
    52095466        Test if #6377 is fixed::
     
    52175474            ...
    52185475            RuntimeError: exp_eval(): exp^(unsigned_infinity) encountered
    52195476        """
    5220         return new_Expression_from_GEx(self._parent, g_exp(self._gobj))
    5221 
    5222     def log(self, b=None):
     5477        return new_Expression_from_GEx(self._parent,
     5478                g_hold_wrapper(g_exp, self._gobj, hold))
     5479
     5480    def log(self, b=None, hold=False):
    52235481        """
    52245482        Return the logarithm of self.
    52255483
     
    52465504            -0.69314718055994529
    52475505            sage: plot(lambda x: SR(x).log(), 0.1,10)
    52485506
     5507        To prevent automatic evaluation use the ``hold`` argument::
     5508
     5509            sage: I.log()
     5510            1/2*I*pi
     5511            sage: I.log(hold=True)
     5512            log(I)
     5513
    52495514        TESTS::
    52505515
    52515516            sage: SR(oo).log()
     
    52555520            sage: SR(unsigned_infinity).log()
    52565521            +Infinity
    52575522        """
    5258         res = new_Expression_from_GEx(self._parent, g_log(self._gobj))
     5523        res = new_Expression_from_GEx(self._parent,
     5524                g_hold_wrapper(g_log, self._gobj, hold))
    52595525        if b is None:
    52605526            return res
    52615527        else:
    5262             return res/self._parent(b).log()
    5263 
    5264     def zeta(self):
     5528            return res/self.coerce_in(b).log(hold=hold)
     5529
     5530    def zeta(self, hold=False):
    52655531        """
    52665532        EXAMPLES::
    52675533       
     
    52785544            0.00330022368532 - 0.418155449141*I
    52795545            sage: plot(lambda x: SR(x).zeta(), -10,10).show(ymin=-3,ymax=3)
    52805546
     5547        To prevent automatic evaluation use the ``hold`` argument::
     5548
     5549            sage: SR(2).zeta(hold=True)
     5550            zeta(2)
     5551
    52815552        TESTS::
    52825553           
    52835554            sage: t = SR(1).zeta(); t
    52845555            Infinity
    52855556        """
    52865557        _sig_on
    5287         cdef GEx x = g_zeta(self._gobj)
     5558        cdef GEx x = g_hold_wrapper(g_zeta, self._gobj, hold)
    52885559        _sig_off
    52895560        return new_Expression_from_GEx(self._parent, x)
    52905561   
    5291     def factorial(self):
     5562    def factorial(self, hold=False):
    52925563        """
    52935564        Return the factorial of self.
    52945565       
     
    53045575            factorial(x)
    53055576            sage: (x^2+y^3).factorial()
    53065577            factorial(x^2 + y^3)
     5578
     5579        To prevent automatic evaluation use the ``hold`` argument::
     5580
     5581            sage: SR(5).factorial(hold=True)
     5582            factorial(5)
    53075583        """
    53085584        _sig_on
    5309         cdef GEx x = g_factorial(self._gobj)
     5585        cdef GEx x = g_hold_wrapper(g_factorial, self._gobj, hold)
    53105586        _sig_off
    53115587        return new_Expression_from_GEx(self._parent, x)
    53125588
    5313     def binomial(self, k):
     5589    def binomial(self, k, hold=False):
    53145590        """
    53155591        Return binomial coefficient "self choose k".
    53165592       
     
    53275603            sage: x.binomial(y)
    53285604            binomial(x, y)
    53295605
     5606        To prevent automatic evaluation use the ``hold`` argument::
     5607
     5608            sage: x.binomial(3, hold=True)
     5609            binomial(x, 3)
     5610            sage: SR(5).binomial(3, hold=True)
     5611            binomial(5, 3)
     5612
    53305613        TESTS:
    53315614
    53325615        Check if we handle zero correctly (#8561)::
     
    53375620        """
    53385621        cdef Expression nexp = self.coerce_in(k)
    53395622        _sig_on
    5340         cdef GEx x = g_binomial(self._gobj, nexp._gobj)
     5623        cdef GEx x = g_hold2_wrapper(g_binomial, self._gobj, nexp._gobj, hold)
    53415624        _sig_off
    53425625        return new_Expression_from_GEx(self._parent, x)
    53435626
    5344     def Order(self):
     5627    def Order(self, hold=False):
    53455628        """
    53465629        Order, as in big oh notation.
    53475630
     
    53545637            Order(n^3)
    53555638            sage: t.derivative(n)
    53565639            Order(n^2)
    5357         """
    5358         return new_Expression_from_GEx(self._parent, g_Order(self._gobj))
    5359 
    5360     def gamma(self):
     5640
     5641        To prevent automatic evaluation use the ``hold`` argument::
     5642
     5643            sage: (17*n^3).Order(hold=True)
     5644            Order(17*n^3)
     5645        """
     5646        return new_Expression_from_GEx(self._parent,
     5647                g_hold_wrapper(g_Order, self._gobj, hold))
     5648
     5649    def gamma(self, hold=False):
    53615650        """
    53625651        Return the Gamma function evaluated at self.
    53635652       
     
    53805669            sage: gp('gamma(1+I)') # 64-bit
    53815670            0.49801566811835604271369111746219809195 - 0.15494982830181068512495513048388660520*I
    53825671
     5672        To prevent automatic evaluation use the ``hold`` argument::
     5673
     5674            sage: SR(1/2).gamma()
     5675            sqrt(pi)
     5676            sage: SR(1/2).gamma(hold=True)
     5677            gamma(1/2)
     5678
     5679        ::
     5680
    53835681            sage: set_verbose(-1); plot(lambda x: SR(x).gamma(), -6,4).show(ymin=-3,ymax=3)
    53845682        """
    53855683        _sig_on
    5386         cdef GEx x = g_tgamma(self._gobj)
     5684        cdef GEx x = g_hold_wrapper(g_tgamma, self._gobj, hold)
    53875685        _sig_off
    53885686        return new_Expression_from_GEx(self._parent, x)
    53895687
    5390     def lgamma(self):
     5688    def lgamma(self, hold=False):
    53915689        """
    53925690        This method is deprecated, please use the `.log_gamma()` function
    53935691        instead.
     
    54015699        """
    54025700        from sage.misc.misc import deprecation
    54035701        deprecation("The lgamma() function is deprecated. Use log_gamma() instead.")
    5404         return self.log_gamma()
    5405 
    5406     def log_gamma(self):
     5702        return self.log_gamma(hold=hold)
     5703
     5704    def log_gamma(self, hold=False):
    54075705        """
    54085706        Return the log-gamma function evaluated at self.
    54095707        This is the logarithm of gamma of self, where
     
    54255723            sage: math.exp(0.5)
    54265724            1.6487212707001282
    54275725            sage: plot(lambda x: (SR(x).exp() - SR(-x).exp())/2 - SR(x).sinh(), -1, 1)
     5726
     5727        To prevent automatic evaluation use the ``hold`` argument::
     5728
     5729            sage: SR(5).log_gamma(hold=True)
     5730            log_gamma(5)
    54285731        """
    54295732        _sig_on
    5430         cdef GEx x = g_lgamma(self._gobj)
     5733        cdef GEx x = g_hold_wrapper(g_lgamma, self._gobj, hold)
    54315734        _sig_off
    54325735        return new_Expression_from_GEx(self._parent, x)
    54335736
  • sage/symbolic/expression_conversions.py

    diff --git a/sage/symbolic/expression_conversions.py b/sage/symbolic/expression_conversions.py
    a b  
    530530            sage: m.composition(sin(x), sin)
    531531            'Sin[x]'       
    532532        """
    533         ops = [self(a) for a in ex.operands()]
     533        ops = ex.operands()
     534        #FIXME: consider stripping pyobjects() in ops
    534535        if hasattr(operator, self.name_init + "evaled_"):
    535536            return getattr(operator, self.name_init + "evaled_")(*ops)
     537        else:
     538            ops = map(self, ops)
    536539        try:
    537540            op = getattr(operator, self.name_init)()
    538541        except (TypeError, AttributeError):