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

Skip to content

Commit abed45a

Browse files
committed
added halldors and norberts inter funcs
svn path=/trunk/matplotlib/; revision=2244
1 parent fd96ef0 commit abed45a

5 files changed

Lines changed: 148 additions & 3 deletions

File tree

CHANGELOG

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
2006-03-31 Ported Norbert's rewriting of Halldor's stineman_interp
2+
algorithm to make it numerix compatible and added code to
3+
matplotlib.mlab. See examples/interp_demo.py - JDH
4+
15
2006-03-30 Fixed a bug in aspect ratio handling; blocked potential
26
crashes when panning with button 3; added axis('image')
37
support. - EF

examples/interp_demo.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from pylab import figure, show, nx, linspace, stineman_interp
2+
x = linspace(0,2*nx.pi,20);
3+
y = nx.sin(x); yp = None
4+
xi = linspace(x[0],x[-1],100);
5+
yi = stineman_interp(xi,x,y,yp);
6+
fig = figure()
7+
ax = fig.add_subplot(111)
8+
ax.plot(x,y,'ro',xi,yi,'-b.')
9+
show()
10+

lib/matplotlib/mlab.py

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,6 +1485,139 @@ def load(fname,comments='%',delimiter=None, converters=None,skiprows=0,
14851485
if unpack: return transpose(X)
14861486
else: return X
14871487

1488+
def slopes(x,y):
1489+
"""
1490+
SLOPES calculate the slope y'(x) Given data vectors X and Y SLOPES
1491+
calculates Y'(X), i.e the slope of a curve Y(X). The slope is
1492+
estimated using the slope obtained from that of a parabola through
1493+
any three consecutive points.
1494+
1495+
This method should be superior to that described in the appendix
1496+
of A CONSISTENTLY WELL BEHAVED METHOD OF INTERPOLATION by Russel
1497+
W. Stineman (Creative Computing July 1980) in at least one aspect:
1498+
1499+
Circles for interpolation demand a known aspect ratio between x-
1500+
and y-values. For many functions, however, the abscissa are given
1501+
in different dimensions, so an aspect ratio is completely
1502+
arbitrary.
1503+
1504+
The parabola method gives very similar results to the circle
1505+
method for most regular cases but behaves much better in special
1506+
cases
1507+
1508+
Norbert Nemec, Institute of Theoretical Physics, University or
1509+
Regensburg, April 2006 Norbert.Nemec at physik.uni-regensburg.de
1510+
1511+
(inspired by a original implementation by Halldor Bjornsson,
1512+
Icelandic Meteorological Office, March 2006 halldor at vedur.is)
1513+
"""
1514+
# Cast key variables as float.
1515+
x=nx.asarray(x, nx.Float)
1516+
y=nx.asarray(y, nx.Float)
1517+
1518+
yp=nx.zeros(y.shape, nx.Float)
1519+
1520+
dx=x[1:] - x[:-1]
1521+
dy=y[1:] - y[:-1]
1522+
dydx = dy/dx
1523+
yp[1:-1] = (dydx[:-1] * dx[1:] + dydx[1:] * dx[:-1])/(dx[1:] + dx[:-1])
1524+
yp[0] = 2.0 * dy[0]/dx[0] - yp[1]
1525+
yp[-1] = 2.0 * dy[-1]/dx[-1] - yp[-2]
1526+
return yp
1527+
1528+
1529+
def stineman_interp(xi,x,y,yp=None):
1530+
"""
1531+
STINEMAN_INTERP Well behaved data interpolation. Given data
1532+
vectors X and Y, the slope vector YP and a new abscissa vector XI
1533+
the function stineman_interp(X,Y,YP,XI) uses Stineman
1534+
interpolation to calculate a vector YI corresponding to XI.
1535+
1536+
Here's an example that generates a coarse sine curve, then
1537+
interpolates over a finer abscissa:
1538+
1539+
x = linspace(0,2*pi,20); y = sin(x); yp = cos(x)
1540+
xi = linspace(0,2*pi,40);
1541+
yi = stineman_interp(x,y,yp,xi);
1542+
plot(x,y,'o',xi,yi)
1543+
1544+
The interpolation method is described in the article A
1545+
CONSISTENTLY WELL BEHAVED METHOD OF INTERPOLATION by Russell
1546+
W. Stineman. The article appeared in the July 1980 issue of
1547+
Creative computing with a note from the editor stating that while
1548+
they were
1549+
1550+
not an academic journal but once in a while something serious
1551+
and original comes in adding that this was
1552+
"apparently a real solution" to a well known problem.
1553+
1554+
For yp=None, the routine automatically determines the slopes using
1555+
the "slopes" routine.
1556+
1557+
X is assumed to be sorted in increasing order
1558+
1559+
For values xi[j] < x[0] or xi[j] > x[-1], the routine tries a
1560+
extrapolation. The relevance of the data obtained from this, of
1561+
course, questionable...
1562+
1563+
original implementation by Halldor Bjornsson, Icelandic
1564+
Meteorolocial Office, March 2006 halldor at vedur.is
1565+
1566+
completely reworked and optimized for Python by Norbert Nemec,
1567+
Institute of Theoretical Physics, University or Regensburg, April
1568+
2006 Norbert.Nemec at physik.uni-regensburg.de
1569+
1570+
"""
1571+
1572+
# Cast key variables as float.
1573+
x=nx.asarray(x, nx.Float)
1574+
y=nx.asarray(y, nx.Float)
1575+
assert x.shape == y.shape
1576+
N=len(y)
1577+
1578+
if yp is None:
1579+
yp = slopes(x,y)
1580+
else:
1581+
yp=nx.asarray(yp, nx.Float)
1582+
1583+
xi=nx.asarray(xi, nx.Float)
1584+
yi=nx.zeros(xi.shape, nx.Float)
1585+
1586+
# calculate linear slopes
1587+
dx = x[1:] - x[:-1]
1588+
dy = y[1:] - y[:-1]
1589+
s = dy/dx #note length of s is N-1 so last element is #N-2
1590+
1591+
# find the segment each xi is in
1592+
# this line actually is the key to the efficiency of this implementation
1593+
idx = nx.searchsorted(x[1:-1], xi)
1594+
1595+
# now we have generally: x[idx[j]] <= xi[j] <= x[idx[j]+1]
1596+
# except at the boundaries, where it may be that xi[j] < x[0] or xi[j] > x[-1]
1597+
1598+
# the y-values that would come out from a linear interpolation:
1599+
sidx = nx.take(s, idx)
1600+
xidx = nx.take(x, idx)
1601+
yidx = nx.take(y, idx)
1602+
xidxp1 = nx.take(x, idx+1)
1603+
yo = yidx + sidx * (xi - xidx)
1604+
1605+
# the difference that comes when using the slopes given in yp
1606+
dy1 = (nx.take(yp, idx)- sidx) * (xi - xidx) # using the yp slope of the left point
1607+
dy2 = (nx.take(yp, idx+1)-sidx) * (xi - xidxp1) # using the yp slope of the right point
1608+
1609+
dy1dy2 = dy1*dy2
1610+
# The following is optimized for Python. The solution actually
1611+
# does more calculations than necessary but exploiting the power
1612+
# of numpy, this is far more efficient than coding a loop by hand
1613+
# in Python
1614+
yi = yo + dy1dy2 * nx.choose(nx.array(nx.sign(dy1dy2), nx.Int32)+1,
1615+
((2*xi-xidx-xidxp1)/((dy1-dy2)*(xidxp1-xidx)),
1616+
0.0,
1617+
1/(dy1+dy2),))
1618+
1619+
return yi
1620+
14881621
### the following code was written and submitted by Fernando Perez
14891622
### from the ipython numutils package under a BSD license
14901623
"""

lib/matplotlib/numerix/linear_algebra/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
from LinearAlgebra import *
77
elif which[0] == "numpy":
88
from numpy.linalg import *
9-
inverse = inv
10-
eigenvectors = eig
119
try:
1210
from numpy.linalg.old import *
1311
except:

lib/matplotlib/pylab.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@
294294
sqrtm, prctile, center_matrix, meshgrid, rk4, exp_safe, amap,\
295295
sum_flat, mean_flat, rms_flat, l1norm, l2norm, norm, frange,\
296296
diagonal_matrix, base_repr, binary_repr, log2, ispower2,\
297-
bivariate_normal, load, save
297+
bivariate_normal, load, save, stineman_interp
298298

299299

300300
"""

0 commit comments

Comments
 (0)