傅里叶变换和拉普拉斯变换
一、回顾欧拉公式
1.1 欧拉公式
欧拉公式为:
它表示单位圆上的一个点。随着 θ 变大,这个复数就在平面上旋转。
例如:
如果取实部:
如果取虚部:

二、傅里叶变换就是频率探针
2.1 案例
假设我们的源信号是:

其含义是:
x(t) = 50Hz 正弦波 + 120Hz 正弦波
其中成分为:
- 50Hz 分量幅值 = 1
- 120Hz 分量幅值为 = 0.5
2.2 使用积分计算函数成分
2.2.1 频率探针
可以把傅里叶分析理解成:拿不同频率的波,一个个去和原信号对暗号。
2.2.1 50Hz 积分探针
首先用 50Hz 的波去测试,让它与原信号相乘 (相当于重合的面积相乘),然后在一段时间内积分:
因为 x(t) 原本就有50Hz信号,所以平方永远不小于零,所以会不断累加,结果比较大。
2.2.2 120Hz 积分探针
同样的,我们对 120Hz 也求积分,求他们重合的面积:
2.2.3 计算结果
在下列案例中,引入了实部和虚部的概念。
这是因为我们的案例波形 t=0 时刻开始周期,所以实部统计不到为 0。
为了避免复杂,这里不举例 t=x 时刻开始周期的 f=(t) 函数了。
#include <stdio.h> // 标准输入输出函数
#include <math.h> // sin、cos、sqrt 数学函数
#define PI 3.14159265358979323846
#define N 100000 // 数值积分分段数量
#define T 1.0 // 信号观察时间,单位:s
// 生成包含 50 Hz 和 120 Hz 的测试信号
double signal(double t)
{
return sin(2.0 * PI * 50.0 * t) + 0.5 * sin(2.0 * PI * 120.0 * t);
}
// 计算信号在指定频率 f 下的傅里叶积分
void calculate_fourier(double f)
{
double dt = T / N; // 每个积分小区间的时间宽度
double real = 0.0; // 傅里叶变换的实部
double imag = 0.0; // 傅里叶变换的虚部
// 用矩形面积累加的方式近似计算连续积分
for (int n = 0; n < N; n++)
{
double t = n * dt; // 当前时刻
double x = signal(t); // 当前时刻的信号值
double angle = 2.0 * PI * f * t; // 检测频率对应的相位角
real += x * cos(angle) * dt; // 计算实部积分
imag -= x * sin(angle) * dt; // 计算虚部积分
}
// 根据实部和虚部计算复数模长
double magnitude = sqrt(real * real + imag * imag);
// 将傅里叶积分模长还原为单边正弦波幅值
double amplitude = 2.0 * magnitude / T;
// 输出当前检测频率的计算结果
printf("检测频率:%6.1f Hz\n", f);
printf("实部 Re: % .6f\n", real);
printf("虚部 Im: % .6f\n", imag);
printf("模长: %.6f\n", magnitude);
printf("幅值: %.6f\n\n", amplitude);
}
int main(void)
{
// 分别检测 50 Hz、120 Hz 和 80 Hz
calculate_fourier(50.0);
calculate_fourier(120.0);
calculate_fourier(80.0);
return 0;
}
2.3 引入真正的傅里叶公式
其含义是原信号乘反向旋转频率,然后积分累加。
其中:
就是用来检测频率 f=x(t) 的反向旋转探针。
将 公式展开后得到:
积分后也就是:
将实部分虚部分离可得:
2.4 离散化的 C 代码
离散化代码如下:
#include <stdio.h>
#include <math.h>
#define N 1000 // 定义采样点数,也就是信号长度为 1000 个点
#define FS 1000.0 // 定义采样频率,单位为 Hz,这里表示每秒采样 1000 次
#define PI 3.14159265358979323846 // 定义圆周率常量,用于角度计算
int main(void)
{ // 主函数函数体开始
double x[N]; // 定义长度为 N 的数组,用来保存测试信号的采样值
// 构造一个测试信号:由 50Hz 正弦波和 120Hz 正弦波叠加而成
for (int n = 0; n < N; n++)
{
double t = n / FS; // 根据采样点序号计算当前时间,单位为秒
// 给第 n 个采样点赋值生成 50Hz、幅值为 1 的正弦信号叠加 120Hz、幅值为 0.5 的正弦信号
x[n] = sin(2.0 * PI * 50.0 * t) + 0.5 * sin(2.0 * PI * 120.0 * t);
}
// 对信号 x 进行离散傅里叶变换 DFT,计算频谱
for (int k = 0; k < N / 2; k++) // 遍历频率下标,只计算前半部分频谱
{ // 外层 for 循环函数体开始
double real = 0.0; // 保存 DFT 结果的实部,初始值为 0
double imag = 0.0; // 保存 DFT 结果的虚部,初始值为 0
for (int n = 0; n < N; n++) // 遍历所有采样点,用于计算当前频率 k 的 DFT
{ // 内层 for 循环函数体开始
double angle = 2.0 * PI * k * n / N; // 计算 DFT 公式中的旋转角度
real += x[n] * cos(angle); // 累加当前频率分量的实部
imag -= x[n] * sin(angle); // 累加当前频率分量的虚部,负号来自 DFT 定义
}
// 根据实部和虚部计算当前频率分量的幅值
double amplitude = 2.0 / N * sqrt(real * real + imag * imag); // 计算单边频谱幅值
// 根据频率下标 k 计算对应的实际频率
double freq = k * FS / N; // 当前频率点对应的频率,单位为 Hz
// 只打印幅值比较明显的频率成分
if (amplitude > 0.1) // 如果当前频率分量的幅值大于 0.1,就认为它比较明显
{ // if 语句函数体开始
printf("freq = %7.2f Hz, amplitude = %.3f\n", freq, amplitude); // 输出频率和幅值
}
}
return 0;
}
三、 漏水水桶案例
3.1 漏水水桶案例引入
假设我们有一个漏水的水桶,水量是:
假设规律是:
- x = 剩余水量
水量的导数是 -2x。
意味着,任意时刻,水量的瞬时减少速率 (每分钟流量),等于当前水量的 2 倍。
假设当前桶中有 1L 水,在不考虑微分的情况,1 分钟后会流出 2L 水。
写成自然常数的形式就是:
- x0 = 初始水量
3.2 变量分离的微分形式计算
我们假设桶里目前水量为 5L,试求 1 分钟后的桶中水量。
已知水量变化的微分方程为:
把 xxx 和 ttt 分到两边:
按照初始 t=0,x=5 (5L 水) 计算 t = 1 (1 分钟),两边做定积分:
所以:
3.3 自然指数 e 形式计算
四、赫维塞斯算子
4.1 得到算子
首先定义微分算子 (赫维塞斯算子):
那么 px 的意思是:
所以在水桶案例中,可以将原来的导数形式:
写成:
提取可得:
最后得到:
4.2 使用算子
我们知道指数函数满足:
把我们的赫维塞斯算子代入:
因此水量函数一定具有下面的形式:
将我们的初始水量 5L 带入公式,得到:
4.3 总结
这个例子中,把微分直接转化成 p:
于是:
直接变成:
微分方程就像普通代数一样处理了。
五、拉普拉斯变换
5.1 拉普拉斯变换公式
- x(t) = 时间有关的函数
- t = 时间
= 瞬时变化速度
= 拉普拉斯变换符号
- s = 拉普拉斯域的自变量
= 拉普拉斯域的函数
= 时间的初始值
可以理解为:
导数的拉普拉斯变换 = s乘原函数的变换结果 − 初始值
5.2 使用拉普拉斯变换计算水桶案例
5.2.1 两侧拉普拉斯变换
水桶案例的原微分方程是:
两边同时进行拉普拉斯变换:
得到:
5.2.2 求 X(s)
提取 X(s):
两侧相除得到水量在 s 域的表达式:
5.2.3 拉普拉斯反变换查表
现在我们需要把拉普拉斯域反变换,目前已有公式:
我们直接将 X(s) 根据公式转换得到:
我们的初始水量是 5L 时间是 1 分钟,代入得到:
5.3 拉普拉斯变换和傅里叶变换的关系
5.3.1 两个公式
傅里叶变换的公式是:
而拉普拉斯变换的公式多了一个 s:
5.3.2 s 的定义
= 频率旋转
= 指数增长/衰减
5.3.3 两者关系总结
拉普拉斯变换 = 傅里叶变换 + 指数衰减 / 增长因子
在傅里叶分析中,我们只能分析不衰减的波形:
拉普拉斯变换则可以分析增长信号和衰减信号:
这样就是衰减了:
拉普拉斯变换把探针升级了,也就是说,不仅可以分析波形的频率成分,还可以分析衰减状态。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)