comparison doc/interpreter/poly.txi @ 14509:a88f8e4fae56

New Function, splinefit.m * __splinefit__.m: New private file. Jonas Lundgren's splinefit.m with BSD License. Jonas emailed this version to Octave's developers. * splinefit.m: New File. Piece-wise polynomial fit. This is a wrapper for __splinefit__.m. The wrapper allows for Octave's tex-info documentation, demos, and tests to be added. In addition the input syntax has been sligtly modified to allow new options to be added without breaking compatiblity. * doc/splineimages.m: New file to produce splineimages<#> for the docs. * doc/images: Include splineimages.m and the figues for the docs. * scripts/polynomial/module.mk: Add new files. * doc/interpreter/poly.txi: Minimal description of splinefit.
author Ben Abbott <bpabbott@mac.com>
date Thu, 29 Mar 2012 19:13:21 -0400
parents 72c96de7a403
children 8985cbbd2fe4
comparison
equal deleted inserted replaced
14508:0901f926ed50 14509:a88f8e4fae56
130 @section Polynomial Interpolation 130 @section Polynomial Interpolation
131 131
132 Octave comes with good support for various kinds of interpolation, 132 Octave comes with good support for various kinds of interpolation,
133 most of which are described in @ref{Interpolation}. One simple alternative 133 most of which are described in @ref{Interpolation}. One simple alternative
134 to the functions described in the aforementioned chapter, is to fit 134 to the functions described in the aforementioned chapter, is to fit
135 a single polynomial to some given data points. To avoid a highly 135 a single polynomial, or a piecewise polynomial (spline) to some given
136 fluctuating polynomial, one most often wants to fit a low-order polynomial 136 data points. To avoid a highly fluctuating polynomial, one most often
137 to data. This usually means that it is necessary to fit the polynomial 137 wants to fit a low-order polynomial to data. This usually means that it
138 in a least-squares sense, which just is what the @code{polyfit} function does. 138 is necessary to fit the polynomial in a least-squares sense, which just
139 is what the @code{polyfit} function does.
139 140
140 @DOCSTRING(polyfit) 141 @DOCSTRING(polyfit)
141 142
142 In situations where a single polynomial isn't good enough, a solution 143 In situations where a single polynomial isn't good enough, a solution
143 is to use several polynomials pieced together. The function @code{mkpp} 144 is to use several polynomials pieced together. The function
144 creates a piecewise polynomial, @code{ppval} evaluates the function 145 @code{splinefit} fits a peicewise polynomial (spline) to a set of
145 created by @code{mkpp}, and @code{unmkpp} returns detailed information 146 data.
146 about the function. 147
148 @DOCSTRING(splinefit)
149
150 The number of @var{breaks} (or knots) used to construct the piecewise
151 polynomial is a significant factor in suppressing the noise present in
152 the input data, @var{x} and @var{y}. This is demostrated by the example
153 below.
154
155 @example
156 @group
157 x = 2 * pi * rand (1, 200);
158 y = sin (x) + sin (2 * x) + 0.2 * randn (size (x));
159 ## Uniform breaks
160 breaks = linspace (0, 2 * pi, 41); % 41 breaks, 40 pieces
161 pp1 = splinefit (x, y, breaks);
162 ## Breaks interpolated from data
163 pp2 = splinefit (x, y, 10); % 11 breaks, 10 pieces
164 ## Plot
165 xx = linspace (0, 2 * pi, 400);
166 y1 = ppval (pp1, xx);
167 y2 = ppval (pp2, xx);
168 plot (x, y, ".", xx, [y1; y2])
169 axis tight
170 ylim auto
171 legend (@{"data", "41 breaks, 40 pieces", "11 breaks, 10 pieces"@})
172 @end group
173 @end example
174
175 @ifnotinfo
176 @noindent
177 The result of which can be seen in @ref{fig:splinefit1}.
178
179 @float Figure,fig:splinefit1
180 @center @image{splinefit1,4in}
181 @caption{Comparison of a fitting a piecewise polynomial with 41 breaks to one
182 with 11 breaks. The fit with the large number of breaks exhibits a fast ripple
183 that is not present in the underlying function.}
184 @end float
185 @end ifnotinfo
186
187 The piece-wise polynomial fit provided by @code{splinefit} provides
188 continuous derivatives up to the @var{order} of the fit. This can
189 be demonstrated by the code
190
191 @example
192 @group
193 ## Data (200 points)
194 x = 2 * pi * rand (1, 200);
195 y = sin (x) + sin (2 * x) + 0.1 * randn (size (x));
196 ## Piecewise constant
197 pp1 = splinefit (x, y, 8, "order", 0);
198 ## Piecewise linear
199 pp2 = splinefit (x, y, 8, "order", 1);
200 ## Piecewise quadratic
201 pp3 = splinefit (x, y, 8, "order", 2);
202 ## Piecewise cubic
203 pp4 = splinefit (x, y, 8, "order", 3);
204 ## Piecewise quartic
205 pp5 = splinefit (x, y, 8, "order", 4);
206 ## Plot
207 xx = linspace (0, 2 * pi, 400);
208 y1 = ppval (pp1, xx);
209 y2 = ppval (pp2, xx);
210 y3 = ppval (pp3, xx);
211 y4 = ppval (pp4, xx);
212 y5 = ppval (pp5, xx);
213 plot (x, y, ".", xx, [y1; y2; y3; y4; y5])
214 axis tight
215 ylim auto
216 legend (@{"data", "order 0", "order 1", "order 2", "order 3", "order 4"@})
217 @end group
218 @end example
219
220 @ifnotinfo
221 @noindent
222 The result of which can be seen in @ref{fig:splinefit2}.
223
224 @float Figure,fig:splinefit2
225 @center @image{splinefit2,4in}
226 @caption{Comparison of a piecewise constant, linear, quadratic, cubic, and
227 quartic polynomials with 8 breaks to noisey data. The higher order solutions
228 more accurately represent the underlying function, but come with the
229 expense of computational complexity.}
230 @end float
231 @end ifnotinfo
232
233 When the underlying function to provide a fit to is periodice, @code{splitfit}
234 is able to apply the boundary conditions needed to manifest a periodic fit.
235 This is demonstrated by the code below.
236
237 @example
238 @group
239 ## Data (100 points)
240 x = 2 * pi * [0, (rand (1, 98)), 1];
241 y = sin (x) - cos (2 * x) + 0.2 * randn (size (x));
242 ## No constraints
243 pp1 = splinefit (x, y, 10, "order", 5);
244 ## Periodic boundaries
245 pp2 = splinefit (x, y, 10, "order", 5, "periodic", true);
246 ## Plot
247 xx = linspace (0, 2 * pi, 400);
248 y1 = ppval (pp1, xx);
249 y2 = ppval (pp2, xx);
250 plot (x, y, ".", xx, [y1; y2])
251 axis tight
252 ylim auto
253 legend (@{"data", "no constraints", "periodic"@})
254 @end group
255 @end example
256
257 @ifnotinfo
258 @noindent
259 The result of which can be seen in @ref{fig:splinefit3}.
260
261 @float Figure,fig:splinefit3
262 @center @image{splinefit3,4in}
263 @caption{Comparison of piecewise cubic fits to a noisy periodic function with,
264 and without, periodic boundary conditions.}
265 @end float
266 @end ifnotinfo
267
268 More complex constaints may be added as well. For example, the code below
269 illustrates a periodic fit with values that have been clamped end point values
270 and a second periodic fit wihh hinged end point values.
271
272 @example
273 @group
274 ## Data (200 points)
275 x = 2 * pi * rand (1, 200);
276 y = sin (2 * x) + 0.1 * randn (size (x));
277 ## Breaks
278 breaks = linspace (0, 2 * pi, 10);
279 ## Clamped endpoints, y = y" = 0
280 xc = [0, 0, 2*pi, 2*pi];
281 cc = [(eye (2)), (eye (2))];
282 con = struct ("xc", xc, "cc", cc);
283 pp1 = splinefit (x, y, breaks, "constraints", con);
284 ## Hinged periodic endpoints, y = 0
285 con = struct ("xc", 0);
286 pp2 = splinefit (x, y, breaks, "constraints", con, "periodic", true);
287 ## Plot
288 xx = linspace (0, 2 * pi, 400);
289 y1 = ppval (pp1, xx);
290 y2 = ppval (pp2, xx);
291 plot (x, y, ".", xx, [y1; y2])
292 axis tight
293 ylim auto
294 legend (@{"data", "clamped", "hinged periodic"@})
295 @end group
296 @end example
297
298 @ifnotinfo
299 @noindent
300 The result of which can be seen in @ref{fig:splinefit4}.
301
302 @float Figure,fig:splinefit4
303 @center @image{splinefit4,4in}
304 @caption{Comparison of two periodic piecewise cubic fits to a noisy periodic
305 signal. One fit has its end points clamped and the second has its end points
306 hinged.}
307 @end float
308 @end ifnotinfo
309
310 The @code{splinefit} function also provides the convenience of a @var{robust}
311 fitting, where the effect of outlying data is reduced. In the example below,
312 three different fits are provided. Two with differing levels of outlier
313 suppressin and a third illustrating the non-robust solution.
314
315 @example
316 @group
317 ## Data
318 x = linspace (0, 2*pi, 200);
319 y = sin (x) + sin (2 * x) + 0.05 * randn (size (x));
320 ## Add outliers
321 x = [x, linspace(0,2*pi,60)];
322 y = [y, -ones(1,60)];
323 ## Fit splines with hinged conditions
324 con = struct ("xc", [0, 2*pi]);
325 ## Robust fitting, beta = 0.25
326 pp1 = splinefit (x, y, 8, "constraints", con, "beta", 0.25);
327 ## Robust fitting, beta = 0.75
328 pp2 = splinefit (x, y, 8, "constraints", con, "beta", 0.75);
329 ## No robust fitting
330 pp3 = splinefit (x, y, 8, "constraints", con);
331 ## Plot
332 xx = linspace (0, 2*pi, 400);
333 y1 = ppval (pp1, xx);
334 y2 = ppval (pp2, xx);
335 y3 = ppval (pp3, xx);
336 plot (x, y, ".", xx, [y1; y2; y3])
337 legend (@{"data with outliers","robust, beta = 0.25", ...
338 "robust, beta = 0.75", "no robust fitting"@})
339 axis tight
340 ylim auto
341 @end group
342 @end example
343
344 @ifnotinfo
345 @noindent
346 The result of which can be seen in @ref{fig:splinefit6}.
347
348 @float Figure,fig:splinefit6
349 @center @image{splinefit6,4in}
350 @caption{Comparison of two differnet levels of robust fitting (@var{beta} = 0.25 and 0.75) to noisy data combined with outlying data. A standard fit is also included.}
351 @end float
352 @end ifnotinfo
353
354 The function, @code{ppval}, evaluates the piecewise polyomials, created
355 by @code{mkpp} or other means, and @code{unmkpp} returns detailed
356 information about the piecewise polynomial.
147 357
148 The following example shows how to combine two linear functions and a 358 The following example shows how to combine two linear functions and a
149 quadratic into one function. Each of these functions is expressed 359 quadratic into one function. Each of these functions is expressed
150 on adjoined intervals. 360 on adjoined intervals.
151 361