Discussion:
collecting terms
Fabrizio Caruso
2005-01-14 23:16:16 UTC
Permalink
Dear Maxima forum

I am looking for a command that collects all the terms
of a polynomial w.r.t. a variable, i.e. it writes the polynomial
as a sum of monomials with increasing/decreasing powers of
a given variable.
Is there one?

In the attempt to find such command I tried
expandwrt, which unfortunately does something else.

expandwrt in my case also produces the
following warning/error message:

Given

t : (x+1)^4 + a*(x+1)^2+b*(x+1)+c;

Then
expandwrt(t,x)

produces:

; In: LAMBDA (FILE &AUX *LOAD-VERBOSE* TEM TRIED)

; (LET (# #) (DECLARE #) (SETQ TEM #) (AND TEM #))
; ==>
; (COMMON-LISP:LET (# #)
; (DECLARE #)
; (SETQ TEM #)
; (AND TEM #))
; Note: Variable IN defined but never used.
;
; #'(LAMBDA (FILE &AUX *LOAD-VERBOSE* TEM TRIED) (BLOCK $ALOAD_MAC #))
; Note: Variable TRIED defined but never used.
; Warning - you are redefining the MACSYMA function INTERSECTION

followed by the output.


Regards

Fabrizio Caruso
Valery Pipin
2005-01-15 16:17:26 UTC
Permalink
On Saturday 15 January 2005 07:16, Fabrizio Caruso wrote:
FC> t :  (x+1)^4 + a*(x+1)^2+b*(x+1)+c;
FC>
Please look at demo(facexp);

(%i2) load(facexp);

Warning - you are redefining the MACSYMA function INTERSECTION
(%o2) ?\/usr\/share\/maxima\/5\.9\.1\/share\/simplification\/facexp\.mac
(%i3) t : (x+1)^4 + a*(x+1)^2+b*(x+1)+c;

(%o3) (x+1)^4+a*(x+1)^2+b*(x+1)+c
(%i4) collecttermsl(expand(t),[x,x^2,x^3,x^4]);

(%o4) x^4+4*x^3+(a+6)*x^2+(b+2*a+4)*x+c+b+a+1

rgds,
Valery
Richard Fateman
2005-01-15 16:28:39 UTC
Permalink
try ratexpand.
you might arrange the variables differently by
using ratvars.
Post by Fabrizio Caruso
Dear Maxima forum
I am looking for a command that collects all the terms
of a polynomial w.r.t. a variable, i.e. it writes the polynomial
as a sum of monomials with increasing/decreasing powers of
a given variable.
Is there one?
Boris Gaertner
2005-01-15 20:23:32 UTC
Permalink
Post by Fabrizio Caruso
I am looking for a command that collects all the terms
of a polynomial w.r.t. a variable, i.e. it writes the polynomial
as a sum of monomials with increasing/decreasing powers of
a given variable.
Is there one?
you may find a definition like this one useful:

rewriteAsPolynomialIn (p, t) :=
block ([expanded, degreeInT, result],
expanded : expand(p),
degreeInT: hipow(expanded, t),
result : 0,
for idx : 0 thru degreeInT do
result : result + t^idx*ratcoeff(expanded, t, idx),
result
);

Usage:
t : (x+1)^4 + a*(x+1)^2+b*(x+1)+c;
rewriteAsPolynomialIn(t, x);


Are there better solutions?

Greetings, Boris
Barton Willis
2005-01-15 20:57:34 UTC
Permalink
After expanding, the polynomial is in general form. For a polynomial
in general form, I suggest that you use 'coeff' instead of 'ratcoeff' to
find its coefficients. For some cases, coeff will be faster. Consider

(%i1) p : sum(k * x^k,k,1,7000)$
Evaluation took 46.12 seconds (46.12 elapsed)

(%i2) sum(coeff(p,x,k),k,5000,5099)$
Evaluation took 0.87 seconds (0.87 elapsed)

(%i3) sum(ratcoeff(p,x,k),k,5000,5099)$
Evaluation took 27.03 seconds (27.03 elapsed)


Barton
Barton Willis
2005-01-16 15:26:44 UTC
Permalink
<FONT face="Default Sans Serif, Verdana, Arial, Helvetica, sans-serif" size=2><FONT face="Default Sans Serif, Verdana, Arial, Helvetica, sans-serif" size=2><FONT face="Default Sans Serif, Verdana, Arial, Helvetica, sans-serif" size=2><DIV>...even on an expanded general form expression, there are reasons to<BR>use 'ratcoeff' instead of 'coeff'</DIV><DIV>&nbsp;</DIV><DIV>(%i2) p : 6/((a+b)*x);<BR>(%o2) 6/((b+a)*x)</DIV><DIV> <BR>&nbsp;</DIV><DIV>(%i3) coeff(p,x,-1);<BR>(%o3) 6/(b+a)</DIV><DIV> <BR>&nbsp;</DIV><DIV>(%i4) coeff(expand(p),x,-1);<BR>(%o4) 0</DIV><DIV> <BR>&nbsp;</DIV><DIV>(%i5) ratcoeff(rat(p,a),x,-1);<BR>(%o5) 6/(b+a)</DIV><DIV><BR>So don't take my suggestion to&nbsp;use 'coeff' instead of 'ratcoeff'&nbsp;too seriously; other<BR>considerations are likely more important.</DIV><DIV>&nbsp;</DIV><DIV>Barton<BR></DIV></FONT></FONT></FONT>
Stavros Macrakis
2005-01-16 15:51:28 UTC
Permalink
As soon as you use ratcoeff, your result will be fully expanded, e.g.

ratcoeff( x * (2*y+1)^23, x, 1) => 8388608*y^23 + ...

I don't know if there is any built-in function which is half-way
between coeff and ratcoeff, expanding only as much as necessary to
extract the coefficients.

But back to the original question, perhaps all you want is rat(...,var), e.g.:

t : (x+1)^4 + a*(x+1)^2+b*(x+1)+c;

rat(t,x) =>

x^4+4*x^3+(a+6)*x^2+(b+2*a+4)*x+C+b+a+1

-s
Stavros Macrakis
2005-01-16 18:46:52 UTC
Permalink
Here is a simple way to re-express something as a polynomial in var:

polyform(expr,var):= ev(ratdisrep(rat(isolate(expr,var),var)),eval);

If there are non-polynomial parts, they end up in the 0th order
(constant) polynomial term.

I don't much like the way it uses "ev" to substitute back the
E-variables, but I don't know any simple way of making that cleaner.
This means that the variables in your expression should not have been
assigned values.

Here are some examples comparing polyform to rat:

ex: x*(y+1)^3-(x+1)*a;

rat(ex,x) => (y^3+3*y^2+3*y-a+1)*x-a
-- expands y subexpression unnecessarily
polyform(ex,x) => x*((y+1)^3-a)-a
-- does not expand y terms

rat(ex,y) => x*y^3+3*x*y^2+3*x*y+(-a+1)*x-a
-- canonicalizes x terms
polyform(ex,y) => x*y^3+3*x*y^2+3*x*y-a*(x+1)+x
-- does not combine x terms

rat(ex,a) => (-x-1)*a+x*y^3+3*x*y^2+3*x*y+x
polyform(ex,a) => x*(y+1)^3+a*(-x-1)
-- does not expand
-- though the a^1 term does not appear first, the exprssion
-- is nonetheless a polynomial in a.
-- This has to do with Maxima's variable order canonicalization

rat(ex,xxx) => x*y^3+3*x*y^2+3*x*y+(-a+1)*x-a
-- expands unnecessarily
polyform(ex,xxx) => x*(y+1)^3-a*(x+1)
-- leaves expression untouched
Stavros Macrakis
2005-01-16 18:48:08 UTC
Permalink
To suppress display of intermediate results:

polyform(expr,var):=
block([dispflag:false],
ev(ratdisrep(rat(isolate(expr,var),var)),eval))$
Richard Fateman
2005-01-16 19:30:33 UTC
Permalink
I don't understand the continuing discussion on this point.
What Stavros has written does not provide an expression
as a SUM OF MONOMIALS, which was the original request.

So far as I can tell, RATEXPAND does exactly, precisely,
what was requested, in that an expression is translated into
a SUM of MONOMIALS. The only remaining requirement is
the ordering.

Since Maxima has its own way of ordering terms, you can insist
on your own in a few ways; e.g. by ratvars() and simp:off,
or by picking out the terms in a sorted list.

Perhaps the simplest way of doing the latter is something like


e1:ratexpand(%);
makelist(coeff(e1,x,i),i,0,hipow(e1,x));

though a faster way would be to make the expression e1 into
a list and then use sort.


For an expression with N terms, ratexpand is like
N calls to ratcoeff, except it is hugely faster.

Am I missing something that ratexpand DOESN'T do the job?
RJF
Post by Stavros Macrakis
polyform(expr,var):= ev(ratdisrep(rat(isolate(expr,var),var)),eval);
If there are non-polynomial parts, they end up in the 0th order
(constant) polynomial term.
I don't much like the way it uses "ev" to substitute back the
E-variables, but I don't know any simple way of making that cleaner.
This means that the variables in your expression should not have been
assigned values.
ex: x*(y+1)^3-(x+1)*a;
rat(ex,x) => (y^3+3*y^2+3*y-a+1)*x-a
-- expands y subexpression unnecessarily
polyform(ex,x) => x*((y+1)^3-a)-a
-- does not expand y terms
rat(ex,y) => x*y^3+3*x*y^2+3*x*y+(-a+1)*x-a
-- canonicalizes x terms
polyform(ex,y) => x*y^3+3*x*y^2+3*x*y-a*(x+1)+x
-- does not combine x terms
rat(ex,a) => (-x-1)*a+x*y^3+3*x*y^2+3*x*y+x
polyform(ex,a) => x*(y+1)^3+a*(-x-1)
-- does not expand
-- though the a^1 term does not appear first, the exprssion
-- is nonetheless a polynomial in a.
-- This has to do with Maxima's variable order canonicalization
rat(ex,xxx) => x*y^3+3*x*y^2+3*x*y+(-a+1)*x-a
-- expands unnecessarily
polyform(ex,xxx) => x*(y+1)^3-a*(x+1)
-- leaves expression untouched
_______________________________________________
Maxima mailing list
http://www.math.utexas.edu/mailman/listinfo/maxima
Stavros Macrakis
2005-01-16 20:54:56 UTC
Permalink
On Sun, 16 Jan 2005 11:30:33 -0800, Richard Fateman
Post by Richard Fateman
I don't understand the continuing discussion on this point.
What Stavros has written does not provide an expression
as a SUM OF MONOMIALS, which was the original request.
I think we will simply have to await clarification from Fabrizio on
what exactly he wants. What is and isn't a monomial depends on what
you're defining as the coefficient ring, doesn't it? If you have a
(univariate) polynomial in x with coefficients in the ring of
polynomials in y over the integers, then (y+1)*x is a monomial. If on
the other hand, you have a bivariate polynomial. in x and y, then it
is not: it is the sum of the monomials x*y and y.

I agree that Ratexpand (with the appropriate ratvar ordering) may well
be what he wants. Ratexpand is just a very thin wrapper on top of
Rat, anyway -- but doesn't allow specifying variable order.

In fact, Rat(...,var) may be what he wants since it allows specifying
the variable odering. In General Representation, the ordering of
variables is global, so it's not possible to have a simplified
expression like

[x+y , <-- expanded w.r.t. x
y+x ] <-- expanded w.r.t. y

whereas CRE does support it:

[ rat(x+y,x), rat(x+y,y) ]

In fact, the polyform function uses rat; it simply avoids
unnecessarily expanding the coefficients.
Fabrizio Caruso
2005-02-14 17:39:36 UTC
Permalink
Dear Maxima-Mailing List

I have a very basic problem:

Is there a command to convert
a list of lists into a matrix?

More generally, is there a way
to convert a list into a sequence,
i.e.:
[a,b,c] -> a,b,c

Or having a list [a_1, ... a_n],
how can I apply this "list" to
a function that takes as input
an arbitrary length "sequence" a_1,...,a_n ,
as for instance the function "matrix"?

Thanks again

Fabrizio
Stavros Macrakis
2005-02-14 20:08:27 UTC
Permalink
On Mon, 14 Feb 2005 18:39:36 +0100 (CET), Fabrizio Caruso
Is there a command to convert a list of lists into a matrix?
apply('matrix,[[a,b],[c,d]]);

or in general

apply('f,[a,b,c]) => f(a,b,c)
Fabrizio Caruso
2005-02-15 15:43:37 UTC
Permalink
Hi all

I am writing some routines that
do something with matrices and
in order to do this
I don't know whether I should use
(1) lists
(2) arrays
(3) matrices (are they still supported?)

If I have understood well, arrays
should allow me to select elements
in constant time.
Is it always so? Even for arrays
defined as make_array('any,size)?

Lists, instead, are implemented
as linked lists and selecting one
element takes linear time.

Maxima also has a built-in type
for matrices but I haven't been
able to find much about it
in the in line documentation.
For instance I don't know how
to read off the size of matrix.
Is there anything like arrayinfo
that works for matrices?
As a consequence I don't know
how to convert an uknown size
matrix into a list of lists.

Regards

Fabrizio
Stavros Macrakis
2005-02-15 16:21:01 UTC
Permalink
Maxima supports lists and matrices as first-class objects, well
integrated into the overall structure and semantics of the system.
Arrays, on the other hand, are a low-level construct with semantics
which are idiosyncratic at best. I do not recommend using arrays
unless efficiency is a real problem (not an imagined or projected
problem) because they are very badly integrated into Maxima as a
whole. So I strongly recommend you avoid arrays and stick with lists,
lists of lists, and matrices.

Lists are of the form [a, b, ...]. The empty list = the list of
length 0 = []. Lists can have arbitrary objects as elements,
including other lists.

Matrices are of the form matrix( [a, b, ...], [g, h, ...], ...). All
rows must be of the same length. Matrices can have arbitrary objects
as elements. Each row of a matrix is a list.

Lists and matrices are both mutable objects, that is, you can modify
parts of them in place. (Note that this is *not* true of most Maxima
objects.) They can be assigned or locally bound to variables, passed
as function parameters, and returned as function results. They can be
printed out and read in.

If M is a matrix, the list of rows is args(M). The list of columns is
args(transpose(M)). Note that transpose must create a new copy of the
matrix, and so is not very efficient. Element m,n is M[m,n]. Row n is
M[n]. Column n is col(M,n). Rows can be assigned to (e.g.
M[2]:[q,r]), but columns cannot. The number of rows in a matrix is
length(M). The number of columns is length(M[1]).

Hope this helps.

-s

Robert Dodier
2005-02-15 01:11:19 UTC
Permalink
Post by Fabrizio Caruso
Is there a command to convert
a list of lists into a matrix?
Yes, you want the "apply" function.
"apply (f, [a, b, c])" is like calling "f(a, b, c)".

(%i1) l: [[a, b, c], [d, e, f]];
(%o1) [[a, b, c], [d, e, f]]
(%i2) apply (matrix, l);
[ a b c ]
(%o2) [ ]
[ d e f ]
Post by Fabrizio Caruso
Or having a list [a_1, ... a_n],
how can I apply this "list" to
a function that takes as input
an arbitrary length "sequence" a_1,...,a_n ,
as for instance the function "matrix"?
I'm not sure I understand completely, but I believe "apply"
is what you want.

(%i1) apply (min, [2, -1, 3, 5]);
(%o1) - 1
(%i2) apply ("+", [a, b, c, d]);
(%o2) d + c + b + a

Hope this helps,
Robert Dodier





__________________________________
Do you Yahoo!?
All your favorites on one personal page � Try My Yahoo!
http://my.yahoo.com
Loading...