- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试从此网页运行 C++ FFT 代码: https://www.nayuki.io/page/free-small-fft-in-multiple-languages
刚接触 C++,所以不知道如何运行它。本质上,我想将一个 REAL vector 和一个 IMAG vector 传递给程序并生成 REAL 和 IMAG vector 的输出。
说我的 REAL_VEC = {1, 2, 3, 4, 5}
假设我的 IMAG_VEC = {0, 1, 0, 1, 0}
正在粘贴我拥有的代码及其编译。但是在哪里提供输入以及如何获得输出(对于上述 vector )?
//FftRealPairTest.cpp
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <random>
#include <vector>
#include "FftRealPair.hpp"
using std::cout;
using std::endl;
using std::vector;
// Private function prototypes
static void testFft(int n);
static vector<double> randomReals(int n);
// Mutable global variable
static double maxLogError = -INFINITY;
// Random number generation
std::default_random_engine randGen((std::random_device())());
int main() {
// Test diverse size FFTs
for (int i = 0, prev = 0; i <= 4; i++) {
int n = static_cast<int>(std::lround(std::pow(1500.0, i / 100.0)));
if (n > prev) {
testFft(n);
prev = n;
}
}
cout << endl;
cout << "Max log err = " << std::setprecision(3) << maxLogError << endl;
cout << "Test " << (maxLogError < -10 ? "passed" : "failed") << endl;
return EXIT_SUCCESS;
}
static void testFft(int n) {
vector<double> inputreal(randomReals(n));
vector<double> inputimag(randomReals(n));
vector<double> actualoutreal(inputreal);
vector<double> actualoutimag(inputimag);
Fft::transform(actualoutreal, actualoutimag);
}
static vector<double> randomReals(int n) {
std::uniform_real_distribution<double> valueDist(-1.0, 1.0);
vector<double> result;
for (int i = 0; i < n; i++)
result.push_back(valueDist(randGen));
return result;
}
/////////////////
//FftRealPair.cpp
/*
* Free FFT and convolution (C++)
*
* Copyright (c) 2017 Project Nayuki. (MIT License)
* https://www.nayuki.io/page/free-small-fft-in-multiple-languages
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* - The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* - The Software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. In no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising from,
* out of or in connection with the Software or the use or other dealings in the
* Software.
*/
#include <algorithm>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include "FftRealPair.hpp"
using std::size_t;
using std::vector;
// Private function prototypes
static size_t reverseBits(size_t x, int n);
void Fft::transform(vector<double> &real, vector<double> &imag) {
size_t n = real.size();
if (n != imag.size())
throw "Mismatched lengths";
if (n == 0)
return;
else if ((n & (n - 1)) == 0) // Is power of 2
transformRadix2(real, imag);
else // More complicated algorithm for arbitrary sizes
transformBluestein(real, imag);
}
void Fft::inverseTransform(vector<double> &real, vector<double> &imag) {
transform(imag, real);
}
void Fft::transformRadix2(vector<double> &real, vector<double> &imag) {
// Length variables
size_t n = real.size();
if (n != imag.size())
throw "Mismatched lengths";
int levels = 0; // Compute levels = floor(log2(n))
for (size_t temp = n; temp > 1U; temp >>= 1)
levels++;
if (static_cast<size_t>(1U) << levels != n)
throw "Length is not a power of 2";
// Trignometric tables
vector<double> cosTable(n / 2);
vector<double> sinTable(n / 2);
for (size_t i = 0; i < n / 2; i++) {
cosTable[i] = std::cos(2 * M_PI * i / n);
sinTable[i] = std::sin(2 * M_PI * i / n);
}
// Bit-reversed addressing permutation
for (size_t i = 0; i < n; i++) {
size_t j = reverseBits(i, levels);
if (j > i) {
std::swap(real[i], real[j]);
std::swap(imag[i], imag[j]);
}
}
// Cooley-Tukey decimation-in-time radix-2 FFT
for (size_t size = 2; size <= n; size *= 2) {
size_t halfsize = size / 2;
size_t tablestep = n / size;
for (size_t i = 0; i < n; i += size) {
for (size_t j = i, k = 0; j < i + halfsize; j++, k += tablestep) {
size_t l = j + halfsize;
double tpre = real[l] * cosTable[k] + imag[l] * sinTable[k];
double tpim = -real[l] * sinTable[k] + imag[l] * cosTable[k];
real[l] = real[j] - tpre;
imag[l] = imag[j] - tpim;
real[j] += tpre;
imag[j] += tpim;
}
}
if (size == n) // Prevent overflow in 'size *= 2'
break;
}
}
void Fft::transformBluestein(vector<double> &real, vector<double> &imag) {
// Find a power-of-2 convolution length m such that m >= n * 2 + 1
size_t n = real.size();
if (n != imag.size())
throw "Mismatched lengths";
size_t m = 1;
while (m / 2 <= n) {
if (m > SIZE_MAX / 2)
throw "Vector too large";
m *= 2;
}
// Trignometric tables
vector<double> cosTable(n), sinTable(n);
for (size_t i = 0; i < n; i++) {
unsigned long long temp = static_cast<unsigned long long>(i) * i;
temp %= static_cast<unsigned long long>(n) * 2;
double angle = M_PI * temp / n;
// Less accurate alternative if long long is unavailable: double angle = M_PI * i * i / n;
cosTable[i] = std::cos(angle);
sinTable[i] = std::sin(angle);
}
// Temporary vectors and preprocessing
vector<double> areal(m), aimag(m);
for (size_t i = 0; i < n; i++) {
areal[i] = real[i] * cosTable[i] + imag[i] * sinTable[i];
aimag[i] = -real[i] * sinTable[i] + imag[i] * cosTable[i];
}
vector<double> breal(m), bimag(m);
breal[0] = cosTable[0];
bimag[0] = sinTable[0];
for (size_t i = 1; i < n; i++) {
breal[i] = breal[m - i] = cosTable[i];
bimag[i] = bimag[m - i] = sinTable[i];
}
// Convolution
vector<double> creal(m), cimag(m);
convolve(areal, aimag, breal, bimag, creal, cimag);
// Postprocessing
for (size_t i = 0; i < n; i++) {
real[i] = creal[i] * cosTable[i] + cimag[i] * sinTable[i];
imag[i] = -creal[i] * sinTable[i] + cimag[i] * cosTable[i];
}
}
void Fft::convolve(const vector<double> &x, const vector<double> &y, vector<double> &out) {
size_t n = x.size();
if (n != y.size() || n != out.size())
throw "Mismatched lengths";
vector<double> outimag(n);
convolve(x, vector<double>(n), y, vector<double>(n), out, outimag);
}
void Fft::convolve(
const vector<double> &xreal, const vector<double> &ximag,
const vector<double> &yreal, const vector<double> &yimag,
vector<double> &outreal, vector<double> &outimag) {
size_t n = xreal.size();
if (n != ximag.size() || n != yreal.size() || n != yimag.size()
|| n != outreal.size() || n != outimag.size())
throw "Mismatched lengths";
vector<double> xr(xreal);
vector<double> xi(ximag);
vector<double> yr(yreal);
vector<double> yi(yimag);
transform(xr, xi);
transform(yr, yi);
for (size_t i = 0; i < n; i++) {
double temp = xr[i] * yr[i] - xi[i] * yi[i];
xi[i] = xi[i] * yr[i] + xr[i] * yi[i];
xr[i] = temp;
}
inverseTransform(xr, xi);
for (size_t i = 0; i < n; i++) { // Scaling (because this FFT implementation omits it)
outreal[i] = xr[i] / n;
outimag[i] = xi[i] / n;
}
}
static size_t reverseBits(size_t x, int n) {
size_t result = 0;
for (int i = 0; i < n; i++, x >>= 1)
result = (result << 1) | (x & 1U);
return result;
}
///////////
//FftRealPair.hpp
/*
* Free FFT and convolution (C++)
*
* Copyright (c) 2017 Project Nayuki. (MIT License)
* https://www.nayuki.io/page/free-small-fft-in-multiple-languages
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* - The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* - The Software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. In no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising from,
* out of or in connection with the Software or the use or other dealings in the
* Software.
*/
#pragma once
#include <vector>
namespace Fft {
/*
* Computes the discrete Fourier transform (DFT) of the given complex vector, storing the result back into the vector.
* The vector can have any length. This is a wrapper function.
*/
void transform(std::vector<double> &real, std::vector<double> &imag);
/*
* Computes the inverse discrete Fourier transform (IDFT) of the given complex vector, storing the result back into the vector.
* The vector can have any length. This is a wrapper function. This transform does not perform scaling, so the inverse is not a true inverse.
*/
void inverseTransform(std::vector<double> &real, std::vector<double> &imag);
/*
* Computes the discrete Fourier transform (DFT) of the given complex vector, storing the result back into the vector.
* The vector's length must be a power of 2. Uses the Cooley-Tukey decimation-in-time radix-2 algorithm.
*/
void transformRadix2(std::vector<double> &real, std::vector<double> &imag);
/*
* Computes the discrete Fourier transform (DFT) of the given complex vector, storing the result back into the vector.
* The vector can have any length. This requires the convolution function, which in turn requires the radix-2 FFT function.
* Uses Bluestein's chirp z-transform algorithm.
*/
void transformBluestein(std::vector<double> &real, std::vector<double> &imag);
/*
* Computes the circular convolution of the given real vectors. Each vector's length must be the same.
*/
void convolve(const std::vector<double> &x, const std::vector<double> &y, std::vector<double> &out);
/*
* Computes the circular convolution of the given complex vectors. Each vector's length must be the same.
*/
void convolve(
const std::vector<double> &xreal, const std::vector<double> &ximag,
const std::vector<double> &yreal, const std::vector<double> &yimag,
std::vector<double> &outreal, std::vector<double> &outimag);
}
最佳答案
如果您查看 .hpp file您发布的第一个函数 transform()
接受两个输入:您的实 vector 和虚 vector 。 FFT 是“就地”完成的,因此结果以相同的 vector 返回。
如果你想试一试,你可以看看 testFft()
并初始化inputReal
和 inputImag
与您的数据。然后将 vector 复制到 actualOutReal
和 actualOutImag
(以避免覆盖原始数据)并传递给 transform。
之后,您应该将输出放在相同的 vector 中(actualOutReal
和 actualOutImag
)。
关于c++ - C++ 中的任意长度 FFT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46901897/
FFT 库(例如 FFTW 或 numpy.fft)通常提供两个函数 fft() 和 ifft()(及其用于实值输入的特殊版本)。这些功能似乎被定义为 ifft(fft(X)) == X 和 fft(
如果我有一个特定大小 M(2 的幂)的 FFT 实现,我如何计算一组大小 P=k*M 的 FFT,其中 k 也是 2 的幂? #define M 256 #define P 1024 comple
下午好! 我正在尝试基于我已有的简单递归 FFT 实现来开发 NTT 算法。 考虑以下代码(coefficients'的长度,让它为m,是2的精确幂): /// /// Calculates the
我正在分析时间序列数据,并希望提取 5 个主要频率分量并将其用作训练机器学习模型的特征。我的数据集是 921 x 10080 。每行是一个时间序列,总共有 921 个。 在探索可能的方法时,我遇到了各
我找不到任何官方文档来证明 scipy.fft 实际上是 numpy.fft.fftpack.fft 的链接。这是显示链接的 iPython session : In [1]: import scip
文档说 np.fft.fft 这样做: Compute the one-dimensional discrete Fourier Transform. 和 np.fft.rfft 这样做: Compu
近一个月来,我一直在与一个非常奇怪的错误作斗争。问你们是我最后的希望。我用 C 编写了一个程序,它集成了 2d Cahn–Hilliard equation在傅里叶(或倒数)空间中使用隐式欧拉 (IE
我一直在制作一个例程,使用 NumPy/Scipy 测量两个光谱之间的相位差。 我已经有了Matlab写的例程,所以我基本上是用NumPy重新实现了函数和相应的单元测试。但是,我发现单元测试失败了,因
我正在研究使用 Renderscript 对大型复杂输入数组执行 FFT。 FFT 是相当标准的,因为它涉及三个循环,但内部循环执行 FFT 中的蝶形运算。因为每个蝴蝶使用数组的不同部分,所以没有明显
我需要通过修改 FFT 结果来均衡音乐样本。 我知道如何获得每个输出虚数的频率,问题是修改这个值以获得“均衡器效果”。 我需要知道如何缩放这个值。 条目大小为 4096 个样本,采样率为 44100
我将在 kiss-fft 之前制定几个计划同时(平行),我可以这样做吗,或者换句话说,kiss-fft 线程安全吗? 谢谢 最佳答案 自述文件: No static data is used. Th
要在频域中插入信号,可以在时域中填充零并执行 FFT。 假设给定向量 X 中的元素数为 N 并且 Y 与 X 相同但在一侧用 N 零填充。然后下面给出相同的结果。 $$\hat{x}(k)=\sum_
我通过相关了解了 DFT 的工作原理,并将其用作理解 FFT 结果的基础。如果我有一个以 44.1kHz 采样的离散信号,那么这意味着如果我要获取 1 秒的数据,我将有 44,100 个样本。为了对其
有人知道 Mayer FFT 的实现吗(我不必花很多时间研究代码)? 我正在尝试执行卷积,ifft 似乎产生了我称之为“镜像”的输出。换句话说,我的内核+信号长度被限制为 N/2 并且占据 n=0..
有人知道 Mayer FFT 的实现吗(我不必花很多时间研究代码)? 我正在尝试执行卷积,ifft 似乎产生了我称之为“镜像”的输出。换句话说,我的内核+信号长度被限制为 N/2 并且占据 n=0..
我有以下代码...请注意#生成正弦曲线下的两行。一个使用比另一个更高的 2pi 精度值,但它们仍然应该给出几乎相同的结果。 import numpy as np import matplotlib.p
我正在努力确保 FFTW 做我认为它应该做的事情,但我遇到了问题。我正在使用 OpenCV 的 cv::Mat。我制作了一个测试程序,给定一个 Mat f,计算 ifft(fft(f)) 并将结果与
我是从事电信项目的计算机程序员。 在我们的项目中,我必须将一系列复数更改为它们的傅立叶变换。因此我需要一个高效的 FFT 代码来满足 C89 标准。 我正在使用以下代码,它运行良好: shor
我目前正在尝试了解 numpy 的 fft 函数。为此,我测试了以下假设: 我有两个函数,f(x) = x^2 和 g(x) = f'(x) = 2*x。根据傅立叶变换定律和 wolfram alph
我一直在使用 FFT,目前正在尝试使用 FFT 从文件中获取声音波形(最终对其进行修改),然后将修改后的波形输出回文件。我得到了声波的 FFT,然后对其使用了反 FFT 函数,但输出文件听起来一点也不
我是一名优秀的程序员,十分优秀!