发帖
日期

用北太天元学习傅里叶变换

连续时间傅里叶变换(CTFT)公式:每次看到这样的公式就头大,个人觉得其实是没有把抽象的数学和实际应用场景结合起来,导致理解起来很困难,实际用的时候又不会用,所以想着干脆在北太天元里面搞一遍,既能辅助理解,又解决了应用问题,因为实际场景中做信号分析的时候也就是用北太天元这类工具。应用场景音频处理、图像压缩、通信系统、故障分析...物理意义把时域信号拆成不同频率的正弦波,看每个频率有多强。各符号含义积分的本质是"加权求和":乘以后积分,相当于计算信号与不同频率复指数波的"相似度",相似度越高的积分值就越大。是频谱:表示信号在频率ω处的"强度"(幅值)和"相位"(时间偏移)从时域到频域:原本看信号随时间怎么变(时域),变换后看信号由哪些频率组成(频域)用北太天元代码 + 可视化来进行理解第一步:生成一个复合信号先构造一个看起来有点复杂的信号——比如 50Hz 的基波 + 120Hz 的高频噪声

% 采样参数
fs = 1000;            % 采样频率 1000Hz
t = 0:1/fs:1-1/fs;    % 时间向量,1秒

% 构造复合信号:50Hz基波(幅值1.0) + 120Hz噪声(幅值0.5)
f1 = 50;              % 基波频率 50Hz
f2 = 120;             % 噪声频率 120Hz
signal = sin(2*pi*f1*t) + 0.5*sin(2*pi*f2*t);

% 绘制时域信号
figure(1);
subplot(2,1,1);
plot(t(1:100), signal(1:100), 'b', 'LineWidth', 1.5);
title('时域信号(前0.1秒)');
xlabel('时间 (s)');
ylabel('幅值');
grid on;
该信号肉眼根本看不出来有什么规律,即由哪些频率组成。第二步:对信号做傅里叶变换使用北太天元内置的快速傅里叶变换函数fft :
% 做FFT
N = length(signal);          % 信号长度
Y = fft(signal);             % 快速傅里叶变换

% 计算频率轴
f = (0:N-1)*(fs/N);          % 频率向量
subplot(4,1,2);
plot(f,abs(Y));
title("双边频谱,未做归一化和补偿");
xlabel("频率");
ylabel("幅值:abs(Y)");
grid on;
频率向量(f):形象化地理解就是频域信号的X轴。快速傅里叶变换的结果长度与采样点数是一致的,及length(signal)始终是等于length(t)的,用fs/N,实际是在计算频率分辨率,即两个点之间的频率跨度,而用(0:N-1)*(fs/N)就得到了频率向量,及频域的X轴。这里要注意,fs和N并不一定是相等的,fs是采样频率,决定了能分析的最高频率(奈奎斯特频率 = fs/2),而N是采样点的个数,例如这里fs=1000,但是t如果取2s的话,N就是2000了。第四步,取单边频谱,并进行补偿
% 单边频谱
P1 = P2(1:N/2+1);            
% 补偿单边幅值,end在这里等于501(当N=1000时),
% 所以2:end-1实际是2:500,正好避开了直流(索引1)和奈奎斯特频率(索引501)
P1(2:end-1) = 2*P1(2:end-1); 
subplot(4,1,4);
plot(f(1:end/2+1),P1);
title("补偿后的单边频谱");
xlabel("频率");
ylabel("幅值");
grid on;
单边频谱:由于FFT输出的前半部分(索引 1 ~ N/2+1)对应正频率(0 ~ fs/2 Hz),后半部分(索引 N/2+2 ~ N)对应负频率(-(fs/2-1) ~ -1 Hz),而正、负频率对应位置的幅值是对称相等的,因此我们取一边进行分析即可。单边幅值补偿:由于正、负频率各自包含了一半的幅值,而现在只取了单边频谱,需要将原负频率中的幅值补偿到正频率幅值中,即2*P1(2,end-1)。这里去掉了第1个点和最后一个点,因为:最终结果完整结果如下,可以看到有两个明显的峰值,一个在50Hz处,一个在120Hz处,幅值分别为1和0.5,可以看到傅里叶变换成功把信号拆分出来了。这样一看,傅里叶变换就很好理解了,而且对相关理论知识的实际应用也搞清楚了。QAQ1:除了正余弦波叠加的信号,其他波形叠加的信号能使用傅里叶变换进行分析吗?A:这里使用了两个正弦波的叠加来构造需要分析的信号,实际应用中,傅里叶变换几乎可以应用在所有波形的信号分析中,例如方波、三角波、锯齿波、高斯脉冲等等,只是分解出来的频谱特点有所不同,例如方波叠加的信号,常见信号在傅里叶变换后输出频谱的特点:Q2:进行傅里叶变换后,如何知道原始波形?A:快速傅里叶变换结果Y是一组复数,其取模代表幅值,即abs(Y/N)(除N是在归一化),永远为正,而相位通过相位角angle(Y)得到,再加上频率向量,这样有幅值、有相位、有频率,就可以重建原始信号啦。但实际应用中,通常只关注频率,忽略相位和幅值,因为很多应用只关心“有哪些频率”,不关心“原始信号长什么样”。例如,音频处理的时候,只关心能否过滤掉噪声,振动分析的时候,只关心设备在那个频率共振。Q3:如果是3个及以上的信号叠加,傅里叶变换还能分离出来吗?A:可以,傅里叶变换可以分离任意数量的信号叠加,只要它们的频率不同且间隔大于频率分辨率。

