【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.20 傅里叶变换:从时域到频域的算法实现

在这里插入图片描述

2.20 傅里叶变换:从时域到频域的算法实现

目录
《傅里叶变换:从时域到频域的算法实现》
2.20.1 FFT算法原理
2.20.2 复数数组存储优化
2.20.3 频域滤波案例
2.20.4 音频处理案例
2.20.5 与 CUFFT 性能对比
2.20.6 总结
2.20.7 参考文献

2.20.1 FFT算法原理

傅里叶变换(Fourier Transform,FT)是一种将时域信号转换为频域信号的数学工具,而快速傅里叶变换(Fast Fourier Transform,FFT)则是实现傅里叶变换的一种高效算法。FFT 算法通过递归分治的方法,将一个大问题分解为多个小问题,从而显著减少计算复杂度。

  • 傅里叶变换的基本概念:时域信号和频域信号的概念。
  • FFT算法的数学原理:详细解释 FFT 算法的数学公式和步骤。
  • FFT算法的实现:如何使用 NumPy 实现 FFT 算法。
graph LRA[FFT算法原理] --> B[基本概念]B --> C[时域信号]B --> D[频域信号]A --> E[数学原理]E --> F[离散傅里叶变换 (DFT)]E --> G[快速傅里叶变换 (FFT)]A --> H[实现]H --> I[使用 NumPy]H --> J[示例代码]
2.20.1.1 傅里叶变换的基本概念

傅里叶变换可以将一个在时间域内表示的信号转换为在频率域内表示的信号。

2.20.1.1.1 时域信号

时域信号是随时间变化的信号,通常表示为 ( x(t) )。

import numpy as np
import matplotlib.pyplot as plt# 生成时域信号
t = np.linspace(0, 1, 1000, endpoint=False)  # 时间轴
x = np.sin(2 * np.pi * 5 * t) + 0.5 * np.sin(2 * np.pi * 10 * t)  # 两个正弦波的叠加# 绘制时域信号
plt.plot(t, x)
plt.xlabel('时间 (s)')
plt.ylabel('振幅')
plt.title('时域信号')
plt.grid(True)
plt.show()  # 显示图表
2.20.1.1.2 频域信号

频域信号是通过傅里叶变换得到的信号,通常表示为 ( X(f) )。

# 计算频域信号
X = np.fft.fft(x)  # 使用 NumPy 进行快速傅里叶变换
freqs = np.fft.fftfreq(t.shape[-1], d=t[1] - t[0])  # 计算频率轴# 绘制频域信号
plt.plot(freqs, np.abs(X))
plt.xlabel('频率 (Hz)')
plt.ylabel('幅度')
plt.title('频域信号')
plt.grid(True)
plt.show()  # 显示图表
2.20.1.2 FFT算法的数学原理

离散傅里叶变换(Discrete Fourier Transform,DFT)的公式如下:

[ X[k] = \sum_{n=0}^{N-1} x[n] e^{-j 2 \pi k n / N} ]

其中,( N ) 是信号的长度,( x[n] ) 是时域信号,( X[k] ) 是频域信号。

快速傅里叶变换(FFT)通过递归分治的方法,将 DFT 的计算复杂度从 ( O(N^2) ) 降低到 ( O(N \log N) )。

2.20.1.2.1 离散傅里叶变换 (DFT)
# 手动实现 DFT
def dft(x):N = len(x)X = np.zeros(N, dtype=np.complex128)for k in range(N):for n in range(N):X[k] += x[n] * np.exp(-2j * np.pi * k * n / N)  # 计算 DFTreturn X# 计算 DFT
X_dft = dft(x)
freqs_dft = np.fft.fftfreq(t.shape[-1], d=t[1] - t[0])# 绘制 DFT 结果
plt.plot(freqs_dft, np.abs(X_dft))
plt.xlabel('频率 (Hz)')
plt.ylabel('幅度')
plt.title('离散傅里叶变换 (DFT)')
plt.grid(True)
plt.show()  # 显示图表
2.20.1.2.2 快速傅里叶变换 (FFT)
# 使用 NumPy 的 fft 函数实现 FFT
X_fft = np.fft.fft(x)
freqs_fft = np.fft.fftfreq(t.shape[-1], d=t[1] - t[0])# 绘制 FFT 结果
plt.plot(freqs_fft, np.abs(X_fft))
plt.xlabel('频率 (Hz)')
plt.ylabel('幅度')
plt.title('快速傅里叶变换 (FFT)')
plt.grid(True)
plt.show()  # 显示图表
2.20.1.3 FFT算法的实现

