|
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 |