[c++]Scrittura dati colonna dopo colonna

franbisc
Dovrei stampare su consolle i numeri da 1 a 60,in modo che su ogni riga ce ne siano 5,ma devo riempire prima tutta la prima colonna con i numeri da 1 a 12,poi la seconda(da 13 a 25 e così via).

non ho la più pallida idea di come cominciare.In teoria cosa dovrei fare?

Risposte
hamming_burst
"Mifert4":
Dovrei stampare su consolle i numeri da 1 a 60,in modo che su ogni riga ce ne siano 5,ma devo riempire prima tutta la prima colonna con i numeri da 1 a 12,poi la seconda(da 13 a 25 e così via).

non ho la più pallida idea di come cominciare.In teoria cosa dovrei fare?


aritmetica modulare... :-)

franbisc
un altro aiutino..?

hamming_burst
metti:
N=numero massimo (60)
i=iteratore

cosa succede quando aumentando $i$ fino a $N+1$e ne fai il modulo cioè se $i=N$: \((i+1)\mod N \) cosa ritorna?
nel tuo caso sostituisci $+1$ con $+12$ e magia :-)

vict85
Non è affatto necessario. Il numero sulla colonna i,j con gli indici che partono da 0 è j*12+i+1. È esattamente il metodo per accedere ad una matrice, memorizzata come array e in column major (come in fortran).

[edit] il metodo è lo stesso... non è necessario l'uso dell'aritmetica modulare intendo.

hamming_burst
@vict85: ah in fortran l'accesso ad un array avviene per colonne, invece che per righe?

comunque sì alla fine con un metodo o l'altro si calcola, dovrebbe essere più intuitiva la tua :-)

franbisc
:roll: Proverò a decifrare i vostri indizi...

hamming_burst
"Mifert4":
:roll: Proverò a decifrare i vostri indizi...

dai un po' di fantasia :)
si parla di "indici", si parla di "iterazione", che ti viene in mente?

vict85
Si, è quasi l'unica cosa che so del fortran... http://en.wikipedia.org/wiki/Row-major_order

Il problema sorge perché lapack è scritto in fortran e quindi ti trovi molti algoritmi numerici lineari ottimizzati per il column major... Ovviamente il $+1$ si usa solo qui...

Si, in effetti la formula j*12+i+1 va letta come un doppo ciclo in cui i sono le righe e j sono le colonne. La differenza tra le due impostazioni è solo nel fatto che la sua usa un singolo ciclo, il modulo e un confronto mentre la mia due cicli annidati contenenti somme e stampe a video.

Non c'è molto da decifrare: ti abbiamo quasi scritto lo pseudocodice...

hamming_burst
"vict85":
Si, è quasi l'unica cosa che so del fortran... http://en.wikipedia.org/wiki/Row-major_order

Il problema sorge perché lapack è scritto in fortran e quindi ti trovi molti algoritmi numerici lineari ottimizzati per il column major... Ovviamente il $+1$ si usa solo qui...


interessante questa cosa, non ne ero a conoscenza.
Pensavo che quasi tutti i linguaggi implementasso gli array cercando di ottimizzare tipo il paging o comunque il tipo di indirizzamento dell'architettura del processore.
Sì qua siamo ad un livello di astrazione diverso, buono a sapersi, può tornare utile :-)

apatriarca
Paging e indirizzamento del processore non hanno alcun legame con la scelta di rappresentare le matrici in column-major o row-major. In memoria le due matrici appaiono identiche (anche se sono ovviamente una la trasposta dell'altra).

Ci sono molti vantaggi teorici nell'uso delle matrici colonna per i vettori. La ragione è principalmente legata alle trasformazioni lineari, in cui, rappresentando i vettori come matrici colonna, si ha lo stesso ordine per le composizioni di funzioni e moltiplicazioni di matrici. Usando matrici riga per le colonne si ottiene l'anello opposto (in cui si deve scambiare l'ordine delle matrici nel prodotto per ottenere lo stesso effetto). Ha quindi più senso pensare ai vettori come a matrici colonna e pensare alle applicazioni lineari (il loro duale) come a matrici riga. Se si pensa quindi ad una matrice come ad un "vettore di vettori" ha forse più senso usare matrici column major. In matematica, è in effetti più comune pensare alle singole colonne che alle righe.

A parte questo discorso teorico, l'uso di matrici colonna o riga ha effetto sull'implementazione delle operazioni su queste matrici. E' per esempio opportuno scambiare cicli interni ed esterni ed è spesso utile riordinare le operazioni in modo da iterare su colonne o righe. Ti faccio un esempio. Supponiamo di avere una matrice 4x4 e supponiamo che sia rappresentata in row-major. E' allora equivalente ad un array di vettori 4-dimensionali che chiamo r1, r2, r3 ed r4. Se moltiplichiamo ora questa matrice per un vettore v 4-dimensionale (matrice colonna) e memorizziamo il risultato in un vettore w, avremo il seguente codice:
w.x = dot(r1, v);
w.y = dot(r2, v);
w.z = dot(r3, v);
w.w = dot(r4, v);

dove dot è il prodotto scalare. Usando invece una matrice column-major (con colonne c1, c2, c3 e c4) il codice apparirà come il seguente:
w = v.x * c1;
w += v.y * c2;
w += v.z * c3;
w += v.w * c4;

Se il tuo processore supportasse l'istruzioni multiply-add ma non dot, allora questa seconda versione sarebbe potenzialmente migliore. Se la matrice fosse affine e il tuo processore supportasse il prodotto scalare nativamente, la versione row-major sarebbe migliore perché si avrebbe semplicemente w.w = v.w. Scambiando l'ordine della moltiplicazione, il discorso si capovolgerebbe. Ma in realtà, con il crescere della dimensione, questo genere di discorsi diminuiscono di importanza e diventa più che altro una preferenza personale.

P.S. I discorsi sulle matrici 4x4 sono abbastanza importanti quando si lavora in linguaggi come GLSL o HLSL che permettono di settare il layout di una matrice (se row-major o column-major). Cambiando il layout della matrice cambia l'implementazione delle operazioni sulle matrici (e si può quindi cambiare il layout in base all'uso).

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.