Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/calculus/calculus.py
4056 views
1
r"""
2
Symbolic Computation
3
4
AUTHORS:
5
6
- Bobby Moretti and William Stein (2006-2007)
7
8
- Robert Bradshaw (2007-10): minpoly(), numerical algorithm
9
10
- Robert Bradshaw (2008-10): minpoly(), algebraic algorithm
11
12
- Golam Mortuza Hossain (2009-06-15): _limit_latex()
13
14
- Golam Mortuza Hossain (2009-06-22): _laplace_latex(), _inverse_laplace_latex()
15
16
- Tom Coates (2010-06-11): fixed Trac #9217
17
18
The Sage calculus module is loosely based on the Sage Enhancement
19
Proposal found at: http://www.sagemath.org:9001/CalculusSEP.
20
21
EXAMPLES:
22
23
The basic units of the calculus package are symbolic expressions which
24
are elements of the symbolic expression ring (SR). To create a
25
symbolic variable object in Sage, use the :func:`var` function, whose
26
argument is the text of that variable. Note that Sage is intelligent
27
about LaTeXing variable names.
28
29
::
30
31
sage: x1 = var('x1'); x1
32
x1
33
sage: latex(x1)
34
x_{1}
35
sage: theta = var('theta'); theta
36
theta
37
sage: latex(theta)
38
\theta
39
40
Sage predefines ``x`` to be a global indeterminate.
41
Thus the following works::
42
43
sage: x^2
44
x^2
45
sage: type(x)
46
<type 'sage.symbolic.expression.Expression'>
47
48
More complicated expressions in Sage can be built up using ordinary
49
arithmetic. The following are valid, and follow the rules of Python
50
arithmetic: (The '=' operator represents assignment, and not
51
equality)
52
53
::
54
55
sage: var('x,y,z')
56
(x, y, z)
57
sage: f = x + y + z/(2*sin(y*z/55))
58
sage: g = f^f; g
59
(x + y + 1/2*z/sin(1/55*y*z))^(x + y + 1/2*z/sin(1/55*y*z))
60
61
Differentiation and integration are available, but behind the
62
scenes through Maxima::
63
64
sage: f = sin(x)/cos(2*y)
65
sage: f.derivative(y)
66
2*sin(x)*sin(2*y)/cos(2*y)^2
67
sage: g = f.integral(x); g
68
-cos(x)/cos(2*y)
69
70
Note that these methods usually require an explicit variable name. If none
71
is given, Sage will try to find one for you.
72
73
::
74
75
sage: f = sin(x); f.derivative()
76
cos(x)
77
78
If the expression is a callable symbolic expression (i.e., the
79
variable order is specified), then Sage can calculate the matrix
80
derivative (i.e., the gradient, Jacobian matrix, etc.) if no variables
81
are specified. In the example below, we use the second derivative
82
test to determine that there is a saddle point at (0,-1/2).
83
84
::
85
86
sage: f(x,y)=x^2*y+y^2+y
87
sage: f.diff() # gradient
88
(x, y) |--> (2*x*y, x^2 + 2*y + 1)
89
sage: solve(list(f.diff()),[x,y])
90
[[x == -I, y == 0], [x == I, y == 0], [x == 0, y == (-1/2)]]
91
sage: H=f.diff(2); H # Hessian matrix
92
[(x, y) |--> 2*y (x, y) |--> 2*x]
93
[(x, y) |--> 2*x (x, y) |--> 2]
94
sage: H(x=0,y=-1/2)
95
[-1 0]
96
[ 0 2]
97
sage: H(x=0,y=-1/2).eigenvalues()
98
[-1, 2]
99
100
Here we calculate the Jacobian for the polar coordinate transformation::
101
102
sage: T(r,theta)=[r*cos(theta),r*sin(theta)]
103
sage: T
104
(r, theta) |--> (r*cos(theta), r*sin(theta))
105
sage: T.diff() # Jacobian matrix
106
[ (r, theta) |--> cos(theta) (r, theta) |--> -r*sin(theta)]
107
[ (r, theta) |--> sin(theta) (r, theta) |--> r*cos(theta)]
108
sage: diff(T) # Jacobian matrix
109
[ (r, theta) |--> cos(theta) (r, theta) |--> -r*sin(theta)]
110
[ (r, theta) |--> sin(theta) (r, theta) |--> r*cos(theta)]
111
sage: T.diff().det() # Jacobian
112
(r, theta) |--> r*sin(theta)^2 + r*cos(theta)^2
113
114
When the order of variables is ambiguous, Sage will raise an
115
exception when differentiating::
116
117
sage: f = sin(x+y); f.derivative()
118
Traceback (most recent call last):
119
...
120
ValueError: No differentiation variable specified.
121
122
Simplifying symbolic sums is also possible, using the
123
sum command, which also uses Maxima in the background::
124
125
sage: k, m = var('k, m')
126
sage: sum(1/k^4, k, 1, oo)
127
1/90*pi^4
128
sage: sum(binomial(m,k), k, 0, m)
129
2^m
130
131
Symbolic matrices can be used as well in various ways,
132
including exponentiation::
133
134
sage: M = matrix([[x,x^2],[1/x,x]])
135
sage: M^2
136
[x^2 + x 2*x^3]
137
[ 2 x^2 + x]
138
sage: e^M
139
[ 1/2*(e^(2*sqrt(x)) + 1)*e^(x - sqrt(x)) 1/2*(x*e^(2*sqrt(x)) - x)*sqrt(x)*e^(x - sqrt(x))]
140
[ 1/2*(e^(2*sqrt(x)) - 1)*e^(x - sqrt(x))/x^(3/2) 1/2*(e^(2*sqrt(x)) + 1)*e^(x - sqrt(x))]
141
142
And complex exponentiation works now::
143
144
sage: M = i*matrix([[pi]])
145
sage: e^M
146
[-1]
147
sage: M = i*matrix([[pi,0],[0,2*pi]])
148
sage: e^M
149
[-1 0]
150
[ 0 1]
151
sage: M = matrix([[0,pi],[-pi,0]])
152
sage: e^M
153
[-1 0]
154
[ 0 -1]
155
156
Substitution works similarly. We can substitute with a python
157
dict::
158
159
sage: f = sin(x*y - z)
160
sage: f({x: var('t'), y: z})
161
sin(t*z - z)
162
163
Also we can substitute with keywords::
164
165
sage: f = sin(x*y - z)
166
sage: f(x = t, y = z)
167
sin(t*z - z)
168
169
It was formerly the case that if there was no ambiguity of variable
170
names, we didn't have to specify them; that still works for the moment,
171
but the behavior is deprecated::
172
173
sage: f = sin(x)
174
sage: f(y)
175
doctest:...: DeprecationWarning: Substitution using function-call
176
syntax and unnamed arguments is deprecated and will be removed
177
from a future release of Sage; you can use named arguments instead,
178
like EXPR(x=..., y=...)
179
sin(y)
180
sage: f(pi)
181
0
182
183
However if there is ambiguity, we should explicitly state what
184
variables we're substituting for::
185
186
sage: f = sin(2*pi*x/y)
187
sage: f(x=4)
188
sin(8*pi/y)
189
190
We can also make a ``CallableSymbolicExpression``,
191
which is a ``SymbolicExpression`` that is a function of
192
specified variables in a fixed order. Each
193
``SymbolicExpression`` has a
194
``function(...)`` method that is used to create a
195
``CallableSymbolicExpression``, as illustrated below::
196
197
sage: u = log((2-x)/(y+5))
198
sage: f = u.function(x, y); f
199
(x, y) |--> log(-(x - 2)/(y + 5))
200
201
There is an easier way of creating a
202
``CallableSymbolicExpression``, which relies on the
203
Sage preparser.
204
205
::
206
207
sage: f(x,y) = log(x)*cos(y); f
208
(x, y) |--> log(x)*cos(y)
209
210
Then we have fixed an order of variables and there is no ambiguity
211
substituting or evaluating::
212
213
sage: f(x,y) = log((2-x)/(y+5))
214
sage: f(7,t)
215
log(-5/(t + 5))
216
217
Some further examples::
218
219
sage: f = 5*sin(x)
220
sage: f
221
5*sin(x)
222
sage: f(x=2)
223
5*sin(2)
224
sage: f(x=pi)
225
0
226
sage: float(f(x=pi))
227
0.0
228
229
Another example::
230
231
sage: f = integrate(1/sqrt(9+x^2), x); f
232
arcsinh(1/3*x)
233
sage: f(x=3)
234
arcsinh(1)
235
sage: f.derivative(x)
236
1/3/sqrt(1/9*x^2 + 1)
237
238
We compute the length of the parabola from 0 to 2::
239
240
sage: x = var('x')
241
sage: y = x^2
242
sage: dy = derivative(y,x)
243
sage: z = integral(sqrt(1 + dy^2), x, 0, 2)
244
sage: z
245
sqrt(17) + 1/4*arcsinh(4)
246
sage: n(z,200)
247
4.6467837624329358733826155674904591885104869874232887508703
248
sage: float(z)
249
4.646783762432936
250
251
We test pickling::
252
253
sage: x, y = var('x,y')
254
sage: f = -sqrt(pi)*(x^3 + sin(x/cos(y)))
255
sage: bool(loads(dumps(f)) == f)
256
True
257
258
Coercion examples:
259
260
We coerce various symbolic expressions into the complex numbers::
261
262
sage: CC(I)
263
1.00000000000000*I
264
sage: CC(2*I)
265
2.00000000000000*I
266
sage: ComplexField(200)(2*I)
267
2.0000000000000000000000000000000000000000000000000000000000*I
268
sage: ComplexField(200)(sin(I))
269
1.1752011936438014568823818505956008151557179813340958702296*I
270
sage: f = sin(I) + cos(I/2); f
271
sin(I) + cos(1/2*I)
272
sage: CC(f)
273
1.12762596520638 + 1.17520119364380*I
274
sage: ComplexField(200)(f)
275
1.1276259652063807852262251614026720125478471180986674836290 + 1.1752011936438014568823818505956008151557179813340958702296*I
276
sage: ComplexField(100)(f)
277
1.1276259652063807852262251614 + 1.1752011936438014568823818506*I
278
279
We illustrate construction of an inverse sum where each denominator
280
has a new variable name::
281
282
sage: f = sum(1/var('n%s'%i)^i for i in range(10))
283
sage: f
284
1/n1 + 1/n2^2 + 1/n3^3 + 1/n4^4 + 1/n5^5 + 1/n6^6 + 1/n7^7 + 1/n8^8 + 1/n9^9 + 1
285
286
Note that after calling var, the variables are immediately
287
available for use::
288
289
sage: (n1 + n2)^5
290
(n1 + n2)^5
291
292
We can, of course, substitute::
293
294
sage: f(n9=9,n7=n6)
295
1/n1 + 1/n2^2 + 1/n3^3 + 1/n4^4 + 1/n5^5 + 1/n6^6 + 1/n6^7 + 1/n8^8 + 387420490/387420489
296
297
TESTS:
298
299
Substitution::
300
301
sage: f = x
302
sage: f(x=5)
303
5
304
305
Simplifying expressions involving scientific notation::
306
307
sage: k = var('k')
308
sage: a0 = 2e-06; a1 = 12
309
sage: c = a1 + a0*k; c
310
(2.00000000000000e-6)*k + 12
311
sage: sqrt(c)
312
sqrt((2.00000000000000e-6)*k + 12)
313
sage: sqrt(c^3)
314
sqrt(((2.00000000000000e-6)*k + 12)^3)
315
316
The symbolic calculus package uses its own copy of Maxima for
317
simplification, etc., which is separate from the default
318
system-wide version::
319
320
sage: maxima.eval('[x,y]: [1,2]')
321
'[1,2]'
322
sage: maxima.eval('expand((x+y)^3)')
323
'27'
324
325
If the copy of maxima used by the symbolic calculus package were
326
the same as the default one, then the following would return 27,
327
which would be very confusing indeed!
328
329
::
330
331
sage: x, y = var('x,y')
332
sage: expand((x+y)^3)
333
x^3 + 3*x^2*y + 3*x*y^2 + y^3
334
335
Set x to be 5 in maxima::
336
337
sage: maxima('x: 5')
338
5
339
sage: maxima('x + x + %pi')
340
%pi+10
341
342
Simplifications like these are now done using Pynac::
343
344
sage: x + x + pi
345
pi + 2*x
346
347
But this still uses Maxima::
348
349
sage: (x + x + pi).simplify()
350
pi + 2*x
351
352
Note that ``x`` is still ``x``, since the
353
maxima used by the calculus package is different than the one in
354
the interactive interpreter.
355
356
Check to see that the problem with the variables method mentioned
357
in Trac ticket #3779 is actually fixed::
358
359
sage: f = function('F',x)
360
sage: diff(f*SR(1),x)
361
D[0](F)(x)
362
363
Doubly ensure that Trac #7479 is working::
364
365
sage: f(x)=x
366
sage: integrate(f,x,0,1)
367
1/2
368
369
Check that the problem with Taylor expansions of the gamma function
370
(Trac #9217) is fixed::
371
372
sage: taylor(gamma(1/3+x),x,0,3) # random output - remove this in trac #9880
373
-1/432*((36*(pi*sqrt(3) + 9*log(3))*euler_gamma^2 + 27*pi^2*log(3) + 72*euler_gamma^3 + 243*log(3)^3 + 18*(6*pi*sqrt(3)*log(3) + pi^2 + 27*log(3)^2 + 12*psi(1, 1/3))*euler_gamma + 324*psi(1, 1/3)*log(3) + (pi^3 + 9*(9*log(3)^2 + 4*psi(1, 1/3))*pi)*sqrt(3))*gamma(1/3) - 72*gamma(1/3)*psi(2, 1/3))*x^3 + 1/24*(6*pi*sqrt(3)*log(3) + 4*(pi*sqrt(3) + 9*log(3))*euler_gamma + pi^2 + 12*euler_gamma^2 + 27*log(3)^2 + 12*psi(1, 1/3))*x^2*gamma(1/3) - 1/6*(6*euler_gamma + pi*sqrt(3) + 9*log(3))*x*gamma(1/3) + gamma(1/3)
374
sage: map(lambda f:f[0].n(), _.coeffs()) # numerical coefficients to make comparison easier; Maple 12 gives same answer
375
[2.6789385347..., -8.3905259853..., 26.662447494..., -80.683148377...]
376
377
Ensure that ticket #8582 is fixed::
378
379
sage: k = var("k")
380
sage: sum(1/(1+k^2), k, -oo, oo)
381
-1/2*I*psi(I + 1) - 1/2*I*psi(I) + 1/2*I*psi(-I) + 1/2*I*psi(-I + 1)
382
383
Ensure that ticket #8624 is fixed::
384
385
sage: integrate(abs(cos(x)) * sin(x), x, pi/2, pi)
386
1/2
387
sage: integrate(sqrt(cos(x)^2 + sin(x)^2), x, 0, 2*pi)
388
2*pi
389
"""
390
391
import re
392
from sage.rings.all import RR, Integer, CC, QQ, RealDoubleElement, algdep
393
from sage.rings.real_mpfr import create_RealNumber
394
395
from sage.misc.latex import latex
396
from sage.misc.parser import Parser
397
398
from sage.symbolic.ring import var, SR, is_SymbolicVariable
399
from sage.symbolic.expression import Expression
400
from sage.symbolic.function import Function
401
from sage.symbolic.function_factory import function_factory
402
from sage.symbolic.integration.integral import indefinite_integral, \
403
definite_integral
404
import sage.symbolic.pynac
405
406
"""
407
Check if maxima has redundant variables defined after initialization #9538::
408
409
sage: maxima = sage.interfaces.maxima.maxima
410
sage: maxima('f1')
411
f1
412
sage: sage.calculus.calculus.maxima('f1')
413
f1
414
"""
415
from sage.misc.lazy_import import lazy_import
416
lazy_import('sage.interfaces.maxima_lib','maxima')
417
# This is not the same instance of Maxima as the general purpose one
418
#from sage.interfaces.maxima import Maxima
419
#maxima = Maxima(init_code = ['display2d : false', 'domain : complex',
420
# 'keepfloat : true', 'load(to_poly_solver)',
421
# 'load(simplify_sum)'],
422
# script_subdirectory=None)
423
424
########################################################
425
def symbolic_sum(expression, v, a, b, algorithm='maxima'):
426
r"""
427
Returns the symbolic sum `\sum_{v = a}^b expression` with respect
428
to the variable `v` with endpoints `a` and `b`.
429
430
INPUT:
431
432
- ``expression`` - a symbolic expression
433
434
- ``v`` - a variable or variable name
435
436
- ``a`` - lower endpoint of the sum
437
438
- ``b`` - upper endpoint of the sum
439
440
- ``algorithm`` - (default: 'maxima') one of
441
- 'maxima' - use Maxima (the default)
442
- 'maple' - (optional) use Maple
443
- 'mathematica' - (optional) use Mathematica
444
- 'giac' - (optional) use Giac
445
446
EXAMPLES::
447
448
sage: k, n = var('k,n')
449
sage: from sage.calculus.calculus import symbolic_sum
450
sage: symbolic_sum(k, k, 1, n).factor()
451
1/2*(n + 1)*n
452
453
::
454
455
sage: symbolic_sum(1/k^4, k, 1, oo)
456
1/90*pi^4
457
458
::
459
460
sage: symbolic_sum(1/k^5, k, 1, oo)
461
zeta(5)
462
463
A well known binomial identity::
464
465
sage: symbolic_sum(binomial(n,k), k, 0, n)
466
2^n
467
468
And some truncations thereof::
469
470
sage: assume(n>1)
471
sage: symbolic_sum(binomial(n,k),k,1,n)
472
2^n - 1
473
sage: symbolic_sum(binomial(n,k),k,2,n)
474
2^n - n - 1
475
sage: symbolic_sum(binomial(n,k),k,0,n-1)
476
2^n - 1
477
sage: symbolic_sum(binomial(n,k),k,1,n-1)
478
2^n - 2
479
480
The binomial theorem::
481
482
sage: x, y = var('x, y')
483
sage: symbolic_sum(binomial(n,k) * x^k * y^(n-k), k, 0, n)
484
(x + y)^n
485
486
::
487
488
sage: symbolic_sum(k * binomial(n, k), k, 1, n)
489
n*2^(n - 1)
490
491
::
492
493
sage: symbolic_sum((-1)^k*binomial(n,k), k, 0, n)
494
0
495
496
::
497
498
sage: symbolic_sum(2^(-k)/(k*(k+1)), k, 1, oo)
499
-log(2) + 1
500
501
Summing a hypergeometric term::
502
503
sage: symbolic_sum(binomial(n, k) * factorial(k) / factorial(n+1+k), k, 0, n)
504
1/2*sqrt(pi)/factorial(n + 1/2)
505
506
We check a well known identity::
507
508
sage: bool(symbolic_sum(k^3, k, 1, n) == symbolic_sum(k, k, 1, n)^2)
509
True
510
511
A geometric sum::
512
513
sage: a, q = var('a, q')
514
sage: symbolic_sum(a*q^k, k, 0, n)
515
(a*q^(n + 1) - a)/(q - 1)
516
517
For the geometric series, we will have to assume
518
the right values for the sum to converge::
519
520
sage: assume(abs(q) < 1)
521
sage: symbolic_sum(a*q^k, k, 0, oo)
522
-a/(q - 1)
523
524
A divergent geometric series. Don't forget
525
to forget your assumptions::
526
527
sage: forget()
528
sage: assume(q > 1)
529
sage: symbolic_sum(a*q^k, k, 0, oo)
530
Traceback (most recent call last):
531
...
532
ValueError: Sum is divergent.
533
sage: forget()
534
sage: assumptions() # check the assumptions were really forgotten
535
[]
536
537
This summation only Mathematica can perform::
538
539
sage: symbolic_sum(1/(1+k^2), k, -oo, oo, algorithm = 'mathematica') # optional -- requires mathematica
540
pi*coth(pi)
541
542
An example of this summation with Giac::
543
544
sage: symbolic_sum(1/(1+k^2), k, -oo, oo, algorithm = 'giac') # optional -- requires giac
545
-(pi*e^(-2*pi) - pi*e^(2*pi))/(e^(-2*pi) + e^(2*pi) - 2)
546
547
Use Maple as a backend for summation::
548
549
sage: symbolic_sum(binomial(n,k)*x^k, k, 0, n, algorithm = 'maple') # optional -- requires maple
550
(x + 1)^n
551
552
TESTS:
553
554
Trac #10564 is fixed::
555
556
sage: sum (n^3 * x^n, n, 0, infinity)
557
(x^3 + 4*x^2 + x)/(x^4 - 4*x^3 + 6*x^2 - 4*x + 1)
558
559
.. note::
560
561
Sage can currently only understand a subset of the output of Maxima,
562
Maple and Mathematica, so even if the chosen backend can perform
563
the summation the result might not be convertable into a Sage
564
expression.
565
"""
566
if not is_SymbolicVariable(v):
567
if isinstance(v, str):
568
v = var(v)
569
else:
570
raise TypeError, "need a summation variable"
571
572
if v in SR(a).variables() or v in SR(b).variables():
573
raise ValueError, "summation limits must not depend on the summation variable"
574
575
if algorithm == 'maxima':
576
return maxima.sr_sum(expression,v,a,b)
577
578
elif algorithm == 'mathematica':
579
try:
580
sum = "Sum[%s, {%s, %s, %s}]" % tuple([repr(expr._mathematica_()) for expr in (expression, v, a, b)])
581
except TypeError:
582
raise ValueError, "Mathematica cannot make sense of input"
583
from sage.interfaces.mathematica import mathematica
584
try:
585
result = mathematica(sum)
586
except TypeError:
587
raise ValueError, "Mathematica cannot make sense of: %s" % sum
588
return result.sage()
589
590
elif algorithm == 'maple':
591
sum = "sum(%s, %s=%s..%s)" % tuple([repr(expr._maple_()) for expr in (expression, v, a, b)])
592
from sage.interfaces.maple import maple
593
try:
594
result = maple(sum).simplify()
595
except TypeError:
596
raise ValueError, "Maple cannot make sense of: %s" % sum
597
return result.sage()
598
599
elif algorithm == 'giac':
600
sum = "sum(%s, %s, %s, %s)" % tuple([repr(expr._giac_()) for expr in (expression, v, a, b)])
601
from sage.interfaces.giac import giac
602
try:
603
result = giac(sum)
604
except TypeError:
605
raise ValueError, "Giac cannot make sense of: %s" % sum
606
return result.sage()
607
608
else:
609
raise ValueError, "unknown algorithm: %s" % algorithm
610
611
def nintegral(ex, x, a, b,
612
desired_relative_error='1e-8',
613
maximum_num_subintervals=200):
614
r"""
615
Return a floating point machine precision numerical approximation
616
to the integral of ``self`` from `a` to
617
`b`, computed using floating point arithmetic via maxima.
618
619
INPUT:
620
621
- ``x`` - variable to integrate with respect to
622
623
- ``a`` - lower endpoint of integration
624
625
- ``b`` - upper endpoint of integration
626
627
- ``desired_relative_error`` - (default: '1e-8') the
628
desired relative error
629
630
- ``maximum_num_subintervals`` - (default: 200)
631
maxima number of subintervals
632
633
OUTPUT:
634
635
- float: approximation to the integral
636
637
- float: estimated absolute error of the
638
approximation
639
640
- the number of integrand evaluations
641
642
- an error code:
643
644
- ``0`` - no problems were encountered
645
646
- ``1`` - too many subintervals were done
647
648
- ``2`` - excessive roundoff error
649
650
- ``3`` - extremely bad integrand behavior
651
652
- ``4`` - failed to converge
653
654
- ``5`` - integral is probably divergent or slowly
655
convergent
656
657
- ``6`` - the input is invalid; this includes the case of
658
desired_relative_error being too small to be achieved
659
660
ALIAS: nintegrate is the same as nintegral
661
662
REMARK: There is also a function
663
``numerical_integral`` that implements numerical
664
integration using the GSL C library. It is potentially much faster
665
and applies to arbitrary user defined functions.
666
667
Also, there are limits to the precision to which Maxima can compute
668
the integral due to limitations in quadpack.
669
In the following example, remark that the last value of the returned
670
tuple is ``6``, indicating that the input was invalid, in this case
671
because of a too high desired precision.
672
673
::
674
675
sage: f = x
676
sage: f.nintegral(x,0,1,1e-14)
677
(0.0, 0.0, 0, 6)
678
679
EXAMPLES::
680
681
sage: f(x) = exp(-sqrt(x))
682
sage: f.nintegral(x, 0, 1)
683
(0.5284822353142306, 4.163...e-11, 231, 0)
684
685
We can also use the ``numerical_integral`` function,
686
which calls the GSL C library.
687
688
::
689
690
sage: numerical_integral(f, 0, 1)
691
(0.528482232253147, 6.83928460...e-07)
692
693
Note that in exotic cases where floating point evaluation of the
694
expression leads to the wrong value, then the output can be
695
completely wrong::
696
697
sage: f = exp(pi*sqrt(163)) - 262537412640768744
698
699
Despite appearance, `f` is really very close to 0, but one
700
gets a nonzero value since the definition of
701
``float(f)`` is that it makes all constants inside the
702
expression floats, then evaluates each function and each arithmetic
703
operation using float arithmetic::
704
705
sage: float(f)
706
-480.0
707
708
Computing to higher precision we see the truth::
709
710
sage: f.n(200)
711
-7.4992740280181431112064614366622348652078895136533593355718e-13
712
sage: f.n(300)
713
-7.49927402801814311120646143662663009137292462589621789352095066181709095575681963967103004e-13
714
715
Now numerically integrating, we see why the answer is wrong::
716
717
sage: f.nintegrate(x,0,1)
718
(-480.00000000000006, 5.329070518200754e-12, 21, 0)
719
720
It is just because every floating point evaluation of return -480.0
721
in floating point.
722
723
Important note: using PARI/GP one can compute numerical integrals
724
to high precision::
725
726
sage: gp.eval('intnum(x=17,42,exp(-x^2)*log(x))')
727
'2.565728500561051482917356396 E-127' # 32-bit
728
'2.5657285005610514829173563961304785900 E-127' # 64-bit
729
sage: old_prec = gp.set_real_precision(50)
730
sage: gp.eval('intnum(x=17,42,exp(-x^2)*log(x))')
731
'2.5657285005610514829173563961304785900147709554020 E-127'
732
sage: gp.set_real_precision(old_prec)
733
50
734
735
Note that the input function above is a string in PARI syntax.
736
"""
737
try:
738
v = ex._maxima_().quad_qags(x, a, b,
739
epsrel=desired_relative_error,
740
limit=maximum_num_subintervals)
741
except TypeError, err:
742
if "ERROR" in str(err):
743
raise ValueError, "Maxima (via quadpack) cannot compute the integral"
744
else:
745
raise TypeError, err
746
747
# Maxima returns unevaluated expressions when the underlying library fails
748
# to perfom numerical integration. See:
749
# http://www.math.utexas.edu/pipermail/maxima/2008/012975.html
750
if 'quad_qags' in str(v):
751
raise ValueError, "Maxima (via quadpack) cannot compute the integral"
752
753
return float(v[0]), float(v[1]), Integer(v[2]), Integer(v[3])
754
755
nintegrate = nintegral
756
757
def minpoly(ex, var='x', algorithm=None, bits=None, degree=None, epsilon=0):
758
r"""
759
Return the minimal polynomial of self, if possible.
760
761
INPUT:
762
763
- ``var`` - polynomial variable name (default 'x')
764
765
- ``algorithm`` - 'algebraic' or 'numerical' (default
766
both, but with numerical first)
767
768
- ``bits`` - the number of bits to use in numerical
769
approx
770
771
- ``degree`` - the expected algebraic degree
772
773
- ``epsilon`` - return without error as long as
774
f(self) epsilon, in the case that the result cannot be proven.
775
776
All of the above parameters are optional, with epsilon=0, bits and
777
degree tested up to 1000 and 24 by default respectively. The
778
numerical algorithm will be faster if bits and/or degree are given
779
explicitly. The algebraic algorithm ignores the last three
780
parameters.
781
782
783
OUTPUT: The minimal polynomial of self. If the numerical algorithm
784
is used then it is proved symbolically when epsilon=0 (default).
785
786
If the minimal polynomial could not be found, two distinct kinds of
787
errors are raised. If no reasonable candidate was found with the
788
given bit/degree parameters, a ``ValueError`` will be
789
raised. If a reasonable candidate was found but (perhaps due to
790
limits in the underlying symbolic package) was unable to be proved
791
correct, a ``NotImplementedError`` will be raised.
792
793
ALGORITHM: Two distinct algorithms are used, depending on the
794
algorithm parameter. By default, the numerical algorithm is
795
attempted first, then the algebraic one.
796
797
Algebraic: Attempt to evaluate this expression in QQbar, using
798
cyclotomic fields to resolve exponential and trig functions at
799
rational multiples of pi, field extensions to handle roots and
800
rational exponents, and computing compositums to represent the full
801
expression as an element of a number field where the minimal
802
polynomial can be computed exactly. The bits, degree, and epsilon
803
parameters are ignored.
804
805
Numerical: Computes a numerical approximation of
806
``self`` and use PARI's algdep to get a candidate
807
minpoly `f`. If `f(\mathtt{self})`,
808
evaluated to a higher precision, is close enough to 0 then evaluate
809
`f(\mathtt{self})` symbolically, attempting to prove
810
vanishing. If this fails, and ``epsilon`` is non-zero,
811
return `f` if and only if
812
`f(\mathtt{self}) < \mathtt{epsilon}`.
813
Otherwise raise a ``ValueError`` (if no suitable
814
candidate was found) or a ``NotImplementedError`` (if a
815
likely candidate was found but could not be proved correct).
816
817
EXAMPLES: First some simple examples::
818
819
sage: sqrt(2).minpoly()
820
x^2 - 2
821
sage: minpoly(2^(1/3))
822
x^3 - 2
823
sage: minpoly(sqrt(2) + sqrt(-1))
824
x^4 - 2*x^2 + 9
825
sage: minpoly(sqrt(2)-3^(1/3))
826
x^6 - 6*x^4 + 6*x^3 + 12*x^2 + 36*x + 1
827
828
829
Works with trig and exponential functions too.
830
831
::
832
833
sage: sin(pi/3).minpoly()
834
x^2 - 3/4
835
sage: sin(pi/7).minpoly()
836
x^6 - 7/4*x^4 + 7/8*x^2 - 7/64
837
sage: minpoly(exp(I*pi/17))
838
x^16 - x^15 + x^14 - x^13 + x^12 - x^11 + x^10 - x^9 + x^8 - x^7 + x^6 - x^5 + x^4 - x^3 + x^2 - x + 1
839
840
Here we verify it gives the same result as the abstract number
841
field.
842
843
::
844
845
sage: (sqrt(2) + sqrt(3) + sqrt(6)).minpoly()
846
x^4 - 22*x^2 - 48*x - 23
847
sage: K.<a,b> = NumberField([x^2-2, x^2-3])
848
sage: (a+b+a*b).absolute_minpoly()
849
x^4 - 22*x^2 - 48*x - 23
850
851
The minpoly function is used implicitly when creating
852
number fields::
853
854
sage: x = var('x')
855
sage: eqn = x^3 + sqrt(2)*x + 5 == 0
856
sage: a = solve(eqn, x)[0].rhs()
857
sage: QQ[a]
858
Number Field in a with defining polynomial x^6 + 10*x^3 - 2*x^2 + 25
859
860
Here we solve a cubic and then recover it from its complicated
861
radical expansion.
862
863
::
864
865
sage: f = x^3 - x + 1
866
sage: a = f.solve(x)[0].rhs(); a
867
-1/2*(I*sqrt(3) + 1)*(1/18*sqrt(3)*sqrt(23) - 1/2)^(1/3) - 1/6*(-I*sqrt(3) + 1)/(1/18*sqrt(3)*sqrt(23) - 1/2)^(1/3)
868
sage: a.minpoly()
869
x^3 - x + 1
870
871
Note that simplification may be necessary to see that the minimal
872
polynomial is correct.
873
874
::
875
876
sage: a = sqrt(2)+sqrt(3)+sqrt(5)
877
sage: f = a.minpoly(); f
878
x^8 - 40*x^6 + 352*x^4 - 960*x^2 + 576
879
sage: f(a)
880
((((sqrt(2) + sqrt(3) + sqrt(5))^2 - 40)*(sqrt(2) + sqrt(3) + sqrt(5))^2 + 352)*(sqrt(2) + sqrt(3) + sqrt(5))^2 - 960)*(sqrt(2) + sqrt(3) + sqrt(5))^2 + 576
881
sage: f(a).expand()
882
0
883
884
Here we show use of the ``epsilon`` parameter. That
885
this result is actually exact can be shown using the addition
886
formula for sin, but maxima is unable to see that.
887
888
::
889
890
sage: a = sin(pi/5)
891
sage: a.minpoly(algorithm='numerical')
892
Traceback (most recent call last):
893
...
894
NotImplementedError: Could not prove minimal polynomial x^4 - 5/4*x^2 + 5/16 (epsilon 0.00000000000000e-1)
895
sage: f = a.minpoly(algorithm='numerical', epsilon=1e-100); f
896
x^4 - 5/4*x^2 + 5/16
897
sage: f(a).numerical_approx(100)
898
0.00000000000000000000000000000
899
900
The degree must be high enough (default tops out at 24).
901
902
::
903
904
sage: a = sqrt(3) + sqrt(2)
905
sage: a.minpoly(algorithm='numerical', bits=100, degree=3)
906
Traceback (most recent call last):
907
...
908
ValueError: Could not find minimal polynomial (100 bits, degree 3).
909
sage: a.minpoly(algorithm='numerical', bits=100, degree=10)
910
x^4 - 10*x^2 + 1
911
912
There is a difference between algorithm='algebraic' and
913
algorithm='numerical'::
914
915
sage: cos(pi/33).minpoly(algorithm='algebraic')
916
x^10 + 1/2*x^9 - 5/2*x^8 - 5/4*x^7 + 17/8*x^6 + 17/16*x^5 - 43/64*x^4 - 43/128*x^3 + 3/64*x^2 + 3/128*x + 1/1024
917
sage: cos(pi/33).minpoly(algorithm='numerical')
918
Traceback (most recent call last):
919
...
920
NotImplementedError: Could not prove minimal polynomial x^10 + 1/2*x^9 - 5/2*x^8 - 5/4*x^7 + 17/8*x^6 + 17/16*x^5 - 43/64*x^4 - 43/128*x^3 + 3/64*x^2 + 3/128*x + 1/1024 (epsilon ...)
921
922
Sometimes it fails, as it must given that some numbers aren't algebraic::
923
924
sage: sin(1).minpoly(algorithm='numerical')
925
Traceback (most recent call last):
926
...
927
ValueError: Could not find minimal polynomial (1000 bits, degree 24).
928
929
.. note::
930
931
Of course, failure to produce a minimal polynomial does not
932
necessarily indicate that this number is transcendental.
933
"""
934
if algorithm is None or algorithm.startswith('numeric'):
935
bits_list = [bits] if bits else [100,200,500,1000]
936
degree_list = [degree] if degree else [2,4,8,12,24]
937
938
for bits in bits_list:
939
a = ex.numerical_approx(bits)
940
check_bits = int(1.25 * bits + 80)
941
aa = ex.numerical_approx(check_bits)
942
943
for degree in degree_list:
944
945
f = QQ[var](algdep(a, degree)) # TODO: use the known_bits parameter?
946
# If indeed we have found a minimal polynomial,
947
# it should be accurate to a much higher precision.
948
error = abs(f(aa))
949
dx = ~RR(Integer(1) << (check_bits - degree - 2))
950
expected_error = abs(f.derivative()(CC(aa))) * dx
951
952
if error < expected_error:
953
# Degree might have been an over-estimate,
954
# factor because we want (irreducible) minpoly.
955
ff = f.factor()
956
for g, e in ff:
957
lead = g.leading_coefficient()
958
if lead != 1:
959
g = g / lead
960
expected_error = abs(g.derivative()(CC(aa))) * dx
961
error = abs(g(aa))
962
if error < expected_error:
963
# See if we can prove equality exactly
964
if g(ex).simplify_trig().simplify_radical() == 0:
965
return g
966
# Otherwise fall back to numerical guess
967
elif epsilon and error < epsilon:
968
return g
969
elif algorithm is not None:
970
raise NotImplementedError, "Could not prove minimal polynomial %s (epsilon %s)" % (g, RR(error).str(no_sci=False))
971
972
if algorithm is not None:
973
raise ValueError, "Could not find minimal polynomial (%s bits, degree %s)." % (bits, degree)
974
975
if algorithm is None or algorithm == 'algebraic':
976
from sage.rings.all import QQbar
977
return QQ[var](QQbar(ex).minpoly())
978
979
raise ValueError, "Unknown algorithm: %s" % algorithm
980
981
982
###################################################################
983
# limits
984
###################################################################
985
def limit(ex, dir=None, taylor=False, algorithm='maxima', **argv):
986
r"""
987
Return the limit as the variable `v` approaches `a`
988
from the given direction.
989
990
::
991
992
expr.limit(x = a)
993
expr.limit(x = a, dir='above')
994
995
INPUT:
996
997
- ``dir`` - (default: None); dir may have the value
998
'plus' (or '+' or 'right') for a limit from above,
999
'minus' (or '-' or 'left') for a limit from below, or may be omitted
1000
(implying a two-sided limit is to be computed).
1001
1002
- ``taylor`` - (default: False); if True, use Taylor
1003
series, which allows more limits to be computed (but may also
1004
crash in some obscure cases due to bugs in Maxima).
1005
1006
- ``**argv`` - 1 named parameter
1007
1008
.. note::
1009
1010
The output may also use 'und' (undefined), 'ind'
1011
(indefinite but bounded), and 'infinity' (complex
1012
infinity).
1013
1014
EXAMPLES::
1015
1016
sage: x = var('x')
1017
sage: f = (1+1/x)^x
1018
sage: f.limit(x = oo)
1019
e
1020
sage: f.limit(x = 5)
1021
7776/3125
1022
sage: f.limit(x = 1.2)
1023
2.06961575467...
1024
sage: f.limit(x = I, taylor=True)
1025
(-I + 1)^I
1026
sage: f(x=1.2)
1027
2.0696157546720...
1028
sage: f(x=I)
1029
(-I + 1)^I
1030
sage: CDF(f(x=I))
1031
2.06287223508 + 0.74500706218*I
1032
sage: CDF(f.limit(x = I))
1033
2.06287223508 + 0.74500706218*I
1034
1035
Notice that Maxima may ask for more information::
1036
1037
sage: var('a')
1038
a
1039
sage: limit(x^a,x=0)
1040
Traceback (most recent call last):
1041
...
1042
ValueError: Computation failed since Maxima requested additional
1043
constraints; using the 'assume' command before limit evaluation
1044
*may* help (see `assume?` for more details)
1045
Is a positive, negative, or zero?
1046
1047
With this example, Maxima is looking for a LOT of information::
1048
1049
sage: assume(a>0)
1050
sage: limit(x^a,x=0)
1051
Traceback (most recent call last):
1052
...
1053
ValueError: Computation failed since Maxima requested additional
1054
constraints; using the 'assume' command before limit evaluation
1055
*may* help (see `assume?` for more details)
1056
Is a an integer?
1057
sage: assume(a,'integer')
1058
sage: limit(x^a,x=0)
1059
Traceback (most recent call last):
1060
...
1061
ValueError: Computation failed since Maxima requested additional
1062
constraints; using the 'assume' command before limit evaluation
1063
*may* help (see `assume?` for more details)
1064
Is a an even number?
1065
sage: assume(a,'even')
1066
sage: limit(x^a,x=0)
1067
0
1068
sage: forget()
1069
1070
More examples::
1071
1072
sage: limit(x*log(x), x = 0, dir='+')
1073
0
1074
sage: lim((x+1)^(1/x), x = 0)
1075
e
1076
sage: lim(e^x/x, x = oo)
1077
+Infinity
1078
sage: lim(e^x/x, x = -oo)
1079
0
1080
sage: lim(-e^x/x, x = oo)
1081
-Infinity
1082
sage: lim((cos(x))/(x^2), x = 0)
1083
+Infinity
1084
sage: lim(sqrt(x^2+1) - x, x = oo)
1085
0
1086
sage: lim(x^2/(sec(x)-1), x=0)
1087
2
1088
sage: lim(cos(x)/(cos(x)-1), x=0)
1089
-Infinity
1090
sage: lim(x*sin(1/x), x=0)
1091
0
1092
sage: limit(e^(-1/x), x=0, dir='right')
1093
0
1094
sage: limit(e^(-1/x), x=0, dir='left')
1095
+Infinity
1096
1097
::
1098
1099
sage: f = log(log(x))/log(x)
1100
sage: forget(); assume(x<-2); lim(f, x=0, taylor=True)
1101
0
1102
sage: forget()
1103
1104
Here ind means "indefinite but bounded"::
1105
1106
sage: lim(sin(1/x), x = 0)
1107
ind
1108
1109
TESTS::
1110
1111
sage: lim(x^2, x=2, dir='nugget')
1112
Traceback (most recent call last):
1113
...
1114
ValueError: dir must be one of None, 'plus', '+', 'right',
1115
'minus', '-', 'left'
1116
1117
We check that Trac ticket 3718 is fixed, so that
1118
Maxima gives correct limits for the floor function::
1119
1120
sage: limit(floor(x), x=0, dir='-')
1121
-1
1122
sage: limit(floor(x), x=0, dir='+')
1123
0
1124
sage: limit(floor(x), x=0)
1125
und
1126
1127
Maxima gives the right answer here, too, showing
1128
that Trac 4142 is fixed::
1129
1130
sage: f = sqrt(1-x^2)
1131
sage: g = diff(f, x); g
1132
-x/sqrt(-x^2 + 1)
1133
sage: limit(g, x=1, dir='-')
1134
-Infinity
1135
1136
::
1137
1138
sage: limit(1/x, x=0)
1139
Infinity
1140
sage: limit(1/x, x=0, dir='+')
1141
+Infinity
1142
sage: limit(1/x, x=0, dir='-')
1143
-Infinity
1144
1145
Check that Trac 8942 is fixed::
1146
1147
sage: f(x) = (cos(pi/4-x) - tan(x)) / (1 - sin(pi/4+x))
1148
sage: limit(f(x), x = pi/4, dir='minus')
1149
+Infinity
1150
sage: limit(f(x), x = pi/4, dir='plus')
1151
-Infinity
1152
sage: limit(f(x), x = pi/4)
1153
Infinity
1154
1155
Check that we give deprecation warnings for 'above' and 'below' #9200::
1156
1157
sage: limit(1/x, x=0, dir='above')
1158
doctest:...: DeprecationWarning: (Since Sage version 4.6) the keyword
1159
'above' is deprecated. Please use 'right' or '+' instead.
1160
+Infinity
1161
sage: limit(1/x, x=0, dir='below')
1162
doctest:...: DeprecationWarning: (Since Sage version 4.6) the keyword
1163
'below' is deprecated. Please use 'left' or '-' instead.
1164
-Infinity
1165
"""
1166
if not isinstance(ex, Expression):
1167
ex = SR(ex)
1168
1169
if len(argv) != 1:
1170
raise ValueError, "call the limit function like this, e.g. limit(expr, x=2)."
1171
else:
1172
k = argv.keys()[0]
1173
v = var(k)
1174
a = argv[k]
1175
1176
if taylor and algorithm == 'maxima':
1177
algorithm = 'maxima_taylor'
1178
1179
if dir not in [None, 'plus', '+', 'right', 'minus', '-', 'left',
1180
'above', 'below']:
1181
raise ValueError("dir must be one of None, 'plus', '+', 'right', 'minus', '-', 'left'")
1182
1183
if algorithm == 'maxima':
1184
if dir is None:
1185
l = maxima.sr_limit(ex, v, a)
1186
elif dir in ['plus', '+', 'right', 'above']:
1187
if dir == 'above':
1188
from sage.misc.misc import deprecation
1189
deprecation("the keyword 'above' is deprecated. Please use 'right' or '+' instead.", 'Sage version 4.6')
1190
l = maxima.sr_limit(ex, v, a, 'plus')
1191
elif dir in ['minus', '-', 'left', 'below']:
1192
if dir == 'below':
1193
from sage.misc.misc import deprecation
1194
deprecation("the keyword 'below' is deprecated. Please use 'left' or '-' instead.", 'Sage version 4.6')
1195
l = maxima.sr_limit(ex, v, a, 'minus')
1196
elif algorithm == 'maxima_taylor':
1197
if dir is None:
1198
l = maxima.sr_tlimit(ex, v, a)
1199
elif dir == 'plus' or dir == 'above' or dir == 'from_right':
1200
l = maxima.sr_tlimit(ex, v, a, 'plus')
1201
elif dir == 'minus' or dir == 'below' or dir == 'from_left':
1202
l = maxima.sr_tlimit(ex, v, a, 'minus')
1203
elif algorithm == 'sympy':
1204
if dir is None:
1205
import sympy
1206
l = sympy.limit(ex._sympy_(), v._sympy_(), a._sympy_())
1207
else:
1208
raise NotImplementedError, "sympy does not support one-sided limits"
1209
1210
#return l.sage()
1211
return ex.parent()(l)
1212
1213
# lim is alias for limit
1214
lim = limit
1215
1216
###################################################################
1217
# Laplace transform
1218
###################################################################
1219
def laplace(ex, t, s):
1220
r"""
1221
Attempts to compute and return the Laplace transform of
1222
``self`` with respect to the variable `t` and
1223
transform parameter `s`. If this function cannot find a
1224
solution, a formal function is returned.
1225
1226
The function that is returned may be be viewed as a function of
1227
`s`.
1228
1229
DEFINITION:
1230
1231
The Laplace transform of a function `f(t)`,
1232
defined for all real numbers `t \geq 0`, is the function
1233
`F(s)` defined by
1234
1235
.. math::
1236
1237
F(s) = \int_{0}^{\infty} e^{-st} f(t) dt.
1238
1239
EXAMPLES:
1240
1241
We compute a few Laplace transforms::
1242
1243
sage: var('x, s, z, t, t0')
1244
(x, s, z, t, t0)
1245
sage: sin(x).laplace(x, s)
1246
1/(s^2 + 1)
1247
sage: (z + exp(x)).laplace(x, s)
1248
z/s + 1/(s - 1)
1249
sage: log(t/t0).laplace(t, s)
1250
-(euler_gamma + log(s) + log(t0))/s
1251
1252
We do a formal calculation::
1253
1254
sage: f = function('f', x)
1255
sage: g = f.diff(x); g
1256
D[0](f)(x)
1257
sage: g.laplace(x, s)
1258
s*laplace(f(x), x, s) - f(0)
1259
1260
EXAMPLES:
1261
1262
A BATTLE BETWEEN the X-women and the Y-men (by David
1263
Joyner): Solve
1264
1265
.. math::
1266
1267
x' = -16y, x(0)=270, y' = -x + 1, y(0) = 90.
1268
1269
This models a fight between two sides, the "X-women" and the
1270
"Y-men", where the X-women have 270 initially and the Y-men have
1271
90, but the Y-men are better at fighting, because of the higher
1272
factor of "-16" vs "-1", and also get an occasional reinforcement,
1273
because of the "+1" term.
1274
1275
::
1276
1277
sage: var('t')
1278
t
1279
sage: t = var('t')
1280
sage: x = function('x', t)
1281
sage: y = function('y', t)
1282
sage: de1 = x.diff(t) + 16*y
1283
sage: de2 = y.diff(t) + x - 1
1284
sage: de1.laplace(t, s)
1285
s*laplace(x(t), t, s) + 16*laplace(y(t), t, s) - x(0)
1286
sage: de2.laplace(t, s)
1287
s*laplace(y(t), t, s) - 1/s + laplace(x(t), t, s) - y(0)
1288
1289
Next we form the augmented matrix of the above system::
1290
1291
sage: A = matrix([[s, 16, 270],[1, s, 90+1/s]])
1292
sage: E = A.echelon_form()
1293
sage: xt = E[0,2].inverse_laplace(s,t)
1294
sage: yt = E[1,2].inverse_laplace(s,t)
1295
sage: xt
1296
629/2*e^(-4*t) - 91/2*e^(4*t) + 1
1297
sage: yt
1298
629/8*e^(-4*t) + 91/8*e^(4*t)
1299
sage: p1 = plot(xt,0,1/2,rgbcolor=(1,0,0))
1300
sage: p2 = plot(yt,0,1/2,rgbcolor=(0,1,0))
1301
sage: (p1+p2).save(SAGE_TMP + "de_plot.png")
1302
1303
Another example::
1304
1305
sage: var('a,s,t')
1306
(a, s, t)
1307
sage: f = exp (2*t + a) * sin(t) * t; f
1308
t*e^(a + 2*t)*sin(t)
1309
sage: L = laplace(f, t, s); L
1310
2*(s - 2)*e^a/(s^2 - 4*s + 5)^2
1311
sage: inverse_laplace(L, s, t)
1312
t*e^(a + 2*t)*sin(t)
1313
1314
Unable to compute solution::
1315
1316
sage: laplace(1/s, s, t)
1317
laplace(1/s, s, t)
1318
"""
1319
if not isinstance(ex, (Expression, Function)):
1320
ex = SR(ex)
1321
return ex.parent()(ex._maxima_().laplace(var(t), var(s)))
1322
1323
def inverse_laplace(ex, t, s):
1324
r"""
1325
Attempts to compute the inverse Laplace transform of
1326
``self`` with respect to the variable `t` and
1327
transform parameter `s`. If this function cannot find a
1328
solution, a formal function is returned.
1329
1330
The function that is returned may be be viewed as a function of
1331
`s`.
1332
1333
DEFINITION: The inverse Laplace transform of a function
1334
`F(s)`, is the function `f(t)` defined by
1335
1336
.. math::
1337
1338
F(s) = \frac{1}{2\pi i} \int_{\gamma-i\infty}^{\gamma + i\infty} e^{st} F(s) dt,
1339
1340
where `\gamma` is chosen so that the contour path of
1341
integration is in the region of convergence of `F(s)`.
1342
1343
EXAMPLES::
1344
1345
sage: var('w, m')
1346
(w, m)
1347
sage: f = (1/(w^2+10)).inverse_laplace(w, m); f
1348
1/10*sqrt(10)*sin(sqrt(10)*m)
1349
sage: laplace(f, m, w)
1350
1/(w^2 + 10)
1351
1352
sage: f(t) = t*cos(t)
1353
sage: s = var('s')
1354
sage: L = laplace(f, t, s); L
1355
t |--> 2*s^2/(s^2 + 1)^2 - 1/(s^2 + 1)
1356
sage: inverse_laplace(L, s, t)
1357
t |--> t*cos(t)
1358
sage: inverse_laplace(1/(s^3+1), s, t)
1359
1/3*(sqrt(3)*sin(1/2*sqrt(3)*t) - cos(1/2*sqrt(3)*t))*e^(1/2*t) + 1/3*e^(-t)
1360
1361
No explicit inverse Laplace transform, so one is returned formally
1362
as a function ``ilt``::
1363
1364
sage: inverse_laplace(cos(s), s, t)
1365
ilt(cos(s), s, t)
1366
"""
1367
if not isinstance(ex, Expression):
1368
ex = SR(ex)
1369
return ex.parent()(ex._maxima_().ilt(var(t), var(s)))
1370
1371
###################################################################
1372
# symbolic evaluation "at" a point
1373
###################################################################
1374
def at(ex, *args, **kwds):
1375
"""
1376
Parses ``at`` formulations from other systems, such as Maxima.
1377
Replaces evaluation 'at' a point with substitution method of
1378
a symbolic expression.
1379
1380
EXAMPLES:
1381
1382
We do not import ``at`` at the top level, but we can use it
1383
as a synonym for substitution if we import it::
1384
1385
sage: g = x^3-3
1386
sage: from sage.calculus.calculus import at
1387
sage: at(g, x=1)
1388
-2
1389
sage: g.subs(x=1)
1390
-2
1391
1392
We find a formal Taylor expansion::
1393
1394
sage: h,x = var('h,x')
1395
sage: u = function('u')
1396
sage: u(x + h)
1397
u(h + x)
1398
sage: diff(u(x+h), x)
1399
D[0](u)(h + x)
1400
sage: taylor(u(x+h),h,0,4)
1401
1/24*h^4*D[0, 0, 0, 0](u)(x) + 1/6*h^3*D[0, 0, 0](u)(x) + 1/2*h^2*D[0, 0](u)(x) + h*D[0](u)(x) + u(x)
1402
1403
We compute a Laplace transform::
1404
1405
sage: var('s,t')
1406
(s, t)
1407
sage: f=function('f', t)
1408
sage: f.diff(t,2)
1409
D[0, 0](f)(t)
1410
sage: f.diff(t,2).laplace(t,s)
1411
s^2*laplace(f(t), t, s) - s*f(0) - D[0](f)(0)
1412
1413
We can also accept a non-keyword list of expression substitutions,
1414
like Maxima does, :trac:`12796`::
1415
1416
sage: from sage.calculus.calculus import at
1417
sage: f = function('f')
1418
sage: at(f(x), [x == 1])
1419
f(1)
1420
1421
TESTS:
1422
1423
Our one non-keyword argument must be a list::
1424
1425
sage: from sage.calculus.calculus import at
1426
sage: f = function('f')
1427
sage: at(f(x), x == 1)
1428
Traceback (most recent call last):
1429
...
1430
TypeError: at can take at most one argument, which must be a list
1431
1432
We should convert our first argument to a symbolic expression::
1433
1434
sage: from sage.calculus.calculus import at
1435
sage: at(int(1), x=1)
1436
1
1437
1438
"""
1439
if not isinstance(ex, (Expression, Function)):
1440
ex = SR(ex)
1441
if len(args) == 1 and isinstance(args[0],list):
1442
for c in args[0]:
1443
kwds[str(c.lhs())]=c.rhs()
1444
else:
1445
if len(args) !=0:
1446
raise TypeError,"at can take at most one argument, which must be a list"
1447
1448
return ex.subs(**kwds)
1449
1450
1451
#############################################3333
1452
def var_cmp(x,y):
1453
"""
1454
Return comparison of the two variables x and y, which is just the
1455
comparison of the underlying string representations of the
1456
variables. This is used internally by the Calculus package.
1457
1458
INPUT:
1459
1460
- ``x, y`` - symbolic variables
1461
1462
OUTPUT: Python integer; either -1, 0, or 1.
1463
1464
EXAMPLES::
1465
1466
sage: sage.calculus.calculus.var_cmp(x,x)
1467
0
1468
sage: sage.calculus.calculus.var_cmp(x,var('z'))
1469
-1
1470
sage: sage.calculus.calculus.var_cmp(x,var('a'))
1471
1
1472
"""
1473
return cmp(repr(x), repr(y))
1474
1475
def dummy_limit(*args):
1476
"""
1477
This function is called to create formal wrappers of limits that
1478
Maxima can't compute:
1479
1480
EXAMPLES::
1481
1482
sage: a = lim(exp(x^2)*(1-erf(x)), x=infinity); a
1483
-limit((erf(x) - 1)*e^(x^2), x, +Infinity)
1484
sage: a = sage.calculus.calculus.dummy_limit(sin(x)/x, x, 0);a
1485
limit(sin(x)/x, x, 0)
1486
"""
1487
return _limit(args[0], var(repr(args[1])), SR(args[2]))
1488
1489
def dummy_diff(*args):
1490
"""
1491
This function is called when 'diff' appears in a Maxima string.
1492
1493
EXAMPLES::
1494
1495
sage: from sage.calculus.calculus import dummy_diff
1496
sage: x,y = var('x,y')
1497
sage: dummy_diff(sin(x*y), x, SR(2), y, SR(1))
1498
-x*y^2*cos(x*y) - 2*y*sin(x*y)
1499
1500
Here the function is used implicitly::
1501
1502
sage: a = var('a')
1503
sage: f = function('cr', a)
1504
sage: g = f.diff(a); g
1505
D[0](cr)(a)
1506
"""
1507
f = args[0]
1508
args = list(args[1:])
1509
for i in range(1, len(args), 2):
1510
args[i] = Integer(args[i])
1511
return f.diff(*args)
1512
1513
def dummy_integrate(*args):
1514
"""
1515
This function is called to create formal wrappers of integrals that
1516
Maxima can't compute:
1517
1518
EXAMPLES::
1519
1520
sage: from sage.calculus.calculus import dummy_integrate
1521
sage: f(x) = function('f',x)
1522
sage: dummy_integrate(f(x), x)
1523
integrate(f(x), x)
1524
sage: a,b = var('a,b')
1525
sage: dummy_integrate(f(x), x, a, b)
1526
integrate(f(x), x, a, b)
1527
"""
1528
if len(args) == 4:
1529
return definite_integral(*args, hold=True)
1530
else:
1531
return indefinite_integral(*args, hold=True)
1532
1533
def dummy_laplace(*args):
1534
"""
1535
This function is called to create formal wrappers of laplace transforms
1536
that Maxima can't compute:
1537
1538
EXAMPLES::
1539
1540
sage: from sage.calculus.calculus import dummy_laplace
1541
sage: s,t = var('s,t')
1542
sage: f(t) = function('f',t)
1543
sage: dummy_laplace(f(t),t,s)
1544
laplace(f(t), t, s)
1545
"""
1546
return _laplace(args[0], var(repr(args[1])), var(repr(args[2])))
1547
1548
def dummy_inverse_laplace(*args):
1549
"""
1550
This function is called to create formal wrappers of inverse laplace
1551
transforms that Maxima can't compute:
1552
1553
EXAMPLES::
1554
1555
sage: from sage.calculus.calculus import dummy_inverse_laplace
1556
sage: s,t = var('s,t')
1557
sage: F(s) = function('F',s)
1558
sage: dummy_inverse_laplace(F(s),s,t)
1559
ilt(F(s), s, t)
1560
"""
1561
return _inverse_laplace(args[0], var(repr(args[1])), var(repr(args[2])))
1562
1563
#######################################################
1564
#
1565
# Helper functions for printing latex expression
1566
#
1567
#######################################################
1568
1569
def _limit_latex_(self, f, x, a):
1570
r"""
1571
Return latex expression for limit of a symbolic function.
1572
1573
EXAMPLES::
1574
1575
sage: from sage.calculus.calculus import _limit_latex_
1576
sage: var('x,a')
1577
(x, a)
1578
sage: f = function('f',x)
1579
sage: _limit_latex_(0, f, x, a)
1580
'\\lim_{x \\to a}\\, f\\left(x\\right)'
1581
sage: latex(limit(f, x=oo))
1582
\lim_{x \to +\infty}\, f\left(x\right)
1583
1584
"""
1585
return "\\lim_{%s \\to %s}\\, %s"%(latex(x), latex(a), latex(f))
1586
1587
def _laplace_latex_(self, *args):
1588
r"""
1589
Return LaTeX expression for Laplace transform of a symbolic function.
1590
1591
EXAMPLES::
1592
1593
sage: from sage.calculus.calculus import _laplace_latex_
1594
sage: var('s,t')
1595
(s, t)
1596
sage: f = function('f',t)
1597
sage: _laplace_latex_(0,f,t,s)
1598
'\\mathcal{L}\\left(f\\left(t\\right), t, s\\right)'
1599
sage: latex(laplace(f, t, s))
1600
\mathcal{L}\left(f\left(t\right), t, s\right)
1601
1602
"""
1603
return "\\mathcal{L}\\left(%s\\right)"%(', '.join([latex(x) for x in args]))
1604
1605
def _inverse_laplace_latex_(self, *args):
1606
r"""
1607
Return LaTeX expression for inverse Laplace transform
1608
of a symbolic function.
1609
1610
EXAMPLES::
1611
1612
sage: from sage.calculus.calculus import _inverse_laplace_latex_
1613
sage: var('s,t')
1614
(s, t)
1615
sage: F = function('F',s)
1616
sage: _inverse_laplace_latex_(0,F,s,t)
1617
'\\mathcal{L}^{-1}\\left(F\\left(s\\right), s, t\\right)'
1618
sage: latex(inverse_laplace(F,s,t))
1619
\mathcal{L}^{-1}\left(F\left(s\right), s, t\right)
1620
"""
1621
return "\\mathcal{L}^{-1}\\left(%s\\right)"%(', '.join([latex(x) for x in args]))
1622
1623
# Return un-evaluated expression as instances of SFunction class
1624
_limit = function_factory('limit', print_latex_func=_limit_latex_)
1625
_laplace = function_factory('laplace', print_latex_func=_laplace_latex_)
1626
_inverse_laplace = function_factory('ilt',
1627
print_latex_func=_inverse_laplace_latex_)
1628
1629
######################################i################
1630
1631
1632
1633
1634
#######################################################
1635
1636
symtable = {'%pi':'pi', '%e': 'e', '%i':'I', '%gamma':'euler_gamma'}
1637
1638
from sage.misc.multireplace import multiple_replace
1639
import re
1640
1641
maxima_tick = re.compile("'[a-z|A-Z|0-9|_]*")
1642
1643
maxima_qp = re.compile("\?\%[a-z|A-Z|0-9|_]*") # e.g., ?%jacobi_cd
1644
1645
maxima_var = re.compile("\%[a-z|A-Z|0-9|_]*") # e.g., ?%jacobi_cd
1646
1647
sci_not = re.compile("(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]\d+)")
1648
1649
polylog_ex = re.compile('li\[([0-9]+?)\]\(')
1650
1651
maxima_polygamma = re.compile("psi\[(\d*)\]\(") # matches psi[n]( where n is a number
1652
1653
def symbolic_expression_from_maxima_string(x, equals_sub=False, maxima=maxima):
1654
"""
1655
Given a string representation of a Maxima expression, parse it and
1656
return the corresponding Sage symbolic expression.
1657
1658
INPUT:
1659
1660
- ``x`` - a string
1661
1662
- ``equals_sub`` - (default: False) if True, replace
1663
'=' by '==' in self
1664
1665
- ``maxima`` - (default: the calculus package's
1666
Maxima) the Maxima interpreter to use.
1667
1668
EXAMPLES::
1669
1670
sage: from sage.calculus.calculus import symbolic_expression_from_maxima_string as sefms
1671
sage: sefms('x^%e + %e^%pi + %i + sin(0)')
1672
x^e + e^pi + I
1673
sage: f = function('f',x)
1674
sage: sefms('?%at(f(x),x=2)#1')
1675
f(2) != 1
1676
sage: a = sage.calculus.calculus.maxima("x#0"); a
1677
x#0
1678
sage: a.sage()
1679
x != 0
1680
1681
TESTS:
1682
1683
Trac #8459 fixed::
1684
1685
sage: maxima('3*li[2](u)+8*li[33](exp(u))').sage()
1686
3*polylog(2, u) + 8*polylog(33, e^u)
1687
1688
Check if #8345 is fixed::
1689
1690
sage: assume(x,'complex')
1691
sage: t = x.conjugate()
1692
sage: latex(t)
1693
\overline{x}
1694
sage: latex(t._maxima_()._sage_())
1695
\overline{x}
1696
1697
Check that we can understand maxima's not-equals (:trac:`8969`)::
1698
1699
sage: from sage.calculus.calculus import symbolic_expression_from_maxima_string as sefms
1700
sage: sefms("x != 3") == SR(x != 3)
1701
True
1702
sage: sefms("x # 3") == SR(x != 3)
1703
True
1704
sage: solve([x != 5], x)
1705
[[x - 5 != 0]]
1706
sage: solve([2*x==3, x != 5], x)
1707
[[x == (3/2), (-7/2) != 0]]
1708
1709
"""
1710
syms = sage.symbolic.pynac.symbol_table.get('maxima', {}).copy()
1711
1712
if len(x) == 0:
1713
raise RuntimeError, "invalid symbolic expression -- ''"
1714
maxima.set('_tmp_',x)
1715
1716
# This is inefficient since it so rarely is needed:
1717
#r = maxima._eval_line('listofvars(_tmp_);')[1:-1]
1718
1719
s = maxima._eval_line('_tmp_;')
1720
1721
formal_functions = maxima_tick.findall(s)
1722
if len(formal_functions) > 0:
1723
for X in formal_functions:
1724
syms[X[1:]] = function_factory(X[1:])
1725
# You might think there is a potential very subtle bug if 'foo
1726
# is in a string literal -- but string literals should *never*
1727
# ever be part of a symbolic expression.
1728
s = s.replace("'","")
1729
1730
delayed_functions = maxima_qp.findall(s)
1731
if len(delayed_functions) > 0:
1732
for X in delayed_functions:
1733
if X == '?%at': # we will replace Maxima's "at" with symbolic evaluation, not an SFunction
1734
pass
1735
else:
1736
syms[X[2:]] = function_factory(X[2:])
1737
s = s.replace("?%","")
1738
1739
s = polylog_ex.sub('polylog(\\1,',s)
1740
s = multiple_replace(symtable, s)
1741
s = s.replace("%","")
1742
1743
s = s.replace("#","!=") # a lot of this code should be refactored somewhere...
1744
1745
s = maxima_polygamma.sub('psi(\g<1>,',s) # this replaces psi[n](foo) with psi(n,foo), ensuring that derivatives of the digamma function are parsed properly below
1746
1747
if equals_sub:
1748
s = s.replace('=','==')
1749
# unfortunately, this will turn != into !==, which we correct
1750
s = s.replace("!==", "!=")
1751
1752
#replace %union from to_poly_solve with a list
1753
if s[0:5]=='union':
1754
s = s[5:]
1755
s = s[s.find("(")+1:s.rfind(")")]
1756
s = "[" + s + "]" # turn it into a string that looks like a list
1757
1758
#replace %solve from to_poly_solve with the expressions
1759
if s[0:5]=='solve':
1760
s = s[5:]
1761
s = s[s.find("(")+1:s.find("]")+1]
1762
1763
#replace all instances of Maxima's scientific notation
1764
#with regular notation
1765
search = sci_not.search(s)
1766
while not search is None:
1767
(start, end) = search.span()
1768
r = create_RealNumber(s[start:end]).str(no_sci=2, truncate=True)
1769
s = s.replace(s[start:end], r)
1770
search = sci_not.search(s)
1771
1772
# have to do this here, otherwise maxima_tick catches it
1773
syms['limit'] = dummy_limit
1774
syms['diff'] = dummy_diff
1775
syms['integrate'] = dummy_integrate
1776
syms['laplace'] = dummy_laplace
1777
syms['ilt'] = dummy_inverse_laplace
1778
1779
syms['at'] = at
1780
1781
global is_simplified
1782
try:
1783
# use a global flag so all expressions obtained via
1784
# evaluation of maxima code are assumed pre-simplified
1785
is_simplified = True
1786
return symbolic_expression_from_string(s, syms, accept_sequence=True)
1787
except SyntaxError:
1788
raise TypeError, "unable to make sense of Maxima expression '%s' in Sage"%s
1789
finally:
1790
is_simplified = False
1791
1792
1793
# Comma format options for Maxima
1794
def mapped_opts(v):
1795
"""
1796
Used internally when creating a string of options to pass to
1797
Maxima.
1798
1799
INPUT:
1800
1801
- ``v`` - an object
1802
1803
OUTPUT: a string.
1804
1805
The main use of this is to turn Python bools into lower case
1806
strings.
1807
1808
EXAMPLES::
1809
1810
sage: sage.calculus.calculus.mapped_opts(True)
1811
'true'
1812
sage: sage.calculus.calculus.mapped_opts(False)
1813
'false'
1814
sage: sage.calculus.calculus.mapped_opts('bar')
1815
'bar'
1816
"""
1817
if isinstance(v, bool):
1818
return str(v).lower()
1819
return str(v)
1820
1821
def maxima_options(**kwds):
1822
"""
1823
Used internally to create a string of options to pass to Maxima.
1824
1825
EXAMPLES::
1826
1827
sage: sage.calculus.calculus.maxima_options(an_option=True, another=False, foo='bar')
1828
'an_option=true,foo=bar,another=false'
1829
"""
1830
return ','.join(['%s=%s'%(key,mapped_opts(val)) for key, val in kwds.iteritems()])
1831
1832
1833
# Parser for symbolic ring elements
1834
1835
# We keep two dictionaries syms_cur and syms_default to keep the current symbol
1836
# table and the state of the table at startup respectively. These are used by
1837
# the restore() function (see sage.misc.reset).
1838
#
1839
# The dictionary _syms is used as a lookup table for the system function
1840
# registry by _find_func() below. It gets updated by
1841
# symbolic_expression_from_string() before calling the parser.
1842
from sage.symbolic.pynac import symbol_table
1843
_syms = syms_cur = symbol_table.get('functions', {})
1844
syms_default = dict(syms_cur)
1845
1846
# This dictionary is used to pass a lookup table other than the system registry
1847
# to the parser. A global variable is necessary since the parser calls the
1848
# _find_var() and _find_func() functions below without extra arguments.
1849
_augmented_syms = {}
1850
1851
from sage.symbolic.ring import pynac_symbol_registry
1852
1853
def _find_var(name):
1854
"""
1855
Function to pass to Parser for constructing
1856
variables from strings. For internal use.
1857
1858
EXAMPLES::
1859
1860
sage: y = var('y')
1861
sage: sage.calculus.calculus._find_var('y')
1862
y
1863
sage: sage.calculus.calculus._find_var('I')
1864
I
1865
"""
1866
try:
1867
res = _augmented_syms.get(name)
1868
if res is None:
1869
return pynac_symbol_registry[name]
1870
# _augmented_syms might contain entries pointing to functions if
1871
# previous computations polluted the maxima workspace
1872
if not isinstance(res, Function):
1873
return res
1874
except KeyError:
1875
pass
1876
1877
# try to find the name in the global namespace
1878
# needed for identifiers like 'e', etc.
1879
try:
1880
return SR(sage.all.__dict__[name])
1881
except (KeyError, TypeError):
1882
return var(name)
1883
1884
def _find_func(name, create_when_missing = True):
1885
"""
1886
Function to pass to Parser for constructing
1887
functions from strings. For internal use.
1888
1889
EXAMPLES::
1890
1891
sage: sage.calculus.calculus._find_func('limit')
1892
limit
1893
sage: sage.calculus.calculus._find_func('zeta_zeros')
1894
zeta_zeros
1895
sage: f(x)=sin(x)
1896
sage: sage.calculus.calculus._find_func('f')
1897
f
1898
sage: sage.calculus.calculus._find_func('g', create_when_missing=False)
1899
sage: s = sage.calculus.calculus._find_func('sin')
1900
sage: s(0)
1901
0
1902
"""
1903
try:
1904
func = _augmented_syms.get(name)
1905
if func is None:
1906
func = _syms[name]
1907
if not isinstance(func, Expression):
1908
return func
1909
except KeyError:
1910
pass
1911
try:
1912
func = SR(sage.all.__dict__[name])
1913
if not isinstance(func, Expression):
1914
return func
1915
except (KeyError, TypeError):
1916
if create_when_missing:
1917
return function_factory(name)
1918
else:
1919
return None
1920
1921
SR_parser = Parser(make_int = lambda x: SR(Integer(x)),
1922
make_float = lambda x: SR(RealDoubleElement(x)),
1923
make_var = _find_var,
1924
make_function = _find_func)
1925
1926
def symbolic_expression_from_string(s, syms=None, accept_sequence=False):
1927
"""
1928
Given a string, (attempt to) parse it and return the
1929
corresponding Sage symbolic expression. Normally used
1930
to return Maxima output to the user.
1931
1932
INPUT:
1933
1934
- ``s`` - a string
1935
1936
- ``syms`` - (default: None) dictionary of
1937
strings to be regarded as symbols or functions
1938
1939
- ``accept_sequence`` - (default: False) controls whether
1940
to allow a (possibly nested) set of lists and tuples
1941
as input
1942
1943
EXAMPLES::
1944
1945
sage: y = var('y')
1946
sage: sage.calculus.calculus.symbolic_expression_from_string('[sin(0)*x^2,3*spam+e^pi]',syms={'spam':y},accept_sequence=True)
1947
[0, 3*y + e^pi]
1948
"""
1949
global _syms
1950
_syms = sage.symbolic.pynac.symbol_table['functions'].copy()
1951
parse_func = SR_parser.parse_sequence if accept_sequence else SR_parser.parse_expression
1952
if syms is None:
1953
return parse_func(s)
1954
else:
1955
try:
1956
global _augmented_syms
1957
_augmented_syms = syms
1958
return parse_func(s)
1959
finally:
1960
_augmented_syms = {}
1961
1962