用于信号处理的奇函数?
Odd function used for signal processing?
嗨!我希望这是一个可以接受的问题。
通过一些用于信号处理的代码,我发现了一个奇怪的函数:
let kInd = (k1, pow) => {
let k2 = 0;
let k3 = 0;
for (let i = 0; i < pow; i++) {
k3 = k1 >> 1;
k2 = 2 * (k2 - k3) + k1;
k1 = k3;
}
return k2;
};
在傅立叶变换计算结束时调用此函数以交换实数+虚数数组对中的索引:
let fft = samples => {
let pow = Math.log2(samples.length); // `samples.length` is expected to be 2^int
// ... a bunch of code to generate `rBuff` and `iBuff` arrays representing
// real and imaginary components of fourier values
// Now make use of `kInd`; conditionally swap some indexes in `rBuff` and `iBuff`:
for (let i = 0; i < rBuff.length; i++) {
let k = kInd(i, pow);
if (k >= i) continue;
[ rBuff[i], rBuff[k] ] = [ rBuff[k], rBuff[i] ];
[ iBuff[i], iBuff[k] ] = [ iBuff[k], iBuff[i] ];
}
// ... A bit of code to convert to power spectrum and return result
};
我的问题是:kInd
到底在做什么? 我已经 运行 它输出了一些示例值;看起来它随着 k1
参数递增以几乎随机的顺序输出 2 的幂和。 kInd
的小改动会导致 fft
.
的结果完全错误
谢谢!
(注意:让我知道更多代码是否有帮助。为了 reader 的缘故,尽量保持简短!)
看起来像是某种重新排序。
let kInd = (k1, pow) =>{
let k2 = 0;
let k3 = 0;
for (let i = 0; i < pow; i++) {
k3 = k1 >> 1;
k2 = 2 * (k2 - k3) + k1;
k1 = k3;
}
return k2;
};
const format = (s, p = 5) => s.toString().padStart(p);
var i,
l = 16,
pow = Math.log2(l);
for (i = 0; i < l; i++) {
document.getElementById('out').innerHTML += `${format(i)} ${format(kInd(i, pow))}<br>`;
}
<pre id="out"></pre>
这实现了FFT算法的butterfly操作。
例如,运行...
console.log([0,1,2,3,4,5,6,7].map(i => kInd(i, 3)))
...打印...
[ 0, 4, 2, 6, 1, 5, 3, 7 ]
...这是图中的映射:
http://www.alwayslearn.com/DFT%20and%20FFT%20Tutorial/DFTandFFT_FFT_Butterfly_8_Input.html
对于任何给定的 pow
,递增的 i
会产生一个 k
秒的循环。循环的长度是 2^pow
下面的代码将显示两个循环,每个 pow
的递增 i
。有趣的是 i
的模式导致 k
大于或等于 i
(在下面的输出中以粗体显示)。
对于每个 pow,k(i) >= i
以 i=0
开头的模式是什么:
战俘 0: TFFF...
战俘 1:TTFFF...
战俘 2:TTFTFTFFF...
战俘 3:TTTTFTFTFFF...
战俘 4:TTTTFTTTFTFTFFFTFFF...
战俘 5:TTTTTTTTFTTTFTTTFTFTFTFTFFFTFFFTFFF...
let kInd = (k1, pow) => {
let k2 = 0;
let k3 = 0;
for (let i = 0; i < pow; i++) {
k3 = k1 >> 1;
k2 = 2 * (k2 - k3) + k1;
k1 = k3;
}
return k2;
};
for (let p = 0; p < 7; p++) {
for (let i = 0; i < Math.pow(2, p) * 2; i++) {
let k = kInd(i, p)
if (k >= i) {
$('#output').append("<p><b>" + i + " " + p + "->" + k + "</b></p>");
} else {
$('#output').append("<p>" + i + " " + p + "->" + k + "</p>");
}
}
$('#output').append("<p>----------------</p>");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="output"></div>
我知道这不是答案,但我想提供帮助,但评论不适合我想在此处放置的格式。
嗨!我希望这是一个可以接受的问题。
通过一些用于信号处理的代码,我发现了一个奇怪的函数:
let kInd = (k1, pow) => {
let k2 = 0;
let k3 = 0;
for (let i = 0; i < pow; i++) {
k3 = k1 >> 1;
k2 = 2 * (k2 - k3) + k1;
k1 = k3;
}
return k2;
};
在傅立叶变换计算结束时调用此函数以交换实数+虚数数组对中的索引:
let fft = samples => {
let pow = Math.log2(samples.length); // `samples.length` is expected to be 2^int
// ... a bunch of code to generate `rBuff` and `iBuff` arrays representing
// real and imaginary components of fourier values
// Now make use of `kInd`; conditionally swap some indexes in `rBuff` and `iBuff`:
for (let i = 0; i < rBuff.length; i++) {
let k = kInd(i, pow);
if (k >= i) continue;
[ rBuff[i], rBuff[k] ] = [ rBuff[k], rBuff[i] ];
[ iBuff[i], iBuff[k] ] = [ iBuff[k], iBuff[i] ];
}
// ... A bit of code to convert to power spectrum and return result
};
我的问题是:kInd
到底在做什么? 我已经 运行 它输出了一些示例值;看起来它随着 k1
参数递增以几乎随机的顺序输出 2 的幂和。 kInd
的小改动会导致 fft
.
谢谢!
(注意:让我知道更多代码是否有帮助。为了 reader 的缘故,尽量保持简短!)
看起来像是某种重新排序。
let kInd = (k1, pow) =>{
let k2 = 0;
let k3 = 0;
for (let i = 0; i < pow; i++) {
k3 = k1 >> 1;
k2 = 2 * (k2 - k3) + k1;
k1 = k3;
}
return k2;
};
const format = (s, p = 5) => s.toString().padStart(p);
var i,
l = 16,
pow = Math.log2(l);
for (i = 0; i < l; i++) {
document.getElementById('out').innerHTML += `${format(i)} ${format(kInd(i, pow))}<br>`;
}
<pre id="out"></pre>
这实现了FFT算法的butterfly操作。
例如,运行...
console.log([0,1,2,3,4,5,6,7].map(i => kInd(i, 3)))
...打印...
[ 0, 4, 2, 6, 1, 5, 3, 7 ]
...这是图中的映射:
http://www.alwayslearn.com/DFT%20and%20FFT%20Tutorial/DFTandFFT_FFT_Butterfly_8_Input.html
对于任何给定的 pow
,递增的 i
会产生一个 k
秒的循环。循环的长度是 2^pow
下面的代码将显示两个循环,每个 pow
的递增 i
。有趣的是 i
的模式导致 k
大于或等于 i
(在下面的输出中以粗体显示)。
对于每个 pow,k(i) >= i
以 i=0
开头的模式是什么:
战俘 0: TFFF...
战俘 1:TTFFF...
战俘 2:TTFTFTFFF...
战俘 3:TTTTFTFTFFF...
战俘 4:TTTTFTTTFTFTFFFTFFF...
战俘 5:TTTTTTTTFTTTFTTTFTFTFTFTFFFTFFFTFFF...
let kInd = (k1, pow) => {
let k2 = 0;
let k3 = 0;
for (let i = 0; i < pow; i++) {
k3 = k1 >> 1;
k2 = 2 * (k2 - k3) + k1;
k1 = k3;
}
return k2;
};
for (let p = 0; p < 7; p++) {
for (let i = 0; i < Math.pow(2, p) * 2; i++) {
let k = kInd(i, p)
if (k >= i) {
$('#output').append("<p><b>" + i + " " + p + "->" + k + "</b></p>");
} else {
$('#output').append("<p>" + i + " " + p + "->" + k + "</p>");
}
}
$('#output').append("<p>----------------</p>");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="output"></div>
我知道这不是答案,但我想提供帮助,但评论不适合我想在此处放置的格式。