Piecewise functions#
This module implement piecewise functions in a single variable. See
sage.sets.real_set
for more information about how to construct
subsets of the real line for the domains.
EXAMPLES:
sage: f = piecewise([((0,1), x^3), ([-1,0], -x^2)]); f
piecewise(x|-->x^3 on (0, 1), x|-->-x^2 on [-1, 0]; x)
sage: 2*f
2*piecewise(x|-->x^3 on (0, 1), x|-->-x^2 on [-1, 0]; x)
sage: f(x=1/2)
1/8
sage: plot(f) # not tested
>>> from sage.all import *
>>> f = piecewise([((Integer(0),Integer(1)), x**Integer(3)), ([-Integer(1),Integer(0)], -x**Integer(2))]); f
piecewise(x|-->x^3 on (0, 1), x|-->-x^2 on [-1, 0]; x)
>>> Integer(2)*f
2*piecewise(x|-->x^3 on (0, 1), x|-->-x^2 on [-1, 0]; x)
>>> f(x=Integer(1)/Integer(2))
1/8
>>> plot(f) # not tested
Todo
Implement max/min location and values,
AUTHORS:
David Joyner (2006-04): initial version
David Joyner (2006-09): added __eq__, extend_by_zero_to, unextend, convolution, trapezoid, trapezoid_integral_approximation, riemann_sum, riemann_sum_integral_approximation, tangent_line fixed bugs in __mul__, __add__
David Joyner (2007-03): adding Hann filter for FS, added general FS filter methods for computing and plotting, added options to plotting of FS (eg, specifying rgb values are now allowed). Fixed bug in documentation reported by Pablo De Napoli.
David Joyner (2007-09): bug fixes due to behaviour of SymbolicArithmetic
David Joyner (2008-04): fixed docstring bugs reported by J Morrow; added support for Laplace transform of functions with infinite support.
David Joyner (2008-07): fixed a left multiplication bug reported by C. Boncelet (by defining __rmul__ = __mul__).
Paul Butler (2009-01): added indefinite integration and default_variable
Volker Braun (2013): Complete rewrite
Ralf Stephan (2015): Rewrite of convolution() and other calculus functions; many doctest adaptations
Eric Gourgoulhon (2017): Improve documentation and user interface of Fourier series
- class sage.functions.piecewise.PiecewiseFunction[source]#
Bases:
BuiltinFunction
Piecewise function
EXAMPLES:
sage: var('x, y') (x, y) sage: f = piecewise([((0,1), x^2*y), ([-1,0], -x*y^2)], var=x); f piecewise(x|-->x^2*y on (0, 1), x|-->-x*y^2 on [-1, 0]; x) sage: f(1/2) 1/4*y sage: f(-1/2) 1/2*y^2
>>> from sage.all import * >>> var('x, y') (x, y) >>> f = piecewise([((Integer(0),Integer(1)), x**Integer(2)*y), ([-Integer(1),Integer(0)], -x*y**Integer(2))], var=x); f piecewise(x|-->x^2*y on (0, 1), x|-->-x*y^2 on [-1, 0]; x) >>> f(Integer(1)/Integer(2)) 1/4*y >>> f(-Integer(1)/Integer(2)) 1/2*y^2
- class EvaluationMethods[source]#
Bases:
object
- convolution(parameters, variable, other)[source]#
Return the convolution function, \(f*g(t)=\int_{-\infty}^\infty f(u)g(t-u)du\), for compactly supported \(f,g\).
EXAMPLES:
sage: x = PolynomialRing(QQ, 'x').gen()
>>> from sage.all import * >>> x = PolynomialRing(QQ, 'x').gen()
Example 0:
sage: f = piecewise([[[0,1], 1]]) sage: g = f.convolution(f); g piecewise(x|-->x on (0, 1], x|-->-x + 2 on (1, 2]; x) sage: h = f.convolution(g); h piecewise(x|-->1/2*x^2 on (0, 1], x|-->-x^2 + 3*x - 3/2 on (1, 2], x|-->1/2*x^2 - 3*x + 9/2 on (2, 3]; x)
>>> from sage.all import * >>> f = piecewise([[[Integer(0),Integer(1)], Integer(1)]]) >>> g = f.convolution(f); g piecewise(x|-->x on (0, 1], x|-->-x + 2 on (1, 2]; x) >>> h = f.convolution(g); h piecewise(x|-->1/2*x^2 on (0, 1], x|-->-x^2 + 3*x - 3/2 on (1, 2], x|-->1/2*x^2 - 3*x + 9/2 on (2, 3]; x)
Example 1:
sage: f = piecewise([[(0,1), 1], [(1,2), 2], [(2,3), 1]]) sage: g = f.convolution(f) sage: h = f.convolution(g); h piecewise(x|-->1/2*x^2 on (0, 1], x|-->2*x^2 - 3*x + 3/2 on (1, 3], x|-->-2*x^2 + 21*x - 69/2 on (3, 4], x|-->-5*x^2 + 45*x - 165/2 on (4, 5], x|-->-2*x^2 + 15*x - 15/2 on (5, 6], x|-->2*x^2 - 33*x + 273/2 on (6, 8], x|-->1/2*x^2 - 9*x + 81/2 on (8, 9]; x)
>>> from sage.all import * >>> f = piecewise([[(Integer(0),Integer(1)), Integer(1)], [(Integer(1),Integer(2)), Integer(2)], [(Integer(2),Integer(3)), Integer(1)]]) >>> g = f.convolution(f) >>> h = f.convolution(g); h piecewise(x|-->1/2*x^2 on (0, 1], x|-->2*x^2 - 3*x + 3/2 on (1, 3], x|-->-2*x^2 + 21*x - 69/2 on (3, 4], x|-->-5*x^2 + 45*x - 165/2 on (4, 5], x|-->-2*x^2 + 15*x - 15/2 on (5, 6], x|-->2*x^2 - 33*x + 273/2 on (6, 8], x|-->1/2*x^2 - 9*x + 81/2 on (8, 9]; x)
Example 2:
sage: f = piecewise([[(-1,1), 1]]) sage: g = piecewise([[(0,3), x]]) sage: f.convolution(g) piecewise(x|-->1/2*x^2 + x + 1/2 on (-1, 1], x|-->2*x on (1, 2], x|-->-1/2*x^2 + x + 4 on (2, 4]; x) sage: g = piecewise([[(0,3), 1], [(3,4), 2]]) sage: f.convolution(g) piecewise(x|-->x + 1 on (-1, 1], x|-->2 on (1, 2], x|-->x on (2, 3], x|-->-x + 6 on (3, 4], x|-->-2*x + 10 on (4, 5]; x)
>>> from sage.all import * >>> f = piecewise([[(-Integer(1),Integer(1)), Integer(1)]]) >>> g = piecewise([[(Integer(0),Integer(3)), x]]) >>> f.convolution(g) piecewise(x|-->1/2*x^2 + x + 1/2 on (-1, 1], x|-->2*x on (1, 2], x|-->-1/2*x^2 + x + 4 on (2, 4]; x) >>> g = piecewise([[(Integer(0),Integer(3)), Integer(1)], [(Integer(3),Integer(4)), Integer(2)]]) >>> f.convolution(g) piecewise(x|-->x + 1 on (-1, 1], x|-->2 on (1, 2], x|-->x on (2, 3], x|-->-x + 6 on (3, 4], x|-->-2*x + 10 on (4, 5]; x)
Check that the bugs raised in Issue #12123 are fixed:
sage: f = piecewise([[(-2, 2), 2]]) sage: g = piecewise([[(0, 2), 3/4]]) sage: f.convolution(g) piecewise(x|-->3/2*x + 3 on (-2, 0], x|-->3 on (0, 2], x|-->-3/2*x + 6 on (2, 4]; x) sage: f = piecewise([[(-1, 1), 1]]) sage: g = piecewise([[(0, 1), x], [(1, 2), -x + 2]]) sage: f.convolution(g) piecewise(x|-->1/2*x^2 + x + 1/2 on (-1, 0], x|-->-1/2*x^2 + x + 1/2 on (0, 2], x|-->1/2*x^2 - 3*x + 9/2 on (2, 3]; x)
>>> from sage.all import * >>> f = piecewise([[(-Integer(2), Integer(2)), Integer(2)]]) >>> g = piecewise([[(Integer(0), Integer(2)), Integer(3)/Integer(4)]]) >>> f.convolution(g) piecewise(x|-->3/2*x + 3 on (-2, 0], x|-->3 on (0, 2], x|-->-3/2*x + 6 on (2, 4]; x) >>> f = piecewise([[(-Integer(1), Integer(1)), Integer(1)]]) >>> g = piecewise([[(Integer(0), Integer(1)), x], [(Integer(1), Integer(2)), -x + Integer(2)]]) >>> f.convolution(g) piecewise(x|-->1/2*x^2 + x + 1/2 on (-1, 0], x|-->-1/2*x^2 + x + 1/2 on (0, 2], x|-->1/2*x^2 - 3*x + 9/2 on (2, 3]; x)
- critical_points(parameters, variable)[source]#
Return the critical points of this piecewise function.
EXAMPLES:
sage: R.<x> = QQ[] sage: f1 = x^0 sage: f2 = 10*x - x^2 sage: f3 = 3*x^4 - 156*x^3 + 3036*x^2 - 26208*x sage: f = piecewise([[(0,3), f1], [(3,10), f2], [(10,20), f3]]) sage: expected = [5, 12, 13, 14] sage: all(abs(e-a) < 0.001 for e,a in zip(expected, f.critical_points())) True
>>> from sage.all import * >>> R = QQ['x']; (x,) = R._first_ngens(1) >>> f1 = x**Integer(0) >>> f2 = Integer(10)*x - x**Integer(2) >>> f3 = Integer(3)*x**Integer(4) - Integer(156)*x**Integer(3) + Integer(3036)*x**Integer(2) - Integer(26208)*x >>> f = piecewise([[(Integer(0),Integer(3)), f1], [(Integer(3),Integer(10)), f2], [(Integer(10),Integer(20)), f3]]) >>> expected = [Integer(5), Integer(12), Integer(13), Integer(14)] >>> all(abs(e-a) < RealNumber('0.001') for e,a in zip(expected, f.critical_points())) True
- domain(parameters, variable)[source]#
Return the domain
OUTPUT:
The union of the domains of the individual pieces as a
RealSet
.EXAMPLES:
sage: f = piecewise([([0,0], sin(x)), ((0,2), cos(x))]); f piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x) sage: f.domain() [0, 2)
>>> from sage.all import * >>> f = piecewise([([Integer(0),Integer(0)], sin(x)), ((Integer(0),Integer(2)), cos(x))]); f piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x) >>> f.domain() [0, 2)
- domains(parameters, variable)[source]#
Return the individual domains
See also
expressions()
.OUTPUT:
The collection of domains of the component functions as a tuple of
RealSet
.EXAMPLES:
sage: f = piecewise([([0,0], sin(x)), ((0,2), cos(x))]); f piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x) sage: f.domains() ({0}, (0, 2))
>>> from sage.all import * >>> f = piecewise([([Integer(0),Integer(0)], sin(x)), ((Integer(0),Integer(2)), cos(x))]); f piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x) >>> f.domains() ({0}, (0, 2))
- end_points(parameters, variable)[source]#
Return a list of all interval endpoints for this function.
EXAMPLES:
sage: f1(x) = 1 sage: f2(x) = 1 - x sage: f3(x) = x^2 - 5 sage: f = piecewise([[(0,1), f1], [(1,2), f2], [(2,3), f3]]) sage: f.end_points() [0, 1, 2, 3] sage: f = piecewise([([0,0], sin(x)), ((0,2), cos(x))]); f piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x) sage: f.end_points() [0, 2]
>>> from sage.all import * >>> __tmp__=var("x"); f1 = symbolic_expression(Integer(1)).function(x) >>> __tmp__=var("x"); f2 = symbolic_expression(Integer(1) - x).function(x) >>> __tmp__=var("x"); f3 = symbolic_expression(x**Integer(2) - Integer(5)).function(x) >>> f = piecewise([[(Integer(0),Integer(1)), f1], [(Integer(1),Integer(2)), f2], [(Integer(2),Integer(3)), f3]]) >>> f.end_points() [0, 1, 2, 3] >>> f = piecewise([([Integer(0),Integer(0)], sin(x)), ((Integer(0),Integer(2)), cos(x))]); f piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x) >>> f.end_points() [0, 2]
- expression_at(parameters, variable, point)[source]#
Return the expression defining the piecewise function at
value
INPUT:
point
– a real number.
OUTPUT:
The symbolic expression defining the function value at the given
point
.EXAMPLES:
sage: f = piecewise([([0,0], sin(x)), ((0,2), cos(x))]); f piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x) sage: f.expression_at(0) sin(x) sage: f.expression_at(1) cos(x) sage: f.expression_at(2) Traceback (most recent call last): ... ValueError: point is not in the domain
>>> from sage.all import * >>> f = piecewise([([Integer(0),Integer(0)], sin(x)), ((Integer(0),Integer(2)), cos(x))]); f piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x) >>> f.expression_at(Integer(0)) sin(x) >>> f.expression_at(Integer(1)) cos(x) >>> f.expression_at(Integer(2)) Traceback (most recent call last): ... ValueError: point is not in the domain
- expressions(parameters, variable)[source]#
Return the individual domains
See also
domains()
.OUTPUT:
The collection of expressions of the component functions.
EXAMPLES:
sage: f = piecewise([([0,0], sin(x)), ((0,2), cos(x))]); f piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x) sage: f.expressions() (sin(x), cos(x))
>>> from sage.all import * >>> f = piecewise([([Integer(0),Integer(0)], sin(x)), ((Integer(0),Integer(2)), cos(x))]); f piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x) >>> f.expressions() (sin(x), cos(x))
- extension(parameters, variable, extension, extension_domain=None)[source]#
Extend the function
INPUT:
extension
– a symbolic expressionextension_domain
– aRealSet
orNone
(default). The domain of the extension. By default, the entire complement of the current domain.
EXAMPLES:
sage: f = piecewise([((-1,1), x)]); f piecewise(x|-->x on (-1, 1); x) sage: f(3) Traceback (most recent call last): ... ValueError: point 3 is not in the domain sage: g = f.extension(0); g piecewise(x|-->x on (-1, 1), x|-->0 on (-oo, -1] ∪ [1, +oo); x) sage: g(3) 0 sage: h = f.extension(1, RealSet.unbounded_above_closed(1)); h piecewise(x|-->x on (-1, 1), x|-->1 on [1, +oo); x) sage: h(3) 1
>>> from sage.all import * >>> f = piecewise([((-Integer(1),Integer(1)), x)]); f piecewise(x|-->x on (-1, 1); x) >>> f(Integer(3)) Traceback (most recent call last): ... ValueError: point 3 is not in the domain >>> g = f.extension(Integer(0)); g piecewise(x|-->x on (-1, 1), x|-->0 on (-oo, -1] ∪ [1, +oo); x) >>> g(Integer(3)) 0 >>> h = f.extension(Integer(1), RealSet.unbounded_above_closed(Integer(1))); h piecewise(x|-->x on (-1, 1), x|-->1 on [1, +oo); x) >>> h(Integer(3)) 1
- fourier_series_cosine_coefficient(parameters, variable, n, L=None)[source]#
Return the \(n\)-th cosine coefficient of the Fourier series of the periodic function \(f\) extending the piecewise-defined function
self
.Given an integer \(n\geq 0\), the \(n\)-th cosine coefficient of the Fourier series of \(f\) is defined by
\[a_n = \frac{1}{L}\int_{-L}^L f(x)\cos\left(\frac{n\pi x}{L}\right) dx,\]where \(L\) is the half-period of \(f\). For \(n\geq 1\), \(a_n\) is the coefficient of \(\cos(n\pi x/L)\) in the Fourier series of \(f\), while \(a_0\) is twice the coefficient of the constant term \(\cos(0 x)\), i.e. twice the mean value of \(f\) over one period (cf.
fourier_series_partial_sum()
).INPUT:
n
– a non-negative integerL
– (default:None
) the half-period of \(f\); if none is provided, \(L\) is assumed to be the half-width of the domain ofself
OUTPUT:
the Fourier coefficient \(a_n\), as defined above
EXAMPLES:
A triangle wave function of period 2:
sage: f = piecewise([((0,1), x), ((1,2), 2 - x)]) sage: f.fourier_series_cosine_coefficient(0) 1 sage: f.fourier_series_cosine_coefficient(3) -4/9/pi^2
>>> from sage.all import * >>> f = piecewise([((Integer(0),Integer(1)), x), ((Integer(1),Integer(2)), Integer(2) - x)]) >>> f.fourier_series_cosine_coefficient(Integer(0)) 1 >>> f.fourier_series_cosine_coefficient(Integer(3)) -4/9/pi^2
If the domain of the piecewise-defined function encompasses more than one period, the half-period must be passed as the second argument; for instance:
sage: f2 = piecewise([((0,1), x), ((1,2), 2 - x), ....: ((2,3), x - 2), ((3,4), 2 - (x-2))]) sage: bool(f2.restriction((0,2)) == f) # f2 extends f on (0,4) True sage: f2.fourier_series_cosine_coefficient(3, 1) # half-period = 1 -4/9/pi^2
>>> from sage.all import * >>> f2 = piecewise([((Integer(0),Integer(1)), x), ((Integer(1),Integer(2)), Integer(2) - x), ... ((Integer(2),Integer(3)), x - Integer(2)), ((Integer(3),Integer(4)), Integer(2) - (x-Integer(2)))]) >>> bool(f2.restriction((Integer(0),Integer(2))) == f) # f2 extends f on (0,4) True >>> f2.fourier_series_cosine_coefficient(Integer(3), Integer(1)) # half-period = 1 -4/9/pi^2
The default half-period is 2 and one has:
sage: f2.fourier_series_cosine_coefficient(3) # half-period = 2 0
>>> from sage.all import * >>> f2.fourier_series_cosine_coefficient(Integer(3)) # half-period = 2 0
The Fourier coefficient \(-4/(9\pi^2)\) obtained above is actually recovered for \(n=6\):
sage: f2.fourier_series_cosine_coefficient(6) -4/9/pi^2
>>> from sage.all import * >>> f2.fourier_series_cosine_coefficient(Integer(6)) -4/9/pi^2
Other examples:
sage: f(x) = x^2 sage: f = piecewise([[(-1,1), f]]) sage: f.fourier_series_cosine_coefficient(2) pi^(-2) sage: f1(x) = -1 sage: f2(x) = 2 sage: f = piecewise([[(-pi, pi/2), f1], [(pi/2, pi), f2]]) sage: f.fourier_series_cosine_coefficient(5, pi) -3/5/pi
>>> from sage.all import * >>> __tmp__=var("x"); f = symbolic_expression(x**Integer(2)).function(x) >>> f = piecewise([[(-Integer(1),Integer(1)), f]]) >>> f.fourier_series_cosine_coefficient(Integer(2)) pi^(-2) >>> __tmp__=var("x"); f1 = symbolic_expression(-Integer(1)).function(x) >>> __tmp__=var("x"); f2 = symbolic_expression(Integer(2)).function(x) >>> f = piecewise([[(-pi, pi/Integer(2)), f1], [(pi/Integer(2), pi), f2]]) >>> f.fourier_series_cosine_coefficient(Integer(5), pi) -3/5/pi
- fourier_series_partial_sum(parameters, variable, N, L=None)[source]#
Returns the partial sum up to a given order of the Fourier series of the periodic function \(f\) extending the piecewise-defined function
self
.The Fourier partial sum of order \(N\) is defined as
\[S_{N}(x) = \frac{a_0}{2} + \sum_{n=1}^{N} \left[ a_n\cos\left(\frac{n\pi x}{L}\right) + b_n\sin\left(\frac{n\pi x}{L}\right)\right],\]where \(L\) is the half-period of \(f\) and the \(a_n\)’s and \(b_n\)’s are respectively the cosine coefficients and sine coefficients of the Fourier series of \(f\) (cf.
fourier_series_cosine_coefficient()
andfourier_series_sine_coefficient()
).INPUT:
N
– a positive integer; the order of the partial sumL
– (default:None
) the half-period of \(f\); if none is provided, \(L\) is assumed to be the half-width of the domain ofself
OUTPUT:
the partial sum \(S_{N}(x)\), as a symbolic expression
EXAMPLES:
A square wave function of period 2:
sage: f = piecewise([((-1,0), -1), ((0,1), 1)]) sage: f.fourier_series_partial_sum(5) 4/5*sin(5*pi*x)/pi + 4/3*sin(3*pi*x)/pi + 4*sin(pi*x)/pi
>>> from sage.all import * >>> f = piecewise([((-Integer(1),Integer(0)), -Integer(1)), ((Integer(0),Integer(1)), Integer(1))]) >>> f.fourier_series_partial_sum(Integer(5)) 4/5*sin(5*pi*x)/pi + 4/3*sin(3*pi*x)/pi + 4*sin(pi*x)/pi
If the domain of the piecewise-defined function encompasses more than one period, the half-period must be passed as the second argument; for instance:
sage: f2 = piecewise([((-1,0), -1), ((0,1), 1), ....: ((1,2), -1), ((2,3), 1)]) sage: bool(f2.restriction((-1,1)) == f) # f2 extends f on (-1,3) True sage: f2.fourier_series_partial_sum(5, 1) # half-period = 1 4/5*sin(5*pi*x)/pi + 4/3*sin(3*pi*x)/pi + 4*sin(pi*x)/pi sage: bool(f2.fourier_series_partial_sum(5, 1) == ....: f.fourier_series_partial_sum(5)) True
>>> from sage.all import * >>> f2 = piecewise([((-Integer(1),Integer(0)), -Integer(1)), ((Integer(0),Integer(1)), Integer(1)), ... ((Integer(1),Integer(2)), -Integer(1)), ((Integer(2),Integer(3)), Integer(1))]) >>> bool(f2.restriction((-Integer(1),Integer(1))) == f) # f2 extends f on (-1,3) True >>> f2.fourier_series_partial_sum(Integer(5), Integer(1)) # half-period = 1 4/5*sin(5*pi*x)/pi + 4/3*sin(3*pi*x)/pi + 4*sin(pi*x)/pi >>> bool(f2.fourier_series_partial_sum(Integer(5), Integer(1)) == ... f.fourier_series_partial_sum(Integer(5))) True
The default half-period is 2, so that skipping the second argument yields a different result:
sage: f2.fourier_series_partial_sum(5) # half-period = 2 4*sin(pi*x)/pi
>>> from sage.all import * >>> f2.fourier_series_partial_sum(Integer(5)) # half-period = 2 4*sin(pi*x)/pi
An example of partial sum involving both cosine and sine terms:
sage: f = piecewise([((-1,0), 0), ((0,1/2), 2*x), ....: ((1/2,1), 2*(1-x))]) sage: f.fourier_series_partial_sum(5) -2*cos(2*pi*x)/pi^2 + 4/25*sin(5*pi*x)/pi^2 - 4/9*sin(3*pi*x)/pi^2 + 4*sin(pi*x)/pi^2 + 1/4
>>> from sage.all import * >>> f = piecewise([((-Integer(1),Integer(0)), Integer(0)), ((Integer(0),Integer(1)/Integer(2)), Integer(2)*x), ... ((Integer(1)/Integer(2),Integer(1)), Integer(2)*(Integer(1)-x))]) >>> f.fourier_series_partial_sum(Integer(5)) -2*cos(2*pi*x)/pi^2 + 4/25*sin(5*pi*x)/pi^2 - 4/9*sin(3*pi*x)/pi^2 + 4*sin(pi*x)/pi^2 + 1/4
- fourier_series_sine_coefficient(parameters, variable, n, L=None)[source]#
Return the \(n\)-th sine coefficient of the Fourier series of the periodic function \(f\) extending the piecewise-defined function
self
.Given an integer \(n\geq 0\), the \(n\)-th sine coefficient of the Fourier series of \(f\) is defined by
\[b_n = \frac{1}{L}\int_{-L}^L f(x)\sin\left(\frac{n\pi x}{L}\right) dx,\]where \(L\) is the half-period of \(f\). The number \(b_n\) is the coefficient of \(\sin(n\pi x/L)\) in the Fourier series of \(f\) (cf.
fourier_series_partial_sum()
).INPUT:
n
– a non-negative integerL
– (default:None
) the half-period of \(f\); if none is provided, \(L\) is assumed to be the half-width of the domain ofself
OUTPUT:
the Fourier coefficient \(b_n\), as defined above
EXAMPLES:
A square wave function of period 2:
sage: f = piecewise([((-1,0), -1), ((0,1), 1)]) sage: f.fourier_series_sine_coefficient(1) 4/pi sage: f.fourier_series_sine_coefficient(2) 0 sage: f.fourier_series_sine_coefficient(3) 4/3/pi
>>> from sage.all import * >>> f = piecewise([((-Integer(1),Integer(0)), -Integer(1)), ((Integer(0),Integer(1)), Integer(1))]) >>> f.fourier_series_sine_coefficient(Integer(1)) 4/pi >>> f.fourier_series_sine_coefficient(Integer(2)) 0 >>> f.fourier_series_sine_coefficient(Integer(3)) 4/3/pi
If the domain of the piecewise-defined function encompasses more than one period, the half-period must be passed as the second argument; for instance:
sage: f2 = piecewise([((-1,0), -1), ((0,1), 1), ....: ((1,2), -1), ((2,3), 1)]) sage: bool(f2.restriction((-1,1)) == f) # f2 extends f on (-1,3) True sage: f2.fourier_series_sine_coefficient(1, 1) # half-period = 1 4/pi sage: f2.fourier_series_sine_coefficient(3, 1) # half-period = 1 4/3/pi
>>> from sage.all import * >>> f2 = piecewise([((-Integer(1),Integer(0)), -Integer(1)), ((Integer(0),Integer(1)), Integer(1)), ... ((Integer(1),Integer(2)), -Integer(1)), ((Integer(2),Integer(3)), Integer(1))]) >>> bool(f2.restriction((-Integer(1),Integer(1))) == f) # f2 extends f on (-1,3) True >>> f2.fourier_series_sine_coefficient(Integer(1), Integer(1)) # half-period = 1 4/pi >>> f2.fourier_series_sine_coefficient(Integer(3), Integer(1)) # half-period = 1 4/3/pi
The default half-period is 2 and one has:
sage: f2.fourier_series_sine_coefficient(1) # half-period = 2 0 sage: f2.fourier_series_sine_coefficient(3) # half-period = 2 0
>>> from sage.all import * >>> f2.fourier_series_sine_coefficient(Integer(1)) # half-period = 2 0 >>> f2.fourier_series_sine_coefficient(Integer(3)) # half-period = 2 0
The Fourier coefficients obtained from
f
are actually recovered for \(n=2\) and \(n=6\) respectively:sage: f2.fourier_series_sine_coefficient(2) 4/pi sage: f2.fourier_series_sine_coefficient(6) 4/3/pi
>>> from sage.all import * >>> f2.fourier_series_sine_coefficient(Integer(2)) 4/pi >>> f2.fourier_series_sine_coefficient(Integer(6)) 4/3/pi
- integral(parameters, variable, x=None, a=None, b=None, definite=False, **kwds)[source]#
By default, return the indefinite integral of the function.
If
definite=True
is given, returns the definite integral.AUTHOR:
Paul Butler
EXAMPLES:
sage: f1(x) = 1 - x sage: f = piecewise([((0,1), 1), ((1,2), f1)]) sage: f.integral(definite=True) 1/2
>>> from sage.all import * >>> __tmp__=var("x"); f1 = symbolic_expression(Integer(1) - x).function(x) >>> f = piecewise([((Integer(0),Integer(1)), Integer(1)), ((Integer(1),Integer(2)), f1)]) >>> f.integral(definite=True) 1/2
sage: f1(x) = -1 sage: f2(x) = 2 sage: f = piecewise([((0,pi/2), f1), ((pi/2,pi), f2)]) sage: f.integral(definite=True) 1/2*pi sage: f1(x) = 2 sage: f2(x) = 3 - x sage: f = piecewise([[(-2, 0), f1], [(0, 3), f2]]) sage: f.integral() piecewise(x|-->2*x + 4 on (-2, 0), x|-->-1/2*x^2 + 3*x + 4 on (0, 3); x) sage: f1(y) = -1 sage: f2(y) = y + 3 sage: f3(y) = -y - 1 sage: f4(y) = y^2 - 1 sage: f5(y) = 3 sage: f = piecewise([[[-4,-3], f1], [(-3,-2), f2], [[-2,0], f3], ....: [(0,2), f4], [[2,3], f5]]) sage: F = f.integral(y); F piecewise(y|-->-y - 4 on [-4, -3], y|-->1/2*y^2 + 3*y + 7/2 on (-3, -2), y|-->-1/2*y^2 - y - 1/2 on [-2, 0], y|-->1/3*y^3 - y - 1/2 on (0, 2), y|-->3*y - 35/6 on [2, 3]; y)
>>> from sage.all import * >>> __tmp__=var("x"); f1 = symbolic_expression(-Integer(1)).function(x) >>> __tmp__=var("x"); f2 = symbolic_expression(Integer(2)).function(x) >>> f = piecewise([((Integer(0),pi/Integer(2)), f1), ((pi/Integer(2),pi), f2)]) >>> f.integral(definite=True) 1/2*pi >>> __tmp__=var("x"); f1 = symbolic_expression(Integer(2)).function(x) >>> __tmp__=var("x"); f2 = symbolic_expression(Integer(3) - x).function(x) >>> f = piecewise([[(-Integer(2), Integer(0)), f1], [(Integer(0), Integer(3)), f2]]) >>> f.integral() piecewise(x|-->2*x + 4 on (-2, 0), x|-->-1/2*x^2 + 3*x + 4 on (0, 3); x) >>> __tmp__=var("y"); f1 = symbolic_expression(-Integer(1)).function(y) >>> __tmp__=var("y"); f2 = symbolic_expression(y + Integer(3)).function(y) >>> __tmp__=var("y"); f3 = symbolic_expression(-y - Integer(1)).function(y) >>> __tmp__=var("y"); f4 = symbolic_expression(y**Integer(2) - Integer(1)).function(y) >>> __tmp__=var("y"); f5 = symbolic_expression(Integer(3)).function(y) >>> f = piecewise([[[-Integer(4),-Integer(3)], f1], [(-Integer(3),-Integer(2)), f2], [[-Integer(2),Integer(0)], f3], ... [(Integer(0),Integer(2)), f4], [[Integer(2),Integer(3)], f5]]) >>> F = f.integral(y); F piecewise(y|-->-y - 4 on [-4, -3], y|-->1/2*y^2 + 3*y + 7/2 on (-3, -2), y|-->-1/2*y^2 - y - 1/2 on [-2, 0], y|-->1/3*y^3 - y - 1/2 on (0, 2), y|-->3*y - 35/6 on [2, 3]; y)
Ensure results are consistent with FTC:
sage: F(-3) - F(-4) -1 sage: F(-1) - F(-3) 1 sage: F(2) - F(0) 2/3 sage: f.integral(y, 0, 2) 2/3 sage: F(3) - F(-4) 19/6 sage: f.integral(y, -4, 3) 19/6 sage: f.integral(definite=True) 19/6
>>> from sage.all import * >>> F(-Integer(3)) - F(-Integer(4)) -1 >>> F(-Integer(1)) - F(-Integer(3)) 1 >>> F(Integer(2)) - F(Integer(0)) 2/3 >>> f.integral(y, Integer(0), Integer(2)) 2/3 >>> F(Integer(3)) - F(-Integer(4)) 19/6 >>> f.integral(y, -Integer(4), Integer(3)) 19/6 >>> f.integral(definite=True) 19/6
sage: f1(y) = (y+3)^2 sage: f2(y) = y+3 sage: f3(y) = 3 sage: f = piecewise([[(-infinity, -3), f1], [(-3, 0), f2], ....: [(0, infinity), f3]]) sage: f.integral() piecewise(y|-->1/3*y^3 + 3*y^2 + 9*y + 9 on (-oo, -3), y|-->1/2*y^2 + 3*y + 9/2 on (-3, 0), y|-->3*y + 9/2 on (0, +oo); y)
>>> from sage.all import * >>> __tmp__=var("y"); f1 = symbolic_expression((y+Integer(3))**Integer(2)).function(y) >>> __tmp__=var("y"); f2 = symbolic_expression(y+Integer(3)).function(y) >>> __tmp__=var("y"); f3 = symbolic_expression(Integer(3)).function(y) >>> f = piecewise([[(-infinity, -Integer(3)), f1], [(-Integer(3), Integer(0)), f2], ... [(Integer(0), infinity), f3]]) >>> f.integral() piecewise(y|-->1/3*y^3 + 3*y^2 + 9*y + 9 on (-oo, -3), y|-->1/2*y^2 + 3*y + 9/2 on (-3, 0), y|-->3*y + 9/2 on (0, +oo); y)
sage: f1(x) = e^(-abs(x)) sage: f = piecewise([[(-infinity, infinity), f1]]) sage: result = f.integral(definite=True) ... sage: result 2 sage: f.integral() piecewise(x|-->-integrate(e^(-abs(x)), x, x, +Infinity) on (-oo, +oo); x)
>>> from sage.all import * >>> __tmp__=var("x"); f1 = symbolic_expression(e**(-abs(x))).function(x) >>> f = piecewise([[(-infinity, infinity), f1]]) >>> result = f.integral(definite=True) ... >>> result 2 >>> f.integral() piecewise(x|-->-integrate(e^(-abs(x)), x, x, +Infinity) on (-oo, +oo); x)
sage: f = piecewise([((0, 5), cos(x))]) sage: f.integral() piecewise(x|-->sin(x) on (0, 5); x)
>>> from sage.all import * >>> f = piecewise([((Integer(0), Integer(5)), cos(x))]) >>> f.integral() piecewise(x|-->sin(x) on (0, 5); x)
- items(parameters, variable)[source]#
Iterate over the pieces of the piecewise function
Note
You should probably use
pieces()
instead, which offers a nicer interface.OUTPUT:
This method iterates over pieces of the piecewise function, each represented by a pair. The first element is the support, and the second the function over that support.
EXAMPLES:
sage: f = piecewise([([0,0], sin(x)), ((0,2), cos(x))]) sage: for support, function in f.items(): ....: print('support is {0}, function is {1}'.format(support, function)) support is {0}, function is sin(x) support is (0, 2), function is cos(x)
>>> from sage.all import * >>> f = piecewise([([Integer(0),Integer(0)], sin(x)), ((Integer(0),Integer(2)), cos(x))]) >>> for support, function in f.items(): ... print('support is {0}, function is {1}'.format(support, function)) support is {0}, function is sin(x) support is (0, 2), function is cos(x)
- laplace(parameters, variable, x='x', s='t')[source]#
Return the Laplace transform of
self
with respect to the variable var.INPUT:
x
– variable ofself
s
– variable of Laplace transform.
We assume that a piecewise function is 0 outside of its domain and that the left-most endpoint of the domain is 0.
EXAMPLES:
sage: x, s, w = var('x, s, w') sage: f = piecewise([[(0,1), 1], [[1,2], 1 - x]]) sage: f.laplace(x, s) -e^(-s)/s + (s + 1)*e^(-2*s)/s^2 + 1/s - e^(-s)/s^2 sage: f.laplace(x, w) -e^(-w)/w + (w + 1)*e^(-2*w)/w^2 + 1/w - e^(-w)/w^2
>>> from sage.all import * >>> x, s, w = var('x, s, w') >>> f = piecewise([[(Integer(0),Integer(1)), Integer(1)], [[Integer(1),Integer(2)], Integer(1) - x]]) >>> f.laplace(x, s) -e^(-s)/s + (s + 1)*e^(-2*s)/s^2 + 1/s - e^(-s)/s^2 >>> f.laplace(x, w) -e^(-w)/w + (w + 1)*e^(-2*w)/w^2 + 1/w - e^(-w)/w^2
sage: y, t = var('y, t') sage: f = piecewise([[[1,2], 1 - y]]) sage: f.laplace(y, t) (t + 1)*e^(-2*t)/t^2 - e^(-t)/t^2
>>> from sage.all import * >>> y, t = var('y, t') >>> f = piecewise([[[Integer(1),Integer(2)], Integer(1) - y]]) >>> f.laplace(y, t) (t + 1)*e^(-2*t)/t^2 - e^(-t)/t^2
sage: s = var('s') sage: t = var('t') sage: f1(t) = -t sage: f2(t) = 2 sage: f = piecewise([[[0,1], f1], [(1,infinity), f2]]) sage: f.laplace(t, s) (s + 1)*e^(-s)/s^2 + 2*e^(-s)/s - 1/s^2
>>> from sage.all import * >>> s = var('s') >>> t = var('t') >>> __tmp__=var("t"); f1 = symbolic_expression(-t).function(t) >>> __tmp__=var("t"); f2 = symbolic_expression(Integer(2)).function(t) >>> f = piecewise([[[Integer(0),Integer(1)], f1], [(Integer(1),infinity), f2]]) >>> f.laplace(t, s) (s + 1)*e^(-s)/s^2 + 2*e^(-s)/s - 1/s^2
- pieces(parameters, variable)[source]#
Return the “pieces”.
OUTPUT:
A tuple of piecewise functions, each having only a single expression.
EXAMPLES:
sage: p = piecewise([((-1, 0), -x), ([0, 1], x)], var=x) sage: p.pieces() (piecewise(x|-->-x on (-1, 0); x), piecewise(x|-->x on [0, 1]; x))
>>> from sage.all import * >>> p = piecewise([((-Integer(1), Integer(0)), -x), ([Integer(0), Integer(1)], x)], var=x) >>> p.pieces() (piecewise(x|-->-x on (-1, 0); x), piecewise(x|-->x on [0, 1]; x))
- piecewise_add(parameters, variable, other)[source]#
Return a new piecewise function with domain the union of the original domains and functions summed. Undefined intervals in the union domain get function value \(0\).
EXAMPLES:
sage: f = piecewise([([0,1], 1), ((2,3), x)]) sage: g = piecewise([((1/2, 2), x)]) sage: f.piecewise_add(g).unextend_zero() piecewise(x|-->1 on (0, 1/2], x|-->x + 1 on (1/2, 1], x|-->x on (1, 2) ∪ (2, 3); x)
>>> from sage.all import * >>> f = piecewise([([Integer(0),Integer(1)], Integer(1)), ((Integer(2),Integer(3)), x)]) >>> g = piecewise([((Integer(1)/Integer(2), Integer(2)), x)]) >>> f.piecewise_add(g).unextend_zero() piecewise(x|-->1 on (0, 1/2], x|-->x + 1 on (1/2, 1], x|-->x on (1, 2) ∪ (2, 3); x)
- restriction(parameters, variable, restricted_domain)[source]#
Restrict the domain
INPUT:
restricted_domain
– aRealSet
or something that defines one.
OUTPUT:
A new piecewise function obtained by restricting the domain.
EXAMPLES:
sage: f = piecewise([((-oo, oo), x)]); f piecewise(x|-->x on (-oo, +oo); x) sage: f.restriction([[-1,1], [3,3]]) piecewise(x|-->x on [-1, 1] ∪ {3}; x)
>>> from sage.all import * >>> f = piecewise([((-oo, oo), x)]); f piecewise(x|-->x on (-oo, +oo); x) >>> f.restriction([[-Integer(1),Integer(1)], [Integer(3),Integer(3)]]) piecewise(x|-->x on [-1, 1] ∪ {3}; x)
- trapezoid(parameters, variable, N)[source]#
Return the piecewise line function defined by the trapezoid rule for numerical integration based on a subdivision of each domain interval into N subintervals.
EXAMPLES:
sage: f = piecewise([[[0,1], x^2], ....: [RealSet.open_closed(1,2), 5 - x^2]]) sage: f.trapezoid(2) piecewise(x|-->1/2*x on (0, 1/2), x|-->3/2*x - 1/2 on (1/2, 1), x|-->7/2*x - 5/2 on (1, 3/2), x|-->-7/2*x + 8 on (3/2, 2); x) sage: f = piecewise([[[-1,1], 1 - x^2]]) sage: f.trapezoid(4).integral(definite=True) 5/4 sage: f = piecewise([[[-1,1], 1/2 + x - x^3]]) ## example 3 sage: f.trapezoid(6).integral(definite=True) 1
>>> from sage.all import * >>> f = piecewise([[[Integer(0),Integer(1)], x**Integer(2)], ... [RealSet.open_closed(Integer(1),Integer(2)), Integer(5) - x**Integer(2)]]) >>> f.trapezoid(Integer(2)) piecewise(x|-->1/2*x on (0, 1/2), x|-->3/2*x - 1/2 on (1/2, 1), x|-->7/2*x - 5/2 on (1, 3/2), x|-->-7/2*x + 8 on (3/2, 2); x) >>> f = piecewise([[[-Integer(1),Integer(1)], Integer(1) - x**Integer(2)]]) >>> f.trapezoid(Integer(4)).integral(definite=True) 5/4 >>> f = piecewise([[[-Integer(1),Integer(1)], Integer(1)/Integer(2) + x - x**Integer(3)]]) ## example 3 >>> f.trapezoid(Integer(6)).integral(definite=True) 1
- unextend_zero(parameters, variable)[source]#
Remove zero pieces.
EXAMPLES:
sage: f = piecewise([((-1,1), x)]); f piecewise(x|-->x on (-1, 1); x) sage: g = f.extension(0); g piecewise(x|-->x on (-1, 1), x|-->0 on (-oo, -1] ∪ [1, +oo); x) sage: g(3) 0 sage: h = g.unextend_zero() sage: bool(h == f) True
>>> from sage.all import * >>> f = piecewise([((-Integer(1),Integer(1)), x)]); f piecewise(x|-->x on (-1, 1); x) >>> g = f.extension(Integer(0)); g piecewise(x|-->x on (-1, 1), x|-->0 on (-oo, -1] ∪ [1, +oo); x) >>> g(Integer(3)) 0 >>> h = g.unextend_zero() >>> bool(h == f) True
- which_function(parameters, variable, point)[source]#
Return the expression defining the piecewise function at
value
INPUT:
point
– a real number.
OUTPUT:
The symbolic expression defining the function value at the given
point
.EXAMPLES:
sage: f = piecewise([([0,0], sin(x)), ((0,2), cos(x))]); f piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x) sage: f.expression_at(0) sin(x) sage: f.expression_at(1) cos(x) sage: f.expression_at(2) Traceback (most recent call last): ... ValueError: point is not in the domain
>>> from sage.all import * >>> f = piecewise([([Integer(0),Integer(0)], sin(x)), ((Integer(0),Integer(2)), cos(x))]); f piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x) >>> f.expression_at(Integer(0)) sin(x) >>> f.expression_at(Integer(1)) cos(x) >>> f.expression_at(Integer(2)) Traceback (most recent call last): ... ValueError: point is not in the domain
- static in_operands(ex)[source]#
Return whether a symbolic expression contains a piecewise function as operand
INPUT:
ex
– a symbolic expression.
OUTPUT:
Boolean
EXAMPLES:
sage: f = piecewise([([0,0], sin(x)), ((0,2), cos(x))]); f piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x) sage: piecewise.in_operands(f) True sage: piecewise.in_operands(1+sin(f)) True sage: piecewise.in_operands(1+sin(0*f)) False
>>> from sage.all import * >>> f = piecewise([([Integer(0),Integer(0)], sin(x)), ((Integer(0),Integer(2)), cos(x))]); f piecewise(x|-->sin(x) on {0}, x|-->cos(x) on (0, 2); x) >>> piecewise.in_operands(f) True >>> piecewise.in_operands(Integer(1)+sin(f)) True >>> piecewise.in_operands(Integer(1)+sin(Integer(0)*f)) False
- static simplify(ex)[source]#
Combine piecewise operands into single piecewise function
OUTPUT:
A piecewise function whose operands are not piecewiese if possible, that is, as long as the piecewise variable is the same.
EXAMPLES:
sage: f = piecewise([([0,0], sin(x)), ((0,2), cos(x))]) sage: piecewise.simplify(f) Traceback (most recent call last): ... NotImplementedError
>>> from sage.all import * >>> f = piecewise([([Integer(0),Integer(0)], sin(x)), ((Integer(0),Integer(2)), cos(x))]) >>> piecewise.simplify(f) Traceback (most recent call last): ... NotImplementedError