<div dir="ltr">Matt and Bill,<br><br>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. <br><br>Nate<br><br><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Oct 22, 2014 at 3:32 PM, Matthew Wright <span dir="ltr"><<a href="mailto:mattw@trdlnk.com" target="_blank">mattw@trdlnk.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div>Hi Nate,</div><div><br></div><div>No problem.  </div><div><br></div><div>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.</div><div><br></div><div>In terms of why you initialize statics this way, this stack overflow question might prove helpful, I always found it a bit confusing:  <a href="http://stackoverflow.com/questions/185844/initializing-private-static-members" target="_blank">http://stackoverflow.com/questions/185844/initializing-private-static-members</a></div><div><br></div><div>Matt</div><div><br></div></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Oct 22, 2014 at 2:03 PM, nate russell <span dir="ltr"><<a href="mailto:russell.n2012@gmail.com" target="_blank">russell.n2012@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr">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. <br><br>Nathan Russell<br><br><br><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><span><div>#include <Rcpp.h></div><div>#include <vector></div><div>#include <string></div><div>#include <algorithm></div><div>// [[Rcpp::plugins(cpp11)]]</div><div><br></div></span><div>class trackIdx {</div><span><div>  public:</div><div>    trackIdx(const std::string& s1_, const std::string& s2_)</div><div>    : s1(s1_),s2(s2_) {}</div><div>    int operator() (std::string x1, std::string x2) {</div><div>      tracker++;</div></span><div>      return (s1==x1 && s2==x2 ? (tracker-1) : -10);</div><div>    }</div><div>    void reset() { tracker = 0; }</div><span><div>  private:</div><div>    std::string s1;</div><div>    std::string s2;</div><div>    static int tracker;</div><div>};</div><div><br></div></span><span><div>int trackIdx::tracker = 0;</div><div><br></div></span><span><div>// [[Rcpp::export]]</div><div>std::vector<int> mc_index(const Rcpp::DataFrame& df,</div><div>                           const std::string& c1,</div><div>                           const std::string& c2)</div><div>{</div><div>  std::vector<std::string> vc1 = df["C1"];</div><div>  std::vector<std::string> vc2 = df["C2"];</div><div>  int N = df.nrows();</div><div>  </div><div>  std::vector<int> vcount;</div><div>  vcount.resize( N );</div><div>  </div></span><div>  trackIdx track(c1,c2);</div><div>  </div><div>  std::transform(vc1.begin(),vc1.end(),vc2.begin(),vcount.begin(),track);</div><div>  vcount.erase(</div><div>      std::remove_if(vcount.begin(),vcount.end(),</div><div>      [](int i) -> bool {</div><div>        return (i<0);</div><div>      }),</div><div>    vcount.end());</div><div>  </div><div>  track.reset();</div><div>  return vcount;</div><div>}</div></blockquote><br></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Oct 22, 2014 at 2:29 PM, nate russell <span dir="ltr"><<a href="mailto:russell.n2012@gmail.com" target="_blank">russell.n2012@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr">Matthew, <br><br>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? <br><br>Regards,<br>Nathan Russell</div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Oct 22, 2014 at 2:10 PM, Matthew Wright <span dir="ltr"><<a href="mailto:mattw@trdlnk.com" target="_blank">mattw@trdlnk.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr">Nate,<div><br>The problem here is how you are have implemented your static member of trackIdx.  You only declared it.</div><div><br></div><div>I'd suggest one of two alternatives:</div><div><div><br></div><div>// add this below the struct declaration.</div><div>int trackIdx::tracker = 0;</div></div><div><br></div><div>Or, just create it in the function where you actually use it instead of making it a member.</div><div><span><div>    int operator() (std::string x1, std::string x2) {</div></span><div>      static int tracker;</div><span><div>      tracker++;</div><div>      return ((s1==x1 && s2==x2) ? (tracker-1) : -1);</div><div>    }</div></span></div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote"><div><div>On Wed, Oct 22, 2014 at 12:39 PM, nate russell <span dir="ltr"><<a href="mailto:russell.n2012@gmail.com" target="_blank">russell.n2012@gmail.com</a>></span> wrote:<br></div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div><div><div dir="ltr">Hello,<br><br>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:<br><br><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div>#include <Rcpp.h></div><div>#include <vector></div><div>#include <string></div><div>#include <algorithm></div><div>// [[Rcpp::plugins(cpp11)]]</div><div><br></div><div>/*</div><div> * Works fine. </div><div> */</div><div><br></div><div>struct checkTwo {</div><div>  public:</div><div>    checkTwo(const std::string& s1_, const std::string& s2_)</div><div>    : s1(s1_), s2(s2_) {}</div><div>    int operator() (std::string x1, std::string x2) {</div><div>      return (s1==x1 && s2==x2 ? 1 : 0);</div><div>    }</div><div>  private:</div><div>    std::string s1;</div><div>    std::string s2;</div><div>};</div><div><br></div><div>// [[Rcpp::export]]</div><div>int count_if_if(const Rcpp::DataFrame& df,</div><div>                const std::string& c1,</div><div>                const std::string& c2)</div><div>{</div><div>  std::vector<std::string> vc1 = df["C1"];</div><div>  std::vector<std::string> vc2 = df["C2"];</div><div>  int N = df.nrows();</div><div>  </div><div>  std::vector<int> vcount;</div><div>  vcount.resize( N );</div><div>  </div><div>  std::transform(vc1.begin(),vc1.end(),vc2.begin(),vcount.begin(),checkTwo(c1,c2));</div><div>  int total = std::accumulate(vcount.begin(),vcount.end(),0);</div><div>  </div><div>  return total;</div><div>}</div><div><br></div><div>/*</div><div> * Does not compile. </div><div> */</div><div><br></div><div>struct trackIdx {</div><div>  public:</div><div>    trackIdx(const std::string& s1_, const std::string& s2_)</div><div>    : s1(s1_),s2(s2_) {}</div><div>    int operator() (std::string x1, std::string x2) {</div><div>      tracker++;</div><div>      return ((s1==x1 && s2==x2) ? (tracker-1) : -1);</div><div>    }</div><div>  private:</div><div>    std::string s1;</div><div>    std::string s2;</div><div>    static int tracker;</div><div>};</div><div><br></div><div>// [[Rcpp::export]]</div><div>std::vector<int> mc_index(const Rcpp::DataFrame& df,</div><div>                          const std::string& c1,</div><div>                          const std::string& c2)</div><div>{</div><div>  std::vector<std::string> vc1 = df["C1"];</div><div>  std::vector<std::string> vc2 = df["C2"];</div><div>  int N = df.nrows();</div><div>  </div><div>  std::vector<int> vcount;</div><div>  vcount.resize( N );</div><div>  </div><div>  std::vector<int> result;</div><div>  result.resize( N );</div><div>  </div><div>  std::transform(vc1.begin(),vc1.end(),vc2.begin(),vcount.begin(),trackIdx(c1,c2));</div><div>  std::copy_if(vcount.begin(),vcount.end(),result.begin(),</div><div>    [](int i) -> bool {</div><div>      return !(i<0);</div><div>    });</div><div>  </div><div>  return result;</div><div>}</div></blockquote><div><br>The above functions (only "count_if_if" at the moment) can be tested like this:<br><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div>Df <- data.frame(</div></div><div><div>  C1=rep(LETTERS[1:4],each=15),</div></div><div><div>  C2=as.character(rep(rep(1:3,each=5),4)),</div></div><div><div>  C3=rep(rep(1:3,each=5),4),</div></div><div><div>  stringsAsFactors=FALSE)</div></div><div><div>##</div></div><div><div>count_if_if(Df,"B","3")</div></div><div><div>##</div></div><div><div># mc_index(Df,"B","3")</div></div></blockquote><div><br><br>The exact error message I am getting is:<br><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div>Error in dyn.load("/tmp/Rtmpw7VSkV/sourcecpp_27046ca49cd4/sourceCpp_67600.so") : </div></div><div><div>  unable to load shared object '/tmp/Rtmpw7VSkV/sourcecpp_27046ca49cd4/sourceCpp_67600.so':</div></div><div><div>  /tmp/Rtmpw7VSkV/sourcecpp_27046ca49cd4/sourceCpp_67600.so: undefined symbol: _ZN8trackIdx7trackerE</div></div></blockquote><div><br>and judging by the last bit, "undefined symbol: _ZN8trackIdx7trackerE", it looks like my "trackIdx" function object is the source of the problem. <br><br>I have tested this on two different platforms - <br><br>my network server running CentOS 7:<br><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px">R version 3.1.1 <br>Platform: x86_64-redhat-linux-gnu (64-bit)<br>Rcpp_0.11.3</blockquote><br>and my laptop running Ubuntu 14.04:<br><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px">R version 3.0.2<br>Platform: x86_64-pc-linux-gnu (64-bit)<br>Rcpp_0.11.2</blockquote><br>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. <br><br>Thank you,<br>Nathan Russell<br><br><br><br><br><br></div>
<br></div></div>_______________________________________________<br>
Rcpp-devel mailing list<br>
<a href="mailto:Rcpp-devel@lists.r-forge.r-project.org" target="_blank">Rcpp-devel@lists.r-forge.r-project.org</a><br>
<a href="https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel" target="_blank">https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel</a><span><font color="#888888"><br></font></span></blockquote></div><span><font color="#888888"><br><br clear="all"><div><br></div>-- <br>-------------------------<div>Matt Wright</div><div><a href="tel:312-264-2987" value="+13122642987" target="_blank">312-264-2987</a> (p)</div><div><a href="tel:312-479-6821" value="+13124796821" target="_blank">312-479-6821</a> (m)</div>
</font></span></div>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>-------------------------<div>Matt Wright</div><div><a href="tel:312-264-2987" value="+13122642987" target="_blank">312-264-2987</a> (p)</div><div><a href="tel:312-479-6821" value="+13124796821" target="_blank">312-479-6821</a> (m)</div>
</div>
</div></div></blockquote></div><br></div></div>