2017-10-24 3 views
1
Rekursion

ich ein Problem mit meinem cxxfunction in R. und ich möchte dies selbst nennen, gibt leider mir der Compiler diese Fehlermeldung:eine cxxfunction nennt sich

‚Matmult2‘ deklariert wird nicht in Dieser Bereich

Das Problem ist auch Matmult2 in einer Cxxfunction aufrufen.

Mein ursprüngliches Problem hängt mit dem strassen Algorithmus zusammen, den ich gerne rekursiv mit RCPP/Inline aufrufen würde. Vielen Dank für Ihre Hilfe!

`

Matmult2<- cxxfunction(signature(a="NumericMatrix",b="NumericMatrix"), plugin="RcppArmadillo",includes = rcpp_inc, 
    body=' 

       Rcpp::NumericMatrix verg(a); 
       int n = verg.nrow(); 

       arma::mat A = Rcpp::as<arma::mat>(a); 
       arma::mat B = Rcpp::as<arma::mat>(b); 

       arma::mat a11 = A(span(0,(n/2)-1), span(0,(n/2)-1)); 
       arma::mat a12 = A(span(0,(n/2)-1), span((n/2),n-1)); 
       arma::mat a21 = A(span((n/2),n-1), span(0,(n/2)-1)); 
       arma::mat a22 = A(span((n/2),n-1), span((n/2),n-1)); 

       arma::mat b11 = B(span(0,(n/2)-1), span(0,(n/2)-1)); 
       arma::mat b12 = B(span(0,(n/2)-1), span((n/2),n-1)); 
       arma::mat b21 = B(span((n/2),n-1), span(0,(n/2)-1)); 
       arma::mat b22 = B(span((n/2),n-1), span((n/2),n-1)); 


       if (n < 780) return Rcpp::wrap(A * B); 


       arma::mat P1(Matmult2(a11,(b12-b22))); 
       arma::mat P2(Matmult2((a11+a12),(b22))); 
       arma::mat P3(Matmult2((a21+a22),(b11))); 
       arma::mat P4(Matmult2((a22),(b21-b11))); 
       arma::mat P5(Matmult2((a11+a22),(b11+b22))); 
       arma::mat P6(Matmult2((a12-a22),(b21+b22))); 
       arma::mat P7(Matmult2((a11-a21),(b11+b12))); 

       arma::mat c11((P5+P4-P2+P6)); 
       arma::mat c12((P1+P2)); 
       arma::mat c21((P3+P4)); 
       arma::mat c22((P5+P1-P3-P7)); 

       mat C1 = join_rows(c11, c12); 
       mat C2 = join_rows(c21, c22); 
       mat C = join_cols(C1, C2); 

       return Rcpp::wrap(C); 

‚)

`

+0

Sie sollten wirklich nur RCPP Funktionen inline definieren, die lieber kurzer und einfacher Quellcode Ich rate Ihnen, eine separate C++ - Quelldatei zu verwenden. Das ist nicht schwieriger zu handhaben (insbesondere wenn Sie eine IDE verwenden) und Sie erhalten den zusätzlichen Vorteil der Syntaxhervorhebung und anderer Werkzeuge. – Roland

+0

Guter Rat, und es wird auch empfohlen, von Inline zu Rcpp Attribute zu wechseln. –

Antwort

1

Sie nicht direkte Rekursion tun können, weil der Code Kleber wir legen Sie eine Wrapper-Funktion erstellt, die aufgerufen wird, --- aber Sie Wenn der Wrapper nicht rekursiv aufgerufen werden soll, soll die Funktion aufgerufen werden. Sie müssten also auch: ein Wrapper von R aufgerufen, und eine C (++) - nur rekursive Funktion, die von Ihrem Wrapper aufgerufen wird, und der sich selbst aufruft.

Es funktioniert auch, wenn Sie zu Rcpp Attribute wechseln. Hier haben wir den Standardträger der rekursiven Funktionen zu verwenden, die Fibonacci-Folge:

R> library(Rcpp) 
R> cppFunction("double fib(double n) { if (n < 2) return n; return(fib(n-1) + fib(n-2)); }") 
R> sapply(0:10, fib) 
[1] 0 1 1 2 3 5 8 13 21 34 55 
R> 

(. Und ich double statt int als die letzteren überläuft früher)