使用 NumPy 的 fft 模块可以轻松实现 FFT 算法。

# 计算 FFT
X_fft = np.fft.fft(x)
freqs_fft = np.fft.fftfreq(t.shape[-1], d=t[1] - t[0])# 绘制 FFT 结果
plt.plot(freqs_fft, np.abs(X_fft))
plt.xlabel('频率 (Hz)')
plt.ylabel('幅度')
plt.title('快速傅里叶变换 (FFT)')
plt.grid(True)
plt.show()  # 显示图表

2.20.2 复数数组存储优化

复数数组在存储和计算中占据一定的空间和时间。通过合理的存储优化,可以提高性能。

  • 复数数组的存储方式:NumPy 中复数数组的存储方式。
  • 存储优化技巧:如何优化复数数组的存储。
复数数组存储优化
存储方式
复数类型
内存占用
优化技巧
使用 float64
使用 float32
内存映射
2.20.2.1 复数数组的存储方式

NumPy 中的复数数组通常使用 np.complex128np.complex64 类型。

# 创建复数数组
complex_data = np.array([1 + 2j, 3 + 4j, 5 + 6j], dtype=np.complex128)# 查看复数数组的类型和内存占用
print(f"复数数组类型: {complex_data.dtype}")
print(f"复数数组内存占用: {complex_data.nbytes} 字节")
2.20.2.2 存储优化技巧

可以通过选择不同的数据类型和使用内存映射来优化复数数组的存储。

2.20.2.2.1 使用 float64
# 使用 float64 存储复数数组
real_part = np.array([1, 3, 5], dtype=np.float64)
imag_part = np.array([2, 4, 6], dtype=np.float64)
complex_data_optimized = real_part + 1j * imag_part# 查看优化后的复数数组的类型和内存占用
print(f"优化后的复数数组类型: {complex_data_optimized.dtype}")
print(f"优化后的复数数组内存占用: {complex_data_optimized.nbytes} 字节")
2.20.2.2.2 使用 float32
# 使用 float32 存储复数数组
real_part = np.array([1, 3, 5], dtype=np.float32)
imag_part = np.array([2, 4, 6], dtype=np.float32)
complex_data_optimized = real_part + 1j * imag_part# 查看优化后的复数数组的类型和内存占用
print(f"优化后的复数数组类型: {complex_data_optimized.dtype}")
print(f"优化后的复数数组内存占用: {complex_data_optimized.nbytes} 字节")
2.20.2.2.3 内存映射

对于大规模数据,可以使用内存映射来优化存储和计算性能。

# 创建内存映射文件
filename = 'complex_data_mmap.npy'
size = 10000000  # 大规模数据
complex_data_mmap = np.memmap(filename, dtype=np.complex128, mode='w+', shape=(size,))# 填充示例数据
np.random.seed(42)
complex_data_mmap[:] = np.random.rand(size) + 1j * np.random.rand(size)# 读取内存映射数据
complex_data_read = np.memmap(filename, dtype=np.complex128, mode='r', shape=(size,))# 查看内存占用
print(f"内存映射数据内存占用: {complex_data_read.nbytes / (1024 * 1024):.2f} MB")

2.20.3 频域滤波案例

频域滤波是一种常见的信号处理技术,通过在频域中操作信号来去除噪声或提取有用信息。

  • 频域滤波的基本原理:如何在频域中去除噪声。
  • 低通滤波器实现:如何实现一个低通滤波器。
  • 高通滤波器实现:如何实现一个高通滤波器。
