X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?p=CreaPhase.git;a=blobdiff_plain;f=octave_packages%2Fm%2Fpolynomial%2Fpolygcd.m;fp=octave_packages%2Fm%2Fpolynomial%2Fpolygcd.m;h=5b763e1540f58c15e3bb00e065b1745eb0e3dab3;hp=0000000000000000000000000000000000000000;hb=1c0469ada9531828709108a4882a751d2816994a;hpb=63de9f36673d49121015e3695f2c336ea92bc278 diff --git a/octave_packages/m/polynomial/polygcd.m b/octave_packages/m/polynomial/polygcd.m new file mode 100644 index 0000000..5b763e1 --- /dev/null +++ b/octave_packages/m/polynomial/polygcd.m @@ -0,0 +1,102 @@ +## Copyright (C) 2000-2012 Paul Kienzle +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{q} =} polygcd (@var{b}, @var{a}) +## @deftypefnx {Function File} {@var{q} =} polygcd (@var{b}, @var{a}, @var{tol}) +## +## Find the greatest common divisor of two polynomials. This is equivalent +## to the polynomial found by multiplying together all the common roots. +## Together with deconv, you can reduce a ratio of two polynomials. +## The tolerance @var{tol} defaults to @code{sqrt(eps)}. +## +## @strong{Caution:} This is a numerically unstable algorithm and should not +## be used on large polynomials. +## +## Example code: +## +## @example +## @group +## polygcd (poly (1:8), poly (3:12)) - poly (3:8) +## @result{} [ 0, 0, 0, 0, 0, 0, 0 ] +## deconv (poly (1:8), polygcd (poly (1:8), poly (3:12))) - poly(1:2) +## @result{} [ 0, 0, 0 ] +## @end group +## @end example +## @seealso{poly, roots, conv, deconv, residue} +## @end deftypefn + +function x = polygcd (b, a, tol) + + if (nargin == 2 || nargin == 3) + if (nargin == 2) + if (isa (a, "single") || isa (b, "single")) + tol = sqrt (eps ("single")); + else + tol = sqrt (eps); + endif + endif + if (length (a) == 1 || length (b) == 1) + if (a == 0) + x = b; + elseif (b == 0) + x = a; + else + x = 1; + endif + else + a /= a(1); + while (1) + [d, r] = deconv (b, a); + nz = find (abs (r) > tol); + if (isempty (nz)) + x = a; + break; + else + r = r(nz(1):length(r)); + endif + b = a; + a = r / r(1); + endwhile + endif + else + print_usage (); + endif + +endfunction + + +%!test +%! poly1 = [1 6 11 6]; % (x+1)(x+2)(x+3) +%! poly2 = [1 3 2]; % (x+1)(x+2) +%! poly3 = polygcd (poly1, poly2); +%! assert (poly3, poly2, sqrt (eps)) + +%!test +%! assert (polygcd (poly(1:8), poly(3:12)), poly(3:8), sqrt (eps)) + +%!test +%! assert (deconv (poly(1:8), polygcd (poly(1:8), poly(3:12))), poly(1:2), sqrt (eps)) + +%!test +%! for ii=1:10 +%! p = (unique (randn (10, 1)) * 10).'; +%! p1 = p(3:end); +%! p2 = p(1:end-2); +%! assert (polygcd (poly (-p1), poly (-p2)), poly (- intersect (p1, p2)), sqrt (eps)) +%! endfor