Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e6e977a

Browse files
committed
Remove OutOfBounds exception and factor out Euler step
1 parent 28a9e27 commit e6e977a

1 file changed

Lines changed: 57 additions & 59 deletions

File tree

lib/matplotlib/streamplot.py

Lines changed: 57 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -299,9 +299,6 @@ def _update_trajectory(self, xm, ym):
299299
class InvalidIndexError(Exception):
300300
pass
301301

302-
class OutOfBounds(Exception):
303-
pass
304-
305302

306303
# Integrator definitions
307304
#========================
@@ -401,66 +398,67 @@ def _rk12(x0, y0, dmap, f):
401398
xf_traj = []
402399
yf_traj = []
403400

404-
try:
405-
while dmap.grid.valid_index(xi, yi):
406-
xf_traj.append(xi)
407-
yf_traj.append(yi)
408-
try:
409-
k1x, k1y = f(xi, yi)
410-
k2x, k2y = f(xi + ds * k1x,
411-
yi + ds * k1y)
412-
except IndexError:
413-
# Out of the domain on one of the intermediate steps
414-
raise OutOfBounds
415-
416-
dx1 = ds * k1x
417-
dy1 = ds * k1y
418-
dx2 = ds * 0.5 * (k1x + k2x)
419-
dy2 = ds * 0.5 * (k1y + k2y)
420-
421-
nx, ny = dmap.grid.shape
422-
# Error is normalized to the axes coordinates
423-
error = np.sqrt(((dx2-dx1)/nx)**2 + ((dy2-dy1)/ny)**2)
424-
425-
# Only save step if within error tolerance
426-
if error < maxerror:
427-
xi += dx2
428-
yi += dy2
429-
try:
430-
dmap.update_trajectory(xi, yi)
431-
except InvalidIndexError:
432-
break
433-
if (stotal + ds) > 2:
434-
break
435-
stotal += ds
436-
437-
# recalculate stepsize based on step error
438-
ds = min(maxds, 0.85 * ds * (maxerror/error)**0.2)
439-
440-
except OutOfBounds:
441-
## This is raised when the edge of the domain is
442-
## reached. Here, a simple Euler integration is used up to the
443-
## boundary of the domain, improving the neatness of the
444-
## figure.
401+
while dmap.grid.valid_index(xi, yi):
402+
xf_traj.append(xi)
403+
yf_traj.append(yi)
404+
try:
405+
k1x, k1y = f(xi, yi)
406+
k2x, k2y = f(xi + ds * k1x,
407+
yi + ds * k1y)
408+
except IndexError:
409+
# Out of the domain on one of the intermediate integration steps.
410+
# Take an Euler step to the boundary to improve neatness.
411+
ds, xf_traj, yf_traj = _euler_step(xf_traj, yf_traj, dmap, f)
412+
stotal += ds
413+
break
414+
415+
dx1 = ds * k1x
416+
dy1 = ds * k1y
417+
dx2 = ds * 0.5 * (k1x + k2x)
418+
dy2 = ds * 0.5 * (k1y + k2y)
419+
445420
nx, ny = dmap.grid.shape
446-
xi = xf_traj[-1] # in data coordinates
447-
yi = yf_traj[-1]
448-
cx, cy = f(xi, yi) # ds.cx is in data coordinates, ds in axis coord.
449-
if cx > 0:
450-
dsx = (nx - 1 - xi) / cx
451-
else:
452-
dsx = xi / -cx
453-
if cy > 0:
454-
dsy = (ny - 1 - yi) / cy
455-
else:
456-
dsy = yi / -cy
457-
ds = min(dsx, dsy)
458-
xf_traj.append(xi+cx*ds)
459-
yf_traj.append(yi+cy*ds)
460-
stotal += ds
421+
# Error is normalized to the axes coordinates
422+
error = np.sqrt(((dx2-dx1)/nx)**2 + ((dy2-dy1)/ny)**2)
423+
424+
# Only save step if within error tolerance
425+
if error < maxerror:
426+
xi += dx2
427+
yi += dy2
428+
try:
429+
dmap.update_trajectory(xi, yi)
430+
except InvalidIndexError:
431+
break
432+
if (stotal + ds) > 2:
433+
break
434+
stotal += ds
435+
436+
# recalculate stepsize based on step error
437+
ds = min(maxds, 0.85 * ds * (maxerror/error)**0.2)
461438

462439
return stotal, xf_traj, yf_traj
463440

441+
442+
def _euler_step(xf_traj, yf_traj, dmap, f):
443+
"""Simple Euler integration step."""
444+
nx, ny = dmap.grid.shape
445+
xi = xf_traj[-1]
446+
yi = yf_traj[-1]
447+
cx, cy = f(xi, yi) # ds.cx is in data coordinates, ds in axis coord.
448+
if cx > 0:
449+
dsx = (nx - 1 - xi) / cx
450+
else:
451+
dsx = xi / -cx
452+
if cy > 0:
453+
dsy = (ny - 1 - yi) / cy
454+
else:
455+
dsy = yi / -cy
456+
ds = min(dsx, dsy)
457+
xf_traj.append(xi + cx*ds)
458+
yf_traj.append(yi + cy*ds)
459+
return ds, xf_traj, yf_traj
460+
461+
464462
def _rk4(x0, y0, dmap, f):
465463
"""4th-order Runge-Kutta algorithm with fixed step size"""
466464
ds = min(1./dmap.mask.nx, 1./dmap.mask.ny, 0.01)

0 commit comments

Comments
 (0)