【问题标题】:Fitting piecewise linear function with SVD using MATLAB使用 MATLAB 用 SVD 拟合分段线性函数
【发布时间】:2021-04-09 15:39:01
【问题描述】:

我尝试拟合分段线性函数

y=a1*x + a0, for x < 0 and
y=a1*x + a0 + a01, for x > 0

它们共享相同的斜率。我使用 MATLAB 的反斜杠运算符使用以下方法:

a0 = 1;
a01 = 1.1;
a1 = 0.5;

x= linspace(-1,1, 150);

y = tilt_step(x, a0, a01, a1);
y = y + 0.*rand(size(y));

figure(1); clf;
plot(x, y, '.');

[a0, a01, a1] = fit_tilt_step(x, y, 0.01);

hold on;
plot(x, tilt_step(x, a0, a01, a1), 'r');
grid on

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function y = tilt_step(x, a0, a01, a1)
y = a0 + a1.*x;
fi = find(x>0);
y(fi) = y(fi) + a01;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [a0, a01, a1] = fit_tilt_step(x, y, separation)

x = x(:);
y = y(:);

my = mean(y);
y = y-mean(y);

fi = find(x<separation);
M = [ones(length(fi), 1) zeros(length(fi), 1) x(fi)];

fi = find(x>separation);
M = [M; ones(length(fi), 1) ones(length(fi), 1) x(fi)];

a = M \ y;

a0 = a(1) + my;
a01 = a(2);
a1 = a(3);

end

该方法适用于 = 150 个数据点时,结果有点偏离:

a0 =  1.0362
a01 = 1.0415
a1 =  0.5437

我猜这是数字准确性或稳定性问题。有人可以帮助如何重新制定问题以避免这种情况吗?

【问题讨论】:

    标签: matlab curve-fitting


    【解决方案1】:

    嗯,这很简单:我搞砸了分离参数的数据点选择。这是更正后的代码,正在运行:

    a0 = 1;
    a01 = 1.1;
    a1 = 0.5;
    
    x= linspace(-1,1, 1500);
    
    y = tilt_step(x, a0, a01, a1);
    y = y + 0..*rand(size(y));
    
    figure(1); clf;
    plot(x, y, '.');
    
    [a0, a01, a1] = fit_tilt_step(x, y, 0.1);
    
    hold on;
    plot(x, tilt_step(x, a0, a01, a1), 'r');
    grid on
    
    a0
    a01
    a1
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
    function y = tilt_step(x, a0, a01, a1)
    y = a0 + a1.*x;
    fi = find(x>0);
    y(fi) = y(fi) + a01;
    end
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
    function [a0, a01, a1] = fit_tilt_step(x, y, separation)
    
    x = x(:);
    y = y(:);
    
    my = 0; % mean(y);
    y = y-my;
    
    fi1 = find(x<-separation);
    M = [ones(length(fi1), 1) zeros(length(fi1), 1) x(fi1)];
    
    fi2 = find(x>separation);
    M = [M; ones(length(fi2), 1) ones(length(fi2), 1) x(fi2)];
    
    a = M \ y([fi1;fi2]);
    
    a0 = a(1) + my;
    a01 = a(2);
    a1 = a(3);
    
    end
    

    【讨论】:

      猜你喜欢
      • 2014-03-28
      • 1970-01-01
      • 2014-06-29
      • 2020-07-27
      • 1970-01-01
      • 2017-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多