Mercurial > hg > octave-nkf
view scripts/polynomial/pchip.m @ 16195:b52d2f9294b6
use class for reading lexer input
* input.h, input.cc (octave_base_input_reader, octave_terminal_reader,
octave_file_reader, octave_eval_string_reader): New classes.
(octave_gets): Now a member function of octave_base_reader.
(get_user_input): Delete function. Move actions to
octave_terminal_reader::get_input and
octave_eval_string_reader::get_input.
function. Call from octave_file_reader::get_input. Don't check
whether reading an eval string.
(current_eval_string, get_input_from_eval_string): Delete global
variables.
(get_debug_input): Check CURR_LEXER->input_from_eval_string instead of
global get_input_from_eval_string variable. Don't protect
get_input_from_eval_string.
* lex.h (octave_lexer::input_reader): New data member.
(octave_lexer::octave_lexer (void)): Initialize it.
(octave_lexer::octave_lexer (const std::string&),
octave_lexer::octave_lexer (FILE *)): New constructors.
* lex.h, lex.cc (octave_lexer::input_buffer::fill): New function.
(octave_lexer::input_buffer::read): Delete.
(octave_lexer::read): Rename from octave_read. Call reader to get
input, and then hand it to the input_buffer instead of asking the
input buffer to read input. Change all callers.
(octave_lexer::input_source, octave_lexer::input_from_eval_string):
New functions. Call octave_lexer::input_from_eval_string instead of
using get_input_from_eval_string.
* oct-parse.in.yy (octave_parser::octave_parser (FILE *),
octave_parser::octave_parser (const std::string&)): New constructors.
(parse_fcn_file): Pass FILE pointer to octave_parser constructor.
(eval_string): Pass string to octave_parser constructor instead of
setting global current_eval_string variable.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 05 Mar 2013 10:19:51 -0500 |
parents | f3b5cadfd6d5 |
children | 1c89599167a6 |
line wrap: on
line source
## Copyright (C) 2001-2012 Kai Habel ## ## This file is part of Octave. ## ## Octave is free software; you can redistribute it and/or modify it ## under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or (at ## your option) any later version. ## ## Octave is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Octave; see the file COPYING. If not, see ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{pp} =} pchip (@var{x}, @var{y}) ## @deftypefnx {Function File} {@var{yi} =} pchip (@var{x}, @var{y}, @var{xi}) ## Return the Piecewise Cubic Hermite Interpolating Polynomial (pchip) of ## points @var{x} and @var{y}. ## ## If called with two arguments, return the piecewise polynomial @var{pp} ## that may be used with @code{ppval} to evaluate the polynomial at specific ## points. When called with a third input argument, @code{pchip} evaluates ## the pchip polynomial at the points @var{xi}. The third calling form is ## equivalent to @code{ppval (pchip (@var{x}, @var{y}), @var{xi})}. ## ## The variable @var{x} must be a strictly monotonic vector (either ## increasing or decreasing) of length @var{n}. @var{y} can be either a ## vector or array. If @var{y} is a vector then it must be the same length ## @var{n} as @var{x}. If @var{y} is an array then the size of @var{y} must ## have the form ## @tex ## $$[s_1, s_2, \cdots, s_k, n]$$ ## @end tex ## @ifnottex ## @code{[@var{s1}, @var{s2}, @dots{}, @var{sk}, @var{n}]} ## @end ifnottex ## The array is reshaped internally to a matrix where the leading ## dimension is given by ## @tex ## $$s_1 s_2 \cdots s_k$$ ## @end tex ## @ifnottex ## @code{@var{s1} * @var{s2} * @dots{} * @var{sk}} ## @end ifnottex ## and each row of this matrix is then treated separately. Note that this ## is exactly opposite to @code{interp1} but is done for @sc{matlab} ## compatibility. ## ## @seealso{spline, ppval, mkpp, unmkpp} ## @end deftypefn ## Author: Kai Habel <kai.habel@gmx.de> ## Date: 9. mar 2001 ## ## S_k = a_k + b_k*x + c_k*x^2 + d_k*x^3; (spline polynom) ## ## 4 conditions: ## S_k(x_k) = y_k; ## S_k(x_k+1) = y_k+1; ## S_k'(x_k) = y_k'; ## S_k'(x_k+1) = y_k+1'; function ret = pchip (x, y, xi) if (nargin < 2 || nargin > 3) print_usage (); endif ## make row vector x = x(:).'; n = length (x); ## Check the size and shape of y if (isvector (y)) y = y(:).'; ##row vector szy = size (y); if (! size_equal (x, y)) error ("pchip: length of X and Y must match"); endif else szy = size (y); if (n != szy(end)) error ("pchip: length of X and last dimension of Y must match"); endif y = reshape (y, [prod(szy(1:end-1)), szy(end)]); endif h = diff (x); if (all (h < 0)) x = fliplr (x); h = diff (x); y = fliplr (y); elseif (any (h <= 0)) error ("pchip: X must be strictly monotonic"); endif f1 = y(:, 1:n-1); ## Compute derivatives. d = __pchip_deriv__ (x, y, 2); d1 = d(:, 1:n-1); d2 = d(:, 2:n); ## This is taken from SLATEC. h = diag (h); delta = diff (y, 1, 2) / h; del1 = (d1 - delta) / h; del2 = (d2 - delta) / h; c3 = del1 + del2; c2 = -c3 - del1; c3 = c3 / h; coeffs = cat (3, c3, c2, d1, f1); ret = mkpp (x, coeffs, szy(1:end-1)); if (nargin == 3) ret = ppval (ret, xi); endif endfunction %!demo %! x = 0:8; %! y = [1, 1, 1, 1, 0.5, 0, 0, 0, 0]; %! xi = 0:0.01:8; %! yspline = spline (x,y,xi); %! ypchip = pchip (x,y,xi); %! title ("pchip and spline fit to discontinuous function"); %! plot (xi,yspline, xi,ypchip,"-", x,y,"+"); %! legend ("spline", "pchip", "data"); %! %------------------------------------------------------------------- %! % confirm that pchip agreed better to discontinuous data than spline %!shared x, y, y2, pp, yi1, yi2, yi3 %! x = 0:8; %! y = [1, 1, 1, 1, 0.5, 0, 0, 0, 0]; %!assert (pchip (x,y,x), y) %!assert (pchip (x,y,x'), y') %!assert (pchip (x',y',x'), y') %!assert (pchip (x',y',x), y) %!assert (isempty (pchip (x',y',[]))) %!assert (isempty (pchip (x,y,[]))) %!assert (pchip (x,[y;y],x), [pchip(x,y,x);pchip(x,y,x)]) %!assert (pchip (x,[y;y],x'), [pchip(x,y,x);pchip(x,y,x)]) %!assert (pchip (x',[y;y],x), [pchip(x,y,x);pchip(x,y,x)]) %!assert (pchip (x',[y;y],x'), [pchip(x,y,x);pchip(x,y,x)]) %!test %! x = (0:8)*pi/4; y = [sin(x); cos(x)]; %! y2(:,:,1) = y; y2(:,:,2) = y+1; y2(:,:,3) = y-1; %! pp = pchip (x, shiftdim (y2,2)); %! yi1 = ppval (pp, (1:4)*pi/4); %! yi2 = ppval (pp, repmat ((1:4)*pi/4, [5,1])); %! yi3 = ppval (pp, [pi/2,pi]); %!assert (size (pp.coefs), [48,4]) %!assert (pp.pieces, 8) %!assert (pp.order, 4) %!assert (pp.dim, [3,2]) %!assert (ppval (pp,pi), [0,-1;1,0;-1,-2], 1e-14) %!assert (yi3(:,:,2), ppval (pp,pi), 1e-14) %!assert (yi3(:,:,1), [1,0;2,1;0,-1], 1e-14) %!assert (squeeze (yi1(1,2,:)), [1/sqrt(2); 0; -1/sqrt(2);-1], 1e-14) %!assert (size (yi2), [3,2,5,4]) %!assert (squeeze (yi2(1,2,3,:)), [1/sqrt(2); 0; -1/sqrt(2);-1], 1e-14) %!error (pchip (1,2)); %!error (pchip (1,2,3));