Troubleshooting DFT of Discrete Signal in C

In summary, Enrico, an 18-year-old Italian student studying Electronics&Telecommunications, is seeking advice on a routine he is working on to perform the DFT of a discrete signal in C. He has applied to UCSD/UCLA/Berkeley and is hoping to be accepted. He has also included a plot of the spectrum of a square wave and his program for reference.
  • #1
Ele38
23
0
Hello to everyone :) Since I did not notice a presentation section I put some info about myself before the question,.
My name is Enrico, I am Italian (form Modena) and I am 18. I am studying Electronics&Telecommunications in High School and I have applied for UCSD/UCLA/Berkeley (I hope they want me :smile: ). If you have questions, feel free to ask more about me.
Here the question. I am working on a routine which should perform the DFT of a discrete signal in C. More or less it works, but I noticed that the amplitude of the harmonics is not right. Here a little plot of the spectrum (is this the right word?) af a square wave, whose amplitude is (should be) 255.
[PLAIN]http://img407.imageshack.us/img407/4979/quadramigliore.jpg
Here there is my program:

//---------------------------------------------------------------------------

#include <clx.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#define N 2048
#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused
int main(int argc, char* argv[])
{
FILE *fp;
int Input[N];
int OutputR[N/2];
int OutputI[N/2];
int OutputAmp[N/2];
int OutputPha[N/2];
double Hamming[N];
int i,k;
double angolo;

//input square wave
for(i=0;i<N;i++){
angolo = (i*M_PI)/180;
Input = (int)(324*sin(angolo) + 108*sin(3*angolo) + 65*sin(5*angolo) + 47*sin(7*angolo) + 36*sin(9*angolo) + 30*sin(11*angolo) + 25*sin(13*angolo) );
}
fp = fopen("file.txt","w");
for(i=0;i<N;i++){
fprintf(fp,"%d \n",Input);
}
//Hamming Window data
for(i=0;i<N;i++){
Hamming = 0.54-0.56*cos(i*M_PI/512);
Input = (int)((double)Input*Hamming);
}
//DFT
//azzero i vettori
for(i=0;i<N/2;i++){
OutputR = 0;
OutputI = 0;
}

//calcolo i valori con la formula
for(k=0;k<N/2;k++){
for(i=0;i<N;i++){
OutputR[k] = OutputR[k]+Input*cos(2*M_PI*k*i/N);
OutputI[k] = OutputI[k]-Input*sin(2*M_PI*k*i/N);
}
}
//conversione polare->rettangolare
for(i=0;i<N/2;i++){
OutputAmp = (int)sqrt(abs(OutputR^2+OutputI^2));
}
//scrivo su file
fp = fopen("file1.txt","w");
for(i=0;i<N/2;i++){
fprintf(fp,"%d \n",OutputAmp);
}
fclose(fp);

return 0;
}
//---------------------------------------------------------------------------

Does someone have advice?
Thank you.
 
Last edited by a moderator:
Technology news on Phys.org
  • #2
Ele38 said:
Hello to everyone :) Since I did not notice a presentation section I put some info about myself before the question,.
My name is Enrico, I am Italian (form Modena) and I am 18. I am studying Electronics&Telecommunications in High School and I have applied for UCSD/UCLA/Berkeley (I hope they want me :smile: ). If you have questions, feel free to ask more about me.
Here the question. I am working on a routine which should perform the DFT of a discrete signal in C. More or less it works, but I noticed that the amplitude of the harmonics is not right. Here a little plot of the spectrum (is this the right word?) af a square wave, whose amplitude is (should be) 255.
[PLAIN]http://img407.imageshack.us/img407/4979/quadramigliore.jpg
Here there is my program:
I added [ code] and [ /code] tags around your code so that your indentation will be preserved.
Ele38 said:
Code:
//---------------------------------------------------------------------------

