@@ -142,16 +142,27 @@ def _eval_(self, x):
142142 0
143143 """
144144 try :
145- approx_x = ComplexIntervalField ()(x )
146- if bool (approx_x .imag () == 0 ): # x is real
147- if bool (approx_x .real () == 0 ): # x is zero
148- return None
149- else :
150- return 0
151- except Exception : # x is symbolic
145+ return self ._evalf_ (x )
146+ except (TypeError ,ValueError ): # x is symbolic
152147 pass
153148 return None
154149
150+ def _evalf_ (self , x , ** kwds ):
151+ """
152+ TESTS::
153+
154+ sage: h(x) = dirac_delta(x)
155+ sage: h(pi)._numerical_approx()
156+ 0.000000000000000
157+ """
158+ approx_x = ComplexIntervalField ()(x )
159+ if bool (approx_x .imag () == 0 ): # x is real
160+ if bool (approx_x .real () == 0 ): # x is zero
161+ return None
162+ else :
163+ return 0
164+ raise ValueError ("Numeric evaluation of symbolic expression" )
165+
155166dirac_delta = FunctionDiracDelta ()
156167
157168class FunctionHeaviside (BuiltinFunction ):
@@ -252,19 +263,30 @@ def _eval_(self, x):
252263 2
253264 """
254265 try :
255- approx_x = ComplexIntervalField ()(x )
256- if bool (approx_x .imag () == 0 ): # x is real
257- if bool (approx_x .real () == 0 ): # x is zero
258- return None
259- # Now we have a non-zero real
260- if bool ((approx_x ** (0.5 )).imag () == 0 ): # Check: x > 0
261- return 1
262- else :
263- return 0
264- except Exception : # x is symbolic
266+ return self ._evalf_ (x )
267+ except (TypeError ,ValueError ): # x is symbolic
265268 pass
266269 return None
267270
271+ def _evalf_ (self , x , ** kwds ):
272+ """
273+ TESTS::
274+
275+ sage: h(x) = heaviside(x)
276+ sage: h(pi)._numerical_approx()
277+ 1.00000000000000
278+ """
279+ approx_x = ComplexIntervalField ()(x )
280+ if bool (approx_x .imag () == 0 ): # x is real
281+ if bool (approx_x .real () == 0 ): # x is zero
282+ return None
283+ # Now we have a non-zero real
284+ if bool ((approx_x ** (0.5 )).imag () == 0 ): # Check: x > 0
285+ return 1
286+ else :
287+ return 0
288+ raise ValueError ("Numeric evaluation of symbolic expression" )
289+
268290 def _derivative_ (self , x , diff_param = None ):
269291 """
270292 Derivative of Heaviside step function
@@ -361,19 +383,30 @@ def _eval_(self, x):
361383 1
362384 """
363385 try :
364- approx_x = ComplexIntervalField ()(x )
365- if bool (approx_x .imag () == 0 ): # x is real
366- if bool (approx_x .real () == 0 ): # x is zero
367- return 1
368- # Now we have a non-zero real
369- if bool ((approx_x ** (0.5 )).imag () == 0 ): # Check: x > 0
370- return 1
371- else :
372- return 0
373- except Exception : # x is symbolic
386+ return self ._evalf_ (x )
387+ except (TypeError ,ValueError ): # x is symbolic
374388 pass
375389 return None
376390
391+ def _evalf_ (self , x , ** kwds ):
392+ """
393+ TESTS::
394+
395+ sage: h(x) = unit_step(x)
396+ sage: h(pi)._numerical_approx()
397+ 1.00000000000000
398+ """
399+ approx_x = ComplexIntervalField ()(x )
400+ if bool (approx_x .imag () == 0 ): # x is real
401+ if bool (approx_x .real () == 0 ): # x is zero
402+ return 1
403+ # Now we have a non-zero real
404+ if bool ((approx_x ** (0.5 )).imag () == 0 ): # Check: x > 0
405+ return 1
406+ else :
407+ return 0
408+ raise ValueError ("Numeric evaluation of symbolic expression" )
409+
377410 def _derivative_ (self , x , diff_param = None ):
378411 """
379412 Derivative of unit step function
@@ -491,23 +524,40 @@ def _eval_(self, x):
491524 sage: sign(AA(0))
492525 0
493526 """
527+ try :
528+ return self ._evalf_ (x )
529+ except (TypeError ,ValueError ): # x is symbolic
530+ pass
531+ return None
532+
533+ def _evalf_ (self , x , ** kwds ):
534+ """
535+ TESTS:
536+
537+ Check that :trac:`16587` is fixed::
538+
539+ sage: M = sgn(3/2, hold=True); M
540+ sgn(3/2)
541+ sage: M.n()
542+ 1
543+ sage: h(x) = sgn(x)
544+ sage: h(pi)._numerical_approx()
545+ 1.00000000000000
546+ """
494547 if hasattr (x ,'sign' ): # First check if x has a sign method
495548 return x .sign ()
496549 if hasattr (x ,'sgn' ): # or a sgn method
497550 return x .sgn ()
498- try :
499- approx_x = ComplexIntervalField ()(x )
500- if bool (approx_x .imag () == 0 ): # x is real
501- if bool (approx_x .real () == 0 ): # x is zero
502- return ZZ (0 )
503- # Now we have a non-zero real
504- if bool ((approx_x ** (0.5 )).imag () == 0 ): # Check: x > 0
505- return ZZ (1 )
506- else :
507- return ZZ (- 1 )
508- except Exception : # x is symbolic
509- pass
510- return None
551+ approx_x = ComplexIntervalField ()(x )
552+ if bool (approx_x .imag () == 0 ): # x is real
553+ if bool (approx_x .real () == 0 ): # x is zero
554+ return ZZ (0 )
555+ # Now we have a non-zero real
556+ if bool ((approx_x ** (0.5 )).imag () == 0 ): # Check: x > 0
557+ return ZZ (1 )
558+ else :
559+ return ZZ (- 1 )
560+ raise ValueError ("Numeric evaluation of symbolic expression" )
511561
512562 def _derivative_ (self , x , diff_param = None ):
513563 """
@@ -601,22 +651,33 @@ def _eval_(self, m, n):
601651 sage: kronecker_delta(1,x).subs(x=1)
602652 1
603653 """
654+ try :
655+ return self ._evalf_ (m ,n )
656+ except (TypeError ,ValueError ): # x is symbolic
657+ pass
658+ return None
659+
660+ def _evalf_ (self , m , n , ** kwds ):
661+ """
662+ TESTS::
663+
664+ sage: h(x) = kronecker_delta(3,x)
665+ sage: h(pi)._numerical_approx()
666+ 0.000000000000000
667+ """
604668 if bool (repr (m ) > repr (n )):
605669 return kronecker_delta (n , m )
606670
607671 x = m - n
608- try :
609- approx_x = ComplexIntervalField ()(x )
610- if bool (approx_x .imag () == 0 ): # x is real
611- if bool (approx_x .real () == 0 ): # x is zero
612- return 1
613- else :
614- return 0
672+ approx_x = ComplexIntervalField ()(x )
673+ if bool (approx_x .imag () == 0 ): # x is real
674+ if bool (approx_x .real () == 0 ): # x is zero
675+ return 1
615676 else :
616- return 0 # x is complex
617- except Exception : # x is symbolic
618- pass
619- return None
677+ return 0
678+ else :
679+ return 0 # x is complex
680+ raise ValueError ( "Numeric evaluation of symbolic expression" )
620681
621682 def _derivative_ (self , * args , ** kwds ):
622683 """
0 commit comments