wenxin 0 0 2026-06-24

预测变量必须为数值向量、数值矩阵或分类向量

北太天元不支持 categorical 类型变量作为拟合变量,可使用 CategoricalVars 参数替代

%% 分段线性回归拟合:NIPT检测数据分析
% 业务背景:研究无创产前检测(NIPT)中,胎儿Y染色体浓度的影响因素
% 核心变量说明:
%    Y     - 母血中胎儿Y染色体游离DNA浓度(因变量/核心指标)
%    GA    - 孕妇孕周(自变量)
%    BMI   - 孕妇身体质量指数(分组依据)
% 分析目的:按BMI分组拟合回归线,探究不同肥胖程度下孕周对Y浓度的影响
% 兼容说明:北太天元不支持 categorical 类型变量作为拟合变量,可使用 CategoricalVars 参数替代
clear; clc; close all;

%% ========== 1. 生成模拟数据 ==========
rng(0);                  % 固定随机种子,结果可复现
n = 50;                  % 模拟样本数量
Y  = rand(n,1) * 0.2;    % 模拟胎儿Y染色体浓度数据
GA = rand(n,1) * 20 + 10;% 模拟孕周范围 10~30周
BMI= rand(n,1) * 30 + 15;% 模拟BMI范围 15~45

% BMI分组(固定切点:<30.5 / 30.5~36 / ≥36)
BMI_group = discretize(BMI, [0, 30.5, 36, Inf]); 

% 构建回归分析数据表
model_data = table(Y, GA, BMI_group, 'VariableNames', {'Y','GA','BMI_group'});

%% ========== 2. 【初始方案】转为分类变量(北太天元不支持,会报错) ==========
% 北太天元兼容性问题:不支持 categorical 数据类型,此代码运行报错
% model_data.BMI_group = categorical(model_data.BMI_group); 
% model1 = fitlm(model_data, 'Y ~ BMI_group * GA');

%% ========== 3. 【错误用法】数值型分组直接拟合 ==========
% BMI_group为数值类型,会被模型当作连续变量,无法实现分组分段效果
% model2 = fitlm(model_data, 'Y ~ BMI_group * GA');

