DMUG-Archiv 1998

Frühere

 

Chronologischer Index

 

Spätere

Vorherige

 

Thematischer Index

 

Nächste

Rechenzeiten und Pattern

Liebe Mathematica-User,

ich habe ein Problem mit der Rechenzeit beim Multiplizieren zweier
Polynome. Die Polynome haben Funktionen als Koeffizienten (n[] und CI[]). 
Es ist eine Funktionalgleichung bekannt, die fuer n[]*CI[] und CI[]+CI[]
wieder Werte von CI[] liefert. In dem Beispiel ist der Einfachheit halber
CI[x]*n[y] = CI[x*y] und CI[x]+CI[y] = CI[x+y]. 

Die naheliegende Erweiterung von Plus durch 
 Plus[x_CI,y_CI] := CI[(Identity@@x) + (Identity@@y)]
fuehrt jedoch zu enormen Rechenzeiten (Out[13] im Vergleich zu 
Out[8]+Out[9]).

Schneller geht es mit Definition einer eigenen Funktion plus 
(In[6], In[7]), die im wesentlichen wieder auf das Original-Plus 
zurueckgreift.

Meine Fragen: 
Warum wird Mathematica durch die Umdefinition von Plus derart aus 
dem Tritt gebracht? 
Warum passiert das nicht auch bei der Umdefinition von Times (In[4])? 
Was ist grundsaetzlich bei der Definition von Funktionen mit Pattern 
zu beachten um kurze Rechenzeiten zu erreichen?


Mathematica 3.0 for IBM RISC System/6000
Copyright 1988-97 Wolfram Research, Inc.
 -- Terminal graphics initialized -- 

(* Definition der beiden Polynome *)

In[1]:= f = z^3*CI[1] + z^5*CI[2] + z^4*CI[3]

         3          5          4
Out[1]= z  CI[1] + z  CI[2] + z  CI[3]

In[2]:= g = n[4] + z^1*n[5] + z^5*n[6] + z^7*n[7]

                         5         7
Out[2]= n[4] + z n[5] + z  n[6] + z  n[7]

(* Definition der Multiplikation CI[x]*n[y]=CI[x*y] *)

In[3]:= Unprotect[Times];

In[4]:= Times[x_CI,y_n] := CI[(Identity@@x) (Identity@@y)];

In[5]:= Protect[Times];

(* Eigenes plus  CI[x]+CI[y]=CI[x+y] *)

In[6]:= plus[x_CI, y_CI] := CI[(Identity@@x) + (Identity@@y)];

In[7]:= plus[t__] := Plus[t];

(* Multiplikation der Polynome und Zusammenfassen der Koeffizienten *)

In[8]:= Timing@Collect[f g,z]

                       3          8          6           4
Out[8]= {0.01 Second, z  CI[4] + z  CI[6] + z  CI[10] + z  (CI[5] + CI[12]) + 
 
       10                     12           5                     9
>     z   (CI[7] + CI[12]) + z   CI[14] + z  (CI[8] + CI[15]) + z  CI[18] + 
 
       11
>     z   CI[21]}

In[9]:= Timing[ %[[2]] //. Plus->plus ]

                     3          8          6           12
Out[9]= {0. Second, z  CI[4] + z  CI[6] + z  CI[10] + z   CI[14] + 
 
       4           9           10           11           5
>     z  CI[17] + z  CI[18] + z   CI[19] + z   CI[21] + z  CI[23]}


(* Nochmal mit Umdefinition von Plus *)

In[10]:= Unprotect[Plus];

In[11]:=  Plus[x_CI,y_CI] := CI[(Identity@@x) + (Identity@@y)]

In[12]:= Protect[Plus];

(* Liefert dasselbe Ergebnis, nur wesentlich langsamer *)

In[13]:= Timing@Collect[f g,z]

                        3          8          6           12
Out[13]= {5.09 Second, z  CI[4] + z  CI[6] + z  CI[10] + z   CI[14] + 
 
       4           9           10           11           5
>     z  CI[17] + z  CI[18] + z   CI[19] + z   CI[21] + z  CI[23]}


(* Es geht noch schlimmer mit anderen Pattern (x_ statt x_CI) *)

In[14]:= Unprotect[Plus];

In[15]:=  Plus[x_,y_] := 
CI[(Identity@@x) + (Identity@@y)] /; Head@x==CI && Head@y==CI;

In[16]:= Protect[Plus];

(* ff und gg sind kuerzer als f und g *)

In[17]:= ff = z^3*CI[2] + z^5*CI[2];

In[18]:= gg = n[4] + z^1*n[5] + z^5*n[6];

In[19]:= Timing@Collect[ff gg,z]

                         3          5          4           6
Out[19]= {34.73 Second, z  CI[8] + z  CI[8] + z  CI[10] + z  CI[10] + 
 
       8           10
>     z  CI[12] + z   CI[12]}


      
Noch eine Frage am Rande: Wie erreicht man dass die Summe in Out[1] 
nach Potenzen von z geordnet wird anstatt nach den Argumenten von CI[]?
Also:  z^3*CI[1] + z^4*CI[3] + z^5*CI[2]
statt: z^3*CI[1] + z^5*CI[2] + z^4*CI[3]


Jan Lahmann

-- 
Jan-R. Lahmann       Jan.Lahmann@XXXXXXX.de


Antworten:
Re: Rechenzeiten und Pattern
Roman Maeder, 26.02.1998

Frühere

 

Chronologischer Index

 

Spätere

Vorherige

 

Thematischer Index

 

Nächste

DMUG-Archiv, http://www.mathematica.ch/dmug-liste.html; Letzte Änderung: 08.09.2003 20:44