Paddle 傅里叶变换基础及领域应用

news2024/11/15 11:15:36

Paddle 傅里叶变换基础及领域应用

1. 傅里叶变换基础

1.1 傅里叶变换简介

傅里叶变换是一种重要的信号处理技术,它可以将一个信号从时域转换到频域。在频域中,信号的频率特性更加明显,有利于分析和处理。傅里叶变换的基本思想是将一个信号分解为不同频率的正弦波的叠加,通过计算正弦波的振幅和相位,可以得到信号在频域中的表示。

1.2 傅里叶变换的数学原理

傅里叶变换的数学原理基于傅里叶级数理论,它将任意周期信号分解为不同频率的正弦/余弦函数的无穷级数之和。

对于非周期函数,我们可以将其看作是周期无穷大的周期函数。傅里叶变换就是对这种非周期函数进行周期无穷大时的分解。具体来说:

设f(t)为时域上的非周期函数,F(ω)为其对应的频域函数,傅里叶变换对将它们相互转换:

正变换:

F ( ω ) = ∫ − ∞ ∞ f ( t ) e − j ω t d t F(\omega) = \int_{-\infty}^{\infty} f(t)e^{-j\omega t} dt F(ω)=f(t)etdt

逆变换:

f ( t ) = 1 2 π ∫ − ∞ ∞ F ( ω ) e j ω t d ω f(t) = \frac{1}{2\pi}\int_{-\infty}^{\infty} F(\omega)e^{j\omega t} d\omega f(t)=2π1F(ω)etdω

其中 j = − 1 j = \sqrt{-1} j=1

这里正变换将时域函数f(t)映射到了频域函数 F(ω), ω 表示角频率。逆变换则将频域函数 F(ω) 映射回时域 f(t)。

正弦/余弦函数 e j ω t e^{j\omega t} et 可看作是单位复指数函数,模长为1,角速度为ω,表示无穷持续的单频振荡。

  • 当ω取正值时,表示正向旋转,对应正频率分量
  • 当ω取负值时,表示反向旋转,对应负频率分量

通过上式中的积分操作,原函数f(t)可以分解为无数个不同频率ω的单位复指数函数之和,其系数就是频域函数F(ω)。

因此,傅里叶变换实现了时域函数到频域的无穷级数分解,使我们能观察信号中各个频率分量的振幅。这种时域/频域观察信号的能力是傅里叶分析的关键。

1.3 快速傅里叶变换(FFT)算法

快速傅里叶变换(Fast Fourier Transform, FFT)是一种高效计算离散傅里叶变换(Discrete Fourier Transform, DFT)的算法。相比直接计算DFT,FFT能极大降低计算复杂度。

FFT算法的核心思想是分治法, 将一个长度为N的DFT分解为多个小规模DFT的组合计算, 从而降低计算量。具体来说:

  1. 分治(decimation)

    • 将长度为N的序列拆分成若干较小的序列
    • 小序列分别计算DFT
    • 将小DFT结果组合起来,即可得到大DFT
  2. 对于一个长度为N的复数序列x,可以写作: x ( n ) = x e ( n ) + x o ( n ) W N n x(n) = x_e(n) + x_o(n)W_N^n x(n)=xe(n)+xo(n)WNn
    其中:

    • x e ( n ) x_e(n) xe(n)是x中偶数项的子序列
    • x o ( n ) x_o(n) xo(n)是x中奇数项的子序列
    • W N = e − 2 π j N W_N = e^{-\frac{2\pi j}{N}} WN=eN2πj 是一个长为N的主值为1的复数根
  3. 将x的DFT分成两部分计算,这样就把长度为N的DFT分解为两个长度为N/2的DFT的和:

