Do / Return verhält sich in Compile anders - warum?

8

Ich frage mich, ob das ein Bug oder ein dokumentiertes Verhalten ist?

%Vor%

Wenn Sie sie auf eine Liste anwenden, die keine negativen Zahlen enthält, erhalten wir andere Ergebnisse:

%Vor%

Dies hat einen Fehler verursacht, als ich versucht habe, eine kurze Funktion (eigentlich eine modifizierte Version davon).

Do allein zeigt das Problem nicht:

%Vor%     
Szabolcs 18.11.2011, 15:08
quelle

4 Antworten

3

Wie in den Antworten von @Pillsy und @Leonid angemerkt, besteht das Problem darin, dass die ursprüngliche Funktion manchmal Null und manchmal eine ganze Zahl zurückgibt. Im Gegensatz dazu gibt die kompilierte Funktion immer eine ganze Zahl zurück. In V8 sehen wir das mit CompilePrint :

%Vor%

was unter V8.0.4 dieses Ergebnis erzeugt:

%Vor%

Wir können sehen, dass das Ergebnis der kompilierten Funktion das ist, was im Ganzzahlregister I5 endet. Nach dem Ablauf der dekompilierten Anweisungen sehen wir, dass I5 das letzte Element der Liste enthält, wenn keine Übereinstimmung vorhanden ist.

Das Verhalten des Compilers kann sich zwischen Releases von Mathematica ändern. Ich denke, dass es vernünftig ist zu argumentieren, dass der Compiler mindestens eine Warnung in Fällen ausgeben sollte, in denen der Rückgabetyp nicht eindeutig ist.

    
WReach 18.11.2011, 16:58
quelle
5

Ich würde sagen, das ist ein Fehler mit der Funktionsweise von Compile , aber es ist nicht wirklich überraschend, dass es nicht richtig funktioniert. Compile macht ziemlich spezifische Annahmen über nicht nur seine Eingaben (hier, dass v eine Liste von ganzen Zahlen sein wird), sondern auch seine Ausgaben. Kompilierte Funktionen sollen Werte eines einzelnen spezifischen Typs zurückgeben, und dieser Typ muss einer der Typen sein, die als Eingabe für eine kompilierte Funktion akzeptiert werden können: True|False , Integer , usw. und Arrays der gleich. Es wäre natürlich besser, wenn die Funktion mit einer Nachricht beschwert und dann Null zurückgibt, aber um eine gut funktionierende Funktion für die Kompilierung zu sein, müssen Sie einen entsprechenden Integer-Rückgabewert als Defalult angeben.

BEARBEITEN zur Klärung der Ausgabetypen, nach Szabolcs 'Kommentar unten.

>     
Pillsy 18.11.2011 15:30
quelle
4

Ich würde nicht sagen, dass das ein Fehler ist. Wie @Pillsy bemerkte, ist Compile -d Funktion eingeschränkter, da sie immer den gleichen Typ zurückgeben muss. Da Do ein Scoping-Konstrukt ist, bricht Return in Do nur von Do ab, nicht von Function . Daher gibt es in einigen Fällen ein Vektorelement zurück, in anderen Fällen gibt es Null zurück. Streng genommen sollte die Funktion, wie geschrieben, überhaupt nicht kompilieren. Man kann jedoch flexibler sein und annehmen, dass der Verfasser der Funktion besser weiß und die Antwort in diesem speziellen Fall verwerfen wird. Mit dieser Interpretation kann Compile in diesem Fall keine Antwort geben. Hier wird das letzte Element in der Liste erzeugt. Und ich denke, das ist nicht mehr ad-hoc, als jedes Mal eine feste Nummer zu produzieren. Ich denke auch, dass solche Eckfälle nicht vermieden werden können, wenn ein viel flexiblerer symbolischer Code erstellt wird. Compile könnte in diesem Fall striktere Regeln gehabt haben und erfordern in jedem Fall eine sinnvolle Rückgabe (des gleichen Typs), aber es ist mir nicht klar, ob dies wirklich von Vorteil wäre. In gewissem Sinne ist alles C wie das - der Compiler nimmt an, dass Sie wissen, was Sie tun, aber Sie können viel undefiniertes Verhalten erstellen, wenn Sie nicht vorsichtig sind.

    
Leonid Shifrin 18.11.2011 15:48
quelle
3

Einige zusätzliche Informationen, die Sie nützlich finden könnten. Bedenken Sie Folgendes:

%Vor%

Obwohl die Funktion für das erste Element, das sie erhalten hat, zurückgegeben werden sollte, = 1, ist, wie andere bemerkt haben, die Rückgabe fehlerhaft. Dies wird nicht behoben, da zu viel Code von diesem Verhalten abhängt.

Jetzt können Sie verwenden:

%Vor%

Was sich wie erwartet verhält. Leider jedoch

%Vor%

wird nicht kompiliert.

Hier ist eine Möglichkeit, das zu schaffen.

%Vor%

Überprüfen Sie die Ausgabe.

%Vor%

Einige weitere Hinweise: "RuntimeErrorHandler" - & gt; Funktion [Null] Dies ist eine Funktion! Denken Sie eine Sekunde darüber nach. Sie können Thow, Nachricht irgendetwas!

So etwas funktioniert.

%Vor%

Ich hoffe, das ist nützlich.

    
user1054186 19.11.2011 14:10
quelle

Tags und Links