Newsgroup: it.comp.lang.c
Titolo: [FORSE OT] Implementazione FFT con tecnica butterfly

 
Leggendina:
Il programma usa la libreria complex.h della GNU Standard C Library (Lo sto
facendo da linux)...
COMPLEX ** A è una matrice di numeri complessi...
Da mie osservazioni sembra molto un errore di arrotondamento dovuto alla
trasformazione da reali a numeri macchina (errore di round-off), ma non so
come risolverlo...
Chi mi aiuta...
CIAO
-- 
Nicolò Risitano
nerocl...@gmail.com
http://risitano.altervista.org
Ragionate e visitate:
http://crimini.web-gratis.net/enter.htm

 COMPLEX ** A è una matrice di numeri complessi...
Mica vero. È un puntatore a un puntatore a un numero complesso.
A un bestio così si può applicare un solo operatore [], non due come fai
tu.
--
Cingar
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

Cingar wrote:

Eppure funge, il fatto è che ho un pò mentito dicendo che è una  matrice, in
realtà è un vettore di puntatori a vettori di complessi
--
x  --> [x,x,x,x,...]
x  --> [x,x,x,x,...]
x  --> [...]
.
.
.
--
Capito, non è propio una matrice, comunque funziona anche mettendo la doppia
parentesi...
Prove effettuate sul campo...
PS: 
Piccola dimenticanza nella legenda di prima...
la funzione reverse effettua la reverse binaria di un numero..
0110001 diventa 1000110


 Prove effettuate sul campo...
