Open slwu89 opened 3 years ago
Hi, @slwu89 . It's nice to see someone using this functionality - it was first built in ancient days of yore, and (despite being very fast!) ended up not being used. As such, it has not been actively maintained, and the R folks seem to have been making aggressive changes to how this stuff works that may have broken it. The upshot of this is that I will need to do some digging and look into it. I've not yet started playing with linking to the C backend from Rcpp (being only a recent and somewhat reluctant C++ user - Rcpp inlining was the "killer app" that started seducing me to the dark side), but that is something that would be very useful to support, so this seems like the time to figure it out. :-)
I modified the #include
s to limit what gets pulled into /src/net.h
: https://github.com/knapply/individual.network
Happy to PR, but you can get the gist by looking at the diff here: https://github.com/slwu89/individual.network/compare/main...knapply:main
# remotes::install_github("knapply/individual.network")
m <- matrix(rbinom(25,1,.4),5,5)
diag(m) <- 0
g <- network::network(m, directed=FALSE)
g
#> Network attributes:
#> vertices = 5
#> directed = FALSE
#> hyper = FALSE
#> loops = FALSE
#> multiple = FALSE
#> bipartite = FALSE
#> total edges= 3
#> missing edges= 0
#> non-missing edges= 3
#>
#> Vertex attribute names:
#> vertex.names
#>
#> No edge attributes
individual.network::rnbernexp_CPP(g, 0.5, 0.5, 0.5) # I just plugged in some args to confirm it runs...
#> Network attributes:
#> vertices = 5
#> directed = FALSE
#> hyper = FALSE
#> loops = FALSE
#> multiple = FALSE
#> bipartite = FALSE
#> FirstOnsetTime = 0.4029905
#> LastTerminationTime = 1.456397
#> total edges= 7
#> missing edges= 0
#> non-missing edges= 7
#>
#> Vertex attribute names:
#> FirstOnsetTime LastTerminationTime vertex.names
#>
#> Edge attribute names:
#> OnsetTime TerminationTime
Hello @CarterButts and @knapply!
Thanks so much for the quick help, I really appreciate it. Fixing where the network headers should be included according to @knapply's help, I wrote a working minimal example package with an explanation of the steps required to use the C API from Rcpp code on a fork of the repo here:
https://github.com/slwu89/network/tree/example_rcpp_pkg/inst/examples/networkRcppExample
If you think it's useful I'd be happy to submit a PR.
Just my 2 cents: this seems more appropriate as a standalone repo -- maybe to point to from a vignette?
Another option to consider would be something analogous to Rcpp::Rcpp.package.skeleton()
/RcppEigen::RcppEigen.package.skeleton()
/RcppArmadillo::RcppArmadillo.package.skeleton()
.
I'm a huge fan of Rcpp (and coauthor {RcppSimdJson}
with Dirk) -- @CarterButts, if you haven't considered it already, it'd be extremely appealing as a downstream {network}
user to be able to tap into a network
object class at the C++ level. This is super contrived, but this sort of behavior would be wildly convenient...
RcppNetwork.cpp:
#include <Rcpp.h>
// hypothetical RcppNetwork.hpp
namespace RcppNetwork {
class Network {
Rcpp::List g;
bool directed;
public:
Network(const Rcpp::List g_) : g(g_) {
const Rcpp::List gal = this->g["gal"];
const Rcpp::LogicalVector directed = gal["directed"];
this->directed = directed[0];
};
bool is_directed() const {
return this->directed;
}
};
} // namespace RcppNetwork
// hypothetical RcppNetwork.hpp
// [[Rcpp::export]]
bool is_directed(const Rcpp::List x) {
const auto g = RcppNetwork::Network(x);
return g.is_directed();
}
/*** R
m <- matrix(rbinom(25,1,.4),5,5)
g <- network::network(m, directed=FALSE)
is_directed(g)
*/
Rcpp::sourceCpp('~/r-projects/RcppNetwork.cpp')
##> m <- matrix(rbinom(25,1,.4),5,5)
##> g <- network::network(m, directed=FALSE)
##> is_directed(g)
##> [1] FALSE
Sure @knapply, I have no strong opinions on where, if anywhere it should live. I was looking at what RcppProgress did for their "sample" packages https://github.com/kforner/rcpp_progress/tree/master/inst/examples , but it looks like the statenet org has room for sample packages.
Is your suggestion to use Rcpp Attributes to export some header from network that Rcpp users can easily include? I agree that would be wildly convenient, but also looks like a lot of refactoring work on yours/ @CarterButts end? I'd be happy to help in a few months, but for now the method in the networkRcppExample package has helped me get off the ground for using network in my project.
I'm just a guest here. It's totally up to @CarterButts and the Statnet team.
Ah understood. Thanks for helping out another guest!
Hello network team!
I am writing a package relying in C++ which is compiled and linked against using Rcpp. I'd like to use the C API of network to interact with "network" class objects within the C++ code, using the
extern
keyword to make sure the C++ code knows what C function to use, following an example similar to https://github.com/r-pkg-examples/rcpp-and-c. The "network" vignette remarks that the current version implements R's template for registering C routines, so I thought that adding theLinkingTo: network
line in my package's DESCRIPTION and including the headers from "network" should work but compiling gives a multiple definition error:multiple definition of
netRegisterFunctions'`.My example package is here: https://github.com/slwu89/individual.network
I'd really appreciate any help anyone could provide about how to properly link to network. Thanks!