Skip to content

Commit d229f45

Browse files
author
Release Manager
committed
gh-35717: `sage.calculus`: Modularization fixes, doctest cosmetics, `# needs` <!-- Please provide a concise, informative and self-explanatory title. --> <!-- Don't put issue numbers in the title. Put it in the Description below. --> <!-- For example, instead of "Fixes #12345", use "Add a new method to multiply two integers" --> ### 📚 Description Not all of `sage.calculus` is for symbolic calculus. We change some import statements to `lazy_import` so that some modules can be loaded even when the symbolic subsystem is not present, or move them into methods. We also add `# needs` tags to doctests to enable doctesting of modularized distributions. <!-- Describe your changes here in detail. --> <!-- Why is this change required? What problem does it solve? --> <!-- If this PR resolves an open issue, please link to it here. For example "Fixes #12345". --> - Part of: #29705 - Cherry-picked from: #35095 <!-- If your change requires a documentation PR, please link it appropriately. --> ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. It should be `[x]` not `[x ]`. --> - [x] The title is concise, informative, and self-explanatory. - [x] The description explains in detail what this PR is about. - [x] I have linked a relevant issue or discussion. - [ ] I have created tests covering the changes. - [ ] I have updated the documentation accordingly. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on - #12345: short description why this is a dependency - #34567: ... --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> URL: #35717 Reported by: Matthias Köppe Reviewer(s): Kwankyu Lee, Matthias Köppe, Michael Orlitzky
2 parents 26f5a09 + e1decf3 commit d229f45

File tree

16 files changed

+445
-364
lines changed

16 files changed

+445
-364
lines changed

src/sage/calculus/calculus.py

Lines changed: 153 additions & 139 deletions
Large diffs are not rendered by default.

src/sage/calculus/desolvers.py

