def test_invalid_input_for_lsq_univariate_spline(self): x_values = [1, 2, 4, 6, 8.5] y_values = [0.5, 0.8, 1.3, 2.5, 2.8] spl = UnivariateSpline(x_values, y_values, check_finite=True) t_values = spl.get_knots()[3:4] # interior knots w/ default k=3 with assert_raises(ValueError) as info: x_values = [1, 2, 4, 6, 8.5] y_values = [0.5, 0.8, 1.3, 2.5] LSQUnivariateSpline(x_values, y_values, t_values) assert "x and y should have a same length" in str(info.value) with assert_raises(ValueError) as info: x_values = [1, 2, 4, 6, 8.5] y_values = [0.5, 0.8, 1.3, 2.5, 2.8] w_values = [1.0, 1.0, 1.0, 1.0] LSQUnivariateSpline(x_values, y_values, t_values, w=w_values) assert "x, y, and w should have a same length" in str(info.value) with assert_raises(ValueError) as info: bbox = (100, -100) LSQUnivariateSpline(x_values, y_values, t_values, bbox=bbox) assert "Interior knots t must satisfy Schoenberg-Whitney conditions" in str(info.value) with assert_raises(ValueError) as info: bbox = (-1) LSQUnivariateSpline(x_values, y_values, t_values, bbox=bbox) assert "bbox shape should be (2,)" in str(info.value) with assert_raises(ValueError) as info: LSQUnivariateSpline(x_values, y_values, t_values, k=6) assert "k should be 1 <= k <= 5" in str(info.value)
def test_out_of_range_regression(self): # Test different extrapolation modes. See ticket 3557 x = np.arange(5, dtype=np.float) y = x**3 xp = linspace(-8, 13, 100) xp_zeros = xp.copy() xp_zeros[np.logical_or(xp_zeros < 0., xp_zeros > 4.)] = 0 for cls in [UnivariateSpline, InterpolatedUnivariateSpline]: spl = cls(x=x, y=y) for ext in [0, 'extrapolate']: assert_allclose(spl(xp, ext=ext), xp**3, atol=1e-16) assert_allclose(cls(x, y, ext=ext)(xp), xp**3, atol=1e-16) for ext in [1, 'zeros']: assert_allclose(spl(xp, ext=ext), xp_zeros**3, atol=1e-16) assert_allclose(cls(x, y, ext=ext)(xp), xp_zeros**3, atol=1e-16) for ext in [2, 'raise']: assert_raises(ValueError, spl, xp, **dict(ext=ext)) # also test LSQUnivariateSpline [which needs explicit knots] t = spl.get_knots()[3:4] # interior knots w/ default k=3 spl = LSQUnivariateSpline(x, y, t) assert_allclose(spl(xp, ext=0), xp**3, atol=1e-16) assert_allclose(spl(xp, ext=1), xp_zeros**3, atol=1e-16) assert_raises(ValueError, spl, xp, **dict(ext=2)) # also make sure that unknown values for `ext` are caught early for ext in [-1, 'unknown']: spl = UnivariateSpline(x, y) assert_raises(ValueError, spl, xp, **dict(ext=ext)) assert_raises(ValueError, UnivariateSpline, **dict(x=x, y=y, ext=ext))
def test_strictly_increasing_x(self): # Test the x is not required to be strictly increasing, see ticket #8535 xx = np.arange(10, dtype=float) yy = xx**3 x = np.arange(10, dtype=float) x[1] = x[0] y = x**3 w = np.ones_like(x) # also test LSQUnivariateSpline [which needs explicit knots] spl = UnivariateSpline(xx, yy, check_finite=True) t = spl.get_knots()[3:4] # interior knots w/ default k=3 spl2 = UnivariateSpline(x=x, y=y, w=w, check_finite=True) spl3 = InterpolatedUnivariateSpline(x=x, y=y, check_finite=True) spl4 = LSQUnivariateSpline(x=x, y=y, t=t, w=w, check_finite=True)
def test_strictly_increasing_x(self): # Test the x is required to be strictly increasing for # UnivariateSpline if s=0 and for InterpolatedUnivariateSpline, # but merely increasing for UnivariateSpline if s>0 # and for LSQUnivariateSpline; see gh-8535 xx = np.arange(10, dtype=float) yy = xx**3 x = np.arange(10, dtype=float) x[1] = x[0] y = x**3 w = np.ones_like(x) # also test LSQUnivariateSpline [which needs explicit knots] spl = UnivariateSpline(xx, yy, check_finite=True) t = spl.get_knots()[3:4] # interior knots w/ default k=3 UnivariateSpline(x=x, y=y, w=w, s=1, check_finite=True) LSQUnivariateSpline(x=x, y=y, t=t, w=w, check_finite=True) assert_raises(ValueError, UnivariateSpline, **dict(x=x, y=y, s=0, check_finite=True)) assert_raises(ValueError, InterpolatedUnivariateSpline, **dict(x=x, y=y, check_finite=True))
def computeSpline(cpoints, methode): u""" Calcule la spline (sx, sy) considérée comme une courbe paramétrée sx(t), sy(t). sx et sy sont deux splines à une seule variable au sens scipy. Si cpoints contient des points double consécutifs, la construction échoue. Retourne: T, sx, sy -------- - T np.ndarray(n) = abscisses curvilignes des points de cpoints - sx et sy deux splines d'interpolation de cpoints, i.e. vérifiant [sx(T[i]), sy(T[i])] = cpoints[i] sx, sy = None, None si cpoints.shape = (0,2) ou cpoints = None si cpoints contient deux points consécutifs identique, alors l'exception "ValueError: `x` must be strictly increasing sequence." est levée Parametres : ---------- - cpoints = np.ndarray((n,2)) les points de contrôle. - methode : peut prendre differentes valeurs. Il est de la forme : methode = (type,parametres) avec : # type est une chaîne de caractères parmi ('cubic', 'ius', 'us') c'est le type de spline (suivant la terminologie scipy.interpolate). # paramètres sont les paramètres associés au type de spline # si type = 'cubic' c'est une spline d'INTERPOLATION - parametres = 'periodic' pour splines fermées, sans point anguleux (trous par exemple) - parametres = 'clamped' fixe à zéro les derivées premières de x et y aux extrémités équivaut à parametres=((1, 0, 1, 0), (1, 0, 1, 0)) (un extrados p.ex.) - parametres = 'natural' fixe à zéro les derivées secondes de x et y aux extrémités équivaut à parametres=((2, 0, 2, 0), (2, 0, 2, 0)) - parametres = 'not-a-knot' : The first and second segment at a curve end are the same polynomial. It is a good default when there is no information on boundary conditions. - [obsolete, simplification, cf ci-dessous] parametres = ((dx0, vx0, dy0, vy0), (dxn, vxn, dyn, vyn)) permet de fixer les dérivées aux extrémités * le premier tuple concerne le premier point de la spline - dx0, vx0 : ordre de dérivation en x et valeur de la dérivée dx0-ième. P.ex. si dx0, vx0 = 1, 3.14 on demande que x'(0)=3.14. Usuellement, dx0 et dy0 valent 0,1 ou 2 - dy0, vy0 : analogue pour y(0) * le deuxième tuple définit de la même manière les dérivées de x(t) et y(t) en t=1, donc pour le dernier point de la spline [fin obsolete] - parametres = ((d0, dx0, dy0), (dn, dxn, dyn)) permet de fixer les dérivées aux extrémités * le premier tuple concerne le premier point de la spline - d0 = ordre de dérivation et - dx0,dy0 = le vecteur dérivée d0-ième. P.ex. si d0, dx0, dy0 = 1, 3.14, 7 on demande que x'(0),y'(0) = 3.14, 7 Usuellement, d0 vaut 0,1 ou 2 * le deuxième tuple définit de la même manière le vecteur dérivé-dn-ieme en t=1, donc pour le dernier point de la spline * NB, il est possible de fixer plus finement les valeurs des dérivées aux extrémités (cf § obsolete ci-dessus, on peut fixer (par exemple) x'(0) et y"(0) indépendemment, alors qu'actuellement on fixe v'(0)=(x'(0),y'(0)) ou bien v"(0)=(x"(0),y"(0)) # si type = 'ius' ou 'interpolatedunivariatespline', il s'agit de spline d'INTERPOLATION, (utilise la classe InterpolatedUnivariateSpline de scipy, fille de UnivariateSpline, avec s=0) parametres est alors un entier, le degré de la spline. Un polyligne est de type 'ius', avec degré=1. Les autre degrés ne sont pas forcément utilisés je crois que ('ius', 3) fait double emploi avec ('cubic', 'not-a-knot') # si type = 'us' ou 'univariatespline', c'est une spline d'AJUSTEMENT. Dans ce cas, les paramètres sont un dictionnaire : parametres = {'w':None, 'bbox':[None, None], 'k':3, 's':None, 'ext':0, 'check_finite':False} voir UnivariateSpline(x, y, w=None, bbox=[None, None], k=3, s=None, ext=0, check_finite=False) dans la doc scipy. """ type_, parametres = methode # debug(methode=(type_,parametres),shape=cpoints.shape) if len(cpoints) < 2: #moins de deux points de controle #TODO les knots devraient être de shape (0,)?? _knots, sx, sy = np.zeros((2, )), None, None return _knots, sx, sy if type_ == 'cubic': if parametres in ('periodic', 'per', 'periodique'): #il faut au moins 3 points, avec P[0]==P[-1] #et un des points intermediaires P[k]!=P[0] if len(cpoints) < 3: _knots, sx, sy = np.zeros((2, )), None, None return _knots, sx, sy # debug(cpoints_shape=cpoints.shape, p0=cpoints[0],pn=cpoints[-1]) # if all(cpoints[0] == cpoints[-1]) : pass if np.linalg.norm(cpoints[0] - cpoints[-1]) < 1.0e-10: cpoints[-1] = cpoints[0] else: #On rajoute le premier point a la fin # debug('cpoints[0]-cpoints[1]=%s'%(cpoints[0]-cpoints[1])) # raise ValueError('Spline periodique, %s != %s'%(cpoints[0],cpoints[-1])) cpoints = np.vstack((cpoints, cpoints[0])) N = len(cpoints) # debug(shape=cpoints.shape) T = absCurv(cpoints, normalise=True) # debug(abscurv_cpoints=T) # _knots = T X = cpoints[:, 0] Y = cpoints[:, 1] if type_ == 'cubic': # debug(parametres=parametres) if isinstance(parametres, (str, unicode)): sx = CubicSpline(T, X, bc_type=parametres) sy = CubicSpline(T, Y, bc_type=parametres) # debug(sx,sy) else: (d0, vx0, vy0), (dn, vxn, vyn) = parametres sx = CubicSpline(T, X, bc_type=((d0, vx0), (dn, vxn))) sy = CubicSpline(T, Y, bc_type=((d0, vy0), (dn, vyn))) elif type_ == 'ius': # try : sx = InterpolatedUnivariateSpline( T, X, k=parametres ) #s=la précision de l'ajustement s=0 <=> interpolation sy = InterpolatedUnivariateSpline(T, Y, k=parametres) # except Exception as msg: # rdebug('pas de spline (degre trop eleve ?)') # print unicode (msg) # sx = sy = None elif type_ == 'us': #UnivariateSpline(x, y, w=None, bbox=[None, None], k=3, # s=None, ext=0,check_finite=False) weights = np.ones(N) W = 1000.0 # eps = 1.0e-5#NPrefs.EPS # en supposant que tous les termes erreur di^2=wi*(xi-f(ti))^2 sont egaux # le choix de s suivant implique # abs(xi-f(ti))<eps et # abs(x1-f(t1))<eps/(N*W) et abs(xN-f(tN))<eps/(N*W) weights[0] = weights[-1] = W weights /= np.sum(weights) # s = eps/(N*W) # debug(len(T), parametres) sx = UnivariateSpline( T, X, k=parametres, w=None, s=1.0e-10) #s=la précision de l'ajustement s=0 <=> interpolation sy = UnivariateSpline(T, Y, k=parametres, w=None, s=1.0e-10) # sx = UnivariateSpline(T, X, w=weights, k=parametres, s=s)#s=la précision de l'ajustement s=0 <=> interpolation # sy = UnivariateSpline(T, Y, w=weights, k=parametres, s=s) # weights = np.ones(N) # W = 1000.0 # eps = NPrefs.EPS # # en supposant que tous les termes erreur di^2=wi*(xi-f(ti))^2 sont egaux # # le choix de s suivant implique # # abs(xi-f(ti))<eps et # # abs(x1-f(t1))<eps/(N*W) et abs(xN-f(tN))<eps/(N*W) # weights[0] = weights[-1] = W # weights /= np.sum(weights) # s = eps/(N*W) # # sx = UnivariateSpline(T, X, w=weights, k=parametres, s=s)#s=la précision de l'ajustement s=0 <=> interpolation # sy = UnivariateSpline(T, Y, w=weights, k=parametres, s=s) elif type_ == 'lsqus': raise NotImplementedError('LSQUnivariateSpline non implemente') #LSQUnivariateSpline(x, y, t, w=None, bbox=[None, None], k=3, ext=0, # check_finite=False) weights = np.ones(N) W = 1000.0 # eps = 1.0e-5#NPrefs.EPS # en supposant que tous les termes erreur di^2=wi*(xi-f(ti))^2 sont egaux # le choix de s suivant implique # abs(xi-f(ti))<eps et # abs(x1-f(t1))<eps/(N*W) et abs(xN-f(tN))<eps/(N*W) weights[0] = weights[-1] = W weights /= np.sum(weights) knots = linspace(0, 1, 20) sx = LSQUnivariateSpline( T, X, knots, k=parametres, w=None) #s=la précision de l'ajustement s=0 <=> interpolation sy = LSQUnivariateSpline(T, Y, knots, k=parametres, w=None) # sx = UnivariateSpline(T, X, w=weights, k=parametres, s=s)#s=la précision de l'ajustement s=0 <=> interpolation # sy = UnivariateSpline(T, Y, w=weights, k=parametres, s=s) # weights = np.ones(N) # W = 1000.0 # eps = NPrefs.EPS # # en supposant que tous les termes erreur di^2=wi*(xi-f(ti))^2 sont egaux # # le choix de s suivant implique # # abs(xi-f(ti))<eps et # # abs(x1-f(t1))<eps/(N*W) et abs(xN-f(tN))<eps/(N*W) # weights[0] = weights[-1] = W # weights /= np.sum(weights) # s = eps/(N*W) # # sx = UnivariateSpline(T, X, w=weights, k=parametres, s=s)#s=la précision de l'ajustement s=0 <=> interpolation # sy = UnivariateSpline(T, Y, w=weights, k=parametres, s=s) return T, sx, sy