频域滤波案例
基本原理
去除噪声
保留有用信息
低通滤波器实现
设计滤波器
应用滤波器
示例代码
高通滤波器实现
设计滤波器
应用滤波器
示例代码
2.20.3.1 频域滤波的基本原理

频域滤波的基本原理是在频域中对信号进行操作,去除不需要的频率成分。

2.20.3.1.1 去除噪声
# 生成带有噪声的时域信号
t = np.linspace(0, 1, 1000, endpoint=False)  # 时间轴
x = np.sin(2 * np.pi * 5 * t) + 0.5 * np.sin(2 * np.pi * 10 * t) + 0.1 * np.random.randn(t.shape[0])  # 添加噪声# 计算 FFT
X = np.fft.fft(x)
freqs = np.fft.fftfreq(t.shape[-1], d=t[1] - t[0])# 绘制带噪声的时域信号
plt.plot(t, x)
plt.xlabel('时间 (s)')
plt.ylabel('振幅')
plt.title('带有噪声的时域信号')
plt.grid(True)
plt.show()  # 显示图表# 绘制带噪声的频域信号
plt.plot(freqs, np.abs(X))
plt.xlabel('频率 (Hz)')
plt.ylabel('幅度')
plt.title('带有噪声的频域信号')
plt.grid(True)
plt.show()  # 显示图表
2.20.3.1.2 保留有用信息

通过去除高频噪声,可以保留有用的信息。

# 设计低通滤波器
def low_pass_filter(X, freqs, cutoff):X_filtered = X.copy()X_filtered[np.abs(freqs) > cutoff] = 0  # 高于截止频率的频率成分设为 0return X_filtered# 应用低通滤波器
cutoff = 15  # 截止频率
X_filtered = low_pass_filter(X, freqs, cutoff)# 计算逆 FFT
x_filtered = np.fft.ifft(X_filtered)# 绘制去噪后的时域信号
plt.plot(t, np.real(x_filtered))
plt.xlabel('时间 (s)')
plt.ylabel('振幅')
plt.title('去噪后的时域信号')
plt.grid(True)
plt.show()  # 显示图表# 绘制去噪后的频域信号
plt.plot(freqs, np.abs(X_filtered))
plt.xlabel('频率 (Hz)')
plt.ylabel('幅度')
plt.title('去噪后的频域信号')
plt.grid(True)
plt.show()  # 显示图表
2.20.3.2 低通滤波器实现

低通滤波器可以去除高频噪声,保留低频信号。

2.20.3.2.1 设计滤波器
# 设计低通滤波器
def low_pass_filter(X, freqs, cutoff):X_filtered = X.copy()X_filtered[np.abs(freqs) > cutoff] = 0  # 高于截止频率的频率成分设为 0return X_filtered

2.20.3.3.2 应用滤波器

高通滤波器可以去除低频噪声,保留高频信号。

2.20.3.3.1 设计滤波器
# 设计高通滤波器
def high_pass_filter(X, freqs, cutoff):X_filtered = X.copy()X_filtered[np.abs(freqs) < cutoff] = 0  # 低于截止频率的频率成分设为 0return X_filtered
2.20.3.3.2 应用滤波器
# 应用高通滤波器
cutoff = 15  # 截止频率
X_filtered = high_pass_filter(X, freqs, cutoff)# 计算逆 FFT
x_filtered = np.fft.ifft(X_filtered)# 绘制去噪后的时域信号
plt.plot(t, np.real(x_filtered))
plt.xlabel('时间 (s)')
plt.ylabel('振幅')
plt.title('去噪后的时域信号')
plt.grid(True)
plt.show()  # 显示图表# 绘制去噪后的频域信号
plt.plot(freqs, np.abs(X_filtered))
plt.xlabel('频率 (Hz)')
plt.ylabel('幅度')
plt.title('去噪后的频域信号')
plt.grid(True)
plt.show()  # 显示图表

2.20.4 音频处理案例