Lines changed: 48 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -874,8 +874,8 @@ def desolve_system(des, vars, ics=None, ivar=None, algorithm="maxima"):
874874
875875
::
876876
877-
sage: P1 = plot([solx,soly], (0,1))
878-
sage: P2 = parametric_plot((solx,soly), (0,1))
877+
sage: P1 = plot([solx,soly], (0,1)) # needs sage.plot
878+
sage: P2 = parametric_plot((solx,soly), (0,1)) # needs sage.plot
879879
880880
Now type ``show(P1)``, ``show(P2)`` to view these plots.
881881
@@ -892,7 +892,8 @@ def desolve_system(des, vars, ics=None, ivar=None, algorithm="maxima"):
892892
sage: desolve_system([de1, de2], [x1, x2], ics=[1,1], ivar=t)
893893
Traceback (most recent call last):
894894
...
895-
ValueError: Initial conditions aren't complete: number of vars is different from number of dependent variables. Got ics = [1, 1], vars = [x1(t), x2(t)]
895+
ValueError: Initial conditions aren't complete: number of vars is different
896+
from number of dependent variables. Got ics = [1, 1], vars = [x1(t), x2(t)]
896897
897898
Check that :trac:`9825` is fixed::
898899
@@ -1013,9 +1014,9 @@ def eulers_method(f, x0, y0, h, x1, algorithm="table"):
10131014
::
10141015
10151016
sage: pts = eulers_method(5*x+y-5,0,1,1/2,1,algorithm="none")
1016-
sage: P1 = list_plot(pts)
1017-
sage: P2 = line(pts)
1018-
sage: (P1+P2).show()
1017+
sage: P1 = list_plot(pts) # needs sage.plot
1018+
sage: P2 = line(pts) # needs sage.plot
1019+
sage: (P1 + P2).show() # needs sage.plot
10191020
10201021
AUTHORS:
10211022
@@ -1163,7 +1164,7 @@ def eulers_method_2x2_plot(f, g, t0, x0, y0, h, t1):
11631164
11641165
sage: from sage.calculus.desolvers import eulers_method_2x2_plot
11651166
sage: f = lambda z : z[2]; g = lambda z : -sin(z[1])
1166-
sage: P = eulers_method_2x2_plot(f,g, 0.0, 0.75, 0.0, 0.1, 1.0)
1167+
sage: P = eulers_method_2x2_plot(f,g, 0.0, 0.75, 0.0, 0.1, 1.0) # needs sage.plot
11671168
"""
11681169
from sage.plot.line import line
11691170

@@ -1430,13 +1431,14 @@ def desolve_system_rk4(des, vars, ics=None, ivar=None, end_points=None, step=0.1
14301431
Lotka Volterra system::
14311432
14321433
sage: from sage.calculus.desolvers import desolve_system_rk4
1433-
sage: x,y,t=var('x y t')
1434-
sage: P=desolve_system_rk4([x*(1-y),-y*(1-x)],[x,y],ics=[0,0.5,2],ivar=t,end_points=20)
1435-
sage: Q=[ [i,j] for i,j,k in P]
1436-
sage: LP=list_plot(Q)
1434+
sage: x,y,t = var('x y t')
1435+
sage: P = desolve_system_rk4([x*(1-y),-y*(1-x)], [x,y], ics=[0,0.5,2],
1436+
....: ivar=t, end_points=20)
1437+
sage: Q = [[i,j] for i,j,k in P]
1438+
sage: LP = list_plot(Q) # needs sage.plot
14371439
1438-
sage: Q=[ [j,k] for i,j,k in P]
1439-
sage: LP=list_plot(Q)
1440+
sage: Q = [[j,k] for i,j,k in P]
1441+
sage: LP = list_plot(Q) # needs sage.plot
14401442
14411443
ALGORITHM:
14421444
@@ -1570,49 +1572,52 @@ def desolve_odeint(des, ics, times, dvars, ivar=None, compute_jac=False, args=()
15701572
Lotka Volterra Equations::
15711573
15721574
sage: from sage.calculus.desolvers import desolve_odeint
1573-
sage: x,y=var('x,y')
1574-
sage: f=[x*(1-y),-y*(1-x)]
1575-
sage: sol=desolve_odeint(f,[0.5,2],srange(0,10,0.1),[x,y])
1576-
sage: p=line(zip(sol[:,0],sol[:,1]))
1577-
sage: p.show()
1575+
sage: x,y = var('x,y')
1576+
sage: f = [x*(1-y), -y*(1-x)]
1577+
sage: sol = desolve_odeint(f, [0.5,2], srange(0,10,0.1), [x,y]) # needs scipy
1578+
sage: p = line(zip(sol[:,0],sol[:,1])) # needs scipy sage.plot
1579+
sage: p.show() # needs scipy sage.plot
15781580
15791581
Lorenz Equations::
15801582
1581-
sage: x,y,z=var('x,y,z')
1583+
sage: x,y,z = var('x,y,z')
15821584
sage: # Next we define the parameters
1583-
sage: sigma=10
1584-
sage: rho=28
1585-
sage: beta=8/3
1585+
sage: sigma = 10
1586+
sage: rho = 28
1587+
sage: beta = 8/3
15861588
sage: # The Lorenz equations
1587-
sage: lorenz=[sigma*(y-x),x*(rho-z)-y,x*y-beta*z]
1589+
sage: lorenz = [sigma*(y-x),x*(rho-z)-y,x*y-beta*z]
15881590
sage: # Time and initial conditions
1589-
sage: times=srange(0,50.05,0.05)
1590-
sage: ics=[0,1,1]
1591-
sage: sol=desolve_odeint(lorenz,ics,times,[x,y,z],rtol=1e-13,atol=1e-14)
1591+
sage: times = srange(0,50.05,0.05)
1592+
sage: ics = [0,1,1]
1593+
sage: sol = desolve_odeint(lorenz, ics, times, [x,y,z], # needs scipy
1594+
....: rtol=1e-13, atol=1e-14)
15921595
15931596
One-dimensional stiff system::
15941597
1595-
sage: y= var('y')
1596-
sage: epsilon=0.01
1597-
sage: f=y^2*(1-y)
1598-
sage: ic=epsilon
1599-
sage: t=srange(0,2/epsilon,1)
1600-
sage: sol=desolve_odeint(f,ic,t,y,rtol=1e-9,atol=1e-10,compute_jac=True)
1601-
sage: p=points(zip(t,sol[:,0]))
1602-
sage: p.show()
1598+
sage: y = var('y')
1599+
sage: epsilon = 0.01
1600+
sage: f = y^2*(1-y)
1601+
sage: ic = epsilon
1602+
sage: t = srange(0,2/epsilon,1)
1603+
sage: sol = desolve_odeint(f, ic, t, y, # needs scipy
1604+
....: rtol=1e-9, atol=1e-10, compute_jac=True)
1605+
sage: p = points(zip(t,sol[:,0])) # needs scipy sage.plot
1606+
sage: p.show() # needs scipy sage.plot
16031607
16041608
Another stiff system with some optional parameters with no
16051609
default value::
16061610
1607-
sage: y1,y2,y3=var('y1,y2,y3')
1608-
sage: f1=77.27*(y2+y1*(1-8.375*1e-6*y1-y2))
1609-
sage: f2=1/77.27*(y3-(1+y1)*y2)
1610-
sage: f3=0.16*(y1-y3)
1611-
sage: f=[f1,f2,f3]
1612-
sage: ci=[0.2,0.4,0.7]
1613-
sage: t=srange(0,10,0.01)
1614-
sage: v=[y1,y2,y3]
1615-
sage: sol=desolve_odeint(f,ci,t,v,rtol=1e-3,atol=1e-4,h0=0.1,hmax=1,hmin=1e-4,mxstep=1000,mxords=17)
1611+
sage: y1,y2,y3 = var('y1,y2,y3')
1612+
sage: f1 = 77.27*(y2+y1*(1-8.375*1e-6*y1-y2))
1613+
sage: f2 = 1/77.27*(y3-(1+y1)*y2)
1614+
sage: f3 = 0.16*(y1-y3)
1615+
sage: f = [f1,f2,f3]
1616+
sage: ci = [0.2,0.4,0.7]
1617+
sage: t = srange(0,10,0.01)
1618+
sage: v = [y1,y2,y3]
1619+
sage: sol = desolve_odeint(f, ci, t, v, rtol=1e-3, atol=1e-4, # needs scipy
1620+
....: h0=0.1, hmax=1, hmin=1e-4, mxstep=1000, mxords=17)
16161621
16171622
AUTHOR:
16181623

src/sage/calculus/functional.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# sage.doctest: needs sage.symbolic
12
"""
23
Functional notation support for common calculus methods
34

