Reputation: 259
I have (x,y) dataset which is continuous and differentiable. The exact functional form is not known. I want to taylor expand the graph at some point. I have tried using algopy/Adipy. The problem is they demand the functional form.
I am attaching the sample code of algopy.
import numpy; from numpy import sin,cos
from algopy import UTPM
def f(x):
return sin(cos(x) + sin(x))
D = 100; P = 1
x = UTPM(numpy.zeros((D,P)))
x.data[0,0] = 0.3
x.data[1,0] = 1
y = f(x)
print('coefficients of y =', y.data[:,0])
where D is the order of polynomial.
I tried using the following (x1 and y1 are 1D arrays):
from scipy.interpolate import interp1d
f1 = interp1d(x1, y1, kind='cubic')
def f(x):
temp1=f1(x)
return np.float64(temp1)
However, interpolation does not seem to take in the data type of x returned by UTPM.
Error Message:
Traceback (most recent call last):
File "tay.py", line 26, in <module>
y = f(x)
File "tay.py", line 15, in f
temp1=f1(x)
File "/usr/lib/python2.7/dist-packages/scipy/interpolate/polyint.py", line 54, in __call__
y = self._evaluate(x)
File "/usr/lib/python2.7/dist-packages/scipy/interpolate/interpolate.py", line 449, in _evaluate
y_new = self._call(self, x_new)
File "/usr/lib/python2.7/dist-packages/scipy/interpolate/interpolate.py", line 441, in _call_spline
return spleval(self._spline, x_new)
File "/usr/lib/python2.7/dist-packages/scipy/interpolate/interpolate.py", line 919, in spleval
res[sl] = _fitpack._bspleval(xx,xj,cvals[sl],k,deriv)
TypeError: Cannot cast array data from dtype('O') to dtype('float64') according to the rule 'safe'
Upvotes: 3
Views: 1920
Reputation: 1909
i was looking for the same, so i implemented this:
import numpy as np
import matplotlib.pyplot as plt
from math import factorial as f
def dxdy(x,y,order):
dy = y
for k in range(order+1):
print(k)
dx = (x[-1]-x[0])/len(x)
if k == 1:
dy = y
elif k % 2 == 0:
dy = (dy[1:]-dy[:-1])/dx
x = x[:-1]
elif k % 2 != 0:
dy = (dy[1:]-dy[:-1])/dx
x = x[1:]
return dy
def taylor(x,y,n):
a = x[int(len(x)/2)+1]
center = int(len(x)/2)+1o
#plt.plot(y)
#plt.ylim(min(y),max(y))
for k in range(n+1):
print(k)
if k == 0:
y_hat = (y[center]*((x-a)**k))/f(k)
#plt.plot(y_hat)
else:
y_hat += (dxdy(x,y,k+1)[center]*((x-a)**k))/f(k)
#plt.plot(y_hat)
#plt.plot(y)
return y_hat
points = 101
x = np.linspace(-3*np.pi,3*np.pi,points)
y = 1/(1+np.exp(-x))
y = np.cos(x)#*x#(x**4)
center = int(points/2)
for k in range(21):
y_hat = taylor(x,y,k)
plt.figure(figsize=(8,4))
plt.ylim(min(y)*1.1,max(y)*1.1)
plt.xlim(min(x),max(x))
plt.plot(x,y)
plt.plot(x,y_hat,c='red')
plt.legend(['cs(x)','taylor, k= '+str(k)],loc='upper right')
plt.title('cos(x)')
plt.savefig('cos'+str(k)+'.png')
Upvotes: 3
Reputation: 11201
Doing a Taylor expansion of a dataset defined at discrete points does not makes sense. In particular, the following preposition is wrong,
I have (x,y) dataset which is continuous and differentiable. The exact functional form is not known.
You can only have a continuous function, if you associate some interpolation procedure with your dataset, but then this will also fix the general functional form.
For instance, say we use piecewise cubic interpolations, as in the question. This means that the Taylor expansion, will be effectively constrained by the coefficients of the cubic polynomial used for the interpolation (and can be at most of order 3). In addition, another interpolation routine will produce a different Taylor expansion.
In general, the results will mostly depend on the interpolation routine instead of on your data. This is because the Taylor expansion relies on local behaviour of the function, which is not contained in your (x,y) dataset.
Instead, you could locally fit your data with a polynomial of some order, which will yield an equivalent of the Taylor expansion for sampled data.
Upvotes: 3