音频信号的处理是傅里叶变换的一个重要应用领域。通过频域处理,可以实现音频去噪、音频压缩等操作。

  • 音频信号的基本处理:如何读取和写入音频文件。
  • 音频去噪:如何使用 FFT 在频域中去除音频中的噪声。
  • 音频压缩:如何使用 FFT 实现音频的简单压缩。
音频处理案例
基本处理
读取音频文件
写入音频文件
音频去噪
读取带有噪声的音频文件
应用低通滤波器
写入去噪后的音频文件
音频压缩
读取音频文件
应用频域压缩
写入压缩后的音频文件
2.20.4.1 音频信号的基本处理
2.20.4.1.1 读取音频文件
from scipy.io import wavfile# 读取音频文件
sample_rate, audio_data = wavfile.read('noisy_audio.wav')# 绘制音频信号
plt.plot(audio_data)
plt.xlabel('样本点')
plt.ylabel('振幅')
plt.title('读取的音频信号')
plt.grid(True)
plt.show()  # 显示图表
2.20.4.1.2 写入音频文件
# 写入音频文件
wavfile.write('filtered_audio.wav', sample_rate, np.real(x_filtered).astype(np.int16))# 读取并绘制去噪后的音频信号
sample_rate, filtered_audio_data = wavfile.read('filtered_audio.wav')
plt.plot(filtered_audio_data)
plt.xlabel('样本点')
plt.ylabel('振幅')
plt.title('去噪后的音频信号')
plt.grid(True)
plt.show()  # 显示图表
2.20.4.2 音频去噪
2.20.4.2.1 读取带有噪声的音频文件
# 读取带有噪声的音频文件
sample_rate, noisy_audio_data = wavfile.read('noisy_audio.wav')# 绘制带有噪声的音频信号
plt.plot(noisy_audio_data)
plt.xlabel('样本点')
plt.ylabel('振幅')
plt.title('带有噪声的音频信号')
plt.grid(True)
plt.show()  # 显示图表# 计算 FFT
X_audio = np.fft.fft(noisy_audio_data)
freqs_audio = np.fft.fftfreq(noisy_audio_data.shape[0], d=1.0 / sample_rate)# 绘制带有噪声的频域信号
plt.plot(freqs_audio, np.abs(X_audio))
plt.xlabel('频率 (Hz)')
plt.ylabel('幅度')
plt.title('带有噪声的频域信号')
plt.grid(True)
plt.show()  # 显示图表
2.20.4.2.2 应用低通滤波器
# 应用低通滤波器
cutoff_audio = 1000  # 截止频率
X_audio_filtered = low_pass_filter(X_audio, freqs_audio, cutoff_audio)# 计算逆 FFT
filtered_audio_data = np.fft.ifft(X_audio_filtered)# 绘制去噪后的音频信号
plt.plot(np.real(filtered_audio_data))
plt.xlabel('样本点')
plt.ylabel('振幅')
plt.title('去噪后的音频信号')
plt.grid(True)
plt.show()  # 显示图表# 绘制去噪后的频域信号
plt.plot(freqs_audio, np.abs(X_audio_filtered))
plt.xlabel('频率 (Hz)')
plt.ylabel('幅度')
plt.title('去噪后的频域信号')
plt.grid(True)
plt.show()  # 显示图表
2.20.4.2.3 写入去噪后的音频文件
# 写入去噪后的音频文件
wavfile.write('filtered_audio.wav', sample_rate, np.real(filtered_audio_data).astype(np.int16))# 读取并绘制去噪后的音频信号
sample_rate, filtered_audio_data = wavfile.read('filtered_audio.wav')
plt.plot(filtered_audio_data)
plt.xlabel('样本点')
plt.ylabel('振幅')
plt.title('去噪后的音频信号')
plt.grid(True)
plt.show()  # 显示图表
2.20.4.3 音频压缩
2.20.4.3.1 读取音频文件
# 读取音频文件
sample_rate, audio_data = wavfile.read('original_audio.wav')# 绘制原始音频信号
plt.plot(audio_data)
plt.xlabel('样本点')
plt.ylabel('振幅')
plt.title('原始音频信号')
plt.grid(True)
plt.show()  # 显示图表# 计算 FFT
X_audio = np.fft.fft(audio_data)
freqs_audio = np.fft.fftfreq(audio_data.shape[0], d=1.0 / sample_rate)# 绘制原始频域信号
plt.plot(freqs_audio, np.abs(X_audio))
plt.xlabel('频率 (Hz)')
plt.ylabel('幅度')
plt.title('原始频域信号')
plt.grid(True)
plt.show()  # 显示图表
2.20.4.3.2 应用频域压缩
# 应用频域压缩
def compress_audio(X, freqs, compression_ratio):N = X.shape[0]cutoff = int(N * compression_ratio)X_compressed = X.copy()X_compressed[cutoff:-cutoff] = 0  # 将中间部分频率成分设为 0return X_compressed# 压缩比例
compression_ratio = 0.3  # 保留 30% 的频率成分# 应用频域压缩
X_audio_compressed = compress_audio(X_audio, freqs_audio, compression_ratio)# 计算逆 FFT
compressed_audio_data = np.fft.ifft(X_audio_compressed)# 绘制压缩后的音频信号
plt.plot(np.real(compressed_audio_data))
plt.xlabel('样本点')
plt.ylabel('振幅')
plt.title('压缩后的音频信号')
plt.grid(True)
plt.show()  # 显示图表# 绘制压缩后的频域信号
plt.plot(freqs_audio, np.abs(X_audio_compressed))
plt.xlabel('频率 (Hz)')
plt.ylabel('幅度')
plt.title('压缩后的频域信号')
plt.grid(True)
plt.show()  # 显示图表
2.20.4.3.3 写入压缩后的音频文件
# 写入压缩后的音频文件
wavfile.write('compressed_audio.wav', sample_rate, np.real(compressed_audio_data).astype(np.int16))# 读取并绘制压缩后的音频信号
sample_rate, compressed_audio_data = wavfile.read('compressed_audio.wav')
plt.plot(compressed_audio_data)
plt.xlabel('样本点')
plt.ylabel('振幅')
plt.title('压缩后的音频信号')
plt.grid(True)
plt.show()  # 显示图表

