0
$\begingroup$

I learn IDFT and have created two programs.

  1. Input x(n). It calculates input x(n) values from 2 sinusoids and outputs them.

  2. Output x(n). It performs IDFT on same signal and outputs results.

Results should agree. Unfortunately while first program's output is okay, second's is not. Can you please find the error and say me?

Input x(n) program

// Input x(n) program.
// Grid is created by variables lowTestFreq and highTestFreq
// both of double type, and integer type M.

#include <iostream>
#include "math.h"

int main()
{  
//Unchanged variables.
float pi = 3.141592653589793; //pure number.
int n = 0; // sample.
float input_xn = 0;

//Sampling frequency and samples of segment.
int samplFreq = 100; // sample/second.
int N = 40; //sample.

// 1st existing sinusoidal.
float ampl_1 = 70000; //pure number.
float existFreq_1 = 36; // Hz.
float phase_1 = 0.67 * pi; // rad.
float unitAngle_1 = (existFreq_1 / samplFreq) * (2 * pi); // rad/sample.

// 2nd existing sinusoidal.
float ampl_2 = 600000; // pure number.
float existFreq_2 = 25; // Hz.
float phase_2 = -0.37 * pi; // rad.
float unitAngle_2 = (existFreq_2 / samplFreq) * (2 * pi); // rad/sample.

for (n = 1; n <= N; ++n)
{
input_xn =  ampl_1 * sin(n * unitAngle_1 + phase_1)
      + ampl_2 * sin(n * unitAngle_2 + phase_2); 
std::cout << "input-x(n)" << input_xn << std::endl;
}
return 0;
}

Output x(n) (IDFT) program

// Grid is created by variables lowTestFreq and highTestFreq
// both of double type, and integer type M.

#include <iostream>
#include "math.h"

int main()
{  
//Unchanged variables.
float pi = 3.141592653589793; //pure number.
int n = 0; // sample.
float input_xn = 0; //pure number.
float Re = 0; //pure number.
float Im = 0; //pure number.
float xn_cos = 0; //pure number.
float xn_sin = 0; //pure number.
float co = 0;
float si = 0;
float output_xn_Re = 0;
float sumReal = 0;

//Sampling frequency and samples of segment.
int samplFreq = 100; // sample/second.
int N = 40; //sample.

// 1st existing sinusoidal.
float ampl_1 = 70000; //pure number.
float existFreq_1 = 36; // Hz.
float phase_1 = 0.67 * pi; // rad.
float unitAngle_1 = (existFreq_1 / samplFreq) * (2 * pi); // rad/sample.

// 2nd existing sinusoidal.
float ampl_2 = 600000; // pure number.
float existFreq_2 = 25; // Hz.
float phase_2 = -0.37 * pi; // rad.
float unitAngle_2 = (existFreq_2 / samplFreq) * (2 * pi); // rad/sample.

// Testing grid.
float testFreq = 0; // Hz.
float testUnitAngle = 0; // rad/sample.
float testAngle = 0; // rad.
float lowTestFreq = 0; //Hz.
float highTestFreq = samplFreq; //Hz.
int M = N; // pure number.
int m = 0; // pure number.
float testFreqStep = (highTestFreq - lowTestFreq) / M; // Hz.

for (m = 0; m <= M-1; ++m)
{
testFreq = lowTestFreq + m * testFreqStep; // Hz.
testUnitAngle = (testFreq / samplFreq) * (2 * pi); // rad/sample.

Re = 0; Im = 0;

for (n = 1; n <= N; ++n)
{
input_xn =  ampl_1 * sin(n * unitAngle_1 + phase_1)
      + ampl_2 * sin(n * unitAngle_2 + phase_2);

testAngle = n * testUnitAngle;
xn_cos = input_xn *  cos(testAngle);
xn_sin = input_xn * -sin(testAngle);

Re += xn_cos;
Im += xn_sin;
}
sumReal = 0;
for (n = 0; n <= N-1; ++n)
{
co = cos(2 * pi * m * n / N);
si = sin(2 * pi * m * n / N);
output_xn_Re = Re * co - Im * si;
sumReal += output_xn_Re;
}
std::cout << "output-x(n): " << sumReal / N << std::endl;
}
return 0;
}
$\endgroup$

