ParametricSpline_example2


import numpy as np
import scipy.interpolate as si
import matplotlib.pyplot as plt
from string import split, join

def readXY(filepath="./XYdata.txt"):

 data=open(filepath, "r")
 X=[]
 Y=[]
 for line in data:
  splitline=split(line)
  try:
   X.append(float(splitline[0]))
   Y.append(float(splitline[1]))
  except:
   pass
 data.close()
 return X, Y

def getControlPoints(knots, k):

 n = len(knots)-1-k
 cx = np.zeros(n)
 for i in range(n):
  tsum = 0
  for j in range(1,k+1):
   tsum+=knots[i+j]
  cx[i] = float(tsum)/k
 return cx

def plotSplineFunction(title = "Spline Function", offset_x = 0.5, offset_y = 0.05):

 plt.plot(coeffs_x, coeffs_y, 'go-')
 plt.plot(x, y, 'ro')
 plt.plot(xP, yP, lw=2)
 plt.plot(knots, knotsy, 'gs') # ,markersize=10
 plt.axis([xmin-offset_x, xmax+offset_x, ymin-offset_y, ymax+offset_y])
 plt.grid(True)
 plt.title(title)
 plt.show()

def findLSQSplineRep():
 global knots, knots_full, coeffs_y, coeffs_x, yP, knotsy

 lsqspline = si.LSQUnivariateSpline( x, y, knots, k=k, w = w)
 knots = lsqspline.get_knots()
 coeffs_y = lsqspline.get_coeffs()
 yP = lsqspline(xP)
 knotsy = lsqspline(knots)
 knots_full = np.concatenate(([knots[0]]*k, knots, [knots[-1]]*k ))
 coeffs_x = getControlPoints(knots_full, k)

def findSmoothedSplineRep(s=0.005):
 global knots, knots_full, coeffs_y, coeffs_x, yP, knotsy

 spline = si.UnivariateSpline( x, y, k=k , s=s, w=w)
 knots = spline.get_knots()
 coeffs_y = spline.get_coeffs()
 yP = spline(xP)
 knotsy = spline(knots)
 knots_full = np.concatenate(([knots[0]]*k, knots, [knots[-1]]*k ))
 coeffs_x = getControlPoints(knots_full, k)


##################################### LOAD DATA POINTS #######################################

x, y = readXY("./data_charts/cy_f004.txt")

# print "x:", x
# print "y:", y

### set variables
nsample = 100
nknot = 3
k=3
num_points=len(x)
xmax=max(x)
xmin=min(x)
ymax=max(y)
ymin=min(y)
xP = np.linspace( x[0], x[-1], nsample )
# xP = np.linspace( x[0]-2, x[-1]+2, nsample )

plt.plot(x, y, 'ro')
plt.axis([xmin-0.5, xmax+0.5, ymin-0.05, ymax+0.05])
plt.grid(True)
plt.title("Data points")
plt.show()

### define weight vector to push further approximations stick to end points
wend = 3
w = [wend] + [1]*(num_points-2) + [wend]


################################ FIND LSQ SPLINE REPRESENTATION  ##############################

### try with uniform knot vector

knot_offset=(xmax-xmin)/(nknot+1)
knots = np.linspace( knot_offset, xmax-knot_offset, nknot )

findLSQSplineRep()
plotSplineFunction(title = "LSQ spline function with uniform knot vector", offset_x = 1.)

### manually select best fitting non-uniform knot vector

knots = [1.2, 1.85, 2.1, 2.4, 2.6] # !!
knots = [1.2, 1.85, 2.3, 2.6, 3.2] # !
knots = [1.2, 1.85, 2.0, 2.7, 3.2] # !!!
knots = [1.2, 1.85, 2.0, 2.8, 3.5] # !!!!

findLSQSplineRep()
plotSplineFunction(title = "LSQ spline function with manual selected non-uniform knot vector", offset_x = 1.)

############################        FIND SMOOTHED SPLINE REPRESENTATION   ###########################

