Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Convoluzione di due segnali discreti in C

teoria dei segnali, elaborazione, trasformate Z, Fourier, segnali caratterizzati da processi e variabli aleatorie, stimatori, DSP

Moderatori: Foto Utenteg.schgor, Foto Utentedimaios

2
voti

[1] Convoluzione di due segnali discreti in C

Messaggioda Foto Utentesimo85 » 18 ago 2015, 20:44

Un saluto a tutti O_/

Tra poco comincerò il semestre di Segnali e Sistemi, quel poco che so l'ho studiato tempo fa da autodidatta..
Ci sono concetti che mi ricordo ed altri no, alcune cose che ho tralasciato e altre che penso di non aver appreso a pieno (forse la convoluzione è uno di questi) quindi sto ripassando e studiando in anticipo.

Sto ripassando sul libro Signals & Systems 2nd Edition by Oppenheim, Willsky e Nawab, e sono arrivato al capitolo 2 "Linear Time Invariant Systems", nel quale viene esposto un esempio di una convoluzione tra due segnali discreti:

y[n] = x[n] * h[n]

La rappresentazione grafica dei segnali e della convoluzione è questa:



Dove:

y[n] = x[0]h[n - 0] + x[1]h[n-1] = 0.5h[n] + 2h[n-1]

Per chi possiede questo famoso (e stupendo a mio modesto parere) libro, l'esempio è il 2.1 a pag. 80
E quindi mi sono messo di mio conto ed ho voluto farlo in C.

Lo so che potrei andare su Google e scrivere "C convolution" o spulciare il codice sorgente di qualche audio player con effetti speciali, e questo sarebbe quanto basta a scopiazzare e non imparare, ma questo non è il mio obiettivo. :mrgreen:

Ecco che ho scritto questo programmino, che è un po' fatto su misura per questo esempio, ma l'importante è rassicurarmi di aver capito bene l'implementazione.

Codice: Seleziona tutto
#include <stdio.h>

#define NX 2
#define NY 3

int main(void)
{
   int n = 0;
   int k = 0;

   double h[NY] = {1.0, 1.0, 1.0};
   double x[NX] = {0.5, 2.0};
   double y[NY + 1] = {0};   

   for(n = 0; n < NY + 1; n++)
   {   
      for(k = 0; k < NX; k++)
      {
         if(n >= k)
         {
            /* printf("x[%d]:%.2f\th[%d]:%.2f\ta:%.2f\n", k, x[k], n-k, h[n-k]); */
            y[n] += x[k]*h[n - k];
         }
      }

      printf("y[%d] = %.2f\n", n, y[n]);
   }
   
   return 0;
}


E questo è l'output, che coincide con l'esempio del libro.

Codice: Seleziona tutto
y[0] = 0.50
y[1] = 2.50
y[2] = 2.50
y[3] = 2.00


Ovviamente più che interessarmi il risultato dei valori ed esultare tutto contento, mi interessa essere sicuro di aver fatto bene, e quindi di aver capito bene.

Chiedo scusa per eventuali castronerie varie.
Ringrazio in anticipo.

O_/

Simo
Avatar utente
Foto Utentesimo85
30,9k 7 12 13
Disattivato su sua richiesta
 
Messaggi: 9927
Iscritto il: 30 ago 2010, 4:59

2
voti

[2] Re: Convoluzione di due segnali discreti in C

Messaggioda Foto UtenteDarwinNE » 18 ago 2015, 22:14

Io nel codice delle convoluzioni mi sbaglio sempre semprissimo :oops:

Di solito, uno dei tanti errori che faccio è non calcolare bene i limiti degli array che contengono i segnali. Nel tuo codice, non sarebbe meglio scegliere separatamente la lunghezza dell'array del segnale x e quello di h e poi ricavarsi la lunghezza dell'array che dovrà contenere y (se mi ricordo bene, dovrebbe essere legata alla somma delle due lunghezze)?

Prova semmai con un segnale x molto lungo e h con tre o quattro punti. Prova anche a fare calcolare al programma un filtro con una media mobile, cose del genere di cui puoi calcolare la soluzione in altro modo. Leggere file WAV non è difficile, potresti provare a filtrare un segnale e vedere cosa viene fuori con Audacity.

In certi casi, magari, potrebbe essere più efficiente passare per la FFT, ma quella che otterresti è una convoluzione circolare e non una convoluzione tout-court.
Follow me on Mastodon: @davbucci@mastodon.sdf.org
Avatar utente
Foto UtenteDarwinNE
31,0k 7 11 13
G.Master EY
G.Master EY
 
Messaggi: 4420
Iscritto il: 18 apr 2010, 9:32
Località: Grenoble - France

1
voti

[3] Re: Convoluzione di due segnali discreti in C

Messaggioda Foto Utentesimo85 » 18 ago 2015, 22:30

Ciao Foto UtenteDarwinNE grazie per i consigli e gli spunti !

Per il momento sto provando ad implementare un esercizio successivo..
Questo era giusto per cominciare a recuperare... :mrgreen:

