comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » Smoothing Spline -- any existing efficient routines?
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
Smoothing Spline -- any existing efficient routines? [message #72088] Thu, 12 August 2010 06:25 Go to next message
Neil B. is currently offline  Neil B.
Messages: 2
Registered: August 2010
Junior Member
Hi,

I am trying to find the continuum of various stellar spectra. The
noise of these spectra are fairly non-intrusive and there aren't many
outliers (spikes due to calibration errors etc.).

The arrays I am working with contain about 40000+ elements.

I want to essentially turn the spectra into some linear function, so I
can remove any curvature in the observed data.

I know of the procedure Spline_smooth (http://astro.uni-tuebingen.de/
software/idl/astrolib/math/spline_smooth.html). However, this
function as the restriction tag in its header suggests, is extremely
slow.... It takes about 40 minutes to process a 1000 element sub-
array. The speed issues in this program are due to the fact that it
does not use Cholesky Decomposition. Further more, when I try the
routine on the 40000 element array I receive an error message that
informs me that there are too many elements in the array...

Does anyone know of an efficient version of this routine.

Or is there a better way for determining the continuum of a spectrum?

Thanks very much in advance.
Re: Smoothing Spline -- any existing efficient routines? [message #72177 is a reply to message #72088] Wed, 18 August 2010 06:08 Go to previous messageGo to next message
Nikola is currently offline  Nikola
Messages: 53
Registered: November 2009
Member
> Nikola: this is not a criticism of your program - I am concerned
> about the sources you used to learn IDL and why they failed to mention
> the "[]" syntax.
>
> Ciao,
> Paolo

Thanks for your comment, Paolo. As many other IDL users I guess, I
learned it en route from the help files. The () brackets were, at
least in my case, an atavism from FORTRAN programming.

Cheers,
Nikola
Re: Smoothing Spline -- any existing efficient routines? [message #72199 is a reply to message #72088] Mon, 16 August 2010 07:33 Go to previous messageGo to next message
pgrigis is currently offline  pgrigis
Messages: 436
Registered: September 2007
Senior Member
This post made me reflect upon how IDL is taught - or the sources
that people use to learn IDL by themselves. The fact that somebody
that started IDL around 2006 wrote a program consistently using
parentheses "()" instead of brackets "[]" seems to imply a failure
in communicating "proper" usage to new users.

How and why are we failing in communicating to new users the
importance
to use proper indexing syntax? Is this a problem with documentation,
mentoring or it comes from too much old legacy code laying around?

Nikola: this is not a criticism of your program - I am concerned
about the sources you used to learn IDL and why they failed to mention
the "[]" syntax.

Ciao,
Paolo



On Aug 16, 6:11 am, Nikola <nikola.vi...@gmail.com> wrote:
> You can try this one. It's not very nicely coded - I wrote it as an
> exercise in my early IDL days - but it might work.
>
> ;+
> ; NAME:
> ;   SPLINECOEFF
> ;
> ; PURPOSE:
> ;   This procedure computes coefficients of cubic splines
> ;   for a given observational set and smoothing parameter
> ;   lambda. The method is coded according to Pollock D.S.G.
> ;   (1999), "A Handbook of Time-Series Analysis, Signal
> ;   Processing and Dynamics, Academic Press", San Diego
> ;
> ; CATEGORY:
> ;   Data processing
> ;
> ; CALLING SEQUENCE:
> ;   COEFFS = SPLINECOEFF([X,] Y, [SIGMA], LAMBDA=LAMBDA)
> ;
> ; INPUTS:
> ;   X     = 1D Array (independent variable)
> ;   Y     = 1D Array (function)
> ;   SIGMA = 1D Array (weight of each measurement) By default
> ;           all the measurements are of the same weight.
> ;
> ; KEYWORDS:
> ;   LAMBDA = Smoothing parameter (It can be determined
> ;            empiricali, by the LS method or by cross-
> ;            validation, eg. see book of Pollock.) LAMBDA
> ;            equals 0 results in a cubic spline interpolation.
> ;            In the other extreme, for a very large LAMBDA
> ;            the result is smoothing by a linear function.
> ;
> ; COMMENT:
> ;
> ; EXAMPLE:
> ;   X = .....
> ;   Y = .....
> ;   Coeffs = SPLINECOEFF(X, Y, LAMBDA = 1.d5)
> ;   Y1 = N_ELEMENTS(Y) - 1
> ;   X1 = X(0:N_ELEMENTS(Y)-2)
> ;   FOR i = 0, N_ELEMENTS(Y)-2 DO Y1(i) = Coeff.D(I) + $
> ;                                         Coeff.C(I) * (X(I+1)-X(I)) + $
> ;                                         Coeff.B(I) * (X(I+1)-X(I))^2 + $
> ;                                         Coeff.A(I) * (X(I+1)-X(I))^3
> ;   PLOT, X, Y, PSYM = 3
> ;   OPLOT, X1, Y1
> ;
> ; OUTPUTS:
> ;   COEFFS: Structure of 4 arrays (A, B, C & D) containing
> ;           the coefficients of a spline between each two of
> ;           the given measurements.
> ;
> ; MODIFICATION HISTORY:
> ;   Written by: NV (Jan2006)
> ;               # as a function, NV (Mar2007)
> ;-
> FUNCTION SPLINECOEFF, XX, YY, SS, LAMBDA = LAMBDA
>
> CASE N_PARAMS() OF
>         1: BEGIN
>                 Y = XX
>                 X = INDGEN(N_ELEMENTS(Y))
>                 SIGM = FLTARR(N_ELEMENTS(Y))+1
>         END
>         2: BEGIN
>                 Y = YY
>                 X = XX
>                 SIGM = FLTARR(N_ELEMENTS(Y))+1
>         END
>         3: BEGIN
>                 Y = YY
>                 X = XX
>                 SIGM = SS
>         END
>         ELSE: MESSAGE, 'Wrong number of arguments'
> ENDCASE
>
> NUM = SIZE(X, /N_ELEMENTS)
> N = NUM-1
> IF NOT(KEYWORD_SET(LAMBDA)) THEN MESSAGE, 'Parameter lambda is not
> defined.'
>
> ; Definition of the help variables
> H = DBLARR(NUM) & R = DBLARR(NUM) & F = DBLARR(NUM) & P = DBLARR(NUM)
> Q = DBLARR(NUM) & U = DBLARR(NUM) & V = DBLARR(NUM) & W = DBLARR(NUM)
> ; Definition of the unknown coefficients
> A = DBLARR(NUM) & B = DBLARR(NUM) & C = DBLARR(NUM) & D = DBLARR(NUM)
>
> ; Computation of the starting values
> H(0) = X(1) - X(0)
> R(0) = 3.D/H(0)
>
> ; Computation of all H, R, F, P & Q
> FOR I = 1, N - 1 DO BEGIN
>         H(I) = X(I+1) - X(I)
>         R(I) = 3.D/H(I)
>         F(I) = -(R(I-1) + R(I))
>         P(I) = 2.D * (X(I+1) - X(I-1))
>         Q(I) = 3.D * (Y(I+1) - Y(I))/H(I) - 3.D * (Y(I) - Y(I-1))/H(I-1)
> ENDFOR
>
> ; Compute diagonals of the matrix: W + LAMBDA T' SIGMA T
> FOR I = 1, N - 1 DO BEGIN
>         U(I) = R(I-1)^2 * SIGM(I-1) + F(I)^2 * SIGM(I) + R(I)^2 * SIGM(I+1)
>         U(I) = LAMBDA * U(I) + P(I)
>         V(I) = F(I) * R(I) * SIGM(I) + R(I) * F(I+1) * SIGM(I+1)
>         V(I) = LAMBDA * V(I) + H(I)
>         W(I) = LAMBDA * R(I) * R(I+1) * SIGM(I+1)
> ENDFOR
>
> ; Decomposition in the form L' D L
> V(1) = V(1)/U(1)
> W(1) = W(1)/U(1)
>
> FOR J = 2, N-1 DO BEGIN
>         U(J) = U(J) - U(J-2) * W(J-2)^2 - U(J-1) * V(J-1)^2
>         V(J) = (V(J) - U(J-1) * V(J-1) * W(J-1))/U(J)
>         W(J) = W(J)/U(J)
> ENDFOR
>
> ; Gaussian eliminations to solve Lx = T'y
> Q(0) = 0.D
> FOR J = 2, N-1 DO Q(J) = Q(J) - V(J-1) * Q(J-1) - W(J-2) * Q(J-2)
> FOR J = 1, N-1 DO Q(J) = Q(J)/U(J)
>
> ; Gaussian eliminations to solve L'c = D^{-1}x
> Q(N-2) = Q(N-2) - V(N-2)*Q(N-1)
> FOR J = N-3, 1, -1 DO Q(J) = Q(J) - V(J) * Q(J+1) - W(J) * Q(J+2)
>
> ; Coefficients in the first segment
> D(0) = Y(0) - LAMBDA * R(0) * Q(1) * SIGM(0)
> D(1) = Y(1) - LAMBDA * (F(1) * Q(1) + R(1) * Q(2)) * SIGM(0)
> A(0) = Q(1)/(3.D * H(0))
> B(0) = 0.D
> C(0) = (D(1) - D(0))/H(0) - Q(1) * H(0)/3.D
>
> ; Other coefficients
> FOR J = 1, N-1 DO BEGIN
>         A(J) = (Q(J+1)-Q(J))/(3.D * H(J))
>         B(J) = Q(J)
>         C(J) = (Q(J) + Q(J-1)) * H(J-1) + C(J-1)
>         D(J) = R(J-1) * Q(J-1) + F(J) * Q(J) + R(J) * Q(J+1)
>         D(J) = Y(J) - LAMBDA * D(J) * SIGM(J)
> ENDFOR
> D(N) = Y(N) - LAMBDA * R(N-1) * Q(N-1) * SIGM(N)
>
> SplCoeff = {A:DBLARR(NUM), B:DBLARR(NUM), C:DBLARR(NUM),
> D:DBLARR(NUM)}
> SplCoeff.A = A
> SplCoeff.B = B
> SplCoeff.C = C
> SplCoeff.D = D
>
> RETURN, SPLCOEFF
>
> END
Re: Smoothing Spline -- any existing efficient routines? [message #72200 is a reply to message #72088] Mon, 16 August 2010 03:11 Go to previous messageGo to next message
Nikola is currently offline  Nikola
Messages: 53
Registered: November 2009
Member
You can try this one. It's not very nicely coded - I wrote it as an
exercise in my early IDL days - but it might work.

;+
; NAME:
; SPLINECOEFF
;
; PURPOSE:
; This procedure computes coefficients of cubic splines
; for a given observational set and smoothing parameter
; lambda. The method is coded according to Pollock D.S.G.
; (1999), "A Handbook of Time-Series Analysis, Signal
; Processing and Dynamics, Academic Press", San Diego
;
; CATEGORY:
; Data processing
;
; CALLING SEQUENCE:
; COEFFS = SPLINECOEFF([X,] Y, [SIGMA], LAMBDA=LAMBDA)
;
; INPUTS:
; X = 1D Array (independent variable)
; Y = 1D Array (function)
; SIGMA = 1D Array (weight of each measurement) By default
; all the measurements are of the same weight.
;
; KEYWORDS:
; LAMBDA = Smoothing parameter (It can be determined
; empiricali, by the LS method or by cross-
; validation, eg. see book of Pollock.) LAMBDA
; equals 0 results in a cubic spline interpolation.
; In the other extreme, for a very large LAMBDA
; the result is smoothing by a linear function.
;
; COMMENT:
;
; EXAMPLE:
; X = .....
; Y = .....
; Coeffs = SPLINECOEFF(X, Y, LAMBDA = 1.d5)
; Y1 = N_ELEMENTS(Y) - 1
; X1 = X(0:N_ELEMENTS(Y)-2)
; FOR i = 0, N_ELEMENTS(Y)-2 DO Y1(i) = Coeff.D(I) + $
; Coeff.C(I) * (X(I+1)-X(I)) + $
; Coeff.B(I) * (X(I+1)-X(I))^2 + $
; Coeff.A(I) * (X(I+1)-X(I))^3
; PLOT, X, Y, PSYM = 3
; OPLOT, X1, Y1
;
; OUTPUTS:
; COEFFS: Structure of 4 arrays (A, B, C & D) containing
; the coefficients of a spline between each two of
; the given measurements.
;
; MODIFICATION HISTORY:
; Written by: NV (Jan2006)
; # as a function, NV (Mar2007)
;-
FUNCTION SPLINECOEFF, XX, YY, SS, LAMBDA = LAMBDA

CASE N_PARAMS() OF
1: BEGIN
Y = XX
X = INDGEN(N_ELEMENTS(Y))
SIGM = FLTARR(N_ELEMENTS(Y))+1
END
2: BEGIN
Y = YY
X = XX
SIGM = FLTARR(N_ELEMENTS(Y))+1
END
3: BEGIN
Y = YY
X = XX
SIGM = SS
END
ELSE: MESSAGE, 'Wrong number of arguments'
ENDCASE

NUM = SIZE(X, /N_ELEMENTS)
N = NUM-1
IF NOT(KEYWORD_SET(LAMBDA)) THEN MESSAGE, 'Parameter lambda is not
defined.'

; Definition of the help variables
H = DBLARR(NUM) & R = DBLARR(NUM) & F = DBLARR(NUM) & P = DBLARR(NUM)
Q = DBLARR(NUM) & U = DBLARR(NUM) & V = DBLARR(NUM) & W = DBLARR(NUM)
; Definition of the unknown coefficients
A = DBLARR(NUM) & B = DBLARR(NUM) & C = DBLARR(NUM) & D = DBLARR(NUM)

; Computation of the starting values
H(0) = X(1) - X(0)
R(0) = 3.D/H(0)

; Computation of all H, R, F, P & Q
FOR I = 1, N - 1 DO BEGIN
H(I) = X(I+1) - X(I)
R(I) = 3.D/H(I)
F(I) = -(R(I-1) + R(I))
P(I) = 2.D * (X(I+1) - X(I-1))
Q(I) = 3.D * (Y(I+1) - Y(I))/H(I) - 3.D * (Y(I) - Y(I-1))/H(I-1)
ENDFOR

; Compute diagonals of the matrix: W + LAMBDA T' SIGMA T
FOR I = 1, N - 1 DO BEGIN
U(I) = R(I-1)^2 * SIGM(I-1) + F(I)^2 * SIGM(I) + R(I)^2 * SIGM(I+1)
U(I) = LAMBDA * U(I) + P(I)
V(I) = F(I) * R(I) * SIGM(I) + R(I) * F(I+1) * SIGM(I+1)
V(I) = LAMBDA * V(I) + H(I)
W(I) = LAMBDA * R(I) * R(I+1) * SIGM(I+1)
ENDFOR

; Decomposition in the form L' D L
V(1) = V(1)/U(1)
W(1) = W(1)/U(1)

FOR J = 2, N-1 DO BEGIN
U(J) = U(J) - U(J-2) * W(J-2)^2 - U(J-1) * V(J-1)^2
V(J) = (V(J) - U(J-1) * V(J-1) * W(J-1))/U(J)
W(J) = W(J)/U(J)
ENDFOR

; Gaussian eliminations to solve Lx = T'y
Q(0) = 0.D
FOR J = 2, N-1 DO Q(J) = Q(J) - V(J-1) * Q(J-1) - W(J-2) * Q(J-2)
FOR J = 1, N-1 DO Q(J) = Q(J)/U(J)

; Gaussian eliminations to solve L'c = D^{-1}x
Q(N-2) = Q(N-2) - V(N-2)*Q(N-1)
FOR J = N-3, 1, -1 DO Q(J) = Q(J) - V(J) * Q(J+1) - W(J) * Q(J+2)

; Coefficients in the first segment
D(0) = Y(0) - LAMBDA * R(0) * Q(1) * SIGM(0)
D(1) = Y(1) - LAMBDA * (F(1) * Q(1) + R(1) * Q(2)) * SIGM(0)
A(0) = Q(1)/(3.D * H(0))
B(0) = 0.D
C(0) = (D(1) - D(0))/H(0) - Q(1) * H(0)/3.D

; Other coefficients
FOR J = 1, N-1 DO BEGIN
A(J) = (Q(J+1)-Q(J))/(3.D * H(J))
B(J) = Q(J)
C(J) = (Q(J) + Q(J-1)) * H(J-1) + C(J-1)
D(J) = R(J-1) * Q(J-1) + F(J) * Q(J) + R(J) * Q(J+1)
D(J) = Y(J) - LAMBDA * D(J) * SIGM(J)
ENDFOR
D(N) = Y(N) - LAMBDA * R(N-1) * Q(N-1) * SIGM(N)

SplCoeff = {A:DBLARR(NUM), B:DBLARR(NUM), C:DBLARR(NUM),
D:DBLARR(NUM)}
SplCoeff.A = A
SplCoeff.B = B
SplCoeff.C = C
SplCoeff.D = D

RETURN, SPLCOEFF

END
Re: Smoothing Spline -- any existing efficient routines? [message #82566 is a reply to message #72177] Fri, 21 December 2012 03:31 Go to previous messageGo to next message
malte1982 is currently offline  malte1982
Messages: 1
Registered: December 2012
Junior Member
Hey Nikola,

sorry for replying to such an old post. I came accross your smoothing spline implementation in this forum and it works really nice. However as soon as I use three input parameters, i.e. weighted data, the final result has discontinuities at the breakpoints (between the segments of data points). Obviously there is a bug somewhere. Could you tell me what are the requirements on the vector of weights? I have tried normalizing it, but that did not help. Thank you in advance!

Take care,
Malte

On Wednesday, August 18, 2010 3:08:57 PM UTC+2, Nikola Vitas wrote:
>> Nikola: this is not a criticism of your program - I am concerned
>> about the sources you used to learn IDL and why they failed to mention
>> the "[]" syntax.
>>
>> Ciao,
>> Paolo
>
> Thanks for your comment, Paolo. As many other IDL users I guess, I
> learned it en route from the help files. The () brackets were, at
> least in my case, an atavism from FORTRAN programming.
>
> Cheers,
> Nikola
Re: Smoothing Spline -- any existing efficient routines? [message #93512 is a reply to message #72088] Tue, 09 August 2016 08:11 Go to previous messageGo to next message
florishj is currently offline  florishj
Messages: 1
Registered: August 2016
Junior Member
There appears to be a bug in the line

D(1) = Y(1) - LAMBDA * (F(1) * Q(1) + R(1) * Q(2)) * SIGM(0)

I believe the last term should be SIGM(1)

I found that if the weights of the first two points are different, the original code gives erroneous answers; but when they are the same, it works beautifully. However, when I fix that line to

D(1) = Y(1) - LAMBDA * (F(1) * Q(1) + R(1) * Q(2)) * SIGM(1)

then it works even when the weights are different.

Thank you for posting this!
Re: Smoothing Spline -- any existing efficient routines? [message #93815 is a reply to message #93512] Wed, 26 October 2016 14:04 Go to previous message
norm.sheppard is currently offline  norm.sheppard
Messages: 1
Registered: October 2016
Junior Member
Thanks, I had the same problem with the weights and your fix worked for me.

On Tuesday, August 9, 2016 at 11:11:06 AM UTC-4, flor...@gmail.com wrote:
> There appears to be a bug in the line
>
> D(1) = Y(1) - LAMBDA * (F(1) * Q(1) + R(1) * Q(2)) * SIGM(0)
>
> I believe the last term should be SIGM(1)
>
> I found that if the weights of the first two points are different, the original code gives erroneous answers; but when they are the same, it works beautifully. However, when I fix that line to
>
> D(1) = Y(1) - LAMBDA * (F(1) * Q(1) + R(1) * Q(2)) * SIGM(1)
>
> then it works even when the weights are different.
>
> Thank you for posting this!
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: Logistic model in COMFIT function
Next Topic: Structures and arrays of structures

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Wed Oct 08 13:36:58 PDT 2025

Total time taken to generate the page: 0.00916 seconds