Funzione di correlazione in C

di il
11 risposte

Funzione di correlazione in C

Ciao a tutti,
sto provando a scrivere un programma che calcoli la correlazione tra gli elementi di una matrice LxL che hanno una certa distanza tra di loro :
<f(r) * f(r+dr)>- (<f(r)>)^2 , dove con il simbolo < > ho indicato la media aritmetica. In termini di programmazione ho implementato la seguente formula: < f[j]*f[i+di][j+dj]>- (<f[j]>)^2.

Ho scritto un codice per il calcolo del primo termine ed ho pensato di costruire una matrice B(dr) ovvero B[di][dj] che contenesse i prodotti all'interno della prima media al variare della distanza dr tra le celle della matrice.
Però ho due problemi:
1) il compilatore mi fornisce l'errore Segmentation Fault;
2) non riesco ad imporre le condizioni al contorno, ovvero una volta arrivato a fine riga/colonna dovrei fare il prpdotto tra l'ultimo elemento di riga/colonna e il primo elemento di riga/colonna.

Posto di seguito il codice che ho scritto e ringrazio anticipatamente chi mi aiuterà.

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>

int main()
{

int **f;
int i,j,di,dj;
int L;
int **b;

  time_t t;
  srand(time(&t));
  printf("Inserisci L:\n");
  scanf("%d",&L);

  f=(int**)malloc(L*sizeof(int*));
  for(i=0;i<L;i++)
  f[i]=(int*)malloc(L*sizeof(int));
  for(i=0;i<L;i++)
  {
   for(j=0;j<L;j++)
   f[i][j]= rand();                       //ho riempito la matrice f con numeri random   
  }
  b=(int**)malloc(L*sizeof(int*));
  for(di=0; di<L; i++)
  b[di]=(int*)malloc(L*sizeof(int));

   for(di=0;di<L;di++)
   {
   for(dj=0;dj<L;dj++)
   {
    for(i=0;i<L;i++)

    for(j=0;j<L;j++)
    {
       b[di][dj]+=f[i][j]*f[i+di][j+dj];      //sto calcolando solo i prodotti all'interno della media del primo termine per costruire la matrice B

    }
  }
   }

  for(di=0;di<L;di++)
  {
   for(dj=0;dj<L;dj++)
   {printf("%5d",b[di][dj]);
  }
 }
}

