Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

fix for issue #997 #998

Closed
wants to merge 4 commits into from

5 participants

AmitAronovitch Ian Thomas Benjamin Root Phil Elson Damon McDougall
AmitAronovitch

see discussion in #997

Ian Thomas
Collaborator

I can confirm that this PR solves the issue, and I don't think there are any detrimental side-effects.

The PR should ideally include a unit test; something based on the one in the issue request would be fine. Amit, if you need some help putting the test within the mpl unit test framework, let me know (I recently had to do the same for other delaunay changes).

Benjamin Root
Collaborator

+1 on the unit test. Also, could you provide some possible insight of when/where the results may differ from before? We might want to make some tests to examine those cases as well to evaluate the differences.

AmitAronovitch
Phil Elson
Collaborator

@AmitAronovitch : Did you have any progress on this? It is not going to make 1.2.0, but it can still be merged onto master at any point.

Thanks,

AmitAronovitch

My own tests (direct calls to the function) seem to return identical results, but it seems that the existing Delaunay tests (image diffs) fail. I did not find the time to look into that yet (I want to extract the input and output used in these tests, before conversion to colormap, and check them directly).

p.s. Should the changeset be rebased/merged to the 1.2.0 branch, or to master?

Phil Elson
Collaborator

Thanks for the update.

Should the changeset be rebased/merged to the 1.2.0 branch, or to master?

You don't need to do either at the moment as your branch would currently merge cleanly into master, but if you do need to update it you should rebase (rather than merge) against master. HTH

Amit Aronovitch test_delaunay: expanded bounding box, to avoid numerical instability
due to points that lie exactly on the boundary.
c43a02e
AmitAronovitch

The fix added in c43a02e allows the delaunay tests to pass cleanly with the proposed cpp patch.
This was an edge case caused by numerical difference of size 6.7e-16.
A better solution would be to fix Triangulation.prep_extrapolator itself, to make it more robust (see below), instead of fixing the test. However, I thought it might be better to keep that fix separate from #997.

The linear_extrapolator inserts nan for points that fall outside of its valid domain. Points that fall exactly on the corners of the specified bounding box may lie on the boundary of that domain, hence they might be considered "outside" in case of tiny rounding errors. The fix avoids this situation by specifying a bounding box that strictly contains all points of the grid. A better fix would be to make the domain of the linear extrapolator strictly contain the bounding box (it currently intersects it at two points).

AmitAronovitch

For adding a test for this specific issue, should I:

a) insert it in test_delaunay.py (reason: localize all delaunay-related tests)

or

b) create a new file, e.g. test_delaunay_1d_grid.py (reason: it is quite different than the existing tests, and does not fit in their framework).

Phil Elson
Collaborator

Personally, I would prefer it to be in test_delunay.py. I haven't looked at that test module, but the name suggests to me that it should be a test of everything related to delunay triangulation - so feel free to pop it in there, and if someone would prefer it elsewhere we can adjust later on.

Thanks,

Damon McDougall
Collaborator

@pelson Agreed, it should go in test_delaunay.py.

AmitAronovitch

Added the test, and also published an alternate fix: PR #1477.
I still prefer this one, because it avoids special-casing (and possibly there might be a tiny performance difference), but #1477 does not touch the loop code, so does not require further testing (see 3 below).
Both fixes currently work and pass tests.

I did not declare freetype versions in my test, as the other delaunay tests do. I only tested with 2.4.10, and I am not familiar with the possible font issues. Please advise if this might break something.

Remaining TODO:
1. Possibly handle freetype-version testing issues.
2. fix the problem discovered above in linear extrapolator code (this would make c43a02e redundant, but I think this fix might also avoid future problems).
3. test performance and accuracy differences in extreme cases (very large grid).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 5, 2012
  1. AmitAronovitch
Commits on Nov 2, 2012
  1. test_delaunay: expanded bounding box, to avoid numerical instability

    Amit Aronovitch authored
    due to points that lie exactly on the boundary.