2.20.5 与 CUFFT 性能对比

CUFFT 是 NVIDIA 提供的用于 GPU 加速的 FFT 库。通过与 NumPy 的 FFT 性能对比,可以了解在不同场景下的适用性。

  • CUFFT 的基本原理:CUFFT 的工作原理和使用方法。
  • 性能测试:在不同规模的数据上进行性能测试。
  • 结论:对比结果和适用场景。
与 CUFFT 性能对比
基本原理
工作原理
使用方法
性能测试
不同规模数据
测试代码
测试结果
结论
对比结果
适用场景
2.20.5.1 CUFFT 的基本原理

CUFFT 通过在 GPU 上并行计算 FFT,可以显著提高计算速度。

2.20.5.1.1 工作原理

CUFFT 利用 GPU 的并行计算能力,将 FFT 计算任务分解为多个并行子任务,从而实现高性能计算。

2.20.5.1.2 使用方法
import pycuda.autoinit
import pycuda.driver as cuda
import numpy as np
import cufft# 创建数据并传输到 GPU
size = 10000000
x_gpu = cuda.to_device(np.random.rand(size).astype(np.float32))# 创建 CUFFT 计划
plan = cufft.Plan1d(size, cufft.CUFFT_R2C, 1)# 执行 CUFFT
X_gpu = cuda.empty_like(x_gpu, dtype=np.complex64)
plan.forward(x_gpu, X_gpu)# 从 GPU 传输回 CPU
X_cpu = X_gpu.get()# 计算频域信号
freqs = np.fft.fftfreq(size, d=1.0 / 1000)  # 假设采样率为 1000 Hz# 绘制频域信号
plt.plot(freqs, np.abs(X_cpu))
plt.xlabel('频率 (Hz)')
plt.ylabel('幅度')
plt.title('CUFFT 计算的频域信号')
plt.grid(True)
plt.show()  # 显示图表
2.20.5.2 性能测试
2.20.5.2.1 不同规模数据
sizes = [1000, 10000, 100000, 1000000, 10000000]  # 不同数据规模
numpy_times = []
cufft_times = []for size in sizes:# 生成测试数据x = np.random.rand(size).astype(np.float32)x_gpu = cuda.to_device(x)# 创建 CUFFT 计划plan = cufft.Plan1d(size, cufft.CUFFT_R2C, 1)# NumPy FFT 性能测试import timestart = time.time()X_numpy = np.fft.fft(x)end = time.time()numpy_times.append(end - start)# CUFFT 性能测试start = time.time()X_gpu = cuda.empty_like(x_gpu, dtype=np.complex64)plan.forward(x_gpu, X_gpu)end = time.time()cufft_times.append(end - start)
2.20.5.2.2 测试代码
import pycuda.autoinit
import pycuda.driver as cuda
import numpy as np
import cufft
import timesizes = [1000, 10000, 100000, 1000000, 10000000]  # 不同数据规模
numpy_times = []
cufft_times = []for size in sizes:# 生成测试数据x = np.random.rand(size).astype(np.float32)x_gpu = cuda.to_device(x)# 创建 CUFFT 计划plan = cufft.Plan1d(size, cufft.CUFFT_R2C, 1)# NumPy FFT 性能测试start = time.time()X_numpy = np.fft.fft(x)end = time.time()numpy_times.append(end - start)# CUFFT 性能测试start = time.time()X_gpu = cuda.empty_like(x_gpu, dtype=np.complex64)plan.forward(x_gpu, X_gpu)end = time.time()cufft_times.append(end - start)# 绘制性能对比图
plt.plot(sizes, numpy_times, label='NumPy FFT')
plt.plot(sizes, cufft_times, label='CUFFT')
plt.xlabel('数据规模')
plt.ylabel('计算时间 (s)')
plt.title('NumPy FFT 与 CUFFT 性能对比')
plt.legend()
plt.grid(True)
plt.show()  # 显示图表
2.20.5.2.3 测试结果