findSmoothedSplineRep(s=0.1)
plotSplineFunction(title = "Smoothed spline function s=0.1")
# print "s=0.1, knots:", knots
# findSmoothedSplineRep(s=0)
# plotSplineFunction(title = "Polynomial spline interpolation")
# print "s=0, knots:", knots
findSmoothedSplineRep()
plotSplineFunction(title = "Smoothed spline function s=0.005")
# print "s=0.05, knots:", knots

############################    MANUALLY SELECT BEST_FITTING CONTROL POINTS   #############################

### try to comment next two rows to look at the original smoothed spline curve after parametrization
coeffs_x = [ x[0], 1.1,   1.7,  2.16,  3.1,   3.0,   x[-1]]
coeffs_y = [ y[0], 0.11,  0.17,  0.32,  0.27,  0.19,  y[-1]]

############################        PARAMETRIC SPLINE REPRESENTATION       #############################

### norm knot vector to number of points

num_knots = len(knots_full)
ka = (knots_full[-1] - knots_full[0])/(num_points)
knotsp = np.zeros(num_knots)
for i in range(num_knots):
 knotsp[i] = num_points-((knots_full[-1] - knots_full[i]))/ka
# print "knotsp:", knotsp

### find parametric spline representation based on control points coordinates (coeffs_x, coeffs_y)

tckX = knotsp , coeffs_x, k
tckY = knotsp , coeffs_y, k

splineX = si.UnivariateSpline._from_tck(tckX)
splineY = si.UnivariateSpline._from_tck(tckY)

coeffs_p = getControlPoints(knotsp, k)
tP = np.linspace(0,  num_points, 100)
# tP = np.linspace(-20,  num_points+20, 100)
xP = splineX(tP)
yP = splineY(tP)

################################## PLOT PARAMETRIC SPLINE CURVE #####################################

offset_x = (xmax-xmin)*0.05
offset_y = (ymax-ymin)*0.1
ct = 0.5
tadd = 0.5

# offset_x = (xmax-xmin)*0.2
# offset_y = (ymax-ymin)*0.2
# ct = 0.7
# tadd = 1.0

knotpoints_y = [ymin-offset_y*ct]*len(knotsp)
knotpoints_x = [xmin-offset_x*ct]*len(knotsp)

fig = plt.figure()

ax = fig.add_subplot(224)
ax.grid(True)
plt.plot(coeffs_x, coeffs_p, '-og')
plt.plot(xP, tP, 'r', lw=2)
plt.plot(knotpoints_x, knotsp, '>', ms=6, color='black')
plt.ylim([-tadd, num_points+tadd])
plt.xlim([xmin - offset_x, xmax + offset_x])
plt.ylabel('t', rotation=0,  labelpad=20, fontweight='bold', fontsize=14)
plt.xlabel('x', labelpad=5, fontweight='bold', fontsize=14)
ax.invert_yaxis()
plt.title('Spline function x(t)')

ax = fig.add_subplot(221)
ax.grid(True)
plt.plot(coeffs_p, coeffs_y, '-og')
plt.plot(tP, yP, 'r', lw=2)
plt.plot(knotsp,knotpoints_y, '^', ms=6, color='black')
plt.xlim([-tadd, num_points+tadd])
plt.ylim([ymin - offset_y, ymax + offset_y])
plt.ylabel('y', labelpad=20, rotation=0, fontweight='bold', fontsize=14)
plt.xlabel('t', labelpad=10, fontweight='bold', fontsize=14)
ax.invert_xaxis()
plt.title('Spline function y(t)')

ax = fig.add_subplot(222)
ax.grid(True)
plt.plot(x, y, 'ro')
plt.plot(coeffs_x, coeffs_y, '-og')
plt.plot(xP, yP, 'b', lw=2.5)
plt.xlim([xmin - offset_x, xmax + offset_x])
plt.ylim([ymin - offset_y, ymax + offset_y])
plt.title('Spline curve f(x(t), y(t))')

plt.show()



No comments:

Post a Comment