MathGroup Archive 1998

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Re: Multiplying large polynomials

  • To: mathgroup at smc.vnet.net
  • Subject: [mg14763] Re: [mg14744] Re: Multiplying large polynomials
  • From: Carl Woll <carlw at u.washington.edu>
  • Date: Sat, 14 Nov 1998 03:07:55 -0500
  • Organization: Physics Department, U of Washington
  • References: <7257a7$88m@smc.vnet.net> <199811120717.CAA25067@smc.vnet.net.>
  • Sender: owner-wri-mathgroup at wolfram.com

Hi Allan,

There's a mistake in your large polynomial description

> poly1 =
>       Table[Random[Integer, {1, 50}]h^n, {n, 0, 100}];
>
I think you meant Sum instead of Table. However, this doesn't change the
order of the Timings, so that Tom's method is still the fastest. As you
mentioned, this is due to the length of time Series takes to convert a
simple polynomial into a SeriesData object. Consider the following code
fragment:

In[82]:=
Timing[Do[p1=poly1+O[h]^51,{10}]]
Timing[Do[p2=SeriesData[h,0,CoefficientList[poly1,h],0,51,1],{10}]]
p1===p2

Out[82]=
{9.16 Second,Null}

Out[83]=
{0.11 Second,Null}

Out[84]=
True

where I compare the usual way of converting an expression into a
SeriesData object with just creating the SeriesData object by hand
using CoefficientList. As you can see, the second method is 2 orders of
magnitude faster. I think this is due to the fact that Series works by
really doing a Taylor expansion. That is, Series may actually take 50
derivatives of poly1 to determine the SeriesData object.

Based on the above, the fastest approach is to create the SeriesData
objects by hand, and then multiply the Series expressions. Moreover, if
one will multiply the same SeriesData object more than once, it won't
take long before the approach of converting to Series first wins out,
since multiplying SeriesData objects is very quick. Witness the
following code fragment:

In[90]:=
poly1=Sum[Random[]h^n,{n,0,100}];
poly2=Sum[Random[]h^n,{n,0,100}];
Timing[Do[spoly1=poly1+O[h]^51,{10}]]
Timing[Do[spoly2=poly2+O[h]^51,{10}]] Timing[Do[spoly1
spoly2//Normal,{10}]] Timing[Do[Series[poly1
poly2,{h,0,50}]//Normal,{10}]] Timing[Do[Expand[poly1
poly2]/.h^n_?(#>50&)->0,{10}]]

Out[90]=
{9.25 Second,Null}

Out[91]=
{9.38 Second,Null}

Out[92]=
{0.6 Second,Null}

Out[93]=
{18.9 Second,Null}

Out[94]=
{14. Second,Null}

where multiplying 2 SeriesData objects takes 0.6 seconds, compared to 14
seconds for multiplying out 2 regular polynomial objects.

Carl Woll
Dept of Physics
U of Washington

Allan Hayes wrote:

> Several postings have used Series to do get the answer. In the timings
> below the use of replacement after multiplication (as in Thomas Bell's
> original posting) gives the quickest computation and it appears that
> the difference is because evaluating Series takes a long time (are
> there any memory usage compensations when using Series?)
>
> poly1 = a h^2 + b;
> poly2 = d h + e;
>
> Carl Woll and Rolf Mertig
> Do[(poly1 + O[h]^3 )(poly2 + O[h]^3) // Normal, {100}]//Timing
>
> {0.71 Second, Null}
>
> Ted Ersek
> Do[Series[poly1*poly2, {h, 0, 2}] // Normal, {100}] // Timing
>
> {0.55 Second, Null}
>
> Thomas Bell (Extended)
> Do[Expand[poly1*poly2] /. h^n_?(# > 2 &) -> 0, {100}] // Timing
>
> {0.16 Second, Null}
>
> ** And for larger polynomials**
>
> poly1 =
>     Table[Random[Integer, {1, 50}]h^n, {n, 0, 100}];
>
> poly2 =
>     Table[Random[Integer, {1, 50}]h^n, {n, 0, 100}];
>
> Timing[Do[(poly1 + O[h]^51)(poly2 + O[h]^51) // Normal, {10}]]
>
> {6.59 Second, Null}
>
> Do[Series[poly1*poly2, {h, 0, 50}] // Normal, {10}] // Timing
>
> {3.51 Second, Null}
>
> Do[Expand[poly1*poly2] /. h^n_?(# > 50 &) -> 0, {10}] // Timing
>
> {0.44 Second, Null}
>
> ** Separating out the expansions in the first computation shows that
> most of the time is taken up with the expansions **
>
> Do[(s1 = poly1 + O[h]^51; s2 = poly2 + O[h]^51;), {10}] // Timing
>
> {6.15 Second, Null}
>
> Timing[Do[s1  s2 // Normal, {10}]]
>
> {0.5 Second, Null}
>
> Allan
>
> ---------------------
> Allan Hayes
> Mathematica Training and Consulting
> www.haystack.demon.co.uk
> hay at haystack.demon.co.uk
> Voice: +44 (0)116 271 4198
> Fax: +44 (0)870 164 0565
>
> *******************************************************
>
> Thomas Bell wrote in message <7257a7$88m at smc.vnet.net>...
> >I'm trying to multiply two huge polynomials, and memory is a major
> >concern.  I want to truncate the resulting polynomial to a specified
> >power (N) in one of the variables (h), and I was wondering if it was
> >possible to tell Mathematica to not bother multiplying two terms if the
> >resulting power of h was greater than N.  This is, of course, in the
> >hope that this "automatic truncation" would save time and memory.  For
> >example, if
> >
> >poly1 = a h^2 + b;
> >poly2 = d h + e;
> >N = 2;
> >
> >then I would like to result to be
> >
> >result = a e h^2 + b d h + b e
> >
> >Instead, I have to write
> >
> >result = Expand[poly1 poly2]/.h^3 -> 0;
> >
> >which forces Mathematica to create the enormous product before
> >truncating.  Please cc to tombell at stanford.edu, and thanks in advance
> >for any suggestions.


  • Prev by Date: Re: defining "regions"
  • Next by Date: Contour plot from (x,y,z) numerical data?
  • Previous by thread: Re: Multiplying large polynomials
  • Next by thread: Re: Multiplying large polynomials