通过性能测试,可以看到在大规模数据上,CUFFT 的性能显著优于 NumPy FFT。

测试结果
NumPy FFT
CUFFT
性能对比
大规模数据
小规模数据
2.20.5.3 结论
  • 对比结果:在小规模数据上,NumPy FFT 和 CUFFT 的性能差异不大;但在大规模数据上,CUFFT 的性能显著优于 NumPy FFT。
  • 适用场景:对于大规模数据处理,推荐使用 CUFFT;对于小规模数据处理,NumPy FFT 足够使用且更简单易用。

2.20.6 总结

本文详细介绍了傅里叶变换(FFT)的原理、复数数组的存储优化、频域滤波案例以及音频处理案例,并通过性能测试对比了 NumPy FFT 和 CUFFT 的性能。希望这些内容能帮助你在信号处理和音频处理中更好地应用傅里叶变换。

2.20.7 参考文献

参考资料名称链接
NumPy 官方文档NumPy Documentation
SciPy 官方文档SciPy Documentation
CUFFT 官方文档CUFFT Documentation
Python 数据科学手册Python Data Science Handbook
傅里叶变换原理Fourier Transform
高效傅里叶变换实现Efficient Fourier Transform Implementation
信号处理基础Signal Processing Basics
音频处理指南Audio Processing Guide
傅里叶变换在音频处理中的应用Fourier Transform in Audio Processing
高频滤波器设计High-pass Filter Design
低频滤波器设计Low-pass Filter Design
音频压缩技术Audio Compression Techniques
傅里叶变换与卷积Fourier Transform and Convolution
傅里叶变换在图像处理中的应用Fourier Transform in Image Processing

这篇文章包含了详细的原理介绍、代码示例、源码注释以及案例等。希望这对您有帮助。如果有任何问题请随私信或评论告诉我。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/69095.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

刷题记录 动态规划-7: 63. 不同路径 II

