calcul de distance

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

CHLEMAIRE Nadia
Messages : 5
Enregistré le : 27 Avr 2007, 14:36

calcul de distance

Messagepar CHLEMAIRE Nadia » 27 Avr 2007, 17:48

Bonjour,
cela fait 4 mois que j'apprends à me servir du langage R et j'ai un projet a présenter pour mes exams. je dois créer une fonction qui calcule des ditances entre des points.


Soit une grille G de Z*Z de taille (2,2) (puis (3,3)…).
Chaque point de la grille est déterminé par ses coordonnées entières X,Y, et prend une valeur binaire +1 ou –1 (notée x).
La grille est représentée par une matrice taille (2,2) (puis (3,3)…), dont les coefficients ont pour valeur +1 ou –1.
On définit sur cette grille une distance entre deux points A et B de coordonnées respectives (x1, y1) et (x2,y2) par : d(A,B) = abs(x1-x2) + abs(y1 – y2)
La matrice des distances pour une grille G de taille (n,n) (ayant donc n2 points) est une matrice D de taille (n2, n2) dont l’élément de position i,j correspond à la distance entre les deux points
numérotés i et j.
On souhaite :
1. Calculer cette matrice de distances
2. Calculer pour une grille donnée (choisie au hasard) la fonction U(G) qui est la somme des valeurs xixj pour tous les couples de points (i,j) vérifiant d(A,B)=1
Réaliser les deux étapes précédentes pour des grilles choisies au hasard et de différentes
tailles (n=2,3,4,5…)

Pour la premiere question j'ai réussi a créer une fonction qui calcule la distance entre deux points:

d=function(x1,y1,x2,y2){
di=abs(x1-x2)+abs(y1-y2)
print(di)
}

Mais de cette maniere je suis obligée de rentrer les coordonnées un par un. J'ai donc essayé de faire en sorte de ne rentrer que le nom des points. Ca ne marche que si je cherche la distance enter a et b; mais ca ne fonctionne plus quand je cherche le distance entre a et a ( ce qui devrait normalement me donner O ).

d=function(a,b){
a=c(x[1],y[1])
b=c(x[2],y[2])
x[1]=0
y[1]=0
x[2]=1
y[2]=5
di=abs(x[1]-x[2])+abs(y[1]-y[2]);
print(di)
}

Donc voici mon premiere probleme.

Ensuite, si j'ai une matrice (2,2) j'ai donc 4 points :
a=0,0
b=1,0
c=1,1
d=0,1
J'assaie de créer une fonction qui calcule la distance entre n'importe quel points, c'est a dire, si j'ecris : d(c,b) la fonction calcule la distance entre le point c et le point b et affiche donc 1.
J'ai pensé qu'il fallait créer une boucle, mais je n'y arrive pas :


d=function(a,b){
a=c(x1,y1)
b=c(x2,y2)
c=c(x3,y3)
d=c(x4,y4)
di=abs(x[i]-x[j])+abs(y[i]-y[j]);
for(i in 1:4)
for(j in 1:4)
print(di);
}
x1=0
y1=0
x2=1
y2=0
x3=1
y3=1
x4=1
y4=0

J'ai essayé en entrant un par un les coordonnée, sans succes:
d=function(x1,y1,x2,y2){
x[1]=0
y[1]=0
x[2]=1
y[2]=0
x[3]=1
y[3]=1
x[4]=0
y[4]=1
d(x[i],y[i],x[j],y[j])
for(i in 1:4)
for(j in 1:4)
di=abs(x[i]-x[j])+abs(y[i]-y[j])
print(di)
}

Il y a un message d'erreur qui apparait souvent:
Erreur : évaluations trop profondément imbriquées : récursion infinie / options(expressions=) ?

Je ne comprends pas ce que ca veut dire.

Par contre il y a tout de meme quelque chose que je pense avoir réussis, ou du moins qui pourrait etre une piste, c'est la matrice de distance. c'est a dire, qu'on bidouillant un peu je trouve une suite de chiffre qui correspond a ma matrice de distance sauf que ca n'est pas sous forme de matrice:

for (i in 1:4){
for (j in 1:4){
x[1]=0
y[1]=0
x[2]=0
y[2]=1
x[3]=1
y[3]=1
x[4]=1
y[4]=0
di=abs(x[i]-x[j])+abs((y[i]-y[j]))
print(di)}}
[1] 0
[1] 1
[1] 2
[1] 1
[1] 1
[1] 0
[1] 1
[1] 2
[1] 2
[1] 1
[1] 0
[1] 1
[1] 1
[1] 2
[1] 1
[1] 0

Si quelqu'un peut m'aider pour répondre à la premiere question... merci.

Nicolas Péru
Messages : 1408
Enregistré le : 07 Aoû 2006, 08:13

Messagepar Nicolas Péru » 27 Avr 2007, 20:27

as tu un peu regardé comment est implémenté la fonction dist() ? Cela pourrait peut être t'aider un peu.
Je n'ai pas le temps de regarder plus avant ton code pour le moment mais en regardant rapidement j'ai l'impression que tu as des erreurs sur les boucles (il manque des accolades).

CHLEMAIRE Nadia
Messages : 5
Enregistré le : 27 Avr 2007, 14:36

Messagepar CHLEMAIRE Nadia » 28 Avr 2007, 08:26

