Ich verwende Rcpp
, um einen (nicht von mir) geschriebenen Algorithmus in C-ähnliches C ++ zu schreiben (keine STL, kein Boost, nichts, soweit ich das beurteilen kann). Sie können den implementierten Algorithmus hier sehen (Ich verpacke kmeans_w_03
). Folglich gebe ich einen numeric
Vektor von R ein, der dann in ein double
Array konvertiert werden muss.
Momentan schleife ich Element für Element und fülle das aus dem 'tother, wie folgt:
%Vor% Aber mit numerischen Vektoren mit einzelnen Elementen kann ich Rcpps schöne as
Casting-Funktionalität nutzen:
Versuchen Sie etwas ähnliches für die Länge & gt; 1 numerische Vektoren führen jedoch abhängig von der genauen Syntaxvariante zu einem Absturz oder einem Fehler:
%Vor% Ich mag die Schleife nicht unbedingt, aber ich bin ein totaler Neuling und vermute, dass es einen besseren Weg gibt. Ich habe Rcpp-Einleitung, hadleys Wiki-Tutorial und RcppExamples gelesen und noch nichts gefunden, was diese Frage angeht, aber das bedeutet nicht, dass ich es nicht einfach vermisst habe. Meine Lektüre der Doxygen Rcpp Dokumente ist, dass as
in einen STL-Vektor, aber kein Array umwandeln kann (aber ich habe es sehr schwer, diese Dokumente zu lesen, also vermute ich, dass ich da falsch liege). Wenn dem so ist, könnte ich zu einem Vektor und von dort zu einem Array umwandeln ...
Also meine Frage: Gibt es eine bessere (weniger Codezeilen, mehr expressiven Code und vielleicht sogar zu vermeidende Speicherzuweisung), um eine NumericVector
in eine double[]
?
Ari, in der vorherigen Antwort, John macht einen guten Punkt. Um ein wenig zu erweitern, gibt es ein paar Probleme hier
double[]
oder *double
möchte
Nun, fürchte nicht, wir haben eine einfache Lösung. Bilde die Rcpp::NumericVector X(weightvec);
wie üblich in Sekundenschnelle und gib sie dann an deine Funktion foo()
(oder was auch immer) als
gibt Ihnen die erforderliche double*
und bei Bedarf X.size()
gibt die Länge an. Da Sie aus R kommen, müssen Sie sich nicht um Umfang und Lebensdauer sorgen, wenn Sie danach zu R zurückkehren.
Falls Sie expliziter sein müssen, habe ich auch das hässlichere &(X[0])
verwendet.
Auch der Rcpp::as<>()
Caster funktioniert auch auf std::vector<double>
, also kannst du
aber abgesehen von der Umwandlung in C ++ - Typen erhält es hier nichts.
Schließlich, falls Josh oder andere C-Diehards in der Nähe sind, nutzt all dies die Tatsache, dass der SEXP
du von R garantiert den zusammenhängenden C-Zeiger hat, also könntest du auch über die sehr alte Schule gehen REAL(weightvec)
.
Das Schreiben eines C ++ - Programms, das nicht die Standardbibliothek verwendet (was Sie als "STL" bezeichnen), ist nicht das, was ich als "herkömmliches C ++" bezeichnen würde. Die Standardbibliothek ist Teil von der Sprache, wie sie im Standard definiert ist. Daher ist die Verwendung der im Standard definierten Funktionen kein unkonventionelles C ++. Ganz im Gegenteil, ich würde vorschlagen, dass das absichtliche Ignorieren dieser Einrichtungen unkonventionell ist. Es verwendet C ++ als ein "besseres C" oder ein "C mit Klassen". und das fehlt der Punkt.
Wenn Sie sich vor Augen halten, was Ihre Schleife erreichen möchte, verwenden Sie transform
, um die Quelle zum Ziel zu kopieren, und vector
als Ziel.
Sie haben hier auch einen Vermittler - Sie kopieren weightVec
zuerst in ein neu erstelltes NumericVector
und kopieren dann die Elemente daraus - aber das NumericVector
wird weggeworfen . Das erscheint mir verschwenderisch.
Hier ist das Grundmuster, das ich mir beim Schreiben dieses Codes vorstellen würde:
%Vor%Hier fehlen einige syntaktische Bits, die ich nicht ausfüllen kann, ohne mehr über die Compnents im Spiel zu wissen. Aber angesichts dessen, was Sie tun, scheint die Philosophie solide.
Beispielsweise hat das SEXP
-Objekt möglicherweise nicht die Methoden begin()
oder end()
. Sie konstruieren jedoch bereits direkt ein NumericVector
aus dem SEXP
-Objekt, so dass% code_% wahrscheinlich analoge Möglichkeiten für SEXP
und begin()
hat, die Sie übernehmen oder möglicherweise sogar direkt verwenden können.
Das obige end()
-Konstrukt ist ein Platzhalter für eine Funktion, einen Funktor oder ein Lambda (in C ++ 11), der ein einzelnes converter()
-Element in ein SEXP
umwandelt. Wiederum kenne ich nicht die Details, die ich brauche, um dies zu implementieren, aber es muss möglich sein, da Sie dies bereits auf eine andere Weise tun.
Wenn Ihre Frage ist, wie Daten von Rcpp::NumericVector
nach C ++ Array kopiert werden, ist transform()
eine gute Antwort. Wenn Sie jedoch das innere Array von Rcpp::NumericVector
erhalten möchten, das kein Kopieren enthält, können Sie genau das gleiche wie das extrahierende Array von std::vector
:
wobei vec ein Rcpp::NumericVector
ist.