2017-08-28 1 views
0

In this question zu extrahieren, fragte ich die Gemeinschaft darüber, wie scipy.interpolate.splev berechnet eine Spline-Basis .. Mein Ziel war es, eine Spline schneller als splev durch Vorausberechnen ein bspline basis und erzeugt eine Kurve zu berechnen indem Sie ein basis zu control point Punktprodukt tun.Wie die B-Spline-Basis von scipy.interpolate.BSpline

Seither wurde a new scipy.interpolate.BSpline interpolator zu scipy hinzugefügt. It comes with a basis_element function, von dem ich annehme, könnte verwendet werden, um die Grundlage zurückzugeben, die verwendet wird, um einen Spline zu berechnen.

So zum Beispiel unter Verwendung des Codes from here mit den Eingängen unten:

import numpy as np 

# Control points 
cv = np.array([[ 50., 25., 0.], 
     [ 59., 12., 0.], 
     [ 50., 10., 0.], 
     [ 57., 2., 0.], 
     [ 40., 4., 0.], 
     [ 40., 14., 0.]]) 

kv = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3] # knot vector 
n = 10 # 10 samples (keeping it simple) 
degree = 3 # Curve degree 

I kann folgende BSPLINE Basis berechnen:

[[ 1.   0.   0.   0.   0.   0.  ] 
[ 0.2962963 0.56481481 0.13271605 0.00617284 0.   0.  ] 
[ 0.03703704 0.51851852 0.39506173 0.04938272 0.   0.  ] 
[ 0.   0.25  0.58333333 0.16666667 0.   0.  ] 
[ 0.   0.07407407 0.54938272 0.36728395 0.00925926 0.  ] 
[ 0.   0.00925926 0.36728395 0.54938272 0.07407407 0.  ] 
[ 0.   0.   0.16666667 0.58333333 0.25  0.  ] 
[ 0.   0.   0.04938272 0.39506173 0.51851852 0.03703704] 
[ 0.   0.   0.00617284 0.13271605 0.56481481 0.2962963 ] 
[ 0.   0.   0.   0.   0.   1.  ]] 

Verwendung np.dot mit basis und control points Returns 10 Proben auf der Kurve:

[[ 50.   25.   0.  ] 
[ 55.12654321 15.52469136 0.  ] 
[ 55..19753086 0.  ] 
[ 53.41666667 9.16666667 0.  ] 
[ 53.14506173 7.15432099 0.  ] 
[ 53.1882716 5.179.  ] 
[ 51.58333333 3.83333333 0.  ] 
[ 47.20987654 3.87654321 0.  ] 
[ 42.3179.7345679 0.  ] 
[ 40.   14.   0.  ]] 

Frage: Ist es möglich, die Basis wie oben beschrieben aus scipy.interpolate.BSpline zu extrahieren?

Offensichtlich muß ich es falsch verwenden, weil, wenn ich versuche ich so etwas wie diese:

from scipy.interpolate import BSpline 
b = BSpline.basis_element(kv) 
print b(np.linspace(kv[0],kv[-1],n)) # i'm not sure what these values represent 
[ 0.   0.00256299 0.04495618 0.16555213 0.28691315 0.28691315 
    0.16555213 0.04495618 0.00256299 0.  ] 

Antwort

2

BSpline.basis_element als Argument nimmt die internen Knoten.

In Ihrem Beispiel gepolsterter Sie die Knoten, und das nicht tun, was Sie dachten, es würde:

In [3]: t = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3] 

In [4]: b = BSpline.basis_element(t) 

In [5]: b.k 
Out[5]: 8 

es ist also eine achte Ordnung Spline.

Wenn Sie eine quadratische Spline wollten, würden Sie

In [7]: b1 = BSpline.basis_element([0, 1, 2, 3]) 

In [8]: b1.k 
Out[8]: 2 

In [9]: b1.t 
Out[9]: array([-1., -1., 0., 1., 2., 3., 4., 4.]) 

Confused tun? Die Methode ist ziemlich einfach: https://github.com/scipy/scipy/blob/v0.19.1/scipy/interpolate/_bsplines.py#L243-L302

Die aufrufbare von BSpline.basis_element zurückgegebene ist wirklich eine b-spline Funktion. Das Ergebnis es mit einem Array Argumente des Aufrufs ist dann gleich direkt den Beispielcode in dem BSpline docstring in einer Schleife für jedes Element Ihres Arrays ausgeführt wird, https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.BSpline.html

EDIT: Wenn Sie nach einer Variante von Cox-sind de Boor-Algorithmus zur Berechnung aller Splines nicht Null an einem bestimmten Punkt, dann können Sie auf eine Funktion, https://github.com/scipy/scipy/blob/v0.19.1/scipy/interpolate/_bspl.pyx#L161 (die selbst ist nur ein Wrapper über eine C-Routine, die alle schweren Heben tut, beachten Sie, dass es hart ist um die letztere Leistung Leistung zu schlagen.)

Allerdings ist es keine öffentliche Funktion, so ist es nicht garantiert in zukünftigen Versionen verfügbar sein. Wenn Sie einen guten Zweck dafür haben und einen Vorschlag für eine anwenderorientierte API haben, bringen Sie die Diskussion zum scipy bug tracker.

+0

Danke für die Klärung. Ich wurde von der Terminologie verwirrt. – Fnord

Verwandte Themen