Su un ALTRO campo, però...


 
Il codice è quello, mettendo il blocco a 8 funziona perfettamente perche fa
il calcolo dividendo la matrice in blocchi di 8*8, se porto il blocco a N>8
non funziona più, io devo elaborare un immagine a 256*256, mettendo il
blocco a 256 viene un immagine molto confusa...
Ti poso l'Intero codice compreso di MAIN..
------------------------------------------------------------
#include <stdio.h>
#include <complex.h>
#include <math.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
typedef unsigned char CHAR;
typedef long double complex COMPLEX;
struct elem
{
  long double mod;
  long double fase;
  COMPLEX val;
  int rig;
  int col;
};
typedef struct elem ELEM;
void
Sort (ELEM T[], int root, int bottom, int *operation, int *test, int *swap)
{
  /* Questà funzione ordina l'albero  */
  int maxchild, child1, child2;
  ELEM temp;
  child1 = 2 * root + 1;
  child2 = 2 * (root + 1);
  operation = operation + 6;
  if (child1 <= bottom)
    {
      if (child1 == bottom)
        {
          maxchild = child1;
          operation++;
          test++;
        }
      else
        {
          maxchild = (T[child1].mod >= T[child2].mod) ? child1 : child2;
          test++;
          operation++;
          test++;
        }
      if (T[root].mod < T[maxchild].mod)
        {
          temp = T[root];
          T[root] = T[maxchild];
          T[maxchild] = temp;
          swap++;
          operation = operation + 3;
          Sort (T, maxchild, bottom, operation, test, swap);
        }
      test++;
    }
  test++;
}
void
heapsort (ELEM T[], int n)
{
  int i;
  ELEM temp;
  int operation = 0;
  int test = 0;
  int swap = 0;
  printf ("Ordino gli elementi\n");
  for (i = (n / 2) - 1; i >= 0; i--)
    {
      Sort (T, i, n - 1, &operation, &test, &swap);
      test++;
      operation++;
    }
  for (i = n - 1; i >= 1; i--)
    {
      test++;
      operation++;
      temp = T[0];
      T[0] = T[i];
      T[i] = temp;
      swap++;
      operation = operation + 3;
      Sort (T, 0, i - 1, &operation, &test, &swap);
      operation++;
    }
}
/*****************************************************/
ELEM *
ordina (COMPLEX ** A, int w, int h)
{
  ELEM *x;
  int i, j, k;
  //alloco il vettore di w*h elementi
  x = (ELEM *) malloc (sizeof (ELEM) * w * h);
  k = 0;
  for (i = 0; i < h; i++)
    {
      for (j = 0; j < w; j++)
        {
          x[k].val = A[i][j];
          x[k].rig = i;
          x[k].col = j;
          x[k].mod =
            ((crealf (x[k].val) * crealf (x[k].val)) +
             (cimagf (x[k].val) * cimagf (x[k].val)));
          x[k].fase = atan (cimagf (x[k].val) / crealf (x[k].val));
          k++;
        }
    }
  //ho riempito il vettore, adesso lo riordino
  //selectionSort(x, w*h);
  heapsort (x, w * h);
  return x;
}
void
compress (ELEM x[], int dim, float per)
{
  //per e' la percentuale di compressione
  int i, dim_per;
  printf ("Comprimo l'immagine\n");
  dim_per = (int) ((per * dim) / 100);
  //printf("%d\n", dim_per);
  for (i = 0; i < dim_per; i++)
    x[i].val = 0;
}
COMPLEX **
MatAlloc (int width, int heigth)
{
  int j;
  COMPLEX **M;
  M = (COMPLEX **) malloc (sizeof (COMPLEX *) * width);
  for (j = 0; j < width; j++)
    M[j] = (COMPLEX *) malloc (sizeof (COMPLEX) * heigth);
  return M;
}
COMPLEX **
restore (COMPLEX ** M, ELEM x[], int w, int h)
{
  int i;
  for (i = 0; i < (w * h); i++)
    M[x[i].rig][x[i].col] = x[i].val;
  return M;
}
COMPLEX **
ritaglia (COMPLEX ** A, int w, int h)
{
  int i, j = 0;
  for (i = 0; i < w; i++)
    {
      for (j = 0; j < h; j++)
        {
          if (crealf ((A[j][i])) > 255)
            A[j][i] = 255;
          if (crealf ((A[j][i])) <= 0)
            A[j][i] = 0;
          if (crealf ((A[j][i])) > 255)
            A[j][i] = 255;
          if (crealf ((A[j][i])) <= 0)
            A[j][i] = 0;
        }
    }
  return A;
}
void
write (COMPLEX ** A, char *file, int width, int heigth)
{
  int i, j;
  FILE *f;
  f = fopen (file, "w");
  for (i = 0; (i < width); i++)
    {
      for (j = 0; j < heigth; j++)
        fputc ((CHAR) (crealf (A[i][j])), f);
    }
  fclose (f);
}
COMPLEX **
read (char *file, int width, int heigth)
{
  int i, j;
  FILE *f;
  COMPLEX **mat;
  mat = (COMPLEX **) malloc (sizeof (COMPLEX *) * width);
  for (j = 0; j < width; j++)
    mat[j] = (COMPLEX *) malloc (sizeof (COMPLEX) * heigth);
  f = fopen (file, "r");
  for (i = 0; ((!feof (f)) && (i < width)); i++)
    {
      for (j = 0; ((!feof (f)) && (j < heigth)); j++)
        mat[i][j] = fgetc (f);
    }
  fclose (f);
  return mat;
}
void
stampaMat (COMPLEX ** A, int n, int m)
{
  int i, j;
  for (i = 0; i < n; i++)
    {
      for (j = 0; j < m; j++)
        {
          printf (" [%.0f %.0f] ", crealf (A[i][j]), cimagf (A[i][j]));
        }
      printf ("\n");
    }
  printf ("---------------------\n");
}
/*************************************************************************************/
// scambia i valori di due variabili complesse
void
swap (COMPLEX * a, COMPLEX * b)
{
  COMPLEX t;
  t = *a;
  *a = *b;
  *b = t;
}
CHAR
reverse (CHAR c, int N)
{
  CHAR t;
  int i;
  CHAR *v = (CHAR *) malloc (sizeof (CHAR) * N);
  if (!v)
    exit (0);
  t = 1;
  for (i = 0; i < N; i++)
    {
      v[i] = (c & t);
      if (v[i] >= 1)
        v[i] = 1;
      else
        v[i] = 0;
      t = t << 1;
    }
  t = 0;
  for (i = 0; i < N; i++)
    t = t + (v[i] * pow (2, ((N - 1) - i)));
  return t;
}
// sintesi secondo le righe della matrice A dei coefficienti
COMPLEX **
sintesiFourierMonRig (COMPLEX ** A, int N, int rig)
{
  unsigned int L, LE1, J, i, IP, mod, p;
  COMPLEX U = 1 + 0 * I;
  COMPLEX W, T;
  double M = log (N) / log (2); //logaritmo base 2 di N
  for (i = 0; i < N / 2; i++)
    swap (&(A[rig][i]), &(A[rig][reverse (i, M)]));
  i = 0;
  L = 1;
  do
    {
      LE1 = pow (2, L - 1);
      p = pow (2, L);
      U = 1 + 0 * I;
      W = (cos (2*M_PI / LE1) + I * (sin (2*M_PI / LE1)));
      J = 0;
      do
        {
          i = J;
          do
            {
              IP = i + LE1;
              T = A[rig][IP] * U;
              A[rig][IP] = A[rig][i] - T;
              A[rig][i] = A[rig][i] + T;
              i = i + p;
            }
          while (i < N);
          U = U * W;
          J++;
        }
      while (J < LE1);
      L++;
    }
  while (L <= M);
  return A;
}
//sintesi sulle colonne di A "manipolata" gia sulle righe.Genera quindi la
matrice finale dell'immagine digitalizzata
COMPLEX **
sintesiFourierMonCol (COMPLEX ** A, int N, int col)
{
  unsigned int L, LE1, J, i, IP, mod, p;
  COMPLEX U = 1 + 0 * I;
  COMPLEX W, T;
  double M = log (N) / log (2); //logaritmo base 2 di N
  for (i = 0; i < N / 2; i++)
    swap (&(A[i][col]), &(A[reverse (i, M)][col]));
  i = 0;
  L = 1;
  do
    {
      LE1 = pow (2, L - 1);
      p = pow (2, L);
      U = 1 + 0 * I;
      W = (cos (2*M_PI / LE1) + I * (sin (2*M_PI / LE1)));
      J = 0;
      do
        {
          i = J;
          do
            {
              IP = i + LE1;
              T = A[IP][col] * U;
              A[IP][col] = A[i][col] - T;
              A[i][col] = A[i][col] + T;
              i = i + p;
            }
          while (i < N);
          U = U * W;
          J++;
        }
      while (J < LE1);
      L++;
    }
  while (L <= M);
  return A;
}
//La Matrice A è la matrice 8x8 la matrice B è l'originale
COMPLEX **
creaMat (COMPLEX ** A, COMPLEX ** B, int offx, int offy, int blocco)
{
  int x, y = 0;
  for (x = 0; x < blocco; x++)
    {
      for (y = 0; y < blocco; y++)
        {
          A[y][x] = B[offy + y][offx + x];
        }
    }
  return A;
}
//La Matrice A è la matrice 8x8 la matrice B è l'originale
COMPLEX **
rispristinaMat (COMPLEX ** A, COMPLEX ** B, int offx, int offy, int blocco)
{
  int x, y = 0;
  for (x = 0; x < blocco; x++)
    {
      for (y = 0; y < blocco; y++)
        {
          B[offy + y][offx + x] = A[y][x];
        }
    }
  return B;
}
//effettua prima la sintesi sulle righe e poi sulle colonne
COMPLEX **
sintesiFourier (COMPLEX ** A, int w, int h, int blocco)
{
  int i, j, k = 0;
  COMPLEX **tmp = MatAlloc (blocco, blocco);
  //esegue l'IFT per tutte le righe della matrice dando in output valori
temporali parziali
  /*for (i = 0 ; i < h ; i++)
     A = sintesiFourierMonRig(A, w, i); */
  for (i = 0; i < w; i += blocco)
    {
      for (j = 0; j < h; j += blocco)
        {
          tmp = creaMat (tmp, A, i, j, blocco);
          for (k = 0; k < blocco; k++)
            tmp = sintesiFourierMonRig (tmp, blocco, k);
          A = rispristinaMat (tmp, A, i, j, blocco);
        }
    }
  //esegue l'IFT per tutte le colonne della matrice dando in output i punti
della funzione (l'immagine)
  /*for (i = 0 ; i < w ; i++)
     A = sintesiFourierMonCol(A, h, i); */
  for (i = 0; i < w; i += blocco)
    {
      for (j = 0; j < h; j += blocco)
        {
          tmp = creaMat (tmp, A, i, j, blocco);
          for (k = 0; k < blocco; k++)
            tmp = sintesiFourierMonCol (tmp, blocco, k);
          A = rispristinaMat (tmp, A, i, j, blocco);
        }
    }
  return A;
}
COMPLEX **
analisiFourierMonRig (COMPLEX ** A, int N, int rig)
{
  unsigned int L, LE1, J, i, IP, mod, p;
  COMPLEX U = 1 + 0 * I;
  COMPLEX W, T;
  double M = log (N) / log (2); //logaritmo base 2 di N
  for (i = 0; i < N / 2; i++)
    swap (&(A[rig][i]), &(A[rig][reverse (i, M)]));
  //printf("-------------------\n");
  i = 0;
  L = 1;
  do
    {
      LE1 = pow (2, L - 1);
      p = pow (2, L);
      U = 1 + 0 * I;


  return A;
}

analisiFourierMonCol (COMPLEX ** A, int N, int col)
{
  unsigned int L, LE1, J, i, IP, mod, p;
  COMPLEX U = 1 + 0 * I;
  COMPLEX W, T;
  double M = log (N) / log (2); //logaritmo base 2 di N
  for (i = 0; i < N / 2; i++)
    swap (&(A[i][col]), &(A[reverse (i, M)][col]));
  i = 0;
  L = 1;
  do
    {
      LE1 = pow (2, L - 1);
      p = pow (2, L);
      U = 1 + 0 * I;


  return A;
}

/*************************************************************************************/
int
main (int argc, char *argv[])
{
  COMPLEX **A;
  ELEM *x;
  int i;
  int a = 0;
  int b = 0;
  int sec0 = 0;
  float per = 0;
  int sec1 = 0;
  int dimb=256;
  if (argc != 5)
    {
      printf ("Errore nei parametri\n");
      printf ("USO\n./fft dimx dimy percentuale nome_file\n");
      exit (1);
    }
  a = atoi (argv[1]);
  b = atoi (argv[2]);
  per = (float) atof (argv[3]);
  if (per > 100)
    {
      printf ("Percentuale MAX =100%\n");
      exit (1);
    }
  printf ("Percentuale di compressione = %f%\n", per);
  printf ("Inizio l'esecuzione\n");
  sec0 = time (NULL);
  A = read (argv[4], a, b);
  A = analisiFourier (A, a, b, dimb);
  x = ordina (A, a, b);
  compress (x, a * b, per);
  A = restore (A, x, a, b);
  A = sintesiFourier (A, a, b,dimb);
  A = ritaglia (A, a, b);
  write (A, "output.raw", a, b);
  sec1 = time (NULL);
  printf ("Tempo di esecuzione = %d\n", sec1 - sec0);
  return 0;


     *A[i]
Che vuoi dire ?
Detto cosě, quello che scrivi non č vero.
In C, se ho:
COMPLEX **A;
A[i][j] č una scrittura prefettamente lecita: con A[i] accedo all'i-esimo
COMPLEX * e con l'ulteriore indicizzazione accedo al j-esimo elemento
COMPLEX.
Quindi trattasi, giustamente, di una matrice.


 Quindi trattasi, giustamente, di una matrice.
No. Trattasi di un array di puntatori a COMPLEX. E ognuno di questi
puntatori punta a un array di COMPLEX.
Non è per niente la stessa cosa. Lasciamo perdere i complex, che tanto non
c'entrano: una mantrice bidimensionale di int, la dichiaro così:
   int pippoM[3][3];
Un array di puntatori ad array di int lo dichiaro, per esempio, così:
    int a1[3];
    int a2[3];
    int a3[3];
    int * pippoA[3] = { a1, a2, a3 };
In parte, le due bestie sono analoghe. Per esempio, nello scope della
dichiarazione, con entrambe posso fare questo:
    for (x = 0; x < 3; x++)
       for (y = 0; y < 3; y++)
          pippoX[x][y] = 0;
Ci sono però anche delle belle differenze.
Supponendo che int e puntatori siano grandi quattro byte, la dimensione
della matrice pippoM è 36 byte ( 3*3*sizeof(int) ), che è anche la
dimensione totale della struttura dati. 
La dimensione dell'array di puntatori pippoA è invece 12 byte
(3*sizeof(int*)), mentre la dimensione dell'intera struttura dati (l'array
di puntatori e i tre array di int) è 48 byte ( 3*sizeof(int*) +
3*3*sizeof(int) ).
Ma la differenza principale è che l'array di puntatori lo posso passare a
una funzione generica fatta così:
    void UnaFunzione(int ** a, int numrighe, int numcolonne);
E questa funzione funzionerà quale che sia il valore di numrighe e
numcolonne.
Per la matrice bidimensionale, invece, il massimo si genericità a cui
posso arrivare è questo:
    void AltraFunzione(int a[3][], numrighe);
Cioè, una delle due dimensioni dev'essere per forza 3 (o qualsiasi altro
numero ci sia nella dichiarazione). Questo numero non è generalizzabile
perché quando io scrivo:
   a[2][1]
il compilatore deve sapermelo tradurre in:
   *(  ((int*)a)  +  2*3  +  1  )
e per potere far questo deve conoscere (dalla dichiarazione) quel valore
hard-coded "3".
La mia impressione era che Nicolò avesse in qualche modo confuso nel
codice queste due strutture dati così simili.
Dal codice completo che ha postato in seguito, si dovrebbe riuscire a
capire se quest'impressione era giusta o no, ma non ho ancora avuto il
tempo di leggerlo per bene.
Se sono riuscito a spiegarmi... è un miracolo di Sant'Algoritmo.
--
Cingar


 blocco a 256 viene un immagine molto confusa...
C'è decisamente qualcosa che non quaglia: questo codice non può funzionare
se una delle due dimensioni dell'immagine è minore di 256.
Io l'ho provata con questa riga di comandi:
    fft 8 8 50 miofile
Segui cosa fa il codice:
 
main (int argc, char *argv[])
»   ...
»   int dimb=256;
»   ...
»   a = atoi(argv[1]);
»   b = atoi(argv[2]);
»   // Nota bene: a = b = 8
»   ...
»   A = read(argv[4], a, b);
»   »   read(char *file, int width, int heigth)
»   »   // Nota bene: width = height = 8
»   »   »   ...
»   »   »   mat = malloc(sizeof(COMPLEX*)*width);
»   »   »   for (j = 0; j < width; j++)
»   »   »   »   mat[j] = malloc(sizeof(COMPLEX)*heigth);
»   »   »   // Nota bene: ha allocato mat di 8×8
»   »   »   ...
»   »   »   return mat;
»   A = analisiFourier (A, a, b, dimb);
»   // Nota bene: a = b = 8; dimb = 256
»   »   analisiFourier(COMPLEX ** A, int w, int h, int blocco)
»   »   // Nota bene: A è di 8×8; w = h = 8; blocco = 256
»   »   »   ...
»   »   »   tmp = creaMat (tmp, A, i, j, blocco);
»   »   »   // Nota bene: A è di 8×8; blocco = 256
»   »   »   »   creaMat (... A, COMPLEX ** B, ..., int blocco)
»   »   »   »   // Nota bene: B è di 8×8; blocco = 256
»   »   »   »   »   for (x = 0; x < blocco; x++)
»   »   »   »   »   »   for (y = 0; y < blocco; y++)
»   »   »   »   »   »   »   A[y][x] = B[offy + y][offx + x];
 
Supponendo per semplicità che offx e offy siano zero (come effettivamente
sono alla prima chiamata di creaMat): cosa succede quando x oppure y
raggiungono il valore 8!?
Quando succede questo, stai uscendo dalla memoria che hai allocato per la
matrice "B" (che, fuori dalla creaMat, si chiamava "A")!
Sul mio sistema, a questo punto il sistema operativo, giustamente, uccide
il programma perché sta accedendo a memoria non sua, anche se solo in
lettura.
Sul tuo sistema magari continua, riempiendo parte della matrice "A" (che,
fuori dalla creaMat, si chiamava "mat") con dati a casaccio presi da
chissà dove nella memoria.
Non so se questo è esattamente il problema che hai ma sicuramente è un
problema grosso, per cui suggerirei di metterlo a posto prima di procedere.
In pratica, hai queste scelte:
1) Rifiuti immagini in cui una delle due dimensioni sia inferiore a 256.
2) Le accetti ma imposti dimb a un numero <= alla più piccola delle due
dimensioni.
3) le accetti, lasci dimb com'è, e passi il valore dimb anche alle
funzioni read() e matAlloc(), che dovranno usarlo come valore MINIMO da
allocare in entrambe le dimensioni. In questo caso, la parte di matrice
inutilizzata deve essere opportunamente inizializzata con un valore
"neutro".


     int * pippoA[3] = { a1, a2, a3 };
