Repository: scipy/scipy

Issue:
InterpolatedUnivariateSpline: check_finite fails when w is unspecified
The following code raises a TypeError. This seems to be an issue with InterplatedUnivariateSpline only, UnivariateSpline does not have the same issue. It seems to be arising from an isfinite check on w when it is None. I will try to submit a PR soon, to emulating UnivariateSpline behaviour.

```
from scipy.interpolate import InterpolatedUnivariateSpline

x = np.arange(5) * 1.
y = np.random.randn(5)
InterpolatedUnivariateSpline(x, y, k=1, check_finite=True)

.../scipy/interpolate/fitpack2.py in __init__(self, x, y, w, bbox, k, ext, check_finite)
    588         if check_finite:
    589             if (not np.isfinite(x).all() or not np.isfinite(y).all() or
--> 590                     not np.isfinite(w).all()):
    591                 raise ValueError("Input must not contain NaNs or infs.")
    592 

TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

```



Discussion:
The behaviour of InterplatedUnivariateSpline and UnivariateSpline is currently inconsistent, and I don't think either is what is expected. UnivariateSpline does not check w at all, while InterplatedUnivariateSpline and  LSQUnivariateSpline do. I suggest that we change all 3 to check that w is finite in the same way (LSQ has an addition required input t, but the point remains).

```
w_finite = np.isfinite(w).all() if w is not None else True
if (not np.isfinite(x).all() or not np.isfinite(y).all() or not w_finite):
```

I am also working on changing the test cases to reflect this new behaviour.


Resolving patch:
diff --git a/scipy/interpolate/fitpack2.py b/scipy/interpolate/fitpack2.py
--- a/scipy/interpolate/fitpack2.py
+++ b/scipy/interpolate/fitpack2.py
@@ -168,7 +168,9 @@ def __init__(self, x, y, w=None, bbox=[None]*2, k=3, s=None,
                  ext=0, check_finite=False):
 
         if check_finite:
-            if not np.isfinite(x).all() or not np.isfinite(y).all():
+            w_finite = np.isfinite(w).all() if w is not None else True
+            if (not np.isfinite(x).all() or not np.isfinite(y).all() or
+                    not w_finite):
                 raise ValueError("x and y array must not contain NaNs or infs.")
 
         # _data == x,y,w,xb,xe,k,s,n,t,c,fp,fpint,nrdata,ier
@@ -586,8 +588,9 @@ def __init__(self, x, y, w=None, bbox=[None]*2, k=3,
                  ext=0, check_finite=False):
 
         if check_finite:
+            w_finite = np.isfinite(w).all() if w is not None else True
             if (not np.isfinite(x).all() or not np.isfinite(y).all() or
-                    not np.isfinite(w).all()):
+                    not w_finite):
                 raise ValueError("Input must not contain NaNs or infs.")
 
         # _data == x,y,w,xb,xe,k,s,n,t,c,fp,fpint,nrdata,ier
@@ -722,8 +725,9 @@ def __init__(self, x, y, t, w=None, bbox=[None]*2, k=3,
                  ext=0, check_finite=False):
 
         if check_finite:
+            w_finite = np.isfinite(w).all() if w is not None else True
             if (not np.isfinite(x).all() or not np.isfinite(y).all() or
-                    not np.isfinite(w).all() or not np.isfinite(t).all()):
+                    not w_finite or not np.isfinite(t).all()):
                 raise ValueError("Input(s) must not contain NaNs or infs.")
 
         # _data == x,y,w,xb,xe,k,s,n,t,c,fp,fpint,nrdata,ier


Test patch:
diff --git a/scipy/interpolate/tests/test_fitpack2.py b/scipy/interpolate/tests/test_fitpack2.py
--- a/scipy/interpolate/tests/test_fitpack2.py
+++ b/scipy/interpolate/tests/test_fitpack2.py
@@ -146,10 +146,27 @@ def test_nan(self):
         # bail out early if the input data contains nans
         x = np.arange(10, dtype=float)
         y = x**3
+        w = np.ones_like(x)
+        # also test LSQUnivariateSpline [which needs explicit knots]
+        spl = UnivariateSpline(x, y, check_finite=True)
+        t = spl.get_knots()[3:4]  # interior knots w/ default k=3
+        y_end = y[-1]
         for z in [np.nan, np.inf, -np.inf]:
             y[-1] = z
             assert_raises(ValueError, UnivariateSpline,
                     **dict(x=x, y=y, check_finite=True))
+            assert_raises(ValueError, InterpolatedUnivariateSpline,
+                    **dict(x=x, y=y, check_finite=True))
+            assert_raises(ValueError, LSQUnivariateSpline,
+                    **dict(x=x, y=y, t=t, check_finite=True))
+            y[-1] = y_end  # check valid y but invalid w
+            w[-1] = z
+            assert_raises(ValueError, UnivariateSpline,
+                    **dict(x=x, y=y, w=w, check_finite=True))
+            assert_raises(ValueError, InterpolatedUnivariateSpline,
+                    **dict(x=x, y=y, w=w, check_finite=True))
+            assert_raises(ValueError, LSQUnivariateSpline,
+                    **dict(x=x, y=y, t=t, w=w, check_finite=True))
 
 
 class TestLSQBivariateSpline(TestCase):