src/sage/calculus/functions.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
# sage.doctest: needs sage.symbolic
12
r"""
23
Calculus functions
34
"""
4-
from sage.matrix.constructor import matrix
5+
from sage.misc.lazy_import import lazy_import
56
from sage.structure.element import is_Matrix, is_Vector, Expression
67

8+
lazy_import('sage.matrix.constructor', 'matrix')
9+
710
from .functional import diff
811

912

src/sage/calculus/integration.pyx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# sage.doctest: needs sage.symbolic
12
"""
23
Numerical Integration
34

src/sage/calculus/interpolation.pyx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ cdef class Spline:
5555
5656
This example is in the GSL documentation::
5757
58-
sage: v = [(i + sin(i)/2, i+cos(i^2)) for i in range(10)]
58+
sage: v = [(i + RDF(i).sin()/2, i + RDF(i^2).cos()) for i in range(10)]
5959
sage: s = spline(v)
60-
sage: show(point(v) + plot(s,0,9, hue=.8))
60+
sage: show(point(v) + plot(s,0,9, hue=.8)) # needs sage.plot
6161
6262
We compute the area underneath the spline::
6363
@@ -77,13 +77,13 @@ cdef class Spline:
7777
We compute the first and second-order derivatives at a few points::
7878
7979
sage: s.derivative(5)
80-
-0.16230085261803...
80+
-0.1623008526180...
8181
sage: s.derivative(6)
82-
0.20997986285714...
82+
0.2099798628571...
8383
sage: s.derivative(5, order=2)
84-
-3.08747074561380...
84+
-3.0874707456138...
8585
sage: s.derivative(6, order=2)
86-
2.61876848274853...
86+
2.6187684827485...
8787
8888
Only the first two derivatives are supported::
8989
@@ -118,7 +118,7 @@ cdef class Spline:
118118
119119
Replace `0`-th point, which changes the spline::
120120
121-
sage: S[0]=(0,1); S
121+
sage: S[0] = (0,1); S
122122
[(0, 1), (2, 3), (4, 5)]
123123
sage: S(1.5)
124124
2.5

src/sage/calculus/interpolators.pyx

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# sage.doctest: needs numpy
12
"""
23
Complex Interpolation
34
@@ -49,9 +50,10 @@ def polygon_spline(pts):
4950
sage: ps = polygon_spline(pts)
5051
sage: fx = lambda x: ps.value(x).real
5152
sage: fy = lambda x: ps.value(x).imag
52-
sage: show(parametric_plot((fx, fy), (0, 2*pi)))
53-
sage: m = Riemann_Map([lambda x: ps.value(real(x))], [lambda x: ps.derivative(real(x))],0)
54-
sage: show(m.plot_colored() + m.plot_spiderweb())
53+
sage: show(parametric_plot((fx, fy), (0, 2*pi))) # needs sage.plot
54+
sage: m = Riemann_Map([lambda x: ps.value(real(x))],
55+
....: [lambda x: ps.derivative(real(x))], 0)
56+
sage: show(m.plot_colored() + m.plot_spiderweb()) # needs sage.plot
5557
5658
Polygon approximation of an circle::
5759
@@ -119,7 +121,7 @@ cdef class PSpline:
119121
sage: ps = polygon_spline(pts)
120122
sage: ps.value(.5)
121123
(-0.363380227632...-1j)
122-
sage: ps.value(0) - ps.value(2*pi)
124+
sage: ps.value(0) - ps.value(2*RDF.pi())
123125
0j
124126
sage: ps.value(10)
125127
(0.26760455264...+1j)
@@ -152,6 +154,7 @@ cdef class PSpline:
152154
sage: ps = polygon_spline(pts)
153155
sage: ps.derivative(1 / 3)
154156
(1.27323954473...+0j)
157+
sage: from math import pi
155158
sage: ps.derivative(0) - ps.derivative(2*pi)
156159
0j
157160
sage: ps.derivative(10)
@@ -171,7 +174,7 @@ def complex_cubic_spline(pts):
171174
172175
INPUT:
173176
174-
- ``pts`` A list or array of complex numbers, or tuples of the form
177+
- ``pts`` -- A list or array of complex numbers, or tuples of the form
175178
`(x,y)`.
176179
177180
EXAMPLES:
@@ -182,13 +185,16 @@ def complex_cubic_spline(pts):
182185
sage: cs = complex_cubic_spline(pts)
183186
sage: fx = lambda x: cs.value(x).real
184187
sage: fy = lambda x: cs.value(x).imag
185-
sage: show(parametric_plot((fx, fy), (0, 2*pi)))
186-
sage: m = Riemann_Map([lambda x: cs.value(real(x))], [lambda x: cs.derivative(real(x))], 0)
187-
sage: show(m.plot_colored() + m.plot_spiderweb())
188+
sage: from math import pi
189+
sage: show(parametric_plot((fx, fy), (0, 2*pi))) # needs sage.plot
190+
sage: m = Riemann_Map([lambda x: cs.value(real(x))],
191+
....: [lambda x: cs.derivative(real(x))], 0)
192+
sage: show(m.plot_colored() + m.plot_spiderweb()) # needs sage.plot
188193
189194
Polygon approximation of a circle::
190195
191-
sage: pts = [e^(I*t / 25) for t in range(25)]
196+
sage: from cmath import exp
197+
sage: pts = [exp(1j * t / 25) for t in range(25)]
192198
sage: cs = complex_cubic_spline(pts)
193199
sage: cs.derivative(2)
194200
(-0.0497765406583...+0.151095006434...j)
@@ -273,6 +279,7 @@ cdef class CCSpline:
273279
sage: cs = complex_cubic_spline(pts)
274280
sage: cs.value(4 / 7)
275281
(-0.303961332787...-1.34716728183...j)
282+
sage: from math import pi
276283
sage: cs.value(0) - cs.value(2*pi)
277284
0j
278285
sage: cs.value(-2.73452)
@@ -304,6 +311,7 @@ cdef class CCSpline:
304311
sage: cs = complex_cubic_spline(pts)
305312
sage: cs.derivative(3 / 5)
306313
(1.40578892327...-0.225417136326...j)
314+
sage: from math import pi
307315
sage: cs.derivative(0) - cs.derivative(2 * pi)
308316
0j
309317
sage: cs.derivative(-6)

0 commit comments

Comments
 (0)