# Travailler avec des matrices en objectiv-C



## TopCao (3 Janvier 2011)

Salut,

je débute, merci de votre indulgence.

Je souhaiterai créer un tableau NSArray ou NSMutableArray contenant des int
En effet, mon programme va chercher dans un fichier tiers des variables que je souhaiterai enregistrer dans un tableau dont je ne connais pas la taille a priori.

J'ai essaye de faire : 


```
NSMutableArray *bValues ;
 
- (long) filterImage:(NSString*) menuName
{
(...)
int val = XXX;
[bValues addObject:val];
 
}
(...)
-(IBAction) computeProg:(id)sender;
{
(...)
int bVal = [bValues objectAtIndex:1];
(...)
}
 
Si je fais un NSLog sur bValues, soit dans filterImage soit dans computeProg, je me retrouve avec un (null)
Un petit coup de main serait le bienvenu
 
A+
```


----------



## Céroce (3 Janvier 2011)

Les classes de collection (dont NS(Mutable)Array) ne peuvent contenir que des objets.

Tu pourrais travailler avec la classe NSNumber qui permet d'encapsuler un nombre:

```
NSMutableArray *numbers = [[NSMutableArray alloc] initWithCapacity:20];
NSNumber *number = [NSNumber numberWithInt:13];
[numbers addObject:number];

// Plus loin, quand numbers n'est plus nécessaire:
[numbers release];
```

Mais je le déconseille, parce que les calculs ne peuvent être effectués que sur des types primitifs et pas des objets. Tu serais obligé d'écrire quelque chose comme ça:

```
int entier3 = [[numbers objectAtIndex:3] intValue];
int entier7 = [[numbers objectAtIndex:7] intValue];

int produit = entier3 * entier7;
```

Ce qui est inutilisable quand les calculs sont nombreux.

L'autre solution est d'utiliser les tableaux à la façon du langage C:

```
int numbers[20];
numbers[0] = 13;
```

Ce sera plus pratique:

```
int produit = numbers[3] * numbers[7];
```

On voit ici clairement les limites d'Objective-C: c'est un compromis entre les concepts de la programmation objet, et le modèle de programmation du langage C. Bref, on est très loin de matlab

Le mieux serait d'utiliser des classes qui permettent d'encapsuler des matrices. Je t'avoue ne pas avoir trouvé de classe toute faite. Jette tout de même un il à NSAffineTransform, mais je pense que ce sera limité pour tes besoins.


----------



## ntx (3 Janvier 2011)

Céroce a dit:


> On voit ici clairement les limites d'Objective-C: c'est un compromis entre les concepts de la programmation objet, et le modèle de programmation du langage C. Bref, on est très loin de matlab


Ah le bon vieux C++ et sa surcharge d'opérateurs 


> Le mieux serait d'utiliser des classes qui permettent d'encapsuler des matrices.


Oui garde une représentation de tableau C pour ta matrice et encapsule ce "conteneur" dans une classe qui te permettra de définir une matrice d'une taille donnée lors de la construction d'une instance et où tu pourras implémentation les opérations de base dont tu as besoin (addition, multiplication, ...)


> Je t'avoue ne pas avoir trouvé de classe toute faite.