closed as off-topic by Dilip Sarwate, Matt L., lennon310, Laurent Duval, Peter K. Apr 10 '17 at 0:39

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "This question does not appear to be about signal processing within the scope defined in the help center." – Dilip Sarwate, Matt L., lennon310, Peter K.
If this question can be reworded to fit the rules in the help center, please edit the question.

1
$\begingroup$

I suspect reason is that my IDFT program takes into account every leakage frequency.

Also in complex numbers multiplication I do not take into account imaginary unit.

I apologize for the errors.

My answer to my question is the following C++ program. It performs DFT and IDFT on 20 input values in array, and outputs the same values. Sample rate for calculate input signal from existing sinusoids is 71114 Hz, and N = 20. Existing sinusoids are two:

1. Amplitude = 995,574, frequency = 20247 Hz, phase = 0.34 π.
2.    "      = 492,356      "     = 3818 Hz,    "   = 0.15 π.

Sample rate for DFT and IDFT is 45940 Hz, and N = 20. I point out that existing frequencies are not multiples of sample rate by N. So, there is leakage but is not problem. Any one can change values. These in program are random in limits. Any one can use first program in my question, for calculate input x(n) from any sinusoids.

     #include <iostream>
     #include "math.h"

     int main()
     {
     //Unchanged variables.
     float pi = 3.141592653589793; //pure number.
     int n = 0; // sample.
     float Re = 0; //pure number.
     float Im = 0; //pure number.
     float xn_cos = 0; //pure number.
     float xn_sin = 0; //pure number.
     float cosine = 0;
     float sine = 0;
     float sumReal = 0;
     float real = 0;
    int m = 0;
    int no = 0;

    //Sampling frequency and samples of segment.
    int samplFreq = 45940; // sample/second.
    int N = 20; //sample. Number of input samples.

   // Testing grid.
    float testFreq = 0; // Hz.
    float testUnitAngle = 0; // rad/sample.
    float testAngle = 0; // rad.
    float lowTestFreq = 0; //Hz.
    float highTestFreq = samplFreq; //Hz.
    int M = N; // pure number. Number of DFT output samples.
    float testFreqStep = (highTestFreq - lowTestFreq) / M; // Hz.
    float xn[] =
{ 1.09595e+06,
 635609,
-544799,
 640870,
 1.40537e+06,
-142213,
-392826,
 1.00018e+06,
 307386,
-1.16555e+06,
-211430,
 518555,
-998272,
-1.20759e+06,
 390434,
 26244.3,
-1.18203e+06,
 25149,
 1.08298e+06,
-200068,};
   int No = N; // pure number. Number of IDFT output samples.

  // IDFT including DFT.
  for (no = 0; no <= No - 1; no++)
    {
            sumReal = 0;
            for (m = 0; m <= M - 1; ++m)
            {
                    testFreq = lowTestFreq + m * testFreqStep; // Hz.
                    testUnitAngle = (testFreq / samplFreq) * (2 * pi); // rad/sample.

                    Re = 0; Im = 0;

                    // Start DFT.
                   for (n = 0; n <= N - 1; ++n)
                    {
                            testAngle = n * testUnitAngle;

                            xn_cos = xn[n] * cos(testAngle);
                            xn_sin = xn[n] * -sin(testAngle); 

                            Re += xn_cos;
                            Im += xn_sin;
                    }
                   // End DFT.

                   cosine = cos(((no * 2 * pi) / N) * m);
                    sine = sin(((no * 2 * pi) / N) * m);
                    real = Re * cosine - Im * sine; // Product of complex
//numbers (Re, Im i) * (cosine, sine i) = (Re * cosine + Re * sine i + Im i *
//cosine + Im i * sine i) = (Re * cosine + Re * sine i + Im i * cosine - Im *
//sine), for, by definition, i * i = -1. Then, first and last product in
//parenthesis are real numbers. Other two are imaginary and their sum is
//practically zero. For the values in array are between -26 and 25.
//More over because  input values are real, output should be real.
                    sumReal += real;
            }
            std::cout << sumReal / N << "\n";
    }
    return 0;

}

$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.