Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit e7880b7

Browse files
committed
16587: f(expr,hold).n() fails for all generalized functions
1 parent db5b361 commit e7880b7

File tree

1 file changed

+112
-51
lines changed

1 file changed

+112
-51
lines changed

src/sage/functions/generalized.py

Lines changed: 112 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
155166
dirac_delta = FunctionDiracDelta()
156167

157168
class 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

Comments
 (0)