MATLAB中fittype不接受含conv2卷积的自定义拟合函数如何解决
报错根本原因
MATLAB的fittype在实例化阶段,会默认传入标量测试值验证自定义函数的输出合法性,不会直接使用你后续要拟合的4096×1尺寸X、1×11尺寸Y数组。你在自定义函数内硬编码了固定尺寸的zeros(4095,11),当fittype用标量X做测试时,后面的公式运算得到的是1×1标量,和4095行11列的零矩阵拼接时自然触发维度不匹配错误,和卷积运算本身无关。
可行解决方案
推荐两种解决路径,优先选第二种兼容性更强:
路径1:适配fittype的测试规则
修改自定义函数,兼容标量测试场景,同时不要硬编码固定维度:
% 先定义公共参数 IRF = rand(4096,1); X_fit = (1:4096)'; Y_fit = 1:11; % 自定义函数内置维度判断,处理fittype的标量测试 model_fun = @(mu_a,redmu,X,Y) ... isscalar(X) & isscalar(Y) ... % 判定是fittype的标量测试,直接返回标量 ? 0 ... : conv2([zeros(size(X,1)-1,size(Y,2)); ... ((1/(3*redmu+mu_a))^(-3/2)).*(X).^(-5/2).*... exp(-mu_a*2.*(X)).*exp(-(Y.^2)./(4/(3*redmu+mu_a)*2.*X))],... IRF,'valid'); % 创建fittype,加上'problem'参数绑定IRF避免工作区变量引用问题 ft_fixed = fittype(model_fun,'independent',{'X','Y'},... 'coefficient',{'mu_a','redmu'},'problem',{'IRF'});
调用fit的时候把IRF作为problem参数传入即可。
路径2:改用lsqcurvefit做非线性拟合(更推荐)
lsqcurvefit属于优化工具箱的通用拟合函数,没有fittype的额外测试规则,对自定义卷积这类特殊运算的兼容性更好:
% 准备拟合输入输出,Rw是你的实验测量数据,这里用模拟值代替 redmu_true = 10; mu_a_true = 0; IRF = rand(4096,1); X = (1:4096)'; Y = 1:11; Rw_true = conv2([zeros(4095,11);((1/(3*redmu_true+mu_a_true))^(-3/2)).*(X).^(-5/2).*... exp(mu_a_true*2.*(X)).*exp(-(Y.^2)./(4/(3*redmu_true+mu_a_true)*2.*X))],IRF,'valid'); % 定义拟合模型,输入p是参数向量,p(1)=mu_a, p(2)=redmu model_fun = @(p) conv2([zeros(4095,11);((1/(3*p(2)+p(1)))^(-3/2)).*(X).^(-5/2).*... exp(-p(1)*2.*(X)).*exp(-(Y.^2)./(4/(3*p(2)+p(1))*2.*X))],IRF,'valid'); % 定义残差函数 res_fun = @(p) model_fun(p) - Rw_true; % 初始猜测值,根据你的参数范围调整 p0 = [0.1, 5]; % 上下限,按需设置 lb = [0, 0]; ub = [1, 100]; % 执行拟合 p_fit = lsqcurvefit(res_fun, p0, [], [], lb, ub); mu_a_fit = p_fit(1); redmu_fit = p_fit(2);
内容的提问来源于stack exchange,提问作者Coha
相关产品推荐
相关产品推荐