%% ========== 4. 【替代方案】CategoricalVars 参数指定分组变量 ==========
% 无需转换数据类型,直接指定分组变量,完美替代 categorical,兼容北太天元
model_final = fitlm(model_data, 'Y ~ BMI_group * GA', 'CategoricalVars', "BMI_group");
初始方案报错信息如下:预测变量必须为数值向量、数值矩阵或分类向量。位于 BP 文件 [D:\ProgramFiles\baltamatica\toolbox\Stats\src\FitObject.bp]位于 BP 文件 [D:\ProgramFiles\baltamatica\toolbox\Stats\src\TermsRegression.bp]位于 BP 文件 [D:\ProgramFiles\baltamatica\toolbox\Stats\src\FitObject.bp]位于 BP 文件 [D:\ProgramFiles\baltamatica\toolbox\Stats\src\LinearModel.bp]位于 BP 文件 [D:\ProgramFiles\baltamatica\toolbox\Stats\src\fitlm.bp]位于文件 D:\Baltamatica\Workspace\learn\Baltamatica\产品使用案例制作\NIPT的时点选择与胎儿异常判定\test.m (第 27 行)model1 = fitlm(model_data, 'Y ~ BMI_group * GA');

wenxin 0 0 2026-05-07

MAT 数据文件版本

对于 MATLAB 保存的 MAT 格式数据文件,在北太天元中只能读取 v6 和 v7 两个版本的数据文件,对于 v4 和 v7.3 两个版本的数据文件,在北太天元中均提示数据文件为空。

邱彼郑楠 0 0 2025-11-27

没有内置表示时间的变量类型呀

我分析试飞信号,原始信号是几十赫兹频率采样的时间信号,你们这个里面没有时间类型的变量,导致没法代入进行计算呀。你看竟品时间都能当横轴画图。加减乘除也没啥问题。

飞行的工程师 1 0 2023-03-09

2.0版本导入数据功能功能还要继续开发呀

我试着用软件做我在商飞日常工作:导入试飞数据(时间序列数据,空格分隔,列对齐的文本文档)结果不支持txt后缀,改成csv之后果然导入有些问题。另外,你们导入.mat文件不支持比较新的table变量,这个变量格式我认为比矩阵,向量都要更有生命力。因为以上两个原因,我没能导入试飞数据进行计算尝试。这种导入数据的开发工作只是外围的琐碎开发工作,但对于使用体验影响还是蛮大的。

飞行的工程师 1 0 2023-03-08

北太天元如何导入导出文件数据

在使用北太天元编写一个程序时,经常需要从外部读入数据,或者将程序运行的结果保存为文件,北太天元主要支持以下格式数据文件的导入导出:.mat、.txt、.csv、.xls、.xlsx。具体介绍及用法如下。一、MAT文件的导入导出1. MAT文件的导出1.1 使用save函数

>> help save

  save 将工作区变量保存到文件中。
    
  save(filename),将当前工作区中的所有变量存储在名为 filename 的二进制文件 MAT 文件中。
  filename 为字符向量或字符串标量。例如,将文件名指定为 "myFile" 或 "myFile.mat"。
  如果未指定文件名,则将数据保存到名为 baltamatica.mat 的文件中。
  如果 filename 不包含扩展名,则会默认补充 '.mat' 扩展名。如果文件名不包含完整路径,则保存在当前文件夹中。
  保存路径必须具有写入文件的权限。  
  当第一个参数为 '-struct' 时,会将 '-struct' 后的第二个参数 (非以 '-' 开头的参数) 当做 filename,
  如 save('-struct',structname,filename,fieldnames)。
  
  save(filename,variables),仅存储指定的变量。filename 和 variables 为字符向量或字符串标量。
  variables 可使用 '*' 通配符匹配模式。例如,save('data.mat','A*') 保存以 A 开头的所有变量。
  
  save(filename,'-struct',structname,fieldnames),将标量结构体的字段存储为单个变量。
  如果使用了 fieldnames 参数,则 save 函数仅存储结构体中的 fieldnames 字段。
  fieldnames 与 variables 具有相同的形式。不能在同一调用中指定 variables 和 '-struct' 来保存数据。