11 Risposte

  • Re: Funzione di correlazione in C

    Premesso che non conosco l'argomento, non ho ben capito cosa stai cercando di fare.
    La correlazione è un'unica quantità associata all'intera matrice? In tal caso saresti in grado di spiegare meglio come si calcola la correlazione per una generica matrice quadrata LxL?
  • Re: Funzione di correlazione in C

    Ciao! La correlazione è una grandezza che si calcola tra due elementi di matrice, ad esempio tra l'elemento f[1][2] e l'elemento f[3][4]. Però possiamo anche tralasciare il concetto di correlazione perchè il problema che ho è proprio di programmazione, quindi cerco di porlo in altri termini.
    Ho una matrice LxL che ho indicato con f[j] e che ho riempito con numeri random. Voglio calcolare la somma di tutti gli elementi di matrice che distano di un posto tra di loro, ad esempio se ho una matrice 3x3 dovrò calcolare
    f[1][1]*f[1][2]+ f[1][2]*f[1][3]+f[2][1]*f[2][2]+f[2][2]*f[2][3]+f[3][1]*f[3][2]+f[3][2]*f[3][3] che è la somma del prodotto tra gli elementi che differiscono di un posto lungo tutte le righe ; poi calcolo la somma degli elementi che differiscono di una posizione lungo le colonne e quindi
    f[1][1]*f[2][1]+f[2][1]*f[3][1]+f[1][2]*f[2][2]+f[2][2]*f[3][2]+f[3][1]*f[3][2]+f[3][2]*f[3][3];
    infine dovrei calcolare la somma dei prodotti tra gli elementi che distano di una posizione lungo la diagonale e quindi:
    f[1][1]*f[2][2]+f[1][2]*f[2][3]+f[2][1]*f[3][2]+f[2][2]*f[3][3].
    Poichè devo fare questo procedimento anche per elementi che distano di due posti (es f[1][1]*f[1][3]+f[2][1]*f[2][3]+f[3][1]*f[3][3], ecc), quindi ho pensato di costruire una matrice B[di][di] dove ad esempio l'elemento B[1][1] contiene la somma di tutti gli elementi che distano di un posto lungo tutte le righe; B[1][2] contiene la somma dei termini che distano di un posto lungo le diagonali, e così via.
    Quindi B[di][dj]+= f[j]*f[i+di][j+dj] dove di e dj sono rispettivamente l'incremento della posizione lungo le righe e lungo le colonne.
    Mi rendo conto che non è affatto semplice, ma spero di averlo spiegato in maniera piu chiara; se non mi sono ben spiegato, riprovo...
  • Re: Funzione di correlazione in C

    Magari può aiutare il pensare alla matrice come un quadtrato composto da tanti quadratini, dove ogni elemento di matrice rappresenta un quadratino e vedere la distanza (di, dj) come distanza tra questi quadratini; ad esempio f[1][1] e f[1][3] distano di due quadratini lungo la riga e quindi di=0 (perchè la riga è la stessa) mentre dj=2 perchè distano di due colonne.
  • Re: Funzione di correlazione in C

    Scusa, probabilmente è colpa mia, ma continuo a non capire appieno quello che stai cercando di fare!

    Per esempio:

    - nel post iniziale hai scritto
    2) non riesco ad imporre le condizioni al contorno, ovvero una volta arrivato a fine riga/colonna dovrei fare il prpdotto tra l'ultimo elemento di riga/colonna e il primo elemento di riga/colonna.
    quindi nell'esempio che hai fatto in seguito
    f[1][1]*f[1][2]+ f[1][2]*f[1][3]+f[2][1]*f[2][2]+f[2][2]*f[2][3]+f[3][1]*f[3][2]+f[3][2]*f[3][3] che è la somma del prodotto tra gli elementi che differiscono di un posto lungo tutte le righe;
    non mancherebbero i prodotti f[1][3]*f[1][1], f[2][3]*f[2][1] e f[3][3]*f[3][1]?

    - nella formula iniziale
    <f(r) * f(r+dr)>- (<f(r)>)^2
    cosa rappresenta r? una distanza?
    In tal caso possiamo affermare che la correlazione è un concetto legato ad una distanza piuttosto che a due elementi della matrice? Ossia, mi spiego meglio, la correlazione tra gli elementi f[1][1] e f[1][3] è uguale a quella tra f[2][1] e f[2][3]?

    - consideriamo la seguente matrice 4x4:

    a b c d
    e f g h
    i l m n
    o p q r

    quanto vale la distanza tra a e p?
    Stando a quanto hai detto nell'ultimo post dovrebbe essere di=1 e dj=3, ma quanto vale la distanza?

    Ha un nome preciso questo argomento di teoria? In tal caso faccio qualche ricerca su internet per capire meglio di cosa stiamo parlando.
  • Re: Funzione di correlazione in C

    Per il punto sulle condizioni al contorno hai centrato il problema! dovrei aggiungere anche i termini che hai scritto, ma non riesco ad aggiungere queste condizioni... Per quanto riguarda r, sì, rappresenta la distanza tre i vari elementi della matrice; gli elementi f[1][1] e f[1][3] distano di dr=2, lo stesso vale per f[2][1] e f[2][3] perchè distano di due colonne. In particolare puoi vedere f(r) come f[j], cioè indica il posto dell'elemento di matrice in considerazione; mentre f(r+dr) puoi vederlo come f[i+di][j+dj]. Ad esempio se di=1 e dj=2 vuol dire che sto considerano due elementi di matrice che distano di una riga (di=1) e di due colonne (di=2), quindi se f[j]= f[1][2] allora f[i+di][j+dj] sarà uguale a f[2][4].

    Nella matrice che hai scritto, a e p distano di tre righe e una colonna quindi sarà di=3 e dj=1 perchè ho considerato i come indice di riga, j come indice di colonna. quindi a=f[j]= f[1][1] mentre p=f[i+di][j+dj]= f[1+3][1+1]= f[4][2] infatti p si trova nella quarta riga e seconda colonna.
  • Re: Funzione di correlazione in C

    Pensa al concetto di distanza come alla coppia di valori di e dj che indicano la differenza di righe e colonne tra due elementi. L'argomento fisico è la funzione di correlazione in un reticolo LxL, ma su internet non si trova nulla. Magari ho creato confusione dicendo come ho pensato di risolvere il problema, quindi riepilogo brevemente qual è il problema:

    Ho una matrice LxL e voglio calcolare la seguente quantità <f[j]*f[i+di][j+dj]>- (<f[j]>)^2 per ogni coppia di elementi di questa matrice. Mi sta bene anche capire solo come implementare la prima parte, cioè <f[j]*f[i+di][j+dj]> perchè è qui che ho problemi. Io avevo pensato di racchiudere i prodotti per i vari (di,dj) come elementi di una nuova matrice, ma sbaglio qualcosa...
  • Re: Funzione di correlazione in C

    Uhm, sarò sincero... ancora non mi è molto chiara la questione!

    Provo a fare qualche ipotesi... data una matrice LxL, vogliamo calcolare la correlazione che sussiste tra i suoi elementi per prefissati valori di di e dj tali che di<L e dj<L. In pratica la quantità f[j]*f[i+di][j+dj] costituisce una sommatoria di L*L termini costituiti a loro volta dal prodotto tra il generico elemento della matrice (ossia f[j]) e l'elemento della matrice ad esso associato attraverso di e dj (ossia f[i+di][j+dj]). Per esempio data la seguente matrice:

    a b c d
    e f g h
    i l m n
    o p q r

    e fissato di=2 e dj=3, l'elemento associato ad e è r, mentre l'elemento associato a p è e. Giusto?
    Lo so che cozza un po' con alcune cose che hai scritto, ma è l'unica procedura logica che sono riuscito a ricavare dai tuoi post!

    Fammi sapere quanto sono andato fuori strada con le mie congetture!
  • Re: Funzione di correlazione in C

    Esattamente! La quantità f[j]*f[i+di][j+dj] rappresenta la sommatoria che hai detto, dove la sommatoria viene fatta per di e dj fissati. Ad esempio avrai una sommatoria che racchiude tutti i termini che distano di=2, dj=3 (ad esempio a* n+b* i+ c*l+ d*m+ e*r+ e*o+f* o+...così via), un'altra sommatoria che racchiude i termini con di=1, dj=3 ecc . Cioè per ogni coppia (di, dj) avrai una sommatoria di termini che hai scritto.

    " fissato di=2 e dj=3, l'elemento associato ad e è r, mentre l'elemento associato a p è e. Giusto?"
    Giusto! Però l'ultimo esempio di p ed e lo ottieni imponendo le condizioni al bordo che io non riesco ad imporre perchè quando il programma arriva all'ultima riga o colonna, si intorrompe.
  • Re: Funzione di correlazione in C

    Finalmente ci siamo capiti!

    Altra domanda... sei sicuro che la formula sia

    <f[j]*f[i+di][j+dj]>-(<f[j]>)^2

    e non

    <f[j]*f[i+di][j+dj]>-<f[j]^2>

    ??

    In ogni caso l'espressione che hai riportato può essere calcolata nel seguente modo:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    int main()
    {
        srand(time(0));
        int c_1 = 0;
        int c_2 = 0;
        int L;
        int d_i;
        int d_j;
        printf("L: ");
        scanf("%d", &L);
        int **m = (int**)malloc(L * sizeof(int*));
        for(int i = 0; i < L; ++i)
        {
            m[i] = (int*)malloc(L * sizeof(int));
            printf("\n");
            for(int j = 0; j < L; ++j)
            {
                m[i][j] = rand() % 100;
                printf("%d\t", m[i][j]);
            }
        }
        printf("\n\ndi: ");
        scanf("%d", &d_i);
        printf("dj: ");
        scanf("%d", &d_j);
        for(int i = 0; i < L; ++i)
        {
            for(int j = 0; j < L; ++j)
            {
                c_1 += m[i][j] * m[(i + d_i) % L][(j + d_j) % L];
                c_2 += m[i][j];
            }
        }
        double c = (c_1 - (c_2 * c_2 / (double)(L * L))) / (L * L);
        printf("c = %.2lf", c);
        for(int i = 0; i < L; ++i)
        {
            free(m[i]);
        }
        return 0;
    }
    Se qualcosa non ti è chiaro oppure trovi qualche errore fammi sapere.
  • Re: Funzione di correlazione in C

    La formula è <f[j]*f[i+di][j+dj]>-(<f[j]>)^2. Per calcolare (<f[j]>)^2 devo sommare tutti gli elementi della matrice, dividerli per L*L e poi elevare al quadrato il risultato. Comunque ti ringrazio molto! Mi hai chiarito delle cose e credo di aver risolto! Grazie mille
  • Re: Funzione di correlazione in C

    La formula è <f[j]*f[i+di][j+dj]>-(<f[j]>)^2. Per calcolare (<f[j]>)^2 devo sommare tutti gli elementi della matrice, dividerli per L*L e poi elevare al quadrato il risultato.

    E' esattamente quello che fa il codice che ho postato!

    Ponendo a=f[j]*f[i+di][j+dj] e b=f[j], la suddetta formula può essere scritta come

    <a>-(<b>)^2 = a/(L^2)-[b/(L^2)]^2=a/(L^2)-(b^2)/(L^4)=[a-(b^2)/(L^2)]/(L^2)

    Comunque ti ringrazio molto! Mi hai chiarito delle cose e credo di aver risolto! Grazie mille

    Di niente!
Devi accedere o registrarti per scrivere nel forum
11 risposte