Niente affatto.  Un "array di n puntatori ad array di m int" lo dichiari
cosě:
T (*(A[n]))[m];
Considera l'esempio seguente per chiarirti le idee:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
    int a[4] = {0, 1, 2, 3};
    int b[4] = {-1, -2, -3, -4};
    int c[4] = {5, 6, 7, 8};
    int (*(A[3]))[4] = {&a, &b, &c};
    int i, j;
    for (i=0; i<3; i++)
    {
        printf("*A[%d] = {", i);
        for (j=0; j<4; j++)
        {
            printf("%d;", (*A[i])[j]);
        }
        printf("}\n");


 
-- 


 non un "array di puntatori a T"
E men che meno una "matrice di T", no?
Era questa espressione di Nicolò che volevo contestare, e non per far
accademia ma perché supponevo in questa espressione si potesse annidare
l'errore logico per cui ci ha scritto. (Poi s'è rivelato che il problema
era tutt'altro.)
Diciamo che correggo la mia affermazione sopra così: "Trattasi di un
<puntatore al primo elemento di un> array di puntatori a COMPLEX. E ognuno
di questi puntatori punta a<l primo elemento di> un array di COMPLEX."
Ovviamente, NON è detto che un argomento di tipo (COMPLEX**) sia usato
necessariamente in questo modo. Ma, dal contesto, supponevo che fosse così
(e in effetti lo era: vedi la funzione MatAlloc() nel successivo post di
Nicolò).
--
Cingar


 b, quali che siano i valori di a, b e dimb.


 
Nel senso che lo modificavo a mano e poi ricompilavo.. non ho inserito anche
un parametro pe il blocco... mi sembrava ridondante per quello che dovevo
fare...


 dimb > b, quali che siano i valori di a, b e dimb.
Anzi, pensandoci meglio: c'è anche quando a oppure b (l'altezza o la
larghezza) non sono DIVISIBILI per dimb.
E, quindi, non funziona nessuna delle 3 soluzioni che avevo suggerito
prima.
L'unico possibilità che vedo è che le funzioni read() e matAlloc()
allochino "matrici" con altezza e larghezza MULTIPLE di dimb.
Naturalmente, i pixel eventualmente inutilizzati vanno impostati a un
valore "neutro" di default.


 di questi puntatori punta a<l primo elemento di> un array di COMPLEX."
