Liebe Mathematica-User!
Beim Versuch gewisse Regeln fuer eine Funktion zu definieren habe ich
Probleme mit den entstehenden Rechenzeiten. Diese werden natuerlich
wesentlich von den in den Regeln verwendeten Pattern beeinflusst.
Im ersten Beispiel zeigen sich erhebliche Laufzeitunterschiede, die ich
mir nicht erklaeren kann (es werden einfach die Argumente von CI addiert):
$ math
Mathematica 3.0 for IBM RISC System/6000
Copyright 1988-97 Wolfram Research, Inc.
-- Motif graphics initialized --
(* $Version=IBM RISC System/6000 3.0 (April 25, 1997) *)
In[1]:= t[n_]:=Sum[CI[Random[]], {i,1,n}];
In[2]:= CIRules := {c1_CI+c2_CI :> CI[c1[[1]] + c2[[1]]] }; (* schlecht *)
In[3]:= Timing[ t[13]//.CIRules ]
Out[3]= {18.7 Second, CI[7.45489]}
In[4]:= CIRules := {CI[c1_]+CI[c2_] :> CI[c1 + c2] }; (* gut *)
In[5]:= Timing[ t[13]//.CIRules ]
Out[5]= {0. Second, CI[6.61379]}
In[6]:= CIRules := {(c1:CI[_])+(c2:CI[_]) :> CI[c1[[1]] + c2[[1]]] }; (* gut *)
In[7]:= Timing[ t[13]//.CIRules ]
Out[7]= {0. Second, CI[6.66355]}
Mit
ListPlot[ Table[{i,Timing[t[i]//.CIRules][[1]]/.Second->1}, {i,1,14}] ]
ListPlot[ Table[{i,Log[Timing[t[i]//.CIRules][[1]]/.Second->1]}, {i,1,14}] ]
sieht man, dass die Rechenzeit bei der ersten Regel exponentiell waechst.
Warum verhalten sich diese 3 Pattern so verschieden?
Im zweiten Beispiel matchen die verwendeten Pattern nicht so wie
gewuenscht. Oder habe ich die Dokumentation falsch verstanden?
(Statt der Funktion f kann man sich auch Plus vorstellen)
In[1]:= SetAttributes[f,Orderless];
In[2]:= SetAttributes[f,OneIdentity];
In[3]:= SetAttributes[f,Flat];
(* warum will er folgendes nicht? Das f 3 Argumente hat sollte kein
Problem sein (siehe In[6], dort ist das Pattern mit dem "|" sozusagen
ausgeschrieben). Und das "|" versteht er in In[5] und In[7] ja auch. *)
In[4]:= f[4,CI[v],CI[w]] /. f[c_CI, (e_CI|e_Integer)] -> matched
Out[4]= f[4, CI[v], CI[w]] (* warum passt das Pattern nicht? *)
In[5]:= f[4,CI[v]] /. f[c_CI, (e_CI|e_Integer)] -> matched
Out[5]= matched (* ok *)
In[6]:= f[4,CI[v],CI[w]] /.
{f[c_CI, e_Integer] -> matched, f[c_CI, e_CI] -> matched}
Out[6]= f[matched, CI[w]] (* ok *)
(* das Pattern passt hier, das ist schonmal gut; aber eigentlich sollte er
die Regel nur einmal anwenden, also so etwas wie Out[6] liefern und nicht
alles zusammenstreichen, oder? *)
In[7]:= f[4,CI[v],CI[w]] /. f[_, (e_CI|e_Integer)] -> matched
Out[7]= matched (* ? *)
Ich bin fuer alle Hinweise hierzu dankbar.
Jan Lahmann
--
Dipl.-Math. Jan-R. Lahmann Jan.Lahmann@XXXXXXX.de
Mathematisches Institut I Tel.: (0721) 608 3704
Universit"at Karlsruhe
76128 Karlsruhe Fax: (0721) 608 6530
|