X ( k ) = ∑ n = 0 N − 1 x ( n ) W N n k = ∑ n = 0 N / 2 − 1 x e ( n ) W N / 2 n k + W N k ∑ n = 0 N / 2 − 1 x o ( n ) W N / 2 n k X(k) = \sum_{n=0}^{N-1}x(n)W_N^{nk} \\ = \sum_{n=0}^{N/2-1}x_e(n)W_{N/2}^{nk} + W_N^k\sum_{n=0}^{N/2-1}x_o(n)W_{N/2}^{nk} X(k)=n=0N1x(n)WNnk=n=0N/21xe(n)WN/2nk+WNkn=0N/21xo(n)WN/2nk

  1. 采用递归的方式,不断将较大的DFT分解为较小的DFT,直至长度为2,可直接计算。然后自底向上合并结果。

上面的分治思路称为"蝴蝶操作",是FFT的核心步骤。不同的FFT算法主要是在蝴蝶操作的具体实现上有差异。例如最常用的是基2FFT算法(Cooley-Tukey算法)。除此之外还有分力级数FFT、Rader’s FFT等变种算法。

FFT算法将DFT的计算复杂度从 O ( N 2 ) O(N^2) O(N2) 降低到了 O ( N l o g N ) O(NlogN) O(NlogN) ,因此能高效计算大规模DFT。例如长度为1024的复数序列,基2FFT只需10*1024个复数乘法即可计算其DFT,而直接DFT需要约100万次乘法运算。

1.4 实数傅里叶变换和厄米特傅里叶变换

当输入为实数信号时,傅里叶变换显示出一种特殊的对称性,称为厄米特对称性。这意味着在频率 f k f_k fk 处的频谱分量与在 − f k -f_k fk 处的分量是共轭对称的。基于这种对称性,可以显著减少计算所需的时间和资源。具体而言,实数傅里叶变换(简称rfft)系列函数专为处理实数输入设计,它们仅计算正频率部分,直至达到奈奎斯特频率,从而有效利用了数据的对称性。结果是,对于rfft, n n n 个复数输入仅产生 n / / 2 + 1 n // 2 + 1 n//2+1 个实数输出,这种方法通过减少必要的计算量而提高了效率。

相应地,当频谱本身为纯实数时,输入信号展现出厄米特对称性。在这种情况下,厄米特傅里叶变换(hfft)系列也采用了这一对称性原理,通过使用 n / / 2 + 1 n // 2 + 1 n//2+1 个复数输入点生成 n n n 个实数输出点,从而在计算时实现了高效率。这种对称性不仅在数学上优雅,而且在实际应用中提供了计算上的便利,使得在处理实数信号时能够更加高效地执行傅里叶变换及其逆变换。

2. Paddle 傅里叶变换 API

paddle.fft 模块提供了如下几大类API:

  1. 标准快速傅里叶变换(FFT)API

    • 包括 1维、2维 和 N维的正向和逆向FFT API
  2. 实数傅里叶变换API

    • 用于计算实数多项式系数的离散傅里叶变换及其逆变换
    • 同样包括 1维、2维 和 N维 的变换
  3. 厄米特(半正定)傅里叶变换API

    • 处理半正定厄米特矩阵的傅里叶变换
  4. 辅助功能API

    • 计算FFT的频率采样值
    • 对FFT结果进行直流分量平移 (fftshift/ifftshift)
    • 等辅助操作

通过这些API,paddle.fft模块覆盖了标准复数FFT、实数FFT、半正定FFT等多种变换形式,并且每种变换都支持1维、2维、N维等多种维度,可满足各种傅里叶变换计算需求。同时这些 API 都是自动微分友好的, 支持反向传播, 因此可直接应用于神经网络中。详细的 API 列表可以参考 API文档。下面我们结合一些领域内的应用场景, 介绍如何使用这些API。

3. 傅里叶变换在信号处理中的应用

3.1 信号滤波

在实际信号处理中,常常需要对采集的信号进行降噪处理,去除噪声干扰,以提取有用信号。传统的时域滤波器如 FIR、IIR 滤波器在性能和可设计性上都有一定局限性。基于傅里叶分析的频域滤波, 可以更直接有效地处理噪声问题。

