Objet qui gère les matrices ?

fouffouf Membre
22:56 modifié dans API AppKit #1
A propos de matrices, existe-t-il en Cocoa un objet qui gere les matrices (NSMatrix c'est surtout pour les vues). Un truc qui soit equivalent a la declaration en C
NSObject [a] matrice;

Perce qu'avec cette ligne on peut arriver a avoir des matrices en dimension 2,3 voire 4. Pratique

Réponses

  • mpergandmpergand Membre
    22:56 modifié #2
    A propos de matrices, existe-t-il en Cocoa un objet qui gere les matrices (NSMatrix c'est surtout pour les vues). Un truc qui soit equivalent a la declaration en C
    NSObject [a] matrice;

    Perce qu'avec cette ligne on peut arriver a avoir des matrices en dimension 2,3 voire 4. Pratique


    Le plus simple est d'utiliser les tableaux du C:
    // tableau de 10x10 pointeurs sur NSObject
    NSObject **monTableau=malloc(10*10*sizeof(NSObject*));
    ou
    // tableau de 10x10x10 pointeurs sur NSObject
    NSObject ***monTableau=malloc(10*10*10*sizeof(NSObject*));

    et pour libérer la mémoire:
    free(monTableau);

    On peut aussi utiliser NSArray, pour un tableau à  2 dimensions, ça sera un NSArray de NSArray, pour 3 dimensions, un NSArray de NSArray de NSArray ::) et ainsi de suite (c'est pas la soluce la plus efficace, le C est bien plus rapide), et il sera certainement plus pratique de se faire une petite classe de gestion de ces arrays pour pouvoir faire, par exemple:
    [multiArray getObjectAtX:0 Y:1 Z:5];

    un bon exercice de prog objet ;)
  • fouffouf Membre
    22:56 modifié #3
    dans 1106909281:

    il sera certainement plus pratique de se faire une petite classe de gestion de ces arrays pour pouvoir faire, par exemple:
    [multiArray getObjectAtX:0 Y:1 Z:5];

    un bon exercice de prog objet  ;)


    Je vais essayer ca ce soir, je vous envoie ca quand j'ai fini. Enfin, j'essaye ...  ::)
  • fouffouf Membre
    janvier 2005 modifié #4
    Oui euuhhh ::), mpergand, comment tu fait pour recupere une valeur dans le tableau ??
  • muqaddarmuqaddar Administrateur
    22:56 modifié #5
    Réponse de mpergand :

    Pour remplir un élément du tableau:
    multiArray[1][5]=monObject;

    et pour le récupérer:
    monObject=multiArray[1][5];

    J'ai scindé le sujet au moment où il postait. sorry ;)
  • fouffouf Membre
    22:56 modifié #6
    Si j'ai bien compris, je creer un tableau Obj-C par

    NSObject **tableau = malloc(X*Y*sizeOf(NSObject *));

    Et je recupere la valeur par

    id toto = tableau[1][5];

    Juste une question, a quoi sert sizeOf() ?? J'ai un peu de mal la :why?:
  • mpergandmpergand Membre
    janvier 2005 modifié #7
    j'ai trouvé un tuto multi array

    Bon, un exemple qui marche :)
    <br />// allocation de 10*10 pointeurs de NSObject<br />// se lit (*t)                    pointeur<br />//         (*t)[10]             de 10<br />// NSObject* (*t)[10]     pointeurs de NSObject <br /><br />NSObject* (*t)[10]=malloc(10*10*sizeof(NSObject*));<br /><br />// affectation<br />t[0][1]=[NSString stringWithCString:&quot;chaine1&quot;];<br />t[2][4]=[NSString stringWithCString:&quot;chaine2&quot;];<br />t[9][9]=[NSString stringWithCString:&quot;chaine3&quot;];<br /><br /><br />// on récupère<br />NSString* s1=t[0][1];<br />NSString* s2=t[2][4];<br />NSString* s3=t[9][9];<br /><br />NSLog(@&quot;%s %s %s&quot;,[s1 cString],[s2 cString],[s3 cString]];<br /><br />free(t);<br />
    
  • fouffouf Membre
    22:56 modifié #8
    Bon, j'ai pas vraiment utiliser le lien que m'a passe mpergand mais j'arrive a une ebauche de code :
    Matrix.h
    <br />#import &lt;Cocoa/Cocoa.h&gt;<br /><br />#define SIZE 256<br /><br />@interface Matrix : NSObject {<br />	unsigned int dimension;<br />	<br />	//unsigned int toto;<br />	unsigned int Xcount;<br />	unsigned int Ycount;<br />	unsigned int Zcount;<br />	<br />	//NSObject * Array;<br />	//NSObject **TwoDMatrix;<br />	//NSObject ***ThreeDMatrix;<br />	id matrix [SIZE][SIZE][SIZE]; <br />}<br /><br />@end<br />
    


    et Matrix.m

    <br />#import &quot;Matrix.h&quot;<br />#import &lt;Cocoa/Cocoa.h&gt;<br /><br /><br />@implementation Matrix<br /><br />-(id) init <br />{<br />	dimension = 0;<br />	<br />	return self;<br />}<br /><br />-(id) initWithDimension:(unsigned int)d Xcount:(unsigned int)x Ycount:(unsigned int)y Zcount:(unsigned int)z<br />{<br />	<br />	Xcount = x;<br />	Ycount = y;<br />	Zcount = z;<br />		<br />	dimension = d;<br />	if (dimension &gt; 3) dimension = 3;<br />		<br />	return self;<br />}<br /><br />-(int) dimension<br />{<br />	return dimension;<br />}<br /><br />- (void) setObject:(id)object forX:(unsigned int)x Y:(unsigned int)y Z:(unsigned int)z<br />{<br />	id matrixObject = matrix[x][y][z];<br />	<br />	if(object==matrixObject) return;<br />	<br />	if(matrixObject != nil) [matrixObject release];<br />	<br />	matrixObject = object;<br />	<br />	[matrixObject retain];<br />}<br /><br />- (id) objectForX:(unsigned int)x Y:(unsigned int)y Z:(unsigned int)z<br />{<br />	return matrix[x][y][z];<br />}<br />@end<br />
    


    Il faut encore que j'ecrive le dealloc.

    Je ne sais pas si c'est la meilleure methode mais ca a l'air de tenir debout.

    En ce qui concerne les variable Xcount, Ycount, Zcount et dimension, elles sont la pour eviter un depassement de tableau et pour simuler un tableau de taille variable. Il faut juste que j'implemente les routines pour permettre l'utilisation de ces variables. Je ne sais pas si j'aurais le temps d'ici Lundi (commentaire composé sur Anouilh  ??? Super non ?  :o )
  • mpergandmpergand Membre
    22:56 modifié #9
    Autre tuto pas mal Pointers

    Pour plus de souplesse, il va falloir utiliser les pointeurs plutôt des tableau [][]

    La première chose à  faire, c'est d'utiliser un pointeur générique pour stocker le bloc mémoire:

    void* *blocMem=null; // pointeurs de pointeurs (4octets)

    si j'alloue de la mem pour 100 pointeurs:
    blocMem=malloc(100*sizeof(void*);

    Ce bloc mem peut représenter différents tableaux, par ex:

    [10][10] ou [4][25] ou [50][2] etc

    il suffira de définir le bon type de pointeurs au moment de l'écriture et la lecture dans le tableau, ex:
    <br />initWithX:10 Y:5<br /><br />blocMem=malloc(x*y*sizeof(void*));  // 10x5<br /><br />// et pour lire un élement du tableau à  px py:<br /><br />void* (*t)[y]=(void*)blocMem;  // pour éviter que le compilo ne hurle !<br />element=t[px][py];<br /><br />//pour un tableau à  3 dimension:<br />void* (*t)[y][z]=(void*)blocMem; <br />element=t[px][py][pz];<br /><br />
    

    Jusqu'a présent on a fait des tableaux contenant des pointeurs d'objets, on peut bien sur le faire pour pour des int, long ...
    blocMem=malloc(x*y*sizeof(int)); //pour un tableau de int
    blocMem=malloc(x*y*sizeof(long)); //pour un tableau de long
    blocMem=malloc(x*y*sizeof(maStruct)); //pour une structure perso

    Dernière chose que tu peux faire, c'est un contrôle de débordement des limites du tableau, ce que le C ne fait pas, et lancer une exception lors d'un débordement (comme en java)

    Voilà  pas mal de boulot en fait !
  • fouffouf Membre
    22:56 modifié #10
    Dernière chose que tu peux faire, c'est un contrôle de débordement des limites du tableau, ce que le C ne fait pas, et lancer une exception lors d'un débordement (comme en java)


    Comment fait-on pour le ver des execptions en C ? (en java je sais, mais en C  B) )

    J'avance petit a petit mais c'est dur  :( Vais-je y arriver ?? Oxitan, tu devrais faire un sondage  ;)
  • mpergandmpergand Membre
    22:56 modifié #11
    dans 1107359283:

    Dernière chose que tu peux faire, c'est un contrôle de débordement des limites du tableau, ce que le C ne fait pas, et lancer une exception lors d'un débordement (comme en java)


    Comment fait-on pour le ver des execptions en C ? (en java je sais, mais en C  B) )



    Itou, jamais fait ça en ObjectiveC  :o

    Exception Handling
  • fouffouf Membre
    22:56 modifié #12
    Bon, fouf au rapport :

    j'ai le code :
    <br />- (void) setObject:(id)object forX:(unsigned int)x Y:(unsigned int)y Z:(unsigned int)z<br />{<br />	void *matrixObject;<br />	void* (*t)=(void*)matrix;<br />	matrixObject=t[x][y][z];<br />	<br />	if(object==matrixObject) return;<br />	<br />	if(matrixObject != nil) <br />		<br />		matrixObject = object;<br />	<br />	switch(dimension){<br />		case 1 :<br />			matrix[x]=matrixObject;<br />			break;<br />		case 2 :<br />			matrix[x][y]=matrixObject;<br />			break;<br />		case 3 :<br />			matrix[x][y][z]=matrixObject;<br />			break;<br />	}<br />}<br /><br />
    


    et le retour du compilo :
    Matrix.m: In function `-[Matrix setObject:forX:Y:Z:]':
    Matrix.m:52: warning: dereferencing `void *' pointer
    Matrix.m:52: error: void value not ignored as it ought to be
    Matrix.m:65: warning: dereferencing `void *' pointer
    Matrix.m:65: error: invalid use of void expression
    Matrix.m:68: warning: dereferencing `void *' pointer
    Matrix.m:68: error: void value not ignored as it ought to be


    Avis aux programmeurs C : je suis dans la merde  :why?:
    Les warnings, j'ai compris ce que c'etait : rien d'important. Mais les erreures la ???
    Dis mpergand, t'as deja fait tout le code. T'aurais pas une idee sur l'assignement des pointeurs ?

    A L'AIIIIIIIIIIIIDDDDEEEEEEE  :why?:
  • mpergandmpergand Membre
    février 2005 modifié #13
    <br /> (void) setObject:(id)object forX:(unsigned int)x Y:(unsigned int)y Z:(unsigned int)z<br />{<br /><br />switch(dimension)<br />     {<br />     case 1:<br />     id *t=matrix;<br />     t[x]=object;<br />    break;<br /><br />    case 2:<br />    id (t*)[YDim]=matrix;      // YDim dimension du tableau en Y<br />    t[x][y]=object;<br />    break;<br /><br />    case 3;<br />     id (t*)[YDim][ZDim]=matrix;<br />     t[x][y][z]=object;     // YDim dimension du tableau en Y et ZDim en Z<br />     break;<br />}<br />
    


    Si j'étais toi, je ferais des méthodes séparées:

    (void) setObject:(id)object forX:(unsigned int)x
    et
    (void) setObject:(id)object forX:(unsigned int)x Y:(unsigned int)y
    et
    (void) setObject:(id)object forX:(unsigned int)x Y:(unsigned int)y Z:(unsigned int)z
  • fouffouf Membre
    22:56 modifié #14
    Bon, euh, sur ce coup la, je suis un peu nul. J'aurais du mieux relire ton post de samedi.
    Si j'étais toi, je ferais des méthodes séparées

    C'est ce que je pensai faire.

    C'est promis, jessaye ce soir (enfin j'espere ;))
  • fouffouf Membre
    22:56 modifié #15
    Bon bon bon, le code que tu m'as fourni marche tres bien mpergand, a une chose pres : on initialise un tableau avec une taille variable. Evidemment le compilo hurle.

    Finalement, je pense que je vais revenir a la version avec des tableaux tout bete. C'est peut-etre mois souple, mais c'est plus simple.

    o:) mpergand, pardonne moi  o:)
  • mpergandmpergand Membre
    22:56 modifié #16
    dans 1107628209:

    Bon bon bon, le code que tu m'as fourni marche tres bien mpergand, a une chose pres : on initialise un tableau avec une taille variable. Evidemment le compilo hurle.


    C'est quoi le problème exactement ?


  • mpergandmpergand Membre
    22:56 modifié #17
    Bon, comme tu sembles un peu bloqué  ::) voici un exemple vite fait et sans aucune  prétention d'efficacité:

    MultiArray Demo

    Néanmoins, il m'est venu l'envie d'effectuer quelques tests et de comparer les résultats avec mon langage favori ...
    Le code Java se résume à  des boucles:
    <br />for(int x=0;x&lt;dx;x++)<br />	for(int y=0;y&lt;dy;y++)<br />		a1[x][y]=x*dy+y+1.0f;<br />
    

    et il est sûr que Java fait des prouesses d'optimisation sur ce genre de boucles for imbriquées.
    On pourrait chercher à  optimiser la partie contrôle et recherche de l'adresse dans la classe MultiArray, mais je pense que ça ne changerait pas grand chose, les appels en ObjC sont très couteux...

    Test sur iBook 600 Mhz 10.3.7 :


    [Fichier joint supprimé par l'administrateur]
  • fouffouf Membre
    22:56 modifié #18
    Merci beaucoup mpergand.

    La difference entre les deux langages sont surprenant plus d1 seconde  ???
    En tout cas, bravo pour ton boulot. Je pense que j'aurais besoin de m'en servir d'ici peu. Je te dirai alors comment ca marche en Obj-C.

    Re-merci
  • mpergandmpergand Membre
    22:56 modifié #19
    Une piste pour optimiser le code objc: supprimer les appels à  isValideRange et addressForIndexes, quitte à  dupliquer le même code dans itemAt et setItemAt
Connectez-vous ou Inscrivez-vous pour répondre.