普通会员

wenxin

此用户很神秘,没有留下任何信息

3帖子
0回复
212积分
ID:024583
table类型无法使用.语法新增列

目前,北太天元不支持通过.语法对已有表格类型的变量新增列,例如:

mytable=table(["张三";"李四";"王麻子"],["男";"男";"男"],'VariableNames',{'姓名','性别'});

mytable.年龄=[22;23;21];

会出现:无法识别表变量名称: '年龄'这样的错误输出


现在可以通过表格并置的方式解决,期待后续官方能支持.这种语法


mytable=table(["张三";"李四";"王麻子"],["男";"男";"男"],'VariableNames',{'姓名','性别'});

%并置

newtable=table([22;23;21],'VariableNames',{'年龄'});

mytable=[mytable,newtable];

0 2026-04-30
预测变量必须为数值向量、数值矩阵或分类向量

北太天元不支持 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');

0 2026-05-07
用北太天元学习傅里叶变换

连续时间傅里叶变换(CTFT)公式:

ScreenShot_2026-06-24_093831_206.png

每次看到这样的公式就头大,个人觉得其实是没有把抽象的数学和实际应用场景结合起来,导致理解起来很困难,实际用的时候又不会用,所以想着干脆在北太天元里面搞一遍,既能辅助理解,又解决了应用问题,因为实际场景中做信号分析的时候也就是用北太天元这类工具。

应用场景

音频处理、图像压缩、通信系统、故障分析...

物理意义

把时域信号拆成不同频率的正弦波,看每个频率有多强。

各符号含义

ScreenShot_2026-06-24_100659_196.png

积分的本质是"加权求和":ScreenShot_2026-06-24_100949_893.png乘以ScreenShot_2026-06-24_101010_868.png后积分,相当于计算信号与不同频率复指数波的"相似度",相似度越高的积分值就越大。

ScreenShot_2026-06-24_101041_869.png是频谱:表示信号在频率ω处的"强度"(幅值)和"相位"(时间偏移)

从时域到频域:原本看信号随时间怎么变(时域),变换后看信号由哪些频率组成(频域)

用北太天元代码 + 可视化来进行理解

第一步:生成一个复合信号

先构造一个看起来有点复杂的信号——比如 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;

ScreenShot_2026-06-24_101248_635.png

该信号肉眼根本看不出来有什么规律,即由哪些频率组成。

第二步:对信号做傅里叶变换

使用北太天元内置的快速傅里叶变换函数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了。

ScreenShot_2026-06-24_101745_196.png

第四步,取单边频谱,并进行补偿

% 单边频谱
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个点和最后一个点,因为:

ScreenShot_2026-06-24_101952_629.png

ScreenShot_2026-06-24_102051_273.png

最终结果

完整结果如下,可以看到有两个明显的峰值,一个在50Hz处,一个在120Hz处,幅值分别为1和0.5,可以看到傅里叶变换成功把信号拆分出来了。

ScreenShot_2026-06-24_102147_306.png

这样一看,傅里叶变换就很好理解了,而且对相关理论知识的实际应用也搞清楚了。


QA

Q1:除了正余弦波叠加的信号,其他波形叠加的信号能使用傅里叶变换进行分析吗?

A:这里使用了两个正弦波的叠加来构造需要分析的信号,实际应用中,傅里叶变换几乎可以应用在所有波形的信号分析中,例如方波、三角波、锯齿波、高斯脉冲等等,只是分解出来的频谱特点有所不同,例如方波叠加的信号,常见信号在傅里叶变换后输出频谱的特点:

ScreenShot_2026-06-24_102458_871.png


Q2:进行傅里叶变换后,如何知道原始波形?

A:快速傅里叶变换结果Y是一组复数,其取模代表幅值,即abs(Y/N)(除N是在归一化),永远为正,而相位通过相位角angle(Y)得到,再加上频率向量,这样有幅值、有相位、有频率,就可以重建原始信号啦。但实际应用中,通常只关注频率,忽略相位和幅值,因为很多应用只关心“有哪些频率”,不关心“原始信号长什么样”。例如,音频处理的时候,只关心能否过滤掉噪声,振动分析的时候,只关心设备在那个频率共振。


Q3:如果是3个及以上的信号叠加,傅里叶变换还能分离出来吗?

A:可以,傅里叶变换可以分离任意数量的信号叠加,只要它们的频率不同且间隔大于频率分辨率。

0 2026-06-24