Module calculus
source code
Symbolic Computation.
AUTHORS:
Bobby Moretti and William Stein: 2006--2007
The \sage calculus module is loosely based on the \sage Enhancement Proposal
found at: \url{http://www.sagemath.org:9001/CalculusSEP.}
EXAMPLES:
The basic units of the calculus package are symbolic expressions
which are elements of the symbolic expression ring (SR). There are
many subclasses of \class{SymbolicExpression}. The most basic of these is
the formal indeterminate class, \class{SymbolicVariable}. To create a
\class{SymbolicVariable} object in \sage, use the \code{var()} method, whose
argument is the text of that variable. Note that \sage is
intelligent about {\LaTeX}ing variable names.
sage: x1 = var('x1'); x1
x1
sage: latex(x1)
x_{1}
sage: theta = var('theta'); theta
theta
sage: latex(theta)
\theta
\sage predefines \code{x} to be a global indeterminate. Thus the following works:
sage: x^2
x^2
sage: type(x)
<class 'sage.calculus.calculus.SymbolicVariable'>
More complicated expressions in \sage can be built up using
ordinary arithmetic. The following are valid, and follow the rules
of Python arithmetic: (The '=' operator represents assignment, and
not equality)
sage: var('x,y,z')
(x, y, z)
sage: f = x + y + z/(2*sin(y*z/55))
sage: g = f^f; g
(z/(2*sin(y*z/55)) + y + x)^(z/(2*sin(y*z/55)) + y + x)
Differentiation and integration are available, but behind the
scenes through maxima:
sage: f = sin(x)/cos(2*y)
sage: f.derivative(y)
2*sin(x)*sin(2*y)/cos(2*y)^2
sage: g = f.integral(x); g
-cos(x)/cos(2*y)
Note that these methods require an explicit variable name. If none
is given, \sage will try to find one for you.
sage: f = sin(x); f.derivative()
cos(x)
However when this is ambiguous, \sage will raise an exception:
sage: f = sin(x+y); f.derivative()
Traceback (most recent call last):
...
ValueError: must supply an explicit variable for an expression containing more than one variable
Substitution works similarly. We can substitute with a python dict:
sage: f = sin(x*y - z)
sage: f({x: var('t'), y: z})
sin(t*z - z)
Also we can substitute with keywords:
sage: f = sin(x*y - z)
sage: f(x = t, y = z)
sin(t*z - z)
If there is no ambiguity of variable names, we don't have to specify them:
sage: f = sin(x)
sage: f(y)
sin(y)
sage: f(pi)
0
However if there is ambiguity, we must explicitly state what
variables we're substituting for:
sage: f = sin(2*pi*x/y)
sage: f(4)
sin(8*pi/y)
We can also make a \class{CallableSymbolicExpression}, which is a
\class{SymbolicExpression} that is a function of specified
variables in a fixed order. Each \class{SymbolicExpression} has a
\code{function(...)} method that is used to create a
\class{CallableSymbolicExpression}, as illustrated below:
sage: u = log((2-x)/(y+5))
sage: f = u.function(x, y); f
(x, y) |--> log((2 - x)/(y + 5))
There is an easier way of creating a \class{CallableSymbolicExpression}, which
relies on the \sage preparser.
sage: f(x,y) = log(x)*cos(y); f
(x, y) |--> log(x)*cos(y)
Then we have fixed an order of variables and there is no ambiguity
substituting or evaluating:
sage: f(x,y) = log((2-x)/(y+5))
sage: f(7,t)
log(-5/(t + 5))
Some further examples:
sage: f = 5*sin(x)
sage: f
5*sin(x)
sage: f(2)
5*sin(2)
sage: f(pi)
0
sage: float(f(pi)) # random low order bits
6.1232339957367663e-16
Another example:
sage: f = integrate(1/sqrt(9+x^2), x); f
arcsinh(x/3)
sage: f(3)
arcsinh(1)
sage: f.derivative(x)
1/(3*sqrt(x^2/9 + 1))
We compute the length of the parabola from 0 to 2:
sage: x = var('x')
sage: y = x^2
sage: dy = derivative(y,x)
sage: z = integral(sqrt(1 + dy^2), x, 0, 2)
sage: print z
arcsinh(4) + 4 sqrt(17)
---------------------
4
sage: n(z,200)
4.6467837624329358733826155674904591885104869874232887508703
sage: float(z)
4.6467837624329356
We test pickling:
sage: x, y = var('x,y')
sage: f = -sqrt(pi)*(x^3 + sin(x/cos(y)))
sage: bool(loads(dumps(f)) == f)
True
Coercion examples:
We coerce various symbolic expressions into the complex numbers:
sage: CC(I)
1.00000000000000*I
sage: CC(2*I)
2.00000000000000*I
sage: ComplexField(200)(2*I)
2.0000000000000000000000000000000000000000000000000000000000*I
sage: ComplexField(200)(sin(I))
1.1752011936438014568823818505956008151557179813340958702296*I
sage: f = sin(I) + cos(I/2); f
I*sinh(1) + cosh(1/2)
sage: CC(f)
1.12762596520638 + 1.17520119364380*I
sage: ComplexField(200)(f)
1.1276259652063807852262251614026720125478471180986674836290 + 1.1752011936438014568823818505956008151557179813340958702296*I
sage: ComplexField(100)(f)
1.1276259652063807852262251614 + 1.1752011936438014568823818506*I
We illustrate construction of an inverse sum where each denominator
has a new variable name:
sage: f = sum(1/var('n%s'%i)^i for i in range(10))
sage: print f
1 1 1 1 1 1 1 1 1
--- + --- + --- + --- + --- + --- + --- + --- + -- + 1
9 8 7 6 5 4 3 2 n1
n9 n8 n7 n6 n5 n4 n3 n2
Note that after calling var, the variables are immediately available for use:
sage: (n1 + n2)^5
(n2 + n1)^5
We can, of course, substitute:
sage: print f(n9=9,n7=n6)
1 1 1 1 1 1 1 1 387420490
--- + --- + --- + --- + --- + --- + --- + -- + ---------
8 6 7 5 4 3 2 n1 387420489
n8 n6 n6 n5 n4 n3 n2
TESTS:
Substitution:
sage: f = x
sage: f(x=5)
5
Simplifying expressions involving scientific notation:
sage: k = var('k')
sage: a0 = 2e-6; a1 = 12
sage: c = a1 + a0*k; c
2.000000000000000e-6*k + 12
sage: sqrt(c)
sqrt(2.000000000000000e-6*k + 12)
sage: sqrt(c^3)
sqrt((2.000000000000000e-6*k + 12)^3)
The symbolic Calculus package uses its own copy of maxima for
simplification, etc., which is separate from the default system-wide
version:
sage: maxima.eval('[x,y]: [1,2]')
'[1,2]'
sage: maxima.eval('expand((x+y)^3)')
'27'
If the copy of maxima used by the symbolic calculus package were
the same as the default one, then the following would return 27,
which would be very confusing indeed!
sage: x, y = var('x,y')
sage: expand((x+y)^3)
y^3 + 3*x*y^2 + 3*x^2*y + x^3
Set x to be 5 in maxima:
sage: maxima('x: 5')
5
sage: maxima('x + x + %pi')
%pi+10
This simplification is done using maxima (behind the scenes):
sage: x + x + pi
2*x + pi
Note that \code{x} is still \var{x}, since the maxima used by the calculus package
is different than the one in the interactive interpreter.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var(s,
create=True)
Create a symbolic variable with the name \emph{s}. |
source code
|
|
|
|
|
|
|
| CallableSymbolicExpressionRing(args,
check=True) |
source code
|
|
|
|
|
|
|
arctan2(y,
x)
Modified version of arctan function, since it is used by Maxima. |
source code
|
|
|
|
atan2(y,
x)
Modified version of arctan function, since it is used by Maxima. |
source code
|
|
|
|
|
|
|
log(x,
base=['4ti2-20061025', 'R-2.6.0', 'atlas-3.7.37', 'atlas-3.8.1', 'a...)
Return the logarithm of x to the given base. |
source code
|
|
|
|
polylog(n,
z)
The polylogarithm function $\text{Li}_n(z) = \sum_{k=1}^{\infty} z^k / k^n$. |
source code
|
|
|
|
dilog(z)
The dilogarithm function $\text{Li}_2(z) = \sum_{k=1}^{\infty} z^k / k^2$. |
source code
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
first_var(expr)
Return the first variable in expr or `x' if there are no variables
in expression. |
source code
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
symbolic_expression_from_string(s,
syms=['4ti2-20061025', 'R-2.6.0', 'atlas-3.7.37', 'atlas-3.8.1', 'a...,
accept_sequence=False) |
source code
|
|
|
|
maxima = Maxima
|
|
|
is_simplified = False
|
|
|
infixops = {<built-in function add>: '+', <built-in function d...
|
|
|
arc_functions = ['asin', 'acos', 'atan', 'asinh', 'acosh', 'at...
|
|
|
cache = {<class 'sage.calculus.calculus.SymbolicExpressionRing...
|
|
|
SR = Symbolic Ring
|
|
|
zero_constant = 0
|
|
|
symbols = {<built-in function add>: ' + ', <built-in function ...
|
|
|
is_python_identifier = re.compile(r'[_a-zA-Z][_a-zA-Z0-9]*')
|
|
|
_vars = {'A': A, 'B': B, 'C': C, 'D': D, 'E': E, 'F': F, 'G': ...
|
|
|
_cfr_cache = {}
|
|
|
_syms = {'A': A, 'B': B, 'C': C, 'D': D, 'E': E, 'F': F, 'G': ...
|
|
|
erf = erf
|
|
|
abs_symbolic = abs
|
|
|
ceil = ceil
|
|
|
floor = floor
|
|
|
sin = sin
|
|
|
cos = cos
|
|
|
sec = sec
|
|
|
csc = csc
|
|
|
cot = cot
|
|
|
tan = tan
|
|
|
arcsin = arcsin
|
|
|
asin = arcsin
|
|
|
arcsinh = arcsinh
|
|
|
asinh = arcsinh
|
|
|
arccosh = arccosh
|
|
|
acosh = arccosh
|
|
|
arctanh = arctanh
|
|
|
atanh = arctanh
|
|
|
arccoth = arccoth
|
|
|
acoth = arccoth
|
|
|
arcsech = arcsech
|
|
|
asech = arcsech
|
|
|
arccsch = arccsch
|
|
|
acsch = arccsch
|
|
|
arccos = arccos
|
|
|
acos = arccos
|
|
|
arctan = arctan
|
|
|
atan = arctan
|
|
|
arccot = arccot
|
|
|
acot = arccot
|
|
|
arccsc = arccsc
|
|
|
acsc = arccsc
|
|
|
arcsec = arcsec
|
|
|
asec = arcsec
|
|
|
tanh = tanh
|
|
|
sinh = sinh
|
|
|
cosh = cosh
|
|
|
coth = coth
|
|
|
sech = sech
|
|
|
csch = csch
|
|
|
function_log = log
|
|
|
sqrt = sqrt
|
|
|
exp = exp
|
|
|
_functions = {}
|
|
|
symtable = {'%e': 'e', '%gamma': 'euler_gamma', '%i': 'I', '%p...
|
|
|
maxima_tick = re.compile(r'\'[a-z\|A-Z\|0-9\|_]*')
|
|
|
maxima_qp = re.compile(r'\?%[a-z\|A-Z\|0-9\|_]*')
|
|
|
maxima_var = re.compile(r'%[a-z\|A-Z\|0-9\|_]*')
|
|
|
sci_not = re.compile(r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-\+]\d+)')
|
|
|
syms_cur = {'A': A, 'B': B, 'C': C, 'D': D, 'E': E, 'F': F, 'G...
|
|
|
syms_default = {'abs': abs, 'acos': arccos, 'acosh': arccosh, ...
|
|
|
_augmented_syms = {}
|
|
|
SR_parser = Parser(make_int= lambda x: SymbolicConstant(Intege...
|
EXAMPLES:
sage: is_SymbolicExpression(sin(x))
True
sage: is_SymbolicExpression(2/3)
False
sage: is_SymbolicExpression(sqrt(2))
True
|
EXAMPLES:
sage: is_SymbolicExpressionRing(QQ)
False
sage: is_SymbolicExpressionRing(SR)
True
|
Return the symbolic expression ring. There is one
globally defines symbolic expression ring in the
calculus module.
EXAMPLES:
sage: SymbolicExpressionRing()
Symbolic Ring
sage: SymbolicExpressionRing() is SR
True
|
Return True if $x$ is a symbolic variable.
INPUT:
x -- object
OUTPUT:
bool -- True precisely if x is a symbolic variable.
EXAMPLES:
sage: is_SymbolicVariable('x')
False
sage: is_SymbolicVariable(x)
True
|
Create a symbolic variable with the name \emph{s}.
INPUTS:
s -- a string, either a single variable name
or a space or comma separated list of
variable names
NOTE: sage.calculus.calculus.var is better suited for using var in library
code since it won't touch the global namespace. To create a new variable
in the global namespace, use sage.calculus.var.var. That is, use
sage.calculus.calculus.var when defining a symbolic variable for use in
sage.calculus.calculus functions or library code.
EXAMPLES:
Note that sage.calculus.calculus.var defines a variable which is locally
defined in the calculus namespace but is not globally defined:
sage: alpha = 42; alpha
42
sage: sage.calculus.calculus.var('alpha')
alpha
sage: alpha
42
The variable is still of type SymbolicVariable and belongs to the
symbolic expression ring:
sage: type(alpha)
<type 'sage.rings.integer.Integer'>
sage: type(sage.calculus.calculus.var('alpha'))
<class 'sage.calculus.calculus.SymbolicVariable'>
sage: var('beta')
beta
sage: type(beta)
<class 'sage.calculus.calculus.SymbolicVariable'>
TESTS:
sage: var('xx')
xx
sage: var('.foo')
Traceback (most recent call last):
...
ValueError: variable name is not a valid Python identifier
sage: var('.foo/x')
Traceback (most recent call last):
...
ValueError: variable name is not a valid Python identifier
|
Return True if x is a callable symbolic expression.
INPUT:
x -- object
OUTPUT:
bool
EXAMPLES:
sage: is_CallableSymbolicExpressionRing(QQ)
False
sage: var('x,y,z')
(x, y, z)
sage: is_CallableSymbolicExpressionRing(CallableSymbolicExpressionRing((x,y,z)))
True
|
Returns true if \var{x} is a callable symbolic expression.
EXAMPLES:
sage: var('a x y z')
(a, x, y, z)
sage: f(x,y) = a + 2*x + 3*y + z
sage: is_CallableSymbolicExpression(f)
True
sage: is_CallableSymbolicExpression(a+2*x)
False
sage: def foo(n): return n^2
...
sage: is_CallableSymbolicExpression(foo)
False
|
Modified version of arctan function, since it is used by Maxima.
\code{arctan2(y,x) = arctan(y/x)}
This is mainly for internal use.
TODO: entering 'atan2(1,2)' into Sage returns a NameError that 'atan2'
is not defined despite the two lines following this function definition.
However, one can enter 'atan(1/2)' with no errors.
EXAMPLES:
sage: arctan2 = sage.calculus.calculus.arctan2
sage: arctan2(1,2)
arctan(1/2)
sage: float(arctan2(1,2))
0.46364760900080609
sage: arctan2(2,3)
arctan(2/3)
|
Modified version of arctan function, since it is used by Maxima.
\code{arctan2(y,x) = arctan(y/x)}
This is mainly for internal use.
TODO: entering 'atan2(1,2)' into Sage returns a NameError that 'atan2'
is not defined despite the two lines following this function definition.
However, one can enter 'atan(1/2)' with no errors.
EXAMPLES:
sage: arctan2 = sage.calculus.calculus.arctan2
sage: arctan2(1,2)
arctan(1/2)
sage: float(arctan2(1,2))
0.46364760900080609
sage: arctan2(2,3)
arctan(2/3)
|
The natural logarithm of x.
INPUT:
x -- positive real number
OUTPUT:
ln(x) -- real number
EXAMPLES:
sage: ln(e^2)
2
sage: ln(2)
log(2)
sage: ln(2.0)
0.693147180559945
|
log(x,
base=['4ti2-20061025', 'R-2.6.0', 'atlas-3.7.37', 'atlas-3.8.1', 'a...)
| source code
|
Return the logarithm of x to the given base.
Calls the \code{log} method of the object x when computing the logarithm,
thus allowing use of logarithm on any object containing a \code{log}
method. In other words, log works on more than just real numbers.
TODO: Add p-adic log example.
EXAMPLES:
sage: log(e^2)
2
sage: log(1024, 2); RDF(log(1024, 2))
log(1024)/log(2)
10.0
sage: log(10, 4); RDF(log(10, 4))
log(10)/log(4)
1.66096404744
sage: log(10, 2)
log(10)/log(2)
sage: n(log(10, 2))
3.32192809488736
sage: log(10, e)
log(10)
sage: n(log(10, e))
2.30258509299405
The log function also works in finite fields as long as the base is
generator of the multiplicative group:
sage: F = GF(13); g = F.multiplicative_generator(); g
2
sage: a = F(8)
sage: log(a,g); g^log(a,g)
3
8
sage: log(a,3)
Traceback (most recent call last):
...
ValueError: base (=3) for discrete log must generate multiplicative group
|
The polylogarithm function $\text{Li}_n(z) = \sum_{k=1}^{\infty} z^k / k^n$.
EXAMPLES:
sage: polylog(2,1)
pi^2/6
sage: polylog(2,x^2+1)
polylog(2, x^2 + 1)
sage: polylog(4,0.5)
polylog(4, 0.500000000000000)
sage: float(polylog(4,0.5))
0.51747906167389934
sage: var('z')
z
sage: polylog(2,z).taylor(z, 1/2, 3)
-(6*log(2)^2 - pi^2)/12 + 2*log(2)*(z - 1/2) + (-2*log(2) + 2)*(z - 1/2)^2 + (8*log(2) - 4)*(z - 1/2)^3/3
|
The dilogarithm function $\text{Li}_2(z) = \sum_{k=1}^{\infty} z^k / k^2$.
This is simply an alias for polylog(2, z).
EXAMPLES:
sage: dilog(1)
pi^2/6
sage: dilog(1/2)
pi^2/12 - log(2)^2/2
sage: dilog(x^2+1)
polylog(2, x^2 + 1)
sage: float(dilog(1))
1.6449340668482264
sage: var('z')
z
sage: dilog(z).diff(z, 2)
1/((1 - z)*z) + log(1 - z)/z^2
sage: dilog(z).taylor(z, 1/2, 3)
-(6*log(2)^2 - pi^2)/12 + 2*log(2)*(z - 1/2) + (-2*log(2) + 2)*(z - 1/2)^2 + (8*log(2) - 4)*(z - 1/2)^3/3
|
Create a formal symbolic function with the name \emph{s}.
EXAMPLES:
sage: var('a, b')
(a, b)
sage: f = function('cr', a)
sage: g = f.diff(a).integral(b)
sage: g
diff(cr(a), a, 1)*b
sage: g(cr=cos)
-sin(a)*b
sage: g(cr=sin(x) + cos(x))
(cos(a) - sin(a))*b
Basic arithmetic:
sage: x = var('x')
sage: h = function('f',x)
sage: 2*f
2*f
sage: 2*h
2*f(x)
|
This function is called to create formal wrappers of limits that
Maxima can't compute:
EXAMPLES:
sage: a = lim(exp(x^2)*(1-erf(x)), x=infinity); a
limit(e^x^2 - e^x^2*erf(x), x, +Infinity)
sage: a = sage.calculus.calculus.dummy_limit(sin(x)/x, x, 0);a
limit(sin(x)/x, x, 0)
|
symbolic_expression_from_maxima_string(x,
equals_sub=False,
maxima=Maxima)
| source code
|
Given a string representation of a Maxima expression, parse it and
return the corresponding Sage symbolic expression.
INPUT:
x -- a string
equals_sub -- (default: False) if True, replace '=' by '==' in self
maxima -- (default: the calculus package's Maxima) the Maxima
interpreter to use.
EXAMPLES:
sage: sage.calculus.calculus.symbolic_expression_from_maxima_string('x^%e + %e^%pi + %i + sin(0)')
x^e + I + e^pi
|
Given an element of the calculus copy of the Maxima interface,
create the corresponding Sage symbolic expression.
EXAMPLES:
sage: a = sage.calculus.calculus.maxima('x^(sqrt(y)+%pi) + sin(%e + %pi)')
sage: sage.calculus.calculus.symbolic_expression_from_maxima_element(a)
x^(sqrt(y) + pi) - sin(e)
|
evaled_symbolic_expression_from_maxima_string(x)
| source code
|
Given a string expression that makes sense in Maxima, return the
corresponding Sage symbolic expression. This is used mainly
internally by the Calculus module.
EXAMPLES:
sage: sage.calculus.calculus.evaled_symbolic_expression_from_maxima_string('2*x + x^3 + y*z*sin(sqrt(x)*erf(theta))')
sin(erf(theta)*sqrt(x))*y*z + x^3 + 2*x
sage: sage.calculus.calculus.evaled_symbolic_expression_from_maxima_string('x^%e + %e^%pi + %i')
x^e + I + e^pi
|
Return the first variable in expr or `x' if there are no variables
in expression.
EXAMPLES:
sage: var('a,x,y')
(a, x, y)
sage: sage.calculus.calculus.first_var(a + y^x)
a
sage: sage.calculus.calculus.first_var(y^x - x^3)
x
|
Used internally when creating a string of options to pass to Maxima.
INPUT:
v -- an object
OUTPUT:
a string.
The main use of this is to turn Python bools into lower case strings.
EXAMPLES:
sage: sage.calculus.calculus.mapped_opts(True)
'true'
sage: sage.calculus.calculus.mapped_opts(False)
'false'
sage: sage.calculus.calculus.mapped_opts('bar')
'bar'
|
Used internally to create a string of options to pass to Maxima.
EXAMPLES:
sage: sage.calculus.calculus.maxima_options(an_option=True, another=False, foo='bar')
'an_option=true,foo=bar,another=false'
|
infixops
- Value:
{<built-in function add>: '+',
<built-in function div>: '/',
<built-in function mul>: '*',
<built-in function pow>: '^',
<built-in function sub>: '-'}
|
|
arc_functions
- Value:
['asin',
'acos',
'atan',
'asinh',
'acosh',
'atanh',
'acoth',
'asech',
...
|
|
cache
- Value:
{<class 'sage.calculus.calculus.SymbolicExpressionRing_class'>: Symbol
ic Ring}
|
|
symbols
- Value:
{<built-in function add>: ' + ',
<built-in function div>: '/',
<built-in function mul>: '*',
<built-in function neg>: '-',
<built-in function pow>: '^',
<built-in function sub>: ' - '}
|
|
_vars
- Value:
{'A': A,
'B': B,
'C': C,
'D': D,
'E': E,
'F': F,
'G': G,
'H': H,
...
|
|
_syms
- Value:
{'A': A,
'B': B,
'C': C,
'D': D,
'E': E,
'F': F,
'G': G,
'H': H,
...
|
|
symtable
- Value:
{'%e': 'e',
'%gamma': 'euler_gamma',
'%i': 'I',
'%pi': 'pi',
'li[2]': 'polylog2',
'li[3]': 'polylog3'}
|
|
syms_cur
- Value:
{'A': A,
'B': B,
'C': C,
'D': D,
'E': E,
'F': F,
'G': G,
'H': H,
...
|
|
syms_default
- Value:
{'abs': abs,
'acos': arccos,
'acosh': arccosh,
'acot': arccot,
'acoth': arccoth,
'acsc': arccsc,
'acsch': arccsch,
'asec': arcsec,
...
|
|
SR_parser
- Value:
Parser(make_int= lambda x: SymbolicConstant(Integer(x)), make_float= l
ambda x: SymbolicConstant(create_RealNumber(x)), make_var= _find_var,
make_function= _find_func)
|
|