Newsgroup: it.comp.lang.c++
Titolo: Problema allocamento memoria con matrice

Alloco dinamicamente una matrice in questo modo:
   const int SizeX=limage->w*limage->h;
   const int SizeY=limage->h*limage->h;
    float** matrix;
    matrix=new float*[SizeY];
    for(int i=0;i<SizeX;++i)
        matrix[i]=new float[SizeY];
dove limage->h e limage->w sono rispettivamente altezza e larghezza di
un'immagine caricata da disco.
Il problema è che con immagini di dimesioni tipo 300*400 il programma
termina in modo anormale (dev c++), causa penso la troppa allocazione di
memoria, c'e' un modo per ovviare al problema?
Ciao e grazie per eventuali risposte
Gio

         matrix[i]=new float[SizeY];
Perché ne allochi SizeY se ne vuoi SizeX?????????????????
Kiuhnm

Se l'immagine č MxN...si vuole applicare uno sfocamento (Gauss Smoothing)
moltiplicando la matrice immagine MNx1 per una matrice di degradamento della
dimensione [MxN]x[MxN].

La matrice MN*1 che poi è un vettore ce l'ho gia', devo creare la matrice
MNxMN e riempirla con dei miei valori.
In realtà la matrice contiene per lo piu' zeri, pero' vorrei sapere se è
possibile ovviare al problema dell'allocamento, puo' sempre tornare utile.

 memoria, c'e' un modo per ovviare al problema?
Supponendo limage->w=300 e limage->h=400, si ha SizeX=120000 e SizeY=160000.
Supponendo che sia i puntatori che i float occupino 4 byte, la prima new 
alloca 160000 * 4 = 640000 byte, mentre le successive 120000 new 
allocano 160000 * 4 = 640000 byte ciascuna, per un totale di 640000 + 
120000 * 640000 = 76800640000 byte, ossia oltre 76 GigaByte. Con un 
sistema a 32 bit, non e' indirizzabile cosi' tanta memoria.
-- 
     Carlo Milanesi
 
http://digilander.libero.it/carlmila

         matrix[i]=new float[SizeY];
oltre a tutte le altre osservazioni, pertinenti, che già ti 
hanno esposto altri esperti, aggiungo un mio dubbio :
che ragione particolare hai di adottare le strategie di 
allocazione tipiche di una matrice "sparsa" (tipo quelle per 
righe di testo di lunghezza variabile), quando invece sai a 
priori che la larghezza è costante e, quindi, la tua matrice è 
per definizione rettangolare ?
Mi spiego meglio, a parte l'efficienza peggiore di n+1 new (dove 
  n è il numero di righe, o di colonne), e corrispettive delete, 
e l'indirezione meno efficiente, in effetti sprechi anche lo 
spazio addizionare per l'array di puntatori alle righe, quando 
con la matrice rettangolare basterebbe un unico puntatore 
all'elemento [0][0].
Vero che qualche volta, con memoria a tappo, allocare a 
smozziconi è più facilmente soddisfacibile dagli O.S. un po' 
antiquati (che non compattano la ram), ma questo imho è 
controbilanciato dal maggiore peso totale di risorse chieste. 
Considera inoltre che alcune volte il global heap del programma 
C++, o almeno lo era nelle versioni vecchie, era un blocco di 
memoria contigua, per cui allocare un blocco intero o 
spezzettato non cambiava necessariamente le cose.
Ciao
Soviet_Mario


 se limage->w > limage->h, matrix[i] sfonda l'array.
const int SizeY=limage->h*limage->h;
sarebbe limage->w*limage->h; ho notato prima l'errore che ho fatto in
trascrizione da codice alla mail.
Quindi circa 56GigaByte...considerando che la matrice è del tipo
a1   0   0 0 0 0 0 0 0 ...
a2 a1   0 0 0 0 0 0 0 ...
a3 a2  a1 0 0 0 0 0 0 ...
a4 a3  a2 0 0 0 0 0 0
a5 a4  ...
a6 a5
a7 a6
  0 a7
...
...
Mi devo inventare un algoritmo che moltiplichi questa matrice, senza
allocarla ma conoscendo i 7 calori, con la matrice immagine MN*1.
Ciao e grazie
Bye

 possibile ovviare al problema dell'allocamento, puo' sempre tornare utile.