No, se la dichiarazione è:
T **p;
la parola "array" non la devi tirare proprio fuori.  Quello che affermi
continua ad essere errato.


 continua ad essere errato.
E perché mai, scusa?
   int IlMioBellArrayDiInt [10];
   int * IlMioBelPuntatoreAInt = IlMioBellArrayDiInt;
Il puntatore IlMioBelPuntatoreAInt punta al primo elemento dell'array di
int IlMioBellArrayDiInt sě o no?
   int * IlMioBellArrayDiPuntatoriAInt [10];
   int ** IlMioBelPuntatoreAPuntatoriAInt = IlMioBellArrayDiPuntatoriAInt;
Il puntatore IlMioBelPuntatoreAPuntatoriAInt punta al primo elemento
dell'array di puntatori a int IlMioBellArrayDiPuntatoriAInt sě o no?
--
Cingar


Cingar ha scritto:
<snip>
Stai dicendo delle cose _diverse_ da ciò che hai detto prima.
Se hai:
T** p;
p _è_ e _rimane_ un puntatore a puntatore.  Non punta, di suo, ad "array".
Sono, semmai, gli "array" che _decadono_ in puntatori.
Nel messaggio precedente, ti ho precisato quando si può parlare di
puntatore a puntatore, di puntatore ad array, di array di puntatori e di
puntatore ad array di puntatori.... e chi più ne ha più ne metta.  
Stai attento a non confondere i termini quando parli di array e puntatori
in C.  


 in C.  