题目&#xff1a;63. 不同路径 II 难度&#xff1a;中等 给定一个 m x n 的整数数组 grid。一个机器人初始位于 左上角&#xff08;即 grid[0][0]&#xff09;。机器人尝试移动到 右下角&#xff08;即 grid[m - 1][n - 1]&#xff09;。机器人每次只能向下或者向右移动一步。…

HarmonyOS:给您的应用添加通知

一、通知介绍 通知旨在让用户以合适的方式及时获得有用的新消息&#xff0c;帮助用户高效地处理任务。应用可以通过通知接口发送通知消息&#xff0c;用户可以通过通知栏查看通知内容&#xff0c;也可以点击通知来打开应用&#xff0c;通知主要有以下使用场景&#xff1a; 显示…

Unity飞行代码 超仿真 保姆级教程

本文使用Rigidbody控制飞机&#xff0c;基本不会穿模。 效果 飞行效果 这是一条优雅的广告 如果你也在开发飞机大战等类型的飞行游戏&#xff0c;欢迎在主页搜索博文并参考。 搜索词&#xff1a;Unity游戏(Assault空对地打击)开发。 脚本编写 首先是完整代码。 using System.Co…

图论常见算法

图论常见算法 算法prim算法Dijkstra算法 用途最小生成树&#xff08;MST&#xff09;&#xff1a;最短路径&#xff1a;拓扑排序&#xff1a;关键路径&#xff1a; 算法用途适用条件时间复杂度Kruskal最小生成树无向图&#xff08;稀疏图&#xff09;O(E log E)Prim最小生成树无…

车载软件架构 --- 基于AUTOSAR软件架构的ECU开发流程小白篇

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 简单&#xff0c;单纯&#xff0c;喜欢独处&#xff0c;独来独往&#xff0c;不易合同频过着接地气的生活…

Linux 传输层协议 UDP 和 TCP

UDP 协议 UDP 协议端格式 16 位 UDP 长度, 表示整个数据报(UDP 首部UDP 数据)的最大长度如果校验和出错, 就会直接丢弃 UDP 的特点 UDP 传输的过程类似于寄信 . 无连接: 知道对端的 IP 和端口号就直接进行传输, 不需要建立连接不可靠: 没有确认机制, 没有重传机制; 如果因…

Android学习21 -- launcher

1 前言 之前在工作中&#xff0c;第一次听到launcher有点蒙圈&#xff0c;不知道是啥&#xff0c;当时还赶鸭子上架去和客户PK launcher的事。后来才知道其实就是安卓的桌面。本来还以为很复杂&#xff0c;毕竟之前接触过windows的桌面&#xff0c;那叫一个复杂。。。 后面查了…

unity学习26:用Input接口去监测: 鼠标,键盘,虚拟轴,虚拟按键

目录 1 用Input接口去监测&#xff1a;鼠标&#xff0c;键盘&#xff0c;虚拟轴&#xff0c;虚拟按键 2 鼠标 MouseButton 事件 2.1 鼠标的基本操作 2.2 测试代码 2.3 测试情况 3 键盘Key事件 3.1 键盘的枚举方式 3.2 测试代码同上 3.3 测试代码同上 3.4 测试结果 4…

简单介绍一下什么是OpenFeign

OpenFeign是什么&#xff1f; OpenFeign是一个声明式的Http客户端&#xff0c;它可以用来发起Http请求 它主要用于SpringCloud微服务之间的通讯&#xff0c;让调用另一个服务的Java方法和调用本地方法一样快速和便捷 之前我们是用RestTemplate写一大堆东西发起Http请求远程调…

Hugging Face GGUF 模型可视化

Hugging Face GGUF 模型可视化 1. Finding GGUF files (检索 GGUF 模型)2. Viewer for metadata & tensors info (可视化 GGUF 模型)References 无知小儿&#xff0c;仙家雄霸天下&#xff0c;依附强者才是唯一的出路。否则天地虽大&#xff0c;也让你们无路可走&#xff0…