Commits on Nov 10, 2012
  1. Merge branch 'iss997_test' (test for issue #997)

    Amit Aronovitch authored
This page is out of date. Refresh to see the latest.
6 lib/matplotlib/delaunay/_delaunay.cpp
View
@@ -293,17 +293,19 @@ static PyObject *linear_interpolate_grid(double x0, double x1, int xsteps,
dy = (y1 - y0) / (ysteps-1);
rowtri = 0;
+ targety = y0;
for (iy=0; iy<ysteps; iy++) {
- targety = y0 + dy*iy;
rowtri = walking_triangles(rowtri, x0, targety, x, y, nodes, neighbors);
tri = rowtri;
+ targetx = x0;
for (ix=0; ix<xsteps; ix++) {
- targetx = x0 + dx*ix;
INDEXN(z_ptr, xsteps, iy, ix) = linear_interpolate_single(
targetx, targety,
x, y, nodes, neighbors, planes, defvalue, tri, &coltri);
if (coltri != -1) tri = coltri;
+ targetx+=dx;
}
+ targety+=dy;
}
return z;
BIN  lib/matplotlib/tests/baseline_images/test_delaunay/delaunay-1d-interp.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 lib/matplotlib/tests/test_delaunay.py
View
@@ -93,6 +93,10 @@ def cosine_peak(x, y):
allfuncs = [exponential, cliff, saddle, gentle, steep, sphere, trig, gauss, cloverleaf, cosine_peak]
+def _expand_range(range,epsilon=1e-6):
+ delta = (range[1]-range[0])*epsilon/2.0
+ return (range[0]-delta, range[1]+delta)
+
class LinearTester(object):
name = 'Linear'
def __init__(self, xrange=(0.0, 1.0), yrange=(0.0, 1.0), nrange=101, npoints=250):
@@ -100,6 +104,7 @@ def __init__(self, xrange=(0.0, 1.0), yrange=(0.0, 1.0), nrange=101, npoints=250
self.yrange = yrange
self.nrange = nrange
self.npoints = npoints
+ self.bbox = _expand_range(xrange) + _expand_range(yrange)
rng = np.random.RandomState(1234567890)
self.x = rng.uniform(xrange[0], xrange[1], size=npoints)
@@ -113,7 +118,7 @@ def replace_data(self, dataset):
def interpolator(self, func):
z = func(self.x, self.y)
- return self.tri.linear_extrapolator(z, bbox=self.xrange+self.yrange)
+ return self.tri.linear_extrapolator(z, bbox=self.bbox)
def plot(self, func, interp=True, plotter='imshow'):
if interp:
@@ -157,9 +162,9 @@ class NNTester(LinearTester):
name = 'Natural Neighbors'
def interpolator(self, func):
z = func(self.x, self.y)
- return self.tri.nn_extrapolator(z, bbox=self.xrange+self.yrange)
+ return self.tri.nn_extrapolator(z, bbox=self.bbox)
-def make_all_testfuncs(allfuncs=allfuncs):
+def make_all_2d_testfuncs(allfuncs=allfuncs):
def make_test(func):
filenames = [
'%s-%s' % (func.func_name, x) for x in
@@ -186,4 +191,27 @@ def reference_test():
for func in allfuncs:
globals()['test_%s' % func.func_name] = make_test(func)
-make_all_testfuncs()
+make_all_2d_testfuncs()
+
+# 1d and 0d grid tests
+
+ref_interpolator = Triangulation([0,10,10,0],
+ [0,0,10,10]).linear_interpolator([1,10,5,2.0])
+
+def equal_arrays(a1,a2, tolerance=1e-10):
+ return np.all(np.absolute(a1 - a2) < tolerance)
+
+def test_1d_grid():
+ res = ref_interpolator[3:6:2j,1:1:1j]
+ assert equal_arrays(res, [[1.6],[1.9]])
+
+def test_0d_grid():
+ res = ref_interpolator[3:3:1j,1:1:1j]
+ assert equal_arrays(res, [[1.6]])
+
+@image_comparison(baseline_images=['delaunay-1d-interp'], extensions=['png'])
+def test_1d_plots():
+ x_range = slice(0.25,9.75,20j)
+ x = np.mgrid[x_range]
+ for y in xrange(2,10,2):
+ plt.plot(x, ref_interpolator[x_range,y:y:1j])
Something went wrong with that request. Please try again.