2014-07-23 10 views
5

Ich bin ein absoluter Rcpp-Anfänger, also seien Sie bitte gewarnt, dass eine Anfängerfrage kommt.Wie deklariert man Eingaben in Rcpp-Funktionen?

Betrachten dieses Beispiel:

#include <Rcpp.h> 
using namespace Rcpp; 
// [[Rcpp::export]] 
NumericMatrix mat_1(NumericMatrix X){ 
do.stuff.with.X 
} 

Mein Verständnis ist, dass dies eine Funktion mat_1 im Arbeitsbereich von R definiert, die eine numerische Matrix als eine Eingabe nimmt und gibt eine numerische Matrix am Ende. Jedoch verstehen looking e.g. here ich, auch

SEXP mat_2(SEXP X){ 
Rcpp::NumericMatrix x(X);     
do.stuff.with.x 
} 

oder alternativ

SEXP mat_3(SEXP X){ 
NumericMatrix x(as<NumericMatrix>(X)) 
do.stuff.with.x 
} 

Mein Verständnis definieren kann, ist, daß diese die Ausgabe der Funktion als ein S-Ausdruck definiert, und es erfordert eine S-expression als eine Eingabe, die intern (?) in eine numerische Matrix umgewandelt wird.

Nun looking at this document, die eine sehr wertvolle Ressource für mich gewesen ist, erfahre ich, dass ich auch hier

NumericMatrix mat_4(NumericMatrix X&){ 
do.stuff.with.X 
} 

schreiben kann, ist mein Verständnis, dass statt einer Kopie X machen, die Rcpp -function verwendet einen Verweis auf das Objekt R. Ich bin mir eigentlich nicht sicher, ob ich verstehe, was das bedeutet. War nicht der Sinn, zu benutzen, dass keine Kopie gemacht wurde, oder habe ich etwas falsch gemacht? Wenn es Speicher spart und somit effizienter ist, warum sollte ich dann noch etwas anderes verwenden?

Ich bin sicher, dass ich einige Optionen verpasst habe. Wie auch immer, meine große Frage ist dies: aus der Sicht des Benutzers R (ich), ich rufe jede Funktion mat_1, mat_2, mat_3 oder mat_4 liefert eine numerische Matrix (die ein R-Objekt in meinem Arbeitsbereich ist, und damit eine), und es scheint, ich sollte die gleiche Ausgabe (eine numerische Matrix, die eine sowieso aus R Perspektive ist, richtig?). Ich würde einige Hinweise auf die relativen Vorzüge dieser scheinbar identischen Möglichkeiten zur Definition einer Funktion begrüßen. Das heißt, wenn wir genau wissen, was die Funktion eingegeben werden und was die Ausgabe sein,

  1. Warum und wann wird es sich auszahlen NumericMatrix statt SEXP für das Argument zu verwenden, oder umgekehrt?
  2. Warum und wann zu verwenden &?
  3. Wenn ich weiß, dass die Funktion eine numerische Matrix zurückgibt, gibt es Gründe, die Funktion als zu deklarieren? Gibt es Gründe, sich an NumericMatrix zu halten?

Oder fehlt mir der Punkt vollständig?

Gibt es darüber hinaus einen praktischen Unterschied zwischen der in mat_2 und mat_3 verwendeten Konvertierung? Das heißt, gibt es Unterschiede zwischen Rcpp::NumericMatrix x(X) und NumericMatrix x(as<NumericMatrix>(X))?

Jede Rückmeldung wird geschätzt.

+0