示例:保存structure数组实例。例如有如下的structure数组s1:s1.a = 22.33; s1.b =”Steve”; s1.c = ' World!';使用 save 命令,可将整个structure数组保存为struct_data.mat。
>> save('struct_data.mat', 's1');
1.2 使用界面操作在工作区中使用鼠标左键选中要保存的数据,点击鼠标右键,会弹出操作框,点击保存即可,在工作区空白处点击鼠标右键,可保存工作区的所有变量。2.MAT文件的导入2.1使用load函数
>> help load
    load 将文件变量加载到工作区中。
    load(filename),将 MAT 文件中的变量加载到工作区。
    filename 为字符向量或字符串标量。例如,将文件名指定为 "myFile" 或 "myFile.mat"。
    
    如果未指定文件名,默认读取当前路径下的 baltamatica.mat。
    load(filename,variables),读取指定的变量。filename 和 variables 为字符向量或字符串标量。
    variables 可使用 '*' 通配符匹配模式。例如,load('data.mat','A*') 加载以 A 开头的所有变量。
    
    load(filename,'-mat') 将 filename 视为 mat 文件,而不管文件扩展名如何。
    
    load(filename,'-mat',variables) 加载 filename 文件中的指定变量。
示例:将A.mat文件中的变量导入到structure数组s中。
>> s=load("A.mat")
s =
 1x1 struct
 结构体:
   A1: [3x3 double]
   A2: "string"
   A3: [1x3 double]
   A4: [1x2 cell array]
2.2 使用界面操作点击菜单栏的“导入“->”导入数据”弹出导入文件操作界面二、TXT、CSV及Excel文件的导入导出1. TXT、CSV及Excel文件的导入1.1 使用readmatrix函数(1)导入文本文件文本文件的数据格式在行和列上必须采取一致的模式,并使用分隔符来分隔各个数据项。分隔符可以是空格、逗号、分号或其他字符,单个的数据可以是字母、数值字符或它们的混合形式。示例:文件data.txt包含了两行数据,各数据之间由空格分隔。1 2 34 5 6
>> m=readmatrix("data.txt") %使用readmatrix导入数据
m =
 2x3 double
  1   2   3
  4   5   6
(2)导入csv数据csv文件是逗号分隔的纯文件文件。除了可以使用readmatrix函数读取之外,同时也可以使用csvread函数,推荐使用readmatrix函数。示例:文件data.csv中的数据如下:1.2,2.5,3.2,4.65.4,6.2,7.1,8.2
>> m=readmatrix("data.csv") %使用readmatrix导入数据
m =
 2x4 double
   1.2000    2.5000    3.2000    4.6000
   5.4000    6.2000    7.1000    8.2000
(3)导入Excel数据Excel文件包含.xls及.xlsx两类文件。示例:文件data.xlsx中的数据如下:
>> m=readmatrix("data.xlsx") %使用readmatrix导入数据
m =
 5x2 double
   1.0000    2.0000
   3.0000    4.0000
   5.0000    6.0000
     NaN      NaN
   7.0000    8.0000
1.2 使用界面操作点击菜单栏的“导入“->”导入数据”,弹出导入文件操作界面,选择文件导入即可。2. TXT、CSV及Excel文件的导出2.1使用writematrix函数(1)保存txt文本文件示例:将a=[1,2,3;4,5,6;7,8,9]'所表示的矩阵数据存储到“w_data.txt”的文件当中,以制表符分隔。
>> a =
 3x3 double
  1   4   7
  2   5   8
  3   6   9
>> writematrix(a,"w_data.txt","Delimiter","-")
使用文本查看器查看w_data.txt:(2)保存csv文本文件示例:将a=[1,2,3;4,5,6;7,8,9]'所表示的矩阵数据存储到“w_data.csv”的文件当中。
>> writematrix(a,"w_data.csv")
使用wps查看器查看w_data.csv:(3)保存xlsx文本文件
>> writematrix(a,"w_data.xlsx")
使用wps查看器查看w_data.xlsx:注:暂不支持.xls文件格式的导出操作,excel推荐使用.xlsx的导出文件格式。2.2 使用界面操作在工作区中使用鼠标左键选中要保存的数据,点击鼠标右键,会弹出操作框,点击“导出变量”即可。该方式仅支持”.xlsx”格式文件的导出。

Forever 1 4 2022-12-13