diff scripts/polynomial/mkpp.m @ 12608:59e2460acae1

make piecewise polynomial (pp) functions more compatible
author Kai Habel <kai.habel@gmx.de>
date Wed, 23 Feb 2011 08:11:40 +0100
parents c792872f8942
children e81ddf9cacd5
line wrap: on
line diff
--- a/scripts/polynomial/mkpp.m
+++ b/scripts/polynomial/mkpp.m
@@ -17,50 +17,66 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {@var{pp} =} mkpp (@var{x}, @var{p})
-## @deftypefnx {Function File} {@var{pp} =} mkpp (@var{x}, @var{p}, @var{d})
+## @deftypefn  {Function File} {@var{pp} =} mkpp (@var{breaks}, @var{coefs})
+## @deftypefnx {Function File} {@var{pp} =} mkpp (@var{breaks}, @var{coefs}, @var{d})
+##
+## Construct a piece-wise polynomial (pp) structure from sample points
+## @var{breaks} and coefficients @var{coefs}.  @var{breaks} must be a vector of
+## strictly increasing values. The number of intervals is given by 
+## @code{@var{ni} = length (@var{breaks}) - 1}.
+## When @var{m} is the polynomial order @var{coefs} must be of 
+## size: @var{ni} x @var{m} + 1.
 ##
-## Construct a piecewise polynomial structure from sample points
-## @var{x} and coefficients @var{p}.  The i-th row of @var{p},
-## @code{@var{p} (@var{i},:)}, contains the coefficients for the polynomial
-## over the @var{i}-th interval, ordered from highest to
-## lowest.  There must be one row for each interval in @var{x}, so
-## @code{rows (@var{p}) == length (@var{x}) - 1}.
+## The i-th row of @var{coefs},
+## @code{@var{coefs} (@var{i},:)}, contains the coefficients for the polynomial
+## over the @var{i}-th interval, ordered from highest (@var{m}) to 
+## lowest (@var{0}).
 ##
-## @var{p} may also be a multi-dimensional array, specifying a vector-valued
-## or array-valued polynomial.  The shape is determined by @var{d}.  If @var{d}
-## is
-## not given, the default is @code{size (p)(1:end-2)}.  If @var{d} is given, the
-## leading dimensions of @var{p} are reshaped to conform to @var{d}.
+## @var{coefs} may also be a multi-dimensional array, specifying a vector-valued
+## or array-valued polynomial. In that case the polynomial order is defined
+## by the length of the last dimension of @var{coefs}.
+## The size of first dimension(s) are given by the scalar or
+## vector @var{d}. If @var{d} is not given it is set to @code{1}. 
+## In any case @var{coefs} is reshaped to a 2d matrix of
+## size @code{[@var{ni}*prod(@var{d} @var{m})] }
 ##
 ## @seealso{unmkpp, ppval, spline}
 ## @end deftypefn
 
 function pp = mkpp (x, P, d)
+
+  # check number of arguments
   if (nargin < 2 || nargin > 3)
     print_usage ();
   endif
-  pp.x = x(:);
-  n = length (x) - 1;
-  if (n < 1)
+
+  # check x
+  if (length (x) < 2)
     error ("mkpp: at least one interval is needed");
   endif
-  nd = ndims (P);
-  k = size (P, nd);
-  if (nargin < 3)
-    if (nd == 2)
-      d = 1;
-    else
-      d = prod (size (P)(1:nd-1));
-    endif
+
+  if (!isvector (x))
+    error ("mkpp: x must be a vector");
   endif
-  pp.d = d;
-  pp.P = P = reshape (P, prod (d), [], k);
-  pp.orient = 0;
+
+  len = length (x) - 1;
+  dP = length (size (P));
 
-  if (size (P, 2) != n)
-    error ("mkpp: num intervals in X doesn't match num polynomials in P");
-  endif
+  pp = struct ("form", "pp",
+               "breaks", x(:).',
+               "coefs", [],
+               "pieces", len,
+               "order", prod (size (P)) / len,
+               "dim", 1);
+
+  if (nargin == 3)
+    pp.dim = d;
+    pp.order /= prod (d);
+  endif 
+
+  dim_vec = [pp.pieces * prod(pp.dim), pp.order];
+  pp.coefs = reshape (P, dim_vec);
+
 endfunction
 
 %!demo # linear interpolation
@@ -72,3 +88,25 @@
 %! xi=linspace(0,pi,50);
 %! plot(x,t,"x",xi,ppval(pp,xi));
 %! legend("control","interp");
+
+%!shared b,c,pp
+%! b = 1:3; c = 1:24; pp=mkpp(b,c);
+%!assert (pp.pieces,2);
+%!assert (pp.order,12);
+%!assert (pp.dim,1);
+%!assert (size(pp.coefs),[2,12]);
+%! pp=mkpp(b,c,2);
+%!assert (pp.pieces,2);
+%!assert (pp.order,6);
+%!assert (pp.dim,2);
+%!assert (size(pp.coefs),[4,6]);
+%! pp=mkpp(b,c,3);
+%!assert (pp.pieces,2);
+%!assert (pp.order,4);
+%!assert (pp.dim,3);
+%!assert (size(pp.coefs),[6,4]);
+%! pp=mkpp(b,c,[2,3]);
+%!assert (pp.pieces,2);
+%!assert (pp.order,2);
+%!assert (pp.dim,[2,3]);
+%!assert (size(pp.coefs),[12,2]);