1 ## Copyright (C) 2003 Willem J. Atsma <watsma@users.sf.net>
3 ## This program is free software; you can redistribute it and/or
4 ## modify it under the terms of the GNU General Public
5 ## License as published by the Free Software Foundation;
6 ## either version 2, or (at your option) any later version.
8 ## This software is distributed in the hope that it will be useful,
9 ## but WITHOUT ANY WARRANTY; without even the implied
10 ## warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 ## PURPOSE. See the GNU General Public License for more
14 ## You should have received a copy of the GNU General Public
15 ## License along with this software; see the file COPYING. If not,
16 ## see <http://www.gnu.org/licenses/>.
19 ## @deftypefn {Function File} {@var{c} =} sym2poly (@var{p}, @var{x})
20 ## Returns the coefficients of the symbolic polynomial expression @var{p}
21 ## as a vector. If there is only one free variable in @var{p} the
22 ## coefficient vector @var{c} is a plain numeric vector. If there is more
23 ## than one free variable in @var{p}, a second argument @var{x} specifies the
24 ## free variable and the function returns a cell vector of symbolic expressions.
25 ## The coefficients correspond to decreasing exponent of the free variable.
32 ## c = sym2poly (x^2+3*x-4); # c = [1,3,-4]
33 ## c = sym2poly (x^2+y*x,x); # c = @{2,y,0@}
36 ## If @var{p} is not a polynomial the result has no warranty.
38 ## @seealso{poly2sym,polyval,roots}
41 ## Created: 18 April 2003
42 ## Changed: 25 April 2003
43 ## Removed the use of differentiate to get to coefficients - round-off
44 ## errors cause problems. Now using newly created sumterms().
45 ## Changed: 6 May 2003
46 ## Removed the attempt to use ldegree(), degree() and coeff() - results
47 ## with these are inconsistent.
49 function c = sym2poly(p,x)
51 BADPOLY_COEFF_LIMIT = 500;
54 ## polynomial is one vpa number
57 error("Argument is not a polynomial.");
63 error("Argument has to be a symbolic expression.")
66 pvars = findsymbols(p);
68 ## It is possible that we get an expression without any symbols.
72 nvars = length(pvars);
74 if nvars>1 && exist("x")!=1
75 error("Symbolic expression has more than 1 free variable; no variable specified.")
82 ## GiNaC has commands to access coefficients directly, but in octave this often
83 ## does not work, because for example x^2 typed in octave results in a
84 ## non-integer power in GiNaC: x^2.0 .
86 [num,den] = numden(p);
87 tmp = findsymbols(den);
90 error("Symbolic expression is a ratio of polynomials.")
95 p_terms = sumterms(p);
96 ## if this is well behaved, I can find the coefficients by dividing with x
98 for i=1:length(p_terms)
100 for j=1:BADPOLY_COEFF_LIMIT
101 if disp(differentiate(tmp,x))=="0"
106 if j==BADPOLY_COEFF_LIMIT
107 printf("Please examine your code or adjust this function.\n");
108 printf("This error may occur because the passed expression is not a polynomial.\n");
109 error("Reached the set limit (%d) for the number of coefficients.",BADPOLY_COEFF_LIMIT)
111 if (length(c_ex)<j) || isempty(c_ex{j})
114 c_ex(j) = c_ex{j}+tmp;
117 order = length(c_ex)-1;
124 cvar=findsymbols(c_ex{i});
125 ncvar = length(cvar);
129 if disp(cvar{j})==disp(x)
130 printf("Possibly this error occurs because two symbols with the same name\n");
131 printf("are different to GiNaC. Make sure the free variable exists as a\n");
132 printf("symbol in your workspace.\n");
133 error("The symbolic expression is not a polynomial.")
139 c_ex = reverse(c_ex);
143 c(1,i)=to_double(c_ex{i});
153 % x=sym("x"); y=sym("y");
155 % assert(sym2poly (x^2+3*x-4), [1,3,-4]);
157 % assert (sym2poly (x^2+y*x,x), {2,y,0})