#include <clx.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#define N 2048
#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused
int main(int argc, char* argv[])
{
        FILE *fp;
        int Input[N];
        int OutputR[N/2];
        int OutputI[N/2];
        int OutputAmp[N/2];
        int OutputPha[N/2];
        double Hamming[N];
        int i,k;
        double angolo;

        //input square wave
        for(i=0;i<N;i++){
                angolo = (i*M_PI)/180;
                Input[i] = (int)(324*sin(angolo) + 108*sin(3*angolo) + 65*sin(5*angolo) + 47*sin(7*angolo) + 36*sin(9*angolo) + 30*sin(11*angolo) + 25*sin(13*angolo) );
        }
        fp = fopen("file.txt","w");
        for(i=0;i<N;i++){
                fprintf(fp,"%d \n",Input[i]);
        }
        //Hamming Window data
        for(i=0;i<N;i++){
                Hamming[i] = 0.54-0.56*cos(i*M_PI/512);
                Input[i] = (int)((double)Input[i]*Hamming[i]);
        }
        //DFT
        //azzero i vettori
        for(i=0;i<N/2;i++){
                OutputR[i] = 0;
                OutputI[i] = 0;
        }

        //calcolo i valori con la formula
        for(k=0;k<N/2;k++){
                for(i=0;i<N;i++){
                        OutputR[k] = OutputR[k]+Input[i]*cos(2*M_PI*k*i/N);
                        OutputI[k] = OutputI[k]-Input[i]*sin(2*M_PI*k*i/N);
                }
        }
        //conversione polare->rettangolare
        for(i=0;i<N/2;i++){
                OutputAmp[i] = (int)sqrt(abs(OutputR[i]^2+OutputI[i]^2));
        }
        //scrivo su file         
        fp = fopen("file1.txt","w");
        for(i=0;i<N/2;i++){
                fprintf(fp,"%d \n",OutputAmp[i]);
        }
        fclose(fp);
        
        return 0;
}
//---------------------------------------------------------------------------
Does someone have advice?
Thank you.
Is there some reason all of your arrays except the Hamming array are type int? You might be losing some precision by not making them double.

Also, you should double-check the coefficients that you are using in your Fourier calculation.
 
Last edited by a moderator:
  • #3
Thenk you for the answer :)
I chose to use only int to "simulate" the output of an ADC. I would like to write a FFT/DFT software for a Z80 processor, but beore I wanted to see what happened with integer value on the DFT. Maybe is better the output arrays to be double, isn't it? I make the change right now.
I also checked again the Fourier coefficients and they are right. I use this formula:
[tex]Y_{n} = \frac{4\cdot Y_{M}}{n\cdot \pi }[/tex]
n = 1,3,5, ...

EDIT: I can not use double in Output arrays because the compiler says "Illegal use of floating point" in the conversion polar to rectangular.
 
Last edited:
  • #4
I assume you mean this code.
Code:
//conversione polare->rettangolare
for(i=0;i<N/2;i++){
    OutputAmp[i] = (int)sqrt(abs(OutputR[i]^2+OutputI[i]^2));
}

Instead of the abs() function in math.h, which takes an int or long value and returns an int or long, use the abs() function declared in stdlib.h. See http://www.cplusplus.com/reference/clibrary/cstdlib/.
 
  • #5
Yes I meant that part of code.
How can I choose which abs() function to use? They have the same name(in math.h and stdlib.h) ... Other advice? I think that maybe the Hamming window is not totally right, but I do not know how to make it better.
 
  • #6
The compiler will know which version of abs() to use based on the arguments. Since math.h and stdlib.h include versions of abs() with different signatures (i.e., different parameter types), if you call abs() with a double argument, the compiler will pick the overloaded version with that parameter type.

Can you be more specific about why you think your Hamming window code isn't right?
 
  • #7
Mark44 said:
The compiler will know which version of abs() to use based on the arguments. Since math.h and stdlib.h include versions of abs() with different signatures (i.e., different parameter types), if you call abs() with a double argument, the compiler will pick the overloaded version with that parameter type.

Can you be more specific about why you think your Hamming window code isn't right?

Ok I will try to use the right abs().
I am not completely sure of the constants used in the Hamming Window.

Hamming = 0.54-0.46*cos(i*M_PI/512);

0.54 and 0.46 are OK. I found the formula on the web and taking a look at the plot of the function 512 seemed a reasonable value for M. How can I find the best M ?
What about the amplitudes of the harmonics, which are not right?
 
  • #8
Sorry, I don't know anything about the Hamming window, so I can't suggest a reasonable value for M.
 
  • #9
Mark44 said:
The compiler will know which version of abs() to use based on the arguments. Since math.h and stdlib.h include versions of abs() with different signatures (i.e., different parameter types), if you call abs() with a double argument, the compiler will pick the overloaded version with that parameter type.

Can you be more specific about why you think your Hamming window code isn't right?
As of C99, there is no overloading in C. C1x has plans for a preprocessor based method for making type generic expressions, which can be used to spoof overloading. You're thinking C++.
 
