Beispiel #1
0
    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)
Beispiel #2
0
    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))
Beispiel #3
0
 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))
Beispiel #5
0
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