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

Commit

Permalink
10070: heaviside, unit_step revamp
Browse files Browse the repository at this point in the history
  • Loading branch information
rwst committed Apr 20, 2017
1 parent 7d3fd60 commit 79ab0ac
Showing 1 changed file with 39 additions and 117 deletions.
156 changes: 39 additions & 117 deletions src/sage/functions/generalized.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
#
##############################################################################

from sage.symbolic.function import BuiltinFunction
from sage.symbolic.function import (BuiltinFunction, GinacFunction)
from sage.rings.all import ComplexIntervalField, ZZ

class FunctionDiracDelta(BuiltinFunction):
Expand Down Expand Up @@ -166,7 +166,7 @@ def _evalf_(self, x, **kwds):

dirac_delta = FunctionDiracDelta()

class FunctionHeaviside(BuiltinFunction):
class FunctionHeaviside(GinacFunction):
r"""
The Heaviside step function, `H(x)` (``heaviside(x)``).
Expand All @@ -191,10 +191,29 @@ class FunctionHeaviside(BuiltinFunction):
sage: heaviside(x)
heaviside(x)
sage: heaviside(-1/2)
0
sage: heaviside(exp(-1000000000000000000000))
1
TESTS::
sage: heaviside(x)._sympy_()
Heaviside(x)
sage: heaviside(x).subs(x=1)
1
sage: heaviside(x).subs(x=-1)
0
::
sage: ex = heaviside(x)+1
sage: t = loads(dumps(ex)); t
heaviside(x) + 1
sage: bool(t == ex)
True
sage: t.subs(x=1)
2
REFERENCES:
Expand Down Expand Up @@ -225,74 +244,16 @@ def __init__(self):
Heaviside(x)
sage: heaviside(x)._giac_()
Heaviside(x)
sage: h(x) = heaviside(x)
sage: h(pi).numerical_approx()
1.00000000000000
"""
BuiltinFunction.__init__(self, "heaviside", latex_name="H",
GinacFunction.__init__(self, "heaviside", latex_name="H",
conversions=dict(maxima='hstep',
mathematica='HeavisideTheta',
sympy='Heaviside',
giac='Heaviside'))

def _eval_(self, x):
"""
INPUT:
- ``x`` - a real number or a symbolic expression
EXAMPLES::
sage: heaviside(-1/2)
0
sage: heaviside(1)
1
sage: heaviside(0)
heaviside(0)
sage: heaviside(x)
heaviside(x)
sage: heaviside(exp(-1000000000000000000000))
1
Evaluation test::
sage: heaviside(x).subs(x=1)
1
sage: heaviside(x).subs(x=-1)
0
::
sage: ex = heaviside(x)+1
sage: t = loads(dumps(ex)); t
heaviside(x) + 1
sage: bool(t == ex)
True
sage: t.subs(x=1)
2
"""
try:
return self._evalf_(x)
except (TypeError,ValueError): # x is symbolic
pass
return None

def _evalf_(self, x, **kwds):
"""
TESTS::
sage: h(x) = heaviside(x)
sage: h(pi).numerical_approx()
1.00000000000000
"""
approx_x = ComplexIntervalField()(x)
if bool(approx_x.imag() == 0): # x is real
if bool(approx_x.real() == 0): # x is zero
return None
# Now we have a non-zero real
if bool((approx_x**(0.5)).imag() == 0): # Check: x > 0
return 1
else:
return 0
raise ValueError("Numeric evaluation of symbolic expression")

def _derivative_(self, x, diff_param=None):
"""
Derivative of Heaviside step function
Expand All @@ -306,7 +267,7 @@ def _derivative_(self, x, diff_param=None):

heaviside = FunctionHeaviside()

class FunctionUnitStep(BuiltinFunction):
class FunctionUnitStep(GinacFunction):
r"""
The unit step function, `\mathrm{u}(x)` (``unit_step(x)``).
Expand All @@ -330,6 +291,18 @@ class FunctionUnitStep(BuiltinFunction):
1
sage: unit_step(x)
unit_step(x)
sage: unit_step(-exp(-10000000000000000000))
0
TESTS::
sage: unit_step(x).subs(x=1)
1
sage: unit_step(x).subs(x=0)
1
sage: h(x) = unit_step(x)
sage: h(pi).numerical_approx()
1.00000000000000
"""
def __init__(self):
r"""
Expand Down Expand Up @@ -359,60 +332,9 @@ def __init__(self):
sage: t.subs(x=0)
2
"""
BuiltinFunction.__init__(self, "unit_step", latex_name=r"\mathrm{u}",
GinacFunction.__init__(self, "unit_step", latex_name=r"\mathrm{u}",
conversions=dict(mathematica='UnitStep'))

def _eval_(self, x):
"""
INPUT:
- ``x`` - a real number or a symbolic expression
EXAMPLES::
sage: unit_step(-1)
0
sage: unit_step(1)
1
sage: unit_step(0)
1
sage: unit_step(x)
unit_step(x)
sage: unit_step(-exp(-10000000000000000000))
0
Evaluation test::
sage: unit_step(x).subs(x=1)
1
sage: unit_step(x).subs(x=0)
1
"""
try:
return self._evalf_(x)
except (TypeError,ValueError): # x is symbolic
pass
return None

def _evalf_(self, x, **kwds):
"""
TESTS::
sage: h(x) = unit_step(x)
sage: h(pi).numerical_approx()
1.00000000000000
"""
approx_x = ComplexIntervalField()(x)
if bool(approx_x.imag() == 0): # x is real
if bool(approx_x.real() == 0): # x is zero
return 1
# Now we have a non-zero real
if bool((approx_x**(0.5)).imag() == 0): # Check: x > 0
return 1
else:
return 0
raise ValueError("Numeric evaluation of symbolic expression")

def _derivative_(self, x, diff_param=None):
"""
Derivative of unit step function
Expand Down

0 comments on commit 79ab0ac

Please sign in to comment.