Last edited:
  • #10
Ele38 said:
Hamming = 0.54-0.46*cos(i*M_PI/512);


What you should have is

Hamming = 0.54 - 0.46 * cos(i*M_PI/N);


The window width needs to match the DFT width.

Also in math.h is the function double fabs(double);
 
  • #11
I had time to take a look at my routine. First, the problem was not only in the abs function (by the way fabs() works well, thank you DrGreg ;) ), but seems that i cannot square a double in this way variable^2, I have to use the function pow(x,y). Using this function and doubles instead of int does not work, whe I plt the graph the number are too high (the smaller one is around 100.000.000). I also tried to match the window width with the width of the data, but the spectrum is worst.
 
  • #12
DrGreg said:
Also in math.h is the function double fabs(double);
I was thinking that there was an fabs function that should be used instead of abs, but found a Web page that talked about an abs overload.

Ele38 said:
I had time to take a look at my routine. First, the problem was not only in the abs function (by the way fabs() works well, thank you DrGreg ;) ), but seems that i cannot square a double in this way variable^2, I have to use the function pow(x,y). Using this function and doubles instead of int does not work, whe I plt the graph the number are too high (the smaller one is around 100.000.000). I also tried to match the window width with the width of the data, but the spectrum is worst.
I've gotten so used to working with LaTeX that I did spot those variable^2 expressions. There is a ^ operator in C/C++, but it is the exclusive or operator, not an exponent operator. This is guaranteed to give you bad results. A better choice than using the power function is to just use multiplication, like so:
OutputR * OutputR + OutputI * OutputI)
 
  • #13
Thank you so much :) Now the plot of the spectrum is really clear ... just beautiful!
But the problem still remains ...
[PLAIN]http://img713.imageshack.us/img713/3172/spettroscalasbagliata.jpg
If you take a look at the graph you can see that it is a "good" spectrum qualitative, but a wrong quantitative one, because the amplitudes of the harmonics are all wrong ...
Does anyone know hot so solve the problem?
 
Last edited by a moderator:

1. What is DFT and how does it relate to discrete signals?

The Discrete Fourier Transform (DFT) is a mathematical tool used to analyze and represent a discrete signal (a sequence of values). It converts a signal from its original time or spatial domain into the frequency domain, allowing for the identification of specific frequencies present in the signal.

2. What are some common issues encountered when performing DFT on a discrete signal in C?

Some common issues when performing DFT on a discrete signal in C include incorrect sampling rate, aliasing, leakage, and spectral leakage. These can lead to inaccurate frequency representations or distorted signals.

3. How can I troubleshoot issues with DFT of a discrete signal in C?

To troubleshoot DFT issues, it is important to check the sampling rate and make sure it meets the Nyquist criterion, which states that the sampling rate must be at least twice the highest frequency present in the signal. Other troubleshooting steps include adjusting windowing techniques, using zero-padding, and verifying the input data and output results.

4. Can the results of DFT in C be affected by the programming language or environment?

Yes, the results of DFT in C can be affected by the programming language or environment. Factors such as the precision of data types, rounding errors, and variations in mathematical functions can impact the accuracy of the DFT results. It is important to carefully consider the programming language and environment when performing DFT on a discrete signal.

5. Are there any alternative methods to DFT for analyzing discrete signals in C?

Yes, there are alternative methods to DFT for analyzing discrete signals in C. One alternative is the Fast Fourier Transform (FFT), which is an efficient algorithm for calculating the DFT. Other methods include the Discrete Cosine Transform (DCT) and the Discrete Wavelet Transform (DWT). Each method has its own advantages and limitations, so it is important to choose the appropriate method based on the specific signal and analysis goals.

Similar threads

  • Programming and Computer Science
Replies
3
Views
1K
  • Programming and Computer Science
Replies
25
Views
2K
  • Programming and Computer Science
Replies
1
Views
1K
  • Programming and Computer Science
Replies
15
Views
2K
  • Programming and Computer Science
Replies
20
Views
1K
  • Programming and Computer Science
Replies
5
Views
2K
  • Programming and Computer Science
Replies
1
Views
946
  • Programming and Computer Science
Replies
1
Views
647
  • Programming and Computer Science
Replies
12
Views
1K
  • General Engineering
Replies
3
Views
1K
Back
Top