Si tu pars sur le principe proposé ci-dessus, tu peux essayer de trouver un exemple en Java pour t'inspirer, la "philosophie" est plus proche de celle de l'Obj-C (absence de la surcharge d'opérateur) par rapport à la façon de faire en C++.


----------



## TopCao (4 Janvier 2011)

En effet la solution 
int name _ = num;

répond parfaitement à mon problème, d'autant que les calculs ne sont pas énormes dans cette histoire

Merci bcp !!_


----------



## tatouille (4 Janvier 2011)

TopCao a dit:


> En effet la solution
> int name _ = num;
> 
> répond parfaitement à mon problème, d'autant que les calculs ne sont pas énormes dans cette histoire
> ...


_

ecris ca en C plain, ou utilise deja l'existant ..... tu connais un peu ce qu'est la vectorisation et les ecritures atomiques... et en plus ca depend de ton compiler... et de la platform comment sont "computés" les lvalues

http://developer.apple.com/library/...ce/Conceptual/vecLib/Reference/reference.html

si tu utilises des objets comme des hashmaps pour faire du calcul tu seras en bonne voie pour le guiness des inventions les plus debiles_


----------



## TopCao (4 Janvier 2011)

tatouille a dit:


> ecris ca en C plain, ou utilise deja l'existant ..... tu connais un peu ce qu'est la vectorisation et les ecritures atomiques... et en plus ca depend de ton compiler... et de la platform comment sont "computés" les lvalues
> 
> http://developer.apple.com/library/...ce/Conceptual/vecLib/Reference/reference.html
> 
> si tu utilises des objets comme des hashmaps pour faire du calcul tu seras en bonne voie pour le guiness des inventions les plus debiles


 
Je travaille sur Xcode en Objectiv-C pour développer un plugin pour Osirix (http://www.osirix-viewer.com/)
En gros tout l'environnement est déja programmé, l'objectif est de faire des calculs sur les images.


----------



## tatouille (4 Janvier 2011)

TopCao a dit:


> Je travaille sur Xcode en Objectiv-C pour développer un plugin pour Osirix (http://www.osirix-viewer.com/)
> En gros tout l'environnement est déja programmé, l'objectif est de faire des calculs sur les images.



les images ou plutot les raw data que tu utilises ne sont qu'un bitmap composé de chunk comme l'audio les packets network ecetera tout cela c'est kif kif bouricco, en cocoa tu as access a un objet qui te donne onfly la representation de ces data NSBitmapRef tu n'as besoin que de ca tu changes les pixels cree une nouvelle rep puis repaint 

Exemple:

```
Tatouille (C)

// assume RGB without alpha channel e.g opaque RGB raw data little endian
// http://en.wikipedia.org/wiki/Endianness
// http://en.wikipedia.org/wiki/BMP_file_format

RGB commun (avant, certain format l'utilise toujours)

// l'échantillon Rouge occupe 9 bits, l'échantillon Vert occupe 7 bits et l'échantillon 
// Bleu occupe 8 bits, pour un total de 24 bits par pixel. e,g 24bpp

RGB macos
// l'échantillon Rouge occupe 8 bits, l'échantillon Vert occupe 8 bits et l'échantillon 
// Bleu occupe 8 bits, pour un total de 24 bits par pixel. e,g 24bpp

RGBA (X) macos
// l'échantillon Rouge occupe 8 bits, l'échantillon Vert occupe 8 bits, l'échantillon 
 // Bleu occupe 8 bits, l'échantillon Alpha occupe 8 bits, 
pour un total de 32 bits par pixel. e,g 32bpp
```


```
Tatouille (C)

BGR swapping

indata is RGB 24bpp 8x8x8 e.g un pixel
outdata is BGR 24bpp 8x8x8 e.g un nouveau pixel

// shift end (left e.g endianess) + we want a 8bit mask at this index
int32_t red = (indata >> 16) & 0xFF; 
// shift middle + we want a 8bit mask at this index
int32_t green = (indata >> 8) & 0xFF; 
// shift begin  + we want a 8bit mask at this index
int32_t blue = (indata >> 0) & 0xFF; 

 // inverting in place
int32_t outdata = (blue << 16) | (green << 8) | (red << 0);
```


```
Tatouille (C)


some slang

8bits equals 1byte ce qu'on appel HALF WORD pourquoi? parce un 
mot va consommer 2bytes ( 2 lettres ou 1 lettre plus accent) e.g 16bits 
et une lettre et la representation minimale d'un mot 
(unité de base des alphabets latin ascii)

char is 8bits -> int8_t


16bits equals 2bytes ce qu'on appel WORD (short -> int16_t) 

32bits equals 4bytes ce qu'on appel DWORD (double word)  (int -> int32_t) 
(il n'y a que sous windows que tu trouveras un conversion forcée 
des ints en quad ils sont debiles je sais, donc bien penser a utiliser le type int32)

64bits equals 8bytes ce qu'on appel QWORD QUAD quatre 4x16bits (quad -> int64_t)
```


```
Tatouille (C)

 /*
*  NSColor *AUBitmapImageRepReadColorAverage(NSBitmapImageRep *aBitmapImageRep);
*/
NSColor *AUBitmapImageRepReadColorAverage(NSBitmapImageRep *aBitmapImageRep)
{    
    if (aBitmapImageRep) {
        NSInteger i = 0;
        NSInteger components[3] = {0,0,0};
        unsigned char *data = [aBitmapImageRep bitmapData];
        NSInteger pixels = ([aBitmapImageRep size].width *[aBitmapImageRep size].height);


        do {
            components[0] += *data++;
            components[1] += *data++;
            components[2] += *data++;
        } while (++i < pixels);


        CGFloat red = (CGFloat)components[0] / pixels / 256;
        CGFloat green = (CGFloat)components[1] / pixels / 256;
        CGFloat blue = (CGFloat)components[2] / pixels / 256;


        return [NSColor colorWithDeviceRed:red green:green blue:blue alpha:1.0];
    }


    return nil;
}
```
ou tu peux utiliser directement le CoreGraphics ou openGL si tu dois travailler avec un algo de reconnaissance de profondeur de pixel, toutes ces API te donnent access aux raw data ce que tu veux modifier en place ou non, si tu veux faire du realtime rendering et rapide tu peux aussi faire du GPGPU c'est a dire rendering directement en utilisant le GPU tu peux utiliser l'API  OpenCL sur les nouveaux macs


Objectiv-C  n'est qu'un runtime objet pour C tu peux y melanger du C du C++ et bien sur de l'inline assembleur  (parfois necessaire quand tu dois faire des gros calculs "in place (sans copy e.g realtime)" comme dans le cas d'une FFT fast fourier transformation, convolutions, square signal ecetera)


----------

