Suppose I have impulse response like [1/25,2/25,3/25,4/25,5/25,4/25,3/25,2/25,1/25]. I did convolution with 600 samples of test signal (it seems that I did some filtering). Then I calculated the same thing in frequency domain:
- Found frequency spectrum of test signal and frequency response.
- Multiplied them and via IDFT convert back to time domain.
Then I plotted difference between these two signals and I got that difference between these to signals is about |0.4|.
Is it ok? It seems a little bit huge for me -- the difference is about one-tenth.
function generateConvolution2(x, impResp)
{
var xVal = x();
var irVal = impResp();
var convolution = [];
var data = [];
for (var i = 0; i < xVal.length + irVal.length - 1; i++)
{
convolution[i] = 0;
for (var j = 0; j < irVal.length; j++)
{
if (i - j < 0) convolution[i] += 0;
else convolution[i] += irVal[j] * xVal[i - j];
}
data.push(convolution[i]);
}
return data;
}
//calculate dft magnitude and spectrum of a function
function magnitudeAndPhase(length, dftLength, func)
{
var data = [];
for (var j = 0; j <= dftLength; j++)
{
var f = 0;
var re = 0;
var im = 0;
for (var i = 0; i < length; i++)
{
f = func(i);
re += f * Math.cos(2 * Math.PI * j * i / length);
im -= f * Math.sin(2 * Math.PI * j * i / length);
}
//calculate magnitude
var mag = Math.sqrt(re * re + im * im);
//calculate phase
var phase;
if (re === 0)
{
re = 1e-20;
}
phase = Math.atan(im / re);
if (re < 0 && im < 0) phase -= Math.PI;
if (re < 0 && im >= 0) phase += Math.PI;
data.push({mag: mag, phase: phase});
}
return data;
}
function multDFt(length, dftLength, func1, func2)
{
var data1 = magnitudeAndPhase(length, dftLength, func1);
var data2 = magnitudeAndPhase(length, dftLength, func2);
var result = [];
//1)multiply magnitudes
//2)add phase
for (var i = 0; i <= dftLength; i++)
{
result.push({mag: data1[i].mag * data2[i].mag, phase: data1[i].phase + data2[i].phase });
}
return result;
}
//using magnitude and phase calculate IDFT
function IDFT2(mainLength, length, dftLength, testSignal, imprResp)
{
var rea = [];
var ima = [];
var dftMagResult = multDFt(length, dftLength, testSignal, imprResp);
//create re and im part of coefficients
for (var i = 0; i <= dftLength; i++)
{
rea.push(dftMagResult[i].mag * Math.cos(dftMagResult[i].phase));
ima.push(dftMagResult[i].mag * Math.sin(dftMagResult[i].phase));
}
//prepare re and im coefficients
rea[0] /= length;
rea[dftLength] /= length;
for (var j = 1; j < dftLength; j++)
{
rea[j] /= (length / 2 );
ima[j] /= -1 * (length / 2 );
}
var vala = [];
for (var i = 0; i < mainLength; i++)
{
vala.push(0);
}
//calculate idft
for (var j = 0; j <= dftLength; j++)
{
for (var i = 0; i < length; i++)
{
vala[i] += rea[j] * Math.cos(2 * Math.PI * j * i / length);
vala[i] += ima[j] * Math.sin(2 * Math.PI * j * i / length);
}
}
return vala;
}
UPDATE: Added my js code. Don't bother with my js style (I'm beginner) and some inconsistent naming. Every func. return array because it is needed for plotting libs.
Thanks in advance.