Sie stellen hier einige Fragen, die generische Fragen zu C++ mit Besonderheiten von Rcpp verbinden. SO hat eine Menge großer Ressourcen über ersteres; wir liefern acht Vignetten mit letzterem, und dann gibt es auch das [Buch über Rcpp] (http://www.rcpp.org/book). –

+0

Ich stimme zu. Ein Problem, das ich habe, ist, dass ich nicht leicht zwischen Rcpp und C++ - Besonderheiten unterscheiden kann, da ich nur C++ durch Rcpp kenne, aber ich merke, dass dies ein Problem ist, wenn ich eine Frage stelle. – coffeinjunky

+1

Ich kenne die Vignetten und das Buch. Sie sind enorme Ressourcen und die Beispiele dort haben mir viel geholfen, aber ich denke, dass sie, insbesondere das Buch, viel Hintergrundwissen benötigen, das es schwierig macht, sich über ein bestimmtes Thema zu informieren. Dies ist problematisch, wenn Sie nicht wirklich wissen, was Sie suchen, was ich für ein typisches Anfängerproblem halte. Wenn Sie mich jedoch auf die spezielle Vignette hinweisen könnten, in der ich Antworten auf das oben genannte finde (vielleicht sogar einen bestimmten Abschnitt oder ein Stichwort, nach dem ich suchen sollte), würde ich das schätzen. – coffeinjunky

Antwort

5

In Ordnung. Versuche, einige Hinweise zu geben.Vor allem, wenn Sie ein Anfänger sind, haben Sie es richtig mit der ersten Funktion, verwenden Sie mat_1. Wenn sich Ihre Fähigkeiten verbessern, können Sie einige der Unterschiede zwischen mat_1 und der anderen verstehen und schließlich zu ... mat_1 wechseln, weil Sie das verwenden möchten.

  1. Immer. Die meisten Benutzer sollten nie verwenden.
  2. In diesem Fall macht das keinen Unterschied. Rcpp wird wissen, was mit der Referenz zu tun ist, aber was passiert, ist ziemlich gleich, es erzeugt lokal ein Objekt und gibt Ihnen einen Bezug darauf. Die Unterscheidung zwischen Wert und Verweis macht einen Unterschied, wenn Sie anrufen, wenn Sie mat_4 von einer anderen C++ - Funktion aufrufen.
  3. Wenn Sie den Typ kennen, verwenden Sie den Typ. Das ist der springende Punkt von Rcpp. ist Rs alle fangen, wenn Sie eine zurückgeben kann es alles sein, wenn Sie eine NumericMatrix Sie wissen, dass Sie eine numerische Matrix zurückgeben, riesigen Vorteil und so ziemlich den ganzen Grund Rcpp existiert.

Ich lasse Sie entscheiden, ob Sie den Punkt fehlten.

Im Allgemeinen as<> neigen dazu, härter zu versuchen, aber es macht keinen Unterschied in diesem Fall.

Kurz gesagt: Verwenden Sie mat_1. Es gibt noch viel anderes zu lernen, kümmere dich nicht darum.

+0

Danke Romain! Ich freue mich über Ihr Feedback. Nur eine sehr schnelle Folge zu meiner Frage: 1. [basierend auf dieser Antwort] (http://stackoverflow.com/questions/24781428/how-could-i-speed-up-this-rcpp-code/24782888#24782888), Verstehe ich, dass die Verwendung von 'SEXP' für die Funktionsargumente Kopien im Speicher vermeidet. Wenn ich zum Beispiel sehr große Matrizen habe, sollte ich dann lieber einen 'SEXP' verwenden? 2. Zu deinem Punkt 2, wenn ich die Ausgabe von 'mat_4' in einer anderen 'C++' -Funktion verwenden würde (was ich will), würde ich lieber '&'? – coffeinjunky

+2

Es gibt keinen zusätzlichen Speicher in einer NumericMatrix über den SEXP hinaus, none, zero. unabhängig davon, wie groß die Matrix ist. Sie zahlen nicht für eine NumericMatrix. Sie bekommen jedoch etwas bequemes zu verwenden. Für 2, nicht wirklich, die Matrix durch Wert übergeben ist billig, da wieder die Daten nicht kopiert wird, nur ein Zeiger. Ich kann angesichts des Codebeispiels "do.stuff.with.X" nicht viel mehr sagen. Für Rcpp-Typen wie NumericMatrix übergeben Sie sie einfach als Wert. –

+0

Ok, ich verstehe. Danke Romain, dass du dir die Zeit genommen hast, mir hier zu helfen. Ich weiß das zu schätzen! – coffeinjunky

Verwandte Themen