Skip to content

savgolmat

Returns the Savitzky-Golay filter coefficients as a 2-D array.

savgolmat computes the same coefficients that savgol uses, but returns them instead of filtering a signal. It gives all the derivatives at once, so the kernels can be inspected, plotted, or applied to data with other opcodes.

Syntax

imat[][] = savgolmat(iwinsize, iorder [, idelta])
imat[][] savgolmat iwinsize, iorder [, idelta]

Initialization

iwinsize -- the number of samples in the window. It must be odd and at least 3.

iorder -- the degree of the fitted polynomial, from 0 to iwinsize - 1.

idelta (optional, default 1) -- the spacing between two samples. Row d of the result is scaled by 1 / ideltad, so with the default of 1 the derivatives are per sample. It must be greater than 0.

imat -- an array of iorder + 1 rows and iwinsize columns. Row d holds the coefficients that give the d-th derivative of the fitted polynomial at the centre of the window, already multiplied by d!. Row 0 is the smoothing kernel. The columns go from the oldest sample of the window to the newest.

The dot product of row d with iwinsize consecutive samples gives what savgol outputs with ideriv = d for that window. Even rows are symmetric and odd rows are antisymmetric.

Invalid values cause an initialization error.

Examples

This example prints the kernels for a window of 5 samples and order 2. Row 0 is the classic [-3, 12, 17, 12, -3] / 35 smoothing kernel. It then applies each row to five samples of a parabola and recovers its value, slope and curvature at the centre. It uses the file savgolmat.csd.

Printing and applying the Savitzky-Golay kernels.
<CsoundSynthesizer>
<CsOptions>
-n -d -m0
</CsOptions>
<CsInstruments>
sr = 48000
ksmps = 32
nchnls = 1
0dbfs = 1

; savgolmat returns the Savitzky-Golay kernels as a 2-D array: one row per
; derivative, one column per sample of the window, oldest sample first.

instr 1
  kernels:i[][] = savgolmat(5, 2)

  ; row 0 smooths, row 1 gives the slope, row 2 the curvature.
  ; Each row is printed as integers over a common denominator.
  denom:i[] = fillarray(35, 10, 7)
  row:i = 0
  while row < lenarray(kernels, 1) do
    d:i = denom[row]
    prints("row %d: [%3d %3d %3d %3d %3d] / %d\n", row, \
           round(kernels[row][0] * d), round(kernels[row][1] * d), \
           round(kernels[row][2] * d), round(kernels[row][3] * d), \
           round(kernels[row][4] * d), d)
    row += 1
  od

  ; Applied by hand to five samples of y = x^2 taken at x = 1 .. 5, the
  ; kernels recover the parabola at the centre (x = 3) exactly:
  ; y = 9, y' = 2x = 6, y'' = 2.
  samples:i[] = fillarray(1, 4, 9, 16, 25)
  row = 0
  while row < 3 do
    acc:i = 0
    col:i = 0
    while col < 5 do
      acc += kernels[row][col] * samples[col]
      col += 1
    od
    prints("derivative %d at the centre: %g\n", row, acc)
    row += 1
  od
endin
</CsInstruments>
<CsScore>
i 1 0 0
e
</CsScore>
</CsoundSynthesizer>

Its output is:

row 0: [ -3  12  17  12  -3] / 35
row 1: [ -2  -1   0   1   2] / 10
row 2: [  2  -1  -2  -1   2] / 7
derivative 0 at the centre: 9
derivative 1 at the centre: 6
derivative 2 at the centre: 2

See also

Specialized Filters

savgol

Credits

Author: Pasquale Mainolfi
Italy
New in Csound version 7.0
October 2026