Python 与 PostgreSQL 集成:深入 psycopg2 的应用与实践

title: Python 与 PostgreSQL 集成:深入 psycopg2 的应用与实践 date: 2025/2/4 updated: 2025/2/4 author: cmdragon excerpt: PostgreSQL 作为开源关系型数据库的佼佼者,因其强大的功能与性能被广泛应用于各种项目中。而 Python 则因其简洁易用的语法、丰富的库和强大的…

生成式AI安全最佳实践 - 抵御OWASP Top 10攻击 (上)

今天小李哥将开启全新的技术分享系列&#xff0c;为大家介绍生成式AI的安全解决方案设计方法和最佳实践。近年来&#xff0c;生成式 AI 安全市场正迅速发展。据 IDC 预测&#xff0c;到 2025 年全球 AI 安全解决方案市场规模将突破 200 亿美元&#xff0c;年复合增长率超过 30%…

《LLM大语言模型深度探索与实践:构建智能应用的新范式,融合代理与数据库的高级整合》

文章目录 Langchain的定义Langchain的组成三个核心组件实现整个核心组成部分 为什么要使用LangchainLangchain的底层原理Langchain实战操作LangSmithLangChain调用LLM安装openAI库-国内镜像源代码运行结果小结 使用Langchain的提示模板部署Langchain程序安装langserve代码请求格…

开发板上Qt运行的环境变量的三条设置语句的详解

在终端中运行下面三句命令用于配置开发板上Qt运行的环境变量&#xff1a; export QT_QPA_GENERIC_PLUGINStslib:/dev/input/event1 export QT_QPA_PLATFORMlinuxfb:fb/dev/fb0 export QT_QPA_FONTDIR/usr/lib/fonts/设置成功后可以用下面的语句检查设置成功没有 echo $QT_QPA…

e2studio开发RA4M2(6)----GPIO外部中断(IRQ)配置

e2studio开发RA4M2.6--GPIO外部中断&#xff08;IRQ&#xff09;配置 概述视频教学样品申请硬件准备参考程序源码下载新建工程工程模板保存工程路径芯片配置工程模板选择时钟设置SWD调试口设置GPIO口配置按键中断配置中断回调函数主程序 概述 GPIO&#xff08;通用输入/输出&a…

鸿蒙Harmony-双向数据绑定MVVM以及$$语法糖介绍

鸿蒙Harmony-双向数据绑定MVVM以及$$语法糖介绍 1.1 双向数据绑定概念 在鸿蒙&#xff08;HarmonyOS&#xff09;应用开发中&#xff0c;双向数据改变&#xff08;或双向数据绑定&#xff09;是一种让数据模型和UI组件之间保持同步的机制&#xff0c;当数据发生变化时&#x…

git基础使用--3---git安装和基本使用

文章目录 git基础使用--3--git-安装和基本使用1. git工具安装1.1 git1.2 TortoiseGit1.3 远程仓2. git本地仓库版本管理2.1 git常用命令2.2 git基本操作2.2.1 设置用户名和邮箱 2.2 git基本操作2.2.1 初始化本地仓 git init2.2.2 查看本地库状态 git status2.2.3 添加暂缓区2.2…

JVM执行流程与架构(对应不同版本JDK)

直接上图&#xff08;对应JDK8以及以后的HotSpot&#xff09; 这里主要区分说明一下 方法区于 字符串常量池 的位置更迭&#xff1a; 方法区 JDK7 以及之前的版本将方法区存放在堆区域中的 永久代空间&#xff0c;堆的大小由虚拟机参数来控制。 JDK8 以及之后的版本将方法…

信息安全专业2025最新毕业设计选题汇总:课题精选

目录 前言 毕设选题 开题指导建议 更多精选选题 选题帮助 最后 前言 大家好,这里是海浪学长毕设专题! 大四是整个大学期间最忙碌的时光&#xff0c;一边要忙着准备考研、考公、考教资或者实习为毕业后面临的升学就业做准备,一边要为毕业设计耗费大量精力。学长给大家整理…