You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MATLAB中如何调整现有拟合函数使其通过指定两点并保留原有形状

问题描述

假设我已有一个通过某数据集拟合得到的函数,我希望让该函数经过当前未穿过的两个不同点,同时函数其余部分适配这一改动并保留原有形态,效果示意如下:
效果示意图
我当前使用的是含11个系数的有理拟合(分子为5次多项式共6个系数,分母为5次多项式,最高次项系数固定为1,剩余5个自由系数)。如果有助于实现需求,我也可以更换拟合类型(多项式、正弦和等)。
我曾尝试随机修改两个系数来强制函数匹配两个新点,但得到的结果不符合预期。
当前我的拟合结果如下:
拟合结果图1
拟合结果图2
以下是通过Matlab cftool对Excel数据集进行有理拟合得到的代码:

p1 = 0.09503;
p2 = 0.8033;
p3 = 2.654;
p4 = 4.375;
p5 = 3.691; 
p6 = 1.221;  
q1 = 6.399;
q2 = 21.65;  
q3 = 34.98;  
q4 = 29.02; 
q5 = 9.704;  
m = (x - 0.9857)./0.1235;
y = (p1*m.^5 + p2*m.^4 + p3*m.^3 + p4*m.^2 + p5*m + p6) ./ (m.^5 + q1*m.^4 + q2*m.^3 + q3*m.^2 + q4*m + q5);

我需要让该函数经过(0.78, 0.002)和(1.05473536553, 9.869964329717e-2)两个点,同时保留原有形状。


解决方案

方法1:带约束的最小二乘重拟合(推荐,适配原有有理拟合形式)

你当前的有理函数共有11个自由参数,仅增加2个等式约束后仍有9个自由度,足够完整保留原始拟合的形态。
操作步骤:

  1. 先将两个目标点转换为归一化m坐标:
    • 点1:x=0.78,计算得m1 = (0.78-0.9857)/0.1235 ≈ -1.6656,目标y值为0.002
    • 点2:x=1.05473536553,计算得m2 = (1.05473536553-0.9857)/0.1235 ≈ 0.559,目标y值为0.0987
  2. 写出两个约束方程,形式为分子(m_i) - y_i * 分母(m_i) = 0, i=1,2
  3. 将原始数据集、两个目标点(可给目标点设置10~100倍的高权重,保证强制穿过)代入带线性约束的最小二乘求解,直接得到新的p、q参数。

Matlab示例代码片段:

% 假设原始的x、y数据存在变量x_raw、y_raw里
m_raw = (x_raw - 0.9857)./0.1235;
% 构造最小二乘系数矩阵C和目标向量d
C = [m_raw.^5, m_raw.^4, m_raw.^3, m_raw.^2, m_raw, ones(size(m_raw)), ...
    -y_raw.*m_raw.^4, -y_raw.*m_raw.^3, -y_raw.*m_raw.^2, -y_raw.*m_raw, -y_raw];
d = y_raw.*m_raw.^5;
% 定义约束矩阵A和b,满足A*params = b
m1 = (0.78-0.9857)/0.1235; y1 = 0.002;
m2 = (1.05473536553-0.9857)/0.1235; y2 = 9.869964329717e-2;
A = [m1^5, m1^4, m1^3, m1^2, m1, 1, -y1*m1^4, -y1*m1^3, -y1*m1^2, -y1*m1, -y1;
     m2^5, m2^4, m2^3, m2^2, m2, 1, -y2*m2^4, -y2*m2^3, -y2*m2^2, -y2*m2, -y2];
b = [y1*m1^5; y2*m2^5];
% 用原始参数作为初始值,调用lsqlin求解
params0 = [0.09503,0.8033,2.654,4.375,3.691,1.221,6.399,21.65,34.98,29.02,9.704];
params = lsqlin(C,d,A,b,[],[],[],[],params0);
% 提取新参数
p1_new = params(1); p2_new = params(2); p3_new = params(3); p4_new = params(4); p5_new = params(5); p6_new = params(6);
q1_new = params(7); q2_new = params(8); q3_new = params(9); q4_new = params(10); q5_new = params(11);

方法2:低阶校正项适配(无需重拟合,改动最小)

如果不想修改原始拟合参数,可以在原始函数基础上叠加一个二阶校正项,保证校正项仅在目标点处补全差值,其余区域几乎无影响:

% 定义原始拟合函数
y0 = @(x) (p1*((x-0.9857)/0.1235).^5 + p2*((x-0.9857)/0.1235).^4 + p3*((x-0.9857)/0.1235).^3 + p4*((x-0.9857)/0.1235).^2 + p5*((x-0.9857)/0.1235) + p6) ./ (((x-0.9857)/0.1235).^5 + q1*((x-0.9857)/0.1235).^4 + q2*((x-0.9857)/0.1235).^3 + q3*((x-0.9857)/0.1235).^2 + q4*((x-0.9857)/0.1235) + q5);
% 计算两个点的差值
x1 = 0.78; y1_target = 0.002; delta1 = y1_target - y0(x1);
x2 = 1.05473536553; y2_target = 9.869964329717e-2; delta2 = y2_target - y0(x2);
% 构造线性校正项,仅在两个目标点处有补偿
delta_y = @(x) delta1.*(x-x2)./(x1-x2) + delta2.*(x-x1)./(x2-x1);
% 最终函数
y = @(x) y0(x) + delta_y(x);

内容的提问来源于stack exchange,提问作者stevederekson555

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 21:24:03