Nemmeno quando ciň che stai ipotizzando č proprio una confusione fra array
e puntatori?
--
Cingar


 quanto vuoi, puntare al suo primo elemento.
Impropriamente al punto di generare una confusione terribile.
Ti consiglio un buon tutorial su array e puntatori, come quello di Ted
Jensen.


 Jensen.
.. o forse lo capisco fin troppo bene.
--
Cingar


 ... o forse lo capisco fin troppo bene.
Se lo dici tu... e comunque mai dare niente per scontato.  Una persona che
conosce "fin troppo bene" la differenza tra array e puntatori, in C, non
confonderebbe mai i due concetti.
Ti saluto ;-)


 
Cingar ha scritto:
 > Io (Cingar) ho scritto:
 >
 >>Nel codice che hai postato, il problema c'è sempre se dimb > a oppure
 >>dimb > b, quali che siano i valori di a, b e dimb.
 >
 >
 > Anzi, pensandoci meglio: c'è anche quando a oppure b (l'altezza o la
 > larghezza) non sono DIVISIBILI per dimb.
 >
 > E, quindi, non funziona nessuna delle 3 soluzioni che avevo suggerito
 > prima.
 >
 > L'unico possibilità che vedo è che le funzioni read() e matAlloc()
 > allochino "matrici" con altezza e larghezza MULTIPLE di dimb.
 > Naturalmente, i pixel eventualmente inutilizzati vanno impostati a un
 > valore "neutro" di default.
 >
 > --
 > Cingar
 >
 >
Pensando si sapesse...
La FFT lavora solo su N che sono potenze di 2... e quindi anche dimb è 
una potenza di 2
2
4
8
16
32
64
128
256
512
1024
ecc
ecc
CIAO


La FFT (Fast Fourier Trasformation) lavora solo su N che sono potenze di 
2... e quindi anche dimb è una potenza di 2...


 2
E con ciò?
Evidentemente non sono molto riuscito a spiegarmi in questo thread. E non mi
pare di essere il solo.
Comunque, per l'ultima volta, UN evidente problema nel tuo codice è che
read() e matAlloc() devono sempre allocare una "matrice" multipla di dimb in
entrambe le dimensioni, altrimenti andrai a leggere dati random che non
c'entrano niente con la tua "matrice".
Se correggere questo baco non t'interessa, convivici pure -- per lo meno fin
che sei in un ambiente run-time lassista che non ti uccide il task
all'istante.
Saluti e auguri per l'esame.
--
Cingar
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/