技术原理:

  1. 将时域信号通过傅里叶变换映射到频域
  2. 在频域对信号进行滤波处理,如保留低频部分、阻挡高频噪声等
  3. 对滤波结果进行逆傅里叶变换,得到时域上的降噪信号

下面是代码示例:

import numpy as np
import paddle
import matplotlib.pyplot as plt

# 生成含噪信号
t = np.linspace(0, 1, 4000)
sig = np.sin(2 * np.pi * 50 * t) + 2 * np.cos(
    2 * np.pi * 120 * t
)  # 50Hz正弦 + 120Hz余弦
sig += 0.6 * np.random.randn(len(t))  # 加入高斯白噪声

# 傅里叶变换
sig_fft = paddle.fft.fft(paddle.to_tensor(sig)) # 使用paddle.fft.fft计算傅里叶变换
freqs = paddle.fft.fftfreq(len(sig), 1 / len(sig)) # 使用paddle.fft.fftfreq获取频率采样值

# 理想带通滤波器
filt = paddle.zeros_like(sig_fft)
filt[(freqs > 40) & (freqs < 140)] = 1  # 通过40~140Hz频率

# 滤波并重建时域信号
# paddle.fft.ifft 计算逆傅里叶变换, 取实部得到时域信号
sig_filt = paddle.fft.ifft(sig_fft * filt).real().numpy()



# 绘制原始/滤波信号
plt.figure(figsize=(12, 5))
plt.subplot(121)
plt.plot(t, sig)
plt.title("Noisy Signal")
plt.subplot(122)
plt.plot(t, sig_filt)
plt.title("Filtered Signal")
plt.tight_layout()
plt.show()

上述代码首先生成了一个含50Hz/120Hz分量以及高斯白噪声的合成信号,将其做傅里叶变换,得到了频域表示,构造一个理想带通滤波器,通过40~140Hz频率,阻挡其它频率成分,在频域对原始信号进行滤波,即保留40~140Hz内的分量,最后对滤波结果进行逆傅里叶变换,得到时域的降噪信号,可以看到,频域滤波后的信号,高频噪声成分被大幅减弱,有效去除了噪声干扰。这种思路可广泛应用于通信信号处理、语音降噪、生物医学信号处理等领域。

3.2 频谱分析

接下来,我们通过一个频谱分析的例子,进一步说明傅里叶变换在信号处理中的应用。

频谱分析是信号处理的一个重要任务,目的是研究信号的频率成分及其振幅、相位等特性。它在通信系统、语音识别、故障诊断、地震勘探等领域都有广泛应用。

技术原理:

  1. 采集待分析信号的时域数据
  2. 对时域信号进行傅里叶变换,得到频域表示
  3. 分析频域图像,查看信号在各频率分量上的振幅值
  4. 可结合其他技术,提取频谱峰值、计算功率谱等
import numpy as np
import paddle
import matplotlib.pyplot as plt

# 生成合成信号
t = np.linspace(0, 1, 8000)
sig = (
    np.sin(2 * np.pi * 100 * t)
    + 2 * np.cos(2 * np.pi * 300 * t)
    + 0.3 * np.random.randn(len(t))
)

# 计算傅里叶变换
sig_fft = paddle.fft.fft(paddle.to_tensor(sig))

# 使用paddle.fft.fftfreq计算傅里叶变换的频率采样值
# len(sig)是信号长度, 1/len(sig)是采样间隔
freqs = paddle.fft.fftfreq(len(sig), 1 / len(sig)).numpy()

# 计算振幅谱
# 取sig_fft的绝对值, 得到各频率分量的振幅值
amp_spec = np.abs(sig_fft.numpy()) / (len(sig) / 2)

# 绘制时域/频域图
plt.figure(figsize=(12, 5))
plt.subplot(121)
plt.plot(t, sig)
plt.title("Time Domain")
plt.subplot(122)
plt.plot(freqs, amp_spec)
plt.title("Amplitude Spectrum")
plt.xlim(-600, 600)
plt.tight_layout()
plt.show()

在这里插入图片描述