Posso anche provare ad effettuare delle simulazioni con matlab in parallelo !
Per il momento è la via più veloce. :-)
Avatar utente
Foto Utentesimo85
30,9k 7 12 13
Disattivato su sua richiesta
 
Messaggi: 9927
Iscritto il: 30 ago 2010, 4:59

0
voti

[4] Re: Convoluzione di due segnali discreti in C

Messaggioda Foto Utentesimo85 » 19 ago 2015, 9:44

Foto UtenteDarwinNE, per errore ho cancellato il messaggio precedente. :cry:

La dimensione è (M + N -1), e questo è un esempio (spartano) che ho scritto:

Codice: Seleziona tutto
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void Conv(double x[], int sx, double h[], int sh)
{
   int n = 0;
   int k = 0;

   int sy = (sh + sx - 1);
   double *y = NULL;
   
   y = (double *) malloc(sy * sizeof(double));
   
   for(n = 0; n < sy;  n++)
   {
      y[n] = 0.0;
      for(k = 0; k < sx; k++)
      {   
         if((n >= k) && (n - k) < sh)
            y[n] += x[k]*h[n - k];
      }
         
      printf("y[%d] = %.2f\n", n, y[n]);
   }
   
   free(y);
}

int main(void)
{
   double h[5] = {0.5, 2, 2.5, 1};
   double x[6] = {1, 1, 1, 0, 0, 0};
   
   //double h[4] = {1.0, 2.0, 1.0, 2.0};
   //double x[8] = {2.0, 3.0, 4.0, 1.0, 9.0, 7.0, 8.0, 9.0};

   //double h[4] = {1.0, 2.0, 3.0, 4.0};
   //double x[10] = {1.2, 0.3, 5.7, 3, 2, 8.6, 3.2, 8.8, 3.2, 7.7};
   
   //double x[6] = {3.2, 4.5, 8.6, 2.1, 9.8, 2.2};
   //double h[4] = {2.2, 4.4, 1.2, 3.3};

   //double x[6] = {1.2, 2.5, 8.6, 2.4, 9.8, 2.5};
   //double h[4] = {2.2, 4.4, 1.2, 3.3};

   ///double x[8] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};
   //double h[4] = {0.5, 2, 2.5, 1};

   Conv(x, 6, h, 5);
   return 0;
}


Il codice del messaggio # 1 è sbagliato perché non tiene conto della dimensione di h e dei suoi indici..

Ho fatto varie prove coln matlab in parallelo e dovrebbe essere OK
Ho poi trovato anche questo semplice esempio grafico che è utile.

Convolution_example.pdf
(391.99 KiB) Scaricato 134 volte


Ciao,
Simo
Avatar utente
Foto Utentesimo85
30,9k 7 12 13
Disattivato su sua richiesta
 
Messaggi: 9927
Iscritto il: 30 ago 2010, 4:59

1
voti

[5] Re: Convoluzione di due segnali discreti in C

Messaggioda Foto Utentedimaios » 24 ago 2015, 15:14

Esistono vari algoritmi per la convoluzione e vengono utilizzati in base alla natura dei segnali.
Qui una piccola rassegna non esaustiva ... solo per curiosità. ;-)
Se devi per esempio implementare l'algoritmo su un microcontrollore e non hai a disposizione la FFT oppure non cerchi la convoluzione ciclica puoi utilizzare altri algoritmi.
Ingegneria : alternativa intelligente alla droga.
Avatar utente
Foto Utentedimaios
30,2k 7 10 12
G.Master EY
G.Master EY
 
Messaggi: 3381
Iscritto il: 24 ago 2010, 14:12
Località: Behind the scenes

0
voti

[6] Re: Convoluzione di due segnali discreti in C

Messaggioda Foto Utentesimo85 » 24 ago 2015, 15:55

Grazie Foto Utentedimaios :-)
Avatar utente
Foto Utentesimo85
30,9k 7 12 13
Disattivato su sua richiesta
 
Messaggi: 9927
Iscritto il: 30 ago 2010, 4:59

1
voti

[7] Re: Convoluzione di due segnali discreti in C

Messaggioda Foto Utentedimaios » 24 ago 2015, 16:02

Di nulla. Ricorda che in questo campo bisogna scegliere il tool giusto per l'occasione giusta.
Infatti, soprattutto sui sistemi con scarse risorse di calcolo, esistono tecniche ad-hoc non molto diffuse che però funzionano per segnali con certe caratteristiche ( es. h(n) con pochi campioni oppure x(n) e h(n) brevi ecc. ).
Ingegneria : alternativa intelligente alla droga.
Avatar utente
Foto Utentedimaios
30,2k 7 10 12
G.Master EY
G.Master EY
 
Messaggi: 3381
Iscritto il: 24 ago 2010, 14:12
Località: Behind the scenes


Torna a Elaborazione numerica ed analogica dei segnali

Chi c’è in linea

Visitano il forum: Nessuno e 2 ospiti