Sinceramente, al posto della matrice gigante, userei un semplice filtro.
Comunque le alternative più ovvie sono due:
- definisci una funzione che calcoli l'elemento i,j della matrice 
gigante e la usi al posto di quest'ultima;
- non crei l'intera matrice gigante, ma soltanto la riga che ti serve. 
Praticamente crei la prima riga, la usi (prodotto scalare), la 
sovrascrivi con la riga seguente, la usi, ecc...
Kiuhnm

A priori non conosco la dimensione della matrice, dipende dall'immagine che
carico.
La matrice sarà grande [M*N]*[M*N]. Non potendola allocare staticamente,
ignorando a priori la dimensione, l'alloco in modo dinamico. Il tutto
funziona con immagine relativamente piccole, per via del problema sopra
elencato.
La matrice conterrà molti 0 e principalmente 7 valori che verranno disposti
all'interno della matrice come sopraesposti.

 all'interno della matrice come sopraesposti.
Appunto. Perchè minchia usare una matrice tanto gigantesca se poi devi 
fare i conti solo su pochissimi dei suoi elementi??
Se stai veramente cercando di implementare un filtro grafico su una 
immagine ti conviene usare un algoritmo che non richieda la matrice 
completa ma solo gli elementi strettamente necessari. Kiunhm ti ha già 
dato una dritta, fanne tesoro.

 fare i conti solo su pochissimi dei suoi elementi??
In realtà la matrice mi serve dopo per altri scopi, in particolare per
realizzare una blind deconvolution...quello esposto è solo un piccolo
frammento di un progetto + complesso. L'implementazione di una matrice così
grande per vedere se il progetto funziona, e cosi' è, ora si passerà ad
un'ottimizzazione, cioe' a non allocare la matrice, conoscendo l'ordine
nella matrice degli elementi escogitero' qualcosa per moltiplicare le 2
matrici e per farmi tornare l'elemento della matrice conoscendo le
coordinate riga colonna (questo per gli scopi successivi).
Ciao

Ed infatti mi ero perso il messaggio di Kiunhm per strada...

 Kiunhm
Sulla tastiera, "Kiuhnm" delinea una circonferenza di centro 'J' e 
raggio approssimativamente dist('J','K') ;)
Kiuhnm


Se davvero la matrice contiene solo 7 valori diversi da zero ti
conviene usare una rappresentazione che combini esplicitamente indici e
valori, ad esempio
typedef std::map<std::pair<int, int>, Valore> Matrice;
Nella quale inserire solo gli elementi diversi da zero.
Ciao,
Nicola

 raggio approssimativamente dist('J','K') ;)
Scusami per aver cannato scriverlo ;)....orpo hai ragione!
Bye
Gio

Pensandoci pero', dato l'utilizzo che ne devo fare di questa matrice di
dregado, la soluzione di creare una riga oppure una colonna (a secondo
dell'utilizzo), dato il consumo di memoria, non è male.
Domani mi dedichero' all'implementazione.
Bye
Gio

 La matrice sarà grande [M*N]*[M*N]. Non potendola allocare staticamente,
ma io non ti ho suggerito di farla statica (preallocata), ho 
solo suggerito di fare una sola allocazione dinamica (new) di 
una matrice rettangolare, se davvero è rettangolare.
Poi era un consiglio generale, e date le dimensioni della tua 
matrice avrebbe fallito lo stesso.
In tal caso, dato che la matrice stessa era prevalentemente 
vuota, non in velocità ma in occupazione di ram, effettivamente 
conveniva una notazione ancora più "sparsa" delle righe 
disseminate, come la soluzione suggeritati da Carlo Milanesi 
della mappa dei soli punti non nulli.
ciao
Soviet


 raggio approssimativamente dist('J','K') ;)
Massi e sassi possono rompermi le ossa, ma il sottile umorismo mi fa 
solo il solletico :-)

 suggeritati da Carlo Milanesi della mappa dei soli punti non nulli.
Dire che la matrice è sparsa è ancora riduttivo.
Siano S = {a,b,c} un sottoinsieme di R, e A la seguente matrice in S^{7x5}:
c
b c   0
a b c
   a b c
     a b c
   0   a b
         a
E' possibile definire g:N^2->S t.c. g(i,j) = A_{i,j} per i,j validi, in 
modo molto semplice:
g(i,j) = c, per i=j
          b, per i=j+1
          a, per i=j+2
          0 altrimenti
La generalizzazione dell'esempio è banale.
Kiuhnm