上述代码生成了一个含 100Hz 正弦波和 300Hz 余弦波的合成信号, 并添加了少量噪声, 使用 paddle.fft.fft 计算了信号的傅里叶变换, 得到频域表示, 计算了各频率分量的振幅谱 amp_spec, 在时域和频域图像上绘制了对应的曲线。可以明显看到在频谱图中, 100Hz 和 300Hz处有两个显著的峰值, 对应合成信号中的两个主频率分量, 其它频率分量由于噪声影响, 振幅较低。

4. 傅里叶变换在图像处理中的应用

在图像获取和传输过程中, 图像质量会由于各种因素而降低, 出现模糊、噪声、细节丢失等问题。 图像增强处理旨在提高图像质量, 是图像处理的一个重要环节。其中, 锐化是常用的增强手段,可以使图像的边缘和细节更加清晰。

技术原理:

  1. 将含噪图像进行二维傅里叶变换,得到频域表示
  2. 在频域设计并应用低通滤波器,阻挡高频噪声
  3. 对滤波结果进行逆傅里叶变换,获得去噪后的图像

下面是代码示例:

import paddle
import numpy as np
from PIL import Image
from skimage import util
import matplotlib.pyplot as plt

# 图像路径
image_path = "WechatIMG198.jpg"

# 读取图片并转为灰度图
gray_image = Image.open(image_path).convert("L")

# 将图片尺寸调整为 512x512
resized_image = np.array(gray_image.resize((512, 512)))

# 给图片添加椒盐噪声,噪声比例为 5%
noisy_image = util.random_noise(resized_image, mode="s&p", amount=0.05)

# 创建一个 15x5 英寸的图像窗口用于显示
plt.figure(figsize=(15, 5))

# 显示添加了噪声的图像
plt.subplot(141)
plt.imshow(noisy_image, cmap="gray")
plt.title("Noisy Image")

# 对图像进行傅里叶变换
fft_result = paddle.fft.fft2(paddle.to_tensor(noisy_image))

# 将零频分量移至频谱中心
fft_shifted = paddle.fft.fftshift(fft_result)

# 计算频谱的对数幅度以便更好的显示
log_magnitude_spectrum = paddle.log(1 + paddle.abs(fft_shifted))

# 显示噪声图像的幅度谱
plt.subplot(142)
plt.imshow(log_magnitude_spectrum.numpy(), cmap="gray")
plt.title("Magnitude Spectrum with Noise")

# 修改幅度谱
m, n = fft_shifted.shape  # 获取频谱的尺寸
fft_shifted_numpy = fft_shifted.numpy()  # 转换为 NumPy 数组进行操作
size = 30  # 设置过滤器大小

