Question

J'essaie de créer un wrapper pour du code de gestion de matrice clairsemée basé sur C (voir question précédente).Afin d'appeler la fonction Workhorse C, je dois créer une structure qui ressemble à ceci :

struct smat {
  long rows;
  long cols;
  long vals;     /* Total non-zero entries. */
  long *pointr;  /* For each col (plus 1), index of first non-zero entry. */
  long *rowind;  /* For each nz entry, the row index. */
  double *value; /* For each nz entry, the value. */
};

Ceux-ci correspondent bien aux emplacements d'un dgCMatrix matrice clairsemée.Donc, idéalement, je soulignerais simplement les tableaux internes du dgCMatrix (après avoir vérifié que la fonction C ne jouera pas avec les données [ce que je n'ai pas encore fait]).

Pour *value, il semble que je pourrai utiliser REALSXP ou quelque chose pour obtenir un double[] comme voulu.Mais pour *pointr et *rowind, je ne suis pas sûr de la meilleure façon d'accéder à un tableau approprié.Dois-je parcourir les entrées et les copier dans de nouveaux tableaux, en les diffusant au fur et à mesure ?Ou peut Rcpp fournir du sucre ici ?C'est la première fois que j'utilise vraiment Rcpp et je ne le maîtrise pas encore bien.

Merci.

Modifier:J'ai également des problèmes de liaison que je ne comprends pas :

Error in dyn.load(libLFile) : 
  unable to load shared object '/var/folders/TL/TL+wXnanH5uhWm4RtUrrjE+++TM/-Tmp-//RtmpAA9upc/file2d4606aa.so':
  dlopen(/var/folders/TL/TL+wXnanH5uhWm4RtUrrjE+++TM/-Tmp-//RtmpAA9upc/file2d4606aa.so, 6): Symbol not found: __Z8svdLAS2AP4smatl
  Referenced from: /var/folders/TL/TL+wXnanH5uhWm4RtUrrjE+++TM/-Tmp-//RtmpAA9upc/file2d4606aa.so
  Expected in: flat namespace
 in /var/folders/TL/TL+wXnanH5uhWm4RtUrrjE+++TM/-Tmp-//RtmpAA9upc/file2d4606aa.so

Dois-je créer ma bibliothèque avec des indicateurs de compilation spéciaux ?

Modifier 2 :on dirait mon libargs Le paramètre n'a aucun effet, donc libsvd les symboles n’arrivent jamais dans la bibliothèque.Je ne trouve aucun moyen d'inclure des bibliothèques en utilisant cxxfunction() - voici ce que j'avais essayé, mais les paramètres supplémentaires (empruntés pour des vœux pieux) cfunction()) sont engloutis en silence :

fn <- cxxfunction(sig=c(nrow="integer", mi="long", mp="long", mx="numeric"), 
                  body=code,
                  includes="#include <svdlib.h>\n", 
                  cppargs="-I/Users/u0048513/Downloads/SVDLIBC", 
                  libargs="-L/Users/u0048513/Downloads/SVDLIBC -lsvd", 
                  plugin="Rcpp",
                  verbose=TRUE)

J'ai l'impression que je m'y prends mal dans tout ce processus, puisque rien ne fonctionne.Quelqu'un me donne un coup de pied dans la bonne direction ?

Était-ce utile?

La solution

J'ai décidé de publier également une requête sur la liste de diffusion Rcpp-devel et j'ai reçu de bons conseils et de l'aide de Dirk et Doug :

http://lists.r-forge.r-project.org/pipermail/rcpp-devel/2011-February/001851.html

Je ne suis toujours pas super-facile avec ce genre de choses, mais j'y arrive.=)

Autres conseils

J'ai fait quelque chose de similaire pour une interface [R]-Smalltalk l'année dernière et je l'ai fait de manière plus générique pour pouvoir transmettre toutes les données dans les deux sens en utilisant des tableaux d'octets :

En C j'ai :

DLLIMPORT void getLengthOfNextMessage(byte* a);
DLLIMPORT void getNextMessage(byte* a);

Dans R :

getLengthOfNextMessage <- function() {
    tmp1  <- as.raw(rep(0,4))
    tmp2<-.C("getLengthOfNextMessage", tmp1)
    return(bvToInt(tmp2))
}

receiveMessage <- function() {
    #if(getNumberOfMessages()==0) {
    #   print("error: no messages")
    #   return();
    #}
    tmp1<-as.raw(rep(0, getLengthOfNextMessage()+getSizeOfMessages()))
    tmp2<-.C("getNextMessage", tmp1)
    msg<-as.raw(tmp2[[1]])
        print(":::confirm received")
        print(bvToInt(msg[13:16]))
    # confirmReceived(bvToInt(msg[13:16]))
    return(msg)
}

J'ai commenté l'utilisation des fonctions getNumberOfMessages() et confirmReceived() qui sont spécifiques au problème que je devais résoudre (communications multiples aller-retour).Essentiellement, le code utilise l'argument byte-array pour transférer les informations, d'abord les informations de 4 octets, puis les données réelles.Cela semble moins élégant (même pour moi) que d'utiliser des structures, mais je l'ai trouvé plus générique et je peux me connecter à n'importe quelle DLL, transférant n'importe quel type de données.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top