2017-01-15 2 views
1

J'essaye de traduire un script écrit en matlab en R. Le script mappe les coordonnées 1D aux coordonnées 2D basées sur la courbe de Hilbert.Comment traduire les fonctions bit à bit de matlab/C vers R? Cas particulier: algorithme de courbe de Hilbert

Il y a une ligne dans le script que je ne suis pas sûr de savoir comment traduire en R:

ry = mod (bitxor (uint8 (t), uint8 (rx)), 2) 

Je pense qu'il ya un paquet R avec la fonction BITXOR(), mais pas sûr de ce qu'il faut faire uint8().

Aide appréciée!

Le script Matlab complet peut être consulté ici:

https://people.sc.fsu.edu/~jburkardt/m_src/hilbert_curve/d2xy.m

La fonction pourriture() appelée dans le script est ici:

https://people.sc.fsu.edu/~jburkardt/m_src/hilbert_curve/rot.m

versions C se trouvent ici:

https://en.m.wikipedia.org/wiki/Hilbert_curve

Un peu de contexte, dans le cas où c'est intéressant: je suis un codeur amateur. Normalement, j'écris uniquement des programmes où je comprends le flux de la logique d'une ligne de code à l'autre. Dans ce cas, je ne comprends pas la logique, mais je sais ce que je veux faire et je le veux assez mal pour aller de l'avant plutôt aveuglément avec cette tâche.

En particulier, je n'ai aucune idée de ce que font les fonctions bitxor() et unint8(), bien que je comprenne ce qu'est une porte logique xor en principe.

Je ne vais pas me plaindre si une âme gentille là-bas traduit tout le script.

+1

Savoir ce _actual_ problème que vous essayez de résoudre serait beaucoup mieux, mais puisque vous ne nous avez pas dit que: https : //github.com/hrbrmstr/hilbert – hrbrmstr

+0

@hrbrmstr Le problème réel est de visualiser une série chronologique sous forme d'image. Par exemple, voyez à quoi ressemble le bruit rouge, bleu, brun, blanc en 2D. Peut-être qu'une chanson ou un discours serait intéressant à regarder. Je pense que votre code fonctionnera pour cela, mais j'ai du mal à le télécharger. Lorsque je suis vos instructions, je reçois un message d'erreur m'indiquant d'installer Rtools 3.4 depuis http://cran.r-project.org/bin/windows/Rtools/. Mais je ne peux pas comprendre comment faire cela. – ben

+0

Je suggère de ne pas utiliser le programme à des fins pratiques, car il est très inefficace si vous effectuez une recherche, vous pouvez trouver des programmes vectorisés plus efficaces tels que http://codegolf.stackexchange.com/a/102094/62451 – rahnema1

Répondre

2

Matlab à R

# start d2xy  
d2xy <- function (m, d) 
{ 
    m <- as.integer(m) 
    d <- as.integer(d) 

    n <- 2^m 
    x <- 0 
    y <- 0 
    t <- d 
    s <- 1 

    while (s < n){ 
    rx <- floor (t/2) %% 2 
    if (rx == 0){ 
     ry <- t %% 2 
    } else { 
     ry <- bitwXor(as.integer(t), as.integer(rx)) %% 2 
    } 

    xy <- rot (s, x, y, rx, ry) 
    x <- xy['x'] + s * rx 
    y <- xy['y'] + s * ry 
    t <- floor (t/4) 
    s <- s * 2 
    } 

    return(c(x = x, y = y))  
} 
# end d2xy 

# start rot 
rot <- function(n, x, y, rx, ry) 
{ 
    n <- as.integer(n) 
    x <- as.integer(x) 
    y <- as.integer(y) 
    rx <- as.integer(rx) 
    ry <- as.integer(ry) 

    if (ry == 0){ 
    if (rx == 1){ 
     x <- n - 1 - x 
     y <- n - 1 - y 
    } 
    t <- x 
    x <- y 
    y <- t 
    } 

    return(c(x = x, y = y)) 
} 
# end rot 

essais ci-dessus fonctionne par R

# vectorize our translated R function 
d2xy_R <- Vectorize(d2xy, c('m', 'd'))  
rm(d2xy) 

sont comparés Matlab à R traduites du code avec les fonctions de MATLAB

set.seed(1L) 
m <- 2 
d <- 5 
xx <- runif(n = m*d, min = 0, max = 1) 
mat_R <- d2xy_R(m = m, d = 1:d) 
mat_R 
#  [,1] [,2] [,3] [,4] [,5] 
# x.x 1 1 0 0 0 
# y.y 0 1 1 2 3 

comparer le mat_R sortie avec matlab sortie. Les deux sont identiques, donc aucun problème dans la traduction.

enter image description here

mat_R <- mat_R + 1 
coord2D_R <- matrix(xx[mat_R], nrow = m, ncol = d) 
rownames(coord2D_R) <- c('x', 'y') 

coord2D_R 
#  [,1]  [,2]  [,3]  [,4]  [,5] 
# x 0.3721239 0.3721239 0.2655087 0.2655087 0.2655087 
# y 0.2655087 0.3721239 0.3721239 0.5728534 0.9082078 

parcelle courbe hilbert

set.seed(1L) 
m <- 2 
d <- 50 
xx <- runif(n = m*d, min = 0, max = 1) 
mat_R <- d2xy_R(m = m, d = 1:d) 
mat_R <- mat_R + 1 
coord2D_R <- matrix(xx[mat_R], nrow = m, ncol = d) 
rownames(coord2D_R) <- c('x', 'y') 
plot(t(coord2D_R), type = 'l', col = 'red') 

enter image description here

Comparez Matlab et codes R traduit par @ hrbrmstr paquet de hilbert github

obtenir hilbert.cpp fichier de package hilbert hrbrmstr github

library('Rcpp') 
sourceCpp("hilbert.cpp") # compile C++ functions in hilbert.cpp file 
d2xy_Rcpp <- d2xy 
rm(d2xy) 

mat_Rcpp <- matrix(nrow = m, ncol = d) 
rownames(mat_Rcpp) <- c('x', 'y') 

for(i in seq_len(d)){ # for loop is introduced, because unlike the R translated code, the Rcpp function is not vectorized 
    xy <- d2xy_Rcpp(n = m, d = i) 
    mat_Rcpp['x', i] <- xy['x'] 
    mat_Rcpp['y', i] <- xy['y'] 
} 

mat_Rcpp 
#  [,1] [,2] [,3] [,4] [,5] 
# [1,] 0 1 1 0 0 
# [2,] 1 1 0 0 1 

comparer mat_Rcpp sortie avec mat_R et matlab sorties. Il ne correspond pas avec eux, donc il peut y avoir des bogues dans ce paquet ou le code matlab fourni a des problèmes avec lui.

mat_Rcpp <- mat_Rcpp + 1 
coord2D_Rcpp <- matrix(xx[mat_Rcpp], nrow = m, ncol = d) 
rownames(coord2D_Rcpp) <- c('x', 'y') 

coord2D_Rcpp 
#  [,1]  [,2]  [,3]  [,4]  [,5] 
# x 0.2655087 0.3721239 0.3721239 0.2655087 0.2655087 
# y 0.3721239 0.3721239 0.2655087 0.2655087 0.3721239 

Benchmark Matlab R traduit le code avec le paquet hilbert de hrbrmstr

library('microbenchmark') 
set.seed(1L) 
m <- 2 
d <- 5 
xx <- runif(n = m*d, min = 0, max = 1) 
microbenchmark(d2xy_R(m = m, d = d),  # matlab to R translation 
       d2xy_Rcpp(n = m, d = d), # @hrbrmstr - hilbert github package 
       times = 100000) 

# Unit: microseconds 
#     expr  min  lq  mean median  uq  max neval 
# d2xy_R(m = m, d = d) 169.382 177.534 192.422166 180.252 184.780 94995.239 1e+05 
# d2xy_Rcpp(n = m, d = d) 2.718 4.530 7.309071 8.606 9.512 2099.603 1e+05 
+0

(a) pourquoi une liste pour le retour? (b) il serait intéressant de comparer cela à github.com/hrbrmstr/hilbert – hrbrmstr

+1

oublié d'ajouter que c'est un excellent exemple de traduction pour des opérations comme celle-ci. shld être un bon ref pour les autres qui cherchent à faire des choses similaires avec d'autres algorithmes. J'ajouterais également un 'L' à la fin de tous les nombres numériques pour s'assurer qu'ils restent entiers pour les opérations mathématiques les plus rapides. – hrbrmstr

+0

@Sathish Oui, bien sûr, je suis très reconnaissant. Une chose: après vos modifications, en particulier la vérification de santé mentale, je reçois erreur: all (sapply (as.list (match.call()), is.integer)) n'est pas vrai. Voici ce que je fais: ord <-2 dim2D <-2^ord nCells <-dim2D^2 xx <-runif (n = nCellules, min = 0, max = 1) coord2D_list <-list() tapis ben