1

I wrote IDL code:

zz= [  0,  5, 10, 15, 30, 50, 90, 100,  500]
uz= [ 20, 20, 20, 30, 60, 90, 30, -200, -200]*(-1.)
zp= findgen(120)*500+500
up= spline((zz-10.),uz,(zp/1000.0))
print, up 

and IDL gave me the values of up array from about -20 to 500

.The same I did in Python

import numpy as npy
zz = npy.array([  0,  5, 10, 15, 30, 50, 90, 100,  500])
uz = npy.array([ 20, 20, 20, 30, 60, 90, 30, -200, -200])*(-1.)
zp = npy.arange(0,120)*500+500
from scipy.interpolate import interp1d
cubic_interp_u = interp1d(zz-10., uz, kind='cubic')
up = cubic_interp_u(zp/1000)
print up

and it gave me up with values from about -20 to -160. Any idea? Thanks in advance!

Bogdanovist
  • 1,498
  • 2
  • 11
  • 20
hoang tran
  • 3,918
  • 3
  • 19
  • 21
  • For starters, you could plot the interpolation result over the data points, and see if either makes sense, or if one is completely nonsense. Also, you may want to double check whether IDL and scipy/numpy treat integer arrays the same in their routines (i.e., do they both automatically cast their input to float?) –  Nov 08 '12 at 10:02
  • @Evert: Yes, thanks. That's a good idea to plot the results. I have done it and the pictures are shown here. Please have a look. I guess that the interpolated function of Python cannot catch my profile. However, I still have no idea to modify it! your helps, please! – hoang tran Nov 08 '12 at 12:04
  • Pictures are shown, where? What do you mean by profile? – Janne Karila Nov 08 '12 at 12:50
  • Sorry I cannot post the images because I have not enough reputation – hoang tran Nov 08 '12 at 14:14
  • @JanneKarila by profile I mean my plot, here in python the function spline doesn't follow my plot, it doesn't pass all the points in the plot. It wants to make a 3rd order curve from some beginning points – hoang tran Nov 08 '12 at 15:46

1 Answers1

2

Actually, I don't see a problem. I'm using UnivariateSpline here instead of interp1d and cubic_interp_u, but the underlying routines are essentially the same, as far as I can tell:

import numpy as npy
import pyplot as pl
from scipy.interpolate import UnivariateSpline
zz = npy.array([  0,  5, 10, 15, 30, 50, 90, 100,  500])
uz = npy.array([ 20, 20, 20, 30, 60, 90, 30, -200, -200])*(-1.)
zp = npy.arange(0,120)*500+500
pl.plot(zz, uz, 'ro')
pl.plot(zp/100, UnivariateSpline(zz, uz, s=1, k=3)(zp/100), 'k-.')
pl.plot(zp/1000, UnivariateSpline(zz, uz, s=1, k=3)(zp/1000), 'b-')

The only problem I see is that you limited the interpolation, by using zp/1000. Using zp/100, I get all lots of values outside that -160, -20 range, which you can also see on the graph from the dot-dashed line, compared to the blue line (zp/1000):

enter image description here

It looks like scipy is doing a fine job.

By the way, if you want to (spline-)fit such outlying values, you may want to consider working in log-log space instead, or roughly normalizing your data (log-log space kind-of does that). Most fitting problems work best if the values are in the same order of magnitude.

  • thank you so much! Now I think what I need is not a cubic spline function but a smoothly fitting curve. I want the fitting curve to pass all the given points . Do you have any experience with this? thanks a lot again! – hoang tran Nov 09 '12 at 10:28
  • @hoangtran: I have little to no experience here, but a spline is essentially a smooth curve; it just has a somewhat inconvenient mathematical formulation. Also, have a look at the documentation for UnivariateSpline, in particular about he parameter `s`. –  Nov 09 '12 at 10:47
  • @hoangtran A cubic spline passes (goes through) all the given points. – Janne Karila Nov 09 '12 at 17:21