S'il vous plait, pouvez vous etre plus explicite car c'est la premiere fois que je créer une fonction sous R. Vous dite qu'il me manque des accolades, mais dabord, sur quelle fonction me conseillez-vous de travailler? Laquelle est la moins fausse?
Et deuxiemement, je ne vois pas comment est implémenter la fonction dist()?

CHLEMAIRE Nadia
Messages : 5
Enregistré le : 27 Avr 2007, 14:36

Messagepar CHLEMAIRE Nadia » 28 Avr 2007, 13:49

Bonjour, j'ai réessayé en rajoutant les accolades mais ca ne marche toujours pas.

d=function(x1,y1,x2,y2){
x[1]=0
y[1]=0
x[2]=1
y[2]=0
x[3]=1
y[3]=1
x[4]=0
y[4]=1
for(i in 1:4) {
for(j in 1:4){
di=abs(x[i]-x[j])+abs(y[i]-y[j])
d(x[i],y[i],x[j],y[j])
print(di)
}}}

Est-ce que quelqu'un peut me dire ou sont mes erreurs :?:
Merci.

Renaud Lancelot
Messages : 2484
Enregistré le : 16 Déc 2004, 08:01
Contact :

Messagepar Renaud Lancelot » 28 Avr 2007, 15:23

CHLEMAIRE Nadia a écrit :S'il vous plait, pouvez vous etre plus explicite car c'est la premiere fois que je créer une fonction sous R. Vous dite qu'il me manque des accolades, mais dabord, sur quelle fonction me conseillez-vous de travailler? Laquelle est la moins fausse?
Et deuxiemement, je ne vois pas comment est implémenter la fonction dist()?


Il suffit de taper le nom de la fonction pour voir le code:

Code : Tout sélectionner

> dist
function (x, method = "euclidean", diag = FALSE, upper = FALSE,
    p = 2)
{
    if (!is.na(pmatch(method, "euclidian")))
        method <- "euclidean"
    METHODS <- c("euclidean", "maximum", "manhattan", "canberra",
        "binary", "minkowski")
    method <- pmatch(method, METHODS)
    if (is.na(method))
        stop("invalid distance method")
    if (method == -1)
        stop("ambiguous distance method")
    N <- nrow(x <- as.matrix(x))
    d <- .C("R_distance", x = as.double(x), nr = N, nc = ncol(x),
        d = double(N * (N - 1)/2), diag = as.integer(FALSE),
        method = as.integer(method), p = as.double(p), DUP = FALSE,
        NAOK = TRUE, PACKAGE = "stats")$d
    attr(d, "Size") <- N
    attr(d, "Labels") <- dimnames(x)[[1]]
    attr(d, "Diag") <- diag
    attr(d, "Upper") <- upper
    attr(d, "method") <- METHODS[method]
    if (method == 6)
        attr(d, "p") <- p
    attr(d, "call") <- match.call()
    class(d) <- "dist"
    return(d)
}
<environment: namespace:stats>


En l'occurrence, ça ne fait que repousser le pb dans la mesure où le coeur de la fct est écrit en C:

Code : Tout sélectionner

    d <- .C("R_distance", x = as.double(x), nr = N, nc = ncol(x),
        d = double(N * (N - 1)/2), diag = as.integer(FALSE),
        method = as.integer(method), p = as.double(p), DUP = FALSE,
        NAOK = TRUE, PACKAGE = "stats")$d


Toutefois, si vous connaissez le langage C, il suffit de récupérer les sources de R sur le CRAN et de regarder comment la fonction C appelée R_distance est programmée.

Renaud

CHLEMAIRE Nadia
Messages : 5
Enregistré le : 27 Avr 2007, 14:36

Messagepar CHLEMAIRE Nadia » 28 Avr 2007, 16:36

Toutefois, si vous connaissez le langage C, il suffit de récupérer les sources de R sur le CRAN et de regarder comment la fonction C appelée R_distance est programmée.


Je ne connais pas beaucoup le langage C, mais je veux bien voir ce que donne la fonction R_distance.
Mais comment fait-on pour récupérer les sources de R sur le CRAN?
Et comment cela va t-il m'aider a créer ma fonction de distance?
Merci!

CHLEMAIRE Nadia
Messages : 5
Enregistré le : 27 Avr 2007, 14:36

Messagepar CHLEMAIRE Nadia » 01 Mai 2007, 16:20

merci quand meme pour votre aide

Renaud Lancelot
Messages : 2484
Enregistré le : 16 Déc 2004, 08:01
Contact :

Messagepar Renaud Lancelot » 01 Mai 2007, 16:54

Voir la section "Software" --> "R source" et choisir celles qui vous intéressent. Il faut alors charger les sources (un peu plus de 14 Mo pour R 2.5.0), décompacter l'archive et localiser le fichier qui vous intéresse, en l'occurrence distance.c

Avec la source C et le code R de la fonction dist, vous avez alors tout ce qui est nécessaire pour créer votre fonction, mais rien ne vous oblige à suivre cette voie. Il est même probable que ce serait prendre un marteau pour écraser une mouche, mais nous ne connaissons pas le niveau de la formation que vous suivez ni l'exigence de vos enseignants. Si c'est juste une introduction à R, ne vous lancez pas dans tout ça.

Renaud


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité