Matt and Bill, Thank you both for your input. I was under the impression that std::transform would be calling a new trackIdx(c1,c2) object for each step along the input vectors, and therefore a static data member would be needed to ensure that the count was being accumulated properly (my knowledge of C++ is pretty basic, as you might have picked up on). I took your suggestions about using a non-static data member, though, and it worked correctly. Thanks again for the help guys.
Nate On Wed, Oct 22, 2014 at 3:32 PM, Matthew Wright <ma...@trdlnk.com> wrote: > Hi Nate, > > No problem. > > So the reason it's persisting across method calls is because you made it a > static, which means there's just one instance of that data across the > entire program. In your usage, it doesn't look like you need it to be > static. You could just make it an instance variable and you'd probably get > what you want, so you'd just remove the static keyword and don't initialize > it outside the struct definition. > > In terms of why you initialize statics this way, this stack overflow > question might prove helpful, I always found it a bit confusing: > http://stackoverflow.com/questions/185844/initializing-private-static-members > > Matt > > > On Wed, Oct 22, 2014 at 2:03 PM, nate russell <russell.n2...@gmail.com> > wrote: > >> Just for the sake of completeness, I noticed that the value of >> trackIdx::tracker was persisting (and therefore continuing to be >> incremented) between function calls with mc_index, so in addition to your >> first suggestion, I added a member function to reset the value to zero, and >> everything seems to be working smoothly. Once again, thank you for your >> help. >> >> Nathan Russell >> >> >> >> #include <Rcpp.h> >> #include <vector> >> #include <string> >> #include <algorithm> >> // [[Rcpp::plugins(cpp11)]] >> >> class trackIdx { >> public: >> trackIdx(const std::string& s1_, const std::string& s2_) >> : s1(s1_),s2(s2_) {} >> int operator() (std::string x1, std::string x2) { >> tracker++; >> return (s1==x1 && s2==x2 ? (tracker-1) : -10); >> } >> void reset() { tracker = 0; } >> private: >> std::string s1; >> std::string s2; >> static int tracker; >> }; >> >> int trackIdx::tracker = 0; >> >> // [[Rcpp::export]] >> std::vector<int> mc_index(const Rcpp::DataFrame& df, >> const std::string& c1, >> const std::string& c2) >> { >> std::vector<std::string> vc1 = df["C1"]; >> std::vector<std::string> vc2 = df["C2"]; >> int N = df.nrows(); >> >> std::vector<int> vcount; >> vcount.resize( N ); >> >> trackIdx track(c1,c2); >> >> std::transform(vc1.begin(),vc1.end(),vc2.begin(),vcount.begin(),track); >> vcount.erase( >> std::remove_if(vcount.begin(),vcount.end(), >> [](int i) -> bool { >> return (i<0); >> }), >> vcount.end()); >> >> track.reset(); >> return vcount; >> } >> >> >> >> On Wed, Oct 22, 2014 at 2:29 PM, nate russell <russell.n2...@gmail.com> >> wrote: >> >>> Matthew, >>> >>> Thank you for such a quick response; both of those suggestions worked >>> perfectly. Out of curiosity, is there any reason to use one of these >>> implementations over the other - or are they essentially equivalent? >>> >>> Regards, >>> Nathan Russell >>> >>> On Wed, Oct 22, 2014 at 2:10 PM, Matthew Wright <ma...@trdlnk.com> >>> wrote: >>> >>>> Nate, >>>> >>>> The problem here is how you are have implemented your static member of >>>> trackIdx. You only declared it. >>>> >>>> I'd suggest one of two alternatives: >>>> >>>> // add this below the struct declaration. >>>> int trackIdx::tracker = 0; >>>> >>>> Or, just create it in the function where you actually use it instead of >>>> making it a member. >>>> int operator() (std::string x1, std::string x2) { >>>> static int tracker; >>>> tracker++; >>>> return ((s1==x1 && s2==x2) ? (tracker-1) : -1); >>>> } >>>> >>>> >>>> >>>> On Wed, Oct 22, 2014 at 12:39 PM, nate russell <russell.n2...@gmail.com >>>> > wrote: >>>> >>>>> Hello, >>>>> >>>>> I am running into the "Error in dyn.load [...] unable to load shared >>>>> object ['/tmp/...'] undefined symbol [_...]" error; however it is only >>>>> happening with one particular Rcpp function, which I find puzzling. Here >>>>> is >>>>> my .cpp file containing two functions - I can compile the first one >>>>> without >>>>> any issue (in its own file), but the second brings about the noted error >>>>> message: >>>>> >>>>> >>>>> #include <Rcpp.h> >>>>> #include <vector> >>>>> #include <string> >>>>> #include <algorithm> >>>>> // [[Rcpp::plugins(cpp11)]] >>>>> >>>>> /* >>>>> * Works fine. >>>>> */ >>>>> >>>>> struct checkTwo { >>>>> public: >>>>> checkTwo(const std::string& s1_, const std::string& s2_) >>>>> : s1(s1_), s2(s2_) {} >>>>> int operator() (std::string x1, std::string x2) { >>>>> return (s1==x1 && s2==x2 ? 1 : 0); >>>>> } >>>>> private: >>>>> std::string s1; >>>>> std::string s2; >>>>> }; >>>>> >>>>> // [[Rcpp::export]] >>>>> int count_if_if(const Rcpp::DataFrame& df, >>>>> const std::string& c1, >>>>> const std::string& c2) >>>>> { >>>>> std::vector<std::string> vc1 = df["C1"]; >>>>> std::vector<std::string> vc2 = df["C2"]; >>>>> int N = df.nrows(); >>>>> >>>>> std::vector<int> vcount; >>>>> vcount.resize( N ); >>>>> >>>>> >>>>> std::transform(vc1.begin(),vc1.end(),vc2.begin(),vcount.begin(),checkTwo(c1,c2)); >>>>> int total = std::accumulate(vcount.begin(),vcount.end(),0); >>>>> >>>>> return total; >>>>> } >>>>> >>>>> /* >>>>> * Does not compile. >>>>> */ >>>>> >>>>> struct trackIdx { >>>>> public: >>>>> trackIdx(const std::string& s1_, const std::string& s2_) >>>>> : s1(s1_),s2(s2_) {} >>>>> int operator() (std::string x1, std::string x2) { >>>>> tracker++; >>>>> return ((s1==x1 && s2==x2) ? (tracker-1) : -1); >>>>> } >>>>> private: >>>>> std::string s1; >>>>> std::string s2; >>>>> static int tracker; >>>>> }; >>>>> >>>>> // [[Rcpp::export]] >>>>> std::vector<int> mc_index(const Rcpp::DataFrame& df, >>>>> const std::string& c1, >>>>> const std::string& c2) >>>>> { >>>>> std::vector<std::string> vc1 = df["C1"]; >>>>> std::vector<std::string> vc2 = df["C2"]; >>>>> int N = df.nrows(); >>>>> >>>>> std::vector<int> vcount; >>>>> vcount.resize( N ); >>>>> >>>>> std::vector<int> result; >>>>> result.resize( N ); >>>>> >>>>> >>>>> std::transform(vc1.begin(),vc1.end(),vc2.begin(),vcount.begin(),trackIdx(c1,c2)); >>>>> std::copy_if(vcount.begin(),vcount.end(),result.begin(), >>>>> [](int i) -> bool { >>>>> return !(i<0); >>>>> }); >>>>> >>>>> return result; >>>>> } >>>>> >>>>> >>>>> The above functions (only "count_if_if" at the moment) can be tested >>>>> like this: >>>>> >>>>> Df <- data.frame( >>>>> C1=rep(LETTERS[1:4],each=15), >>>>> C2=as.character(rep(rep(1:3,each=5),4)), >>>>> C3=rep(rep(1:3,each=5),4), >>>>> stringsAsFactors=FALSE) >>>>> ## >>>>> count_if_if(Df,"B","3") >>>>> ## >>>>> # mc_index(Df,"B","3") >>>>> >>>>> >>>>> >>>>> The exact error message I am getting is: >>>>> >>>>> Error in >>>>> dyn.load("/tmp/Rtmpw7VSkV/sourcecpp_27046ca49cd4/sourceCpp_67600.so") : >>>>> unable to load shared object >>>>> '/tmp/Rtmpw7VSkV/sourcecpp_27046ca49cd4/sourceCpp_67600.so': >>>>> /tmp/Rtmpw7VSkV/sourcecpp_27046ca49cd4/sourceCpp_67600.so: undefined >>>>> symbol: _ZN8trackIdx7trackerE >>>>> >>>>> >>>>> and judging by the last bit, "undefined symbol: >>>>> _ZN8trackIdx7trackerE", it looks like my "trackIdx" function object is the >>>>> source of the problem. >>>>> >>>>> I have tested this on two different platforms - >>>>> >>>>> my network server running CentOS 7: >>>>> >>>>> R version 3.1.1 >>>>> Platform: x86_64-redhat-linux-gnu (64-bit) >>>>> Rcpp_0.11.3 >>>>> >>>>> >>>>> and my laptop running Ubuntu 14.04: >>>>> >>>>> R version 3.0.2 >>>>> Platform: x86_64-pc-linux-gnu (64-bit) >>>>> Rcpp_0.11.2 >>>>> >>>>> >>>>> Both of these machines use a reasonably up-to-date version of g++ that >>>>> supports c++11 (although I don't think this has anything to do with the >>>>> issue). I have never had any problems compiling Rcpp functions on either >>>>> of >>>>> these platforms, yet the second function object & Rcpp function above >>>>> produce the same error on each machine. If anyone can explain what is >>>>> going >>>>> wrong and/or suggest how to correct the problem with the above code I >>>>> would >>>>> appreciate it very much. >>>>> >>>>> Thank you, >>>>> Nathan Russell >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> _______________________________________________ >>>>> Rcpp-devel mailing list >>>>> Rcpp-devel@lists.r-forge.r-project.org >>>>> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel >>>>> >>>> >>>> >>>> >>>> -- >>>> ------------------------- >>>> Matt Wright >>>> 312-264-2987 (p) >>>> 312-479-6821 (m) >>>> >>> >>> >> > > > -- > ------------------------- > Matt Wright > 312-264-2987 (p) > 312-479-6821 (m) >
_______________________________________________ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel