Die Koeffizientenfunktion ist langsam

8

Bitte beachten Sie:

%Vor% %Vor% %Vor% %Vor%

Hilfe sagt:

  

Coefficient funktioniert unabhängig davon, ob expr explizit in erweiterter Form angegeben wird.

Gibt es einen Grund, warum Coefficient im letzten Fall so langsam sein muss?

    
Mr.Wizard 23.11.2011, 14:13
quelle

4 Antworten

10

Coefficient wird nicht erweitert, es sei denn, es ist absolut notwendig, dies zu tun. Dies vermeidet tatsächlich Speicherexplosionen. Ich glaube, dass es seit Version 3 so war (ich glaube, ich habe ungefähr 1995 daran gearbeitet).

Es kann auch schneller sein, um eine Erweiterung zu vermeiden. Hier ist ein einfaches Beispiel.

%Vor%

Aber das nächste scheint in Version 8 zu hängen und dauert mindestens eine halbe Minute in der Entwicklung Mathematica (wo Expand geändert wurde).

%Vor%

Möglicherweise sollten einige Heuristiken hinzugefügt werden, um nach Univariaten zu suchen, die nicht explodieren. Scheint jedoch nicht wie ein Gegenstand mit hoher Priorität.

Daniel Lichtblau

    
Daniel Lichtblau 23.11.2011, 16:18
quelle
12

Hier ist ein Hack, der Ihren Code möglicherweise schnell macht, aber ich garantiere nicht, dass er immer korrekt funktioniert:

%Vor%

Wenn wir es verwenden, erhalten wir:

%Vor%

Die Idee ist, dass Coefficient intern Binomial verwendet, um die Anzahl der Terme zu schätzen, und dann expandiert (Aufrufe Expand ), wenn die Anzahl der Terme kleiner als 1000 ist, die Sie überprüfen können mit Trace[..., TraceInternal->True] . Und wenn es nicht expandiert, berechnet es viele Summen von großen Koeffizientenlisten, die von Nullen dominiert werden, und dies ist offensichtlich langsamer als das Expandieren für eine Reihe von Ausdrücken. Ich täusche Binomial , um eine kleine Zahl ( 10 ) zurückzugeben, aber ich habe auch versucht, es so zu machen, dass es nur die Binomial betrifft, die intern von Coefficient aufgerufen wird:

%Vor%

Ich kann jedoch nicht garantieren, dass es keine Beispiele gibt, bei denen Binomial irgendwo anders im Code falsch berechnet wird.

BEARBEITEN

Natürlich ist eine sicherere Alternative, die immer existiert, Coefficient mit dem Villegas - Gayley Trick, erweitern einen Ausdruck darin und rufen es erneut:

%Vor%

BEARBEITEN 2

Mein erster Vorschlag hatte den Vorteil, dass wir ein Makro definierten, das die Eigenschaften von Funktionen lokal änderte, aber den Nachteil, dass es unsicher war. Mein zweiter Vorschlag ist sicherer, aber ändert Coefficient global, so dass immer erweitert wird, bis wir diese Definition entfernen. Wir können das Beste aus beiden Welten mit Hilfe von % co_de haben % , die eine lokale Kopie einer bestimmten Funktion erstellt. Hier ist der Code:

%Vor%

Die Verwendung ähnelt dem ersten Fall:

%Vor%

Die Hauptfunktion Internal'InheritedBlock bleibt jedoch davon unberührt:

%Vor%     
Leonid Shifrin 23.11.2011 15:59
quelle
9
%Vor%

scheint auch ziemlich schnell.

    
Rolf Mertig 23.11.2011 17:16
quelle
1

Nach einigen Versuchen nach Rolf Mertigs Antwort scheint dies die schnellste Methode für die Art des Ausdrucks zu sein, wie zB Sum[x^i, {i, 15}]^30 :

%Vor%     
Mr.Wizard 25.11.2011 16:56
quelle