# 自适应高频过滤
fft_shifted_numpy[: m // 2 - size, :] = 0
fft_shifted_numpy[m // 2 + size :, :] = 0
fft_shifted_numpy[m // 2 - size : m // 2 + size, : n // 2 - size] = 0
fft_shifted_numpy[m // 2 - size : m // 2 + size, n // 2 + size :] = 0

# 将处理过的数据转换回 Paddle 张量
filtered_freq_spectrum = paddle.to_tensor(fft_shifted_numpy)

# 再次计算处理后频谱的对数幅度
log_magnitude_spectrum_filtered = paddle.log(1 + paddle.abs(filtered_freq_spectrum))

# 显示过滤后的幅度谱
plt.subplot(143)
plt.imshow(log_magnitude_spectrum_filtered.numpy(), cmap="gray")
plt.title("Modified Magnitude Spectrum")

# 反傅里叶变换
ifft_shifted = paddle.fft.ifftshift(filtered_freq_spectrum)
reconstructed_image = paddle.fft.ifft2(ifft_shifted)

# 取绝对值并将数据转换回 NumPy 数组
reconstructed_image_abs = paddle.abs(reconstructed_image)
reconstructed_image_numpy = reconstructed_image_abs.numpy()

# 将像素值范围调整为 0-255
final_image = (reconstructed_image_numpy * 255.0).astype(np.uint8)

# 显示最终的过滤后图像
plt.subplot(144)
plt.imshow(final_image, cmap="gray")
plt.title("Filtered Image")

# 显示所有的图像
plt.show()

首先加载测试图像,并人工添加高斯噪声,模拟实际情况,构造一个二维高斯低通滤波器filt,中心区域通过,边缘衰减,使用paddle.fft.fft2计算噪声图像的二维傅里叶变换,平移零频率到中心,进行滤波:fshift *= filt,使用paddle.fft.ifft2计算逆变换,得到去噪后的图像。从结果可以看出,低通滤波可以有效去除图像中的高频噪声,使图像更加平滑,但是也会导致图像细节丢失,因此在实际应用中,需要根据具体情况选择合适的滤波器。

5. 傅里叶变换在 NLP 中的应用

得益于自动微分的特性, 傅里叶变换在深度学习中也有广泛应用。FNet 是一个简化的自然语言处理(NLP)模型,由 Google 在 2021 年提出。FNet 的独特之处在于它用简单的傅里叶变换(Fourier transforms)替换了传统的自注意力(self-attention)机制。

在FNet中,输入的文本首先被转换为嵌入向量,然后通过傅里叶变换来处理这些嵌入。傅里叶变换是一种强大的数学工具,可以将数据从时域(或空间域)转换到频域。在FNet中,这意味着模型可以有效地捕获输入数据的频率特征,这对于理解文本的全局结构非常有用。

通过使用傅里叶变换而非自注意力机制,FNet显著简化了模型的计算复杂性。这使得FNet在训练和推理时更加高效,尤其是对于长文本或大规模数据集,同时在多数任务上保持了与更复杂模型相当的性能。

FNet可以很容易地用标准的深度学习框架实现,并且可以被应用于各种NLP任务,包括文本分类、情感分析、文本摘要等。尽管它在某些任务上的性能可能略低于使用自注意力的最先进模型,但其高效率使其成为在资源受限的情况下的有力候选者。

调用 paddle 中的多维傅里叶变换算子可以很轻松地实现傅里叶层:

import paddle
from paddle.nn import Layer

# 定义一个基础的傅里叶变换层
class FNetBasicFourierTransform(Layer):
    def __init__(self):
        super().__init__()
        # 初始化傅里叶变换函数
        self.fourier_transform = paddle.fft.fftn
    
    def forward(self, hidden_states):
        # 对输入的隐藏状态进行傅里叶变换,并只取实数部分
        outputs = self.fourier_transform(hidden_states).real()
        return outputs
        
# 定义一个进行傅里叶变换的网络层
class FNetFourierTransform(Layer):
    def __init__(self, hidden_size, layer_norm_eps):
        super().__init__()
        # 使用基础的傅里叶变换
        self.fourier_transform = FNetBasicFourierTransform()
        # 初始化一个输出层,可能用于后续的标准化等操作
        self.output = FNetBasicOutput(hidden_size, layer_norm_eps)
    
    def forward(self, hidden_states):
        # 首先通过傅里叶变换层处理隐藏状态
        self_outputs = self.fourier_transform(hidden_states)
        # 将傅里叶变换后的结果以及原始隐藏状态传递给输出层,进行进一步处理
        fourier_output = self.output(self_outputs, hidden_states)
        return fourier_output

5. 总结

Paddle 提供了全面的傅里叶变换 API,包括标准的快速傅里叶变换(FFT)、实数傅里叶变换和厄米特傅里叶变换等多种功能。这些功能广泛应用于信号处理领域,例如信号滤波、频谱分析,以及图像处理领域中的去噪、锐化等任务。通过傅里叶变换,可以将信号从时域转换到频域,更好地理解信号的频率特性,并且对信号进行有效的处理和增强。这些 API 还具有自动微分的特性,可直接应用于神经网络等领域,为信号处理和图像处理任务提供了便利。

参考文献

  1. https://aistudio.baidu.com/projectdetail/7702538?forkThirdPart=1
  2. https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/api/paddle/fft/Overview_cn.html
  3. https://paddlescience-docs.readthedocs.io/zh/latest/zh/examples/deephpms/

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

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

相关文章

P6【知识点】【数据结构】【树tree】C++版

树是由一个集合以及在该集合上定义的一种关系构成的&#xff0c;集合中的元素称为树的结点&#xff0c;所定义的关系称为父子关系。父子关系在树的结点之间建立了一个层次结构&#xff0c;在这种层次结构中有一个结点具有特殊的地位&#xff0c;这个结点称为该树的根结点。 二叉…

接口测试怎么测?为什么要做接口测试?

一、前言 接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间及内部各个子系统之间的交互点。测试的重点是检查数据的交换、传递和控制管理过程&#xff0c;以及系统间的逻辑依赖关系等。 简单地说&#xff0c;接口测试就是通过URL向服务器或者…

【强训笔记】day25

NO.1 思路&#xff1a;哈希质数判断。 代码实现&#xff1a; #include <iostream> #include<string> #include<cmath> using namespace std;bool isprime(int n) {if(n<2) return false;for(int i2;i<sqrt(n);i){if(n%i0) return false;}return true…

AppInventor2要在界面上做一个电量图标,有什么好的思路吗?

问&#xff1a;要在界面上做一个电量图标&#xff0c;有什么好的思路吗&#xff1f; 答&#xff1a;首先&#xff0c;很容易想到使用进度条相关的组件&#xff0c;原生”滑动条“组件可以吗&#xff1f; 答案显而易见&#xff0c;首先它的样式自定义不够&#xff0c;UI不外乎上…

cPanel中如何为数据库添加用户权限

本周有一个客户&#xff0c;购买Hostease的主机&#xff0c;询问我们的在线客服&#xff0c;他的网站安装后再还是无法访问。 客户购买的是Linux虚拟主机&#xff0c;带cPanel面板的。网站访问有如下数据库连接错误: 随后检查发现客户创建的数据库没有添加数据库用户权限。 下面…

企业文件加密软件推荐:迅软DSE加密软件你用了吗?

一、挑选企业文件加密软件需考虑的因素&#xff1f; 1、安全性&#xff1a;软件应采用业界认可的强加密算法&#xff0c;以确保数据的安全性。 迅软特有的256位高强度加密算法&#xff0c;从根本上阻止一切破解的可能性。 2、易用性&#xff1a;软件应该易于部署和管理&…

二进制部署k8s集群 部署高可用master节点

目录 本次部署的环境 一、master02 节点部署 二、负载均衡部署 安装nginx服务 部署keepalive服务 修改node节点上的配置文件 在master节点上创建pod 三、部署 Dashboard 二进制部署k8s集群部署的步骤总结 &#xff08;1&#xff09;k8s的数据存储中中心的搭建 etcd &…

K8S认证|CKA题库+答案| 2. 查看Pod CPU资源使用量

2、查看集群中运行Pod CPU资源使用量 您必须在以下Cluster/Node上完成此考题&#xff1a; Cluster Master node Worker node k8s …

java集合类详解

目录 1、数组导入&#xff1a; 2、单列集合 List接口 1、ArrayList&#xff1a;数组列表 ArrayList类中的方法 2、LinkedList&#xff1a;链表列表 3、Vector&#xff1a;数组列表 4、list集合的遍历 1、for循环遍历 2、增强for循环 3、迭代器遍历 Set接口 1、Has…

word-形状绘制、smartart、visio

一、人员架构图绘制 小技巧&#xff1a; 1、ctrlshift水平复制 2、点击图形&#xff0c;右键设置为默认形状 3、插入-形状-右键-锁定绘图模式&#xff0c;按esc退出状态 4、插入-形状-新建绘图画布&#xff0c;代替组合问题 画布中存在锚点&#xff0c;便于直线连接 二、s…

LP-MSPM03507学习资料汇总

&#xff08;因对MSPM0研究不够深入&#xff0c;故暂不开启浏览权限&#xff0c;权当记录学习。但愿尽快掌握供大家免费阅读。有意者可私信我共同学习&#xff09; 一、延时函数 1、滴答定时器SYSTICK 1.1 SysConfig配置 配置1ms延时函数&#xff0c;并开启中断 1.2 编写延时…

Day21:Leetcode513.找树左下角的值 +112. 路径总和 113.路径总和ii + 106.从中序与后序遍历序列构造二叉树

LeetCode&#xff1a;513.找树左下角的值 解决方案&#xff1a; 1.思路 在遍历一个节点时&#xff0c;需要先把它的非空右子节点放入队列&#xff0c;然后再把它的非空左子节点放入队列&#xff0c;这样才能保证从右到左遍历每一层的节点。广度优先搜索所遍历的最后一个节点…

php基础笔记

开端&#xff1a; PHP 脚本可以放在文本的任意位置 PHP 脚本以 开始&#xff0c;以 ?>** 结束&#xff1a; PHP 文件的默认文件扩展名是 ".php" 标签替换 <? echo 123;?> //short_open_tagson 默认开启 <?(表达式)?> 等价于 <?php echo …

Servlet 的 API

HttpServlet init&#xff1a;当 tomcat 收到了 /hello 这样的路径是请求后就会调用 HelloServlet&#xff0c;于是就需要对 HelloServlet 进行实例化&#xff08;只实例一次&#xff0c;后续再有请求也不实例了&#xff09;。 destory&#xff1a;如果是通过 smart tomcat 的停…

基础常用动词,柯桥西班牙语培训

1. Ser&#xff1a;是 表示身份: Soy Ana. Soy estudiante. 我是安娜。我是一名学生。 表示属性: Es duro. 这是硬的。 表示国籍: Soy espaol, de Madrid. 我是西班牙人&#xff0c;来自马德里。 2. Estar: 是..., 在... 表示身体状况: Estoy muy cansada, necesito dormir.我很…

springboot3项目练习详细步骤(第四部分:文件上传、登录优化、多环境开发)

目录 本地文件上传 接口文档 业务实现 登录优化 SpringBoot集成redis 实现令牌主动失效机制 多环境开发 本地文件上传 接口文档 业务实现 创建FileUploadController类并编写请求方法 RestController public class FileUploadController {PostMapping("/upload&…

英码科技算能系列边缘计算盒子再添新成员!搭载TPU处理器BM1688CV186AH,功耗更低、接口更丰富

在数据呈现指数级增长的今天&#xff0c;越来越多的领域和细分场景对实时、高效的数据处理和分析的需求日益增长&#xff0c;对智能算力的需求也不断增强。为应对新的市场趋势&#xff0c;英码科技凭借自身的硬件研发优势&#xff0c;携手算能相继推出了基于BM1684的边缘计算盒…

uniappx 应用未读角标插件(完善推送、通知、消息效果) Ba-Shortcut-Badge-U

简介&#xff08;下载地址&#xff09; Ba-Shortcut-Badge-U 是设置应用未读角标的原生插件&#xff0c;UTS版本&#xff08;同时支持uniapp和uniappx&#xff09; 支持设置未读、清空未读支持机型有Huawei、oppo、xiaomi、Samsung、Sony、LG、HTC、ZUK、ASUS、ADW、APEX、NO…

如何使用Matlab进行三角剖分(自定义函数实现delaunayTriangulation 使用Bowyer-Watson 算法)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、Delaunay三角形 二、使用步骤 1.Bowyer-Watson算法 2.算法步骤 三、动画演示 四、核心代码 五、对比matlab自带函数和我们的算法&#xff1a; 总结 前…

【C++】学习笔记——二叉搜索树

文章目录 十四、二叉搜索树1. 二叉搜索树的概念2. 二叉搜索树的实现查找插入中序遍历删除拷贝构造析构函数赋值重载完整代码 3. 二叉搜索树的应用K搜索模型KV搜索模型 未完待续 十四、二叉搜索树 1. 二叉搜索树的概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&…