Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 如何将两条多边形拟合线从任意一侧延伸到相交处,并获得组合拟合线_Matlab_Curve Fitting_Polynomial Math_Line Intersection_Linear Equation - Fatal编程技术网

Matlab 如何将两条多边形拟合线从任意一侧延伸到相交处,并获得组合拟合线

Matlab 如何将两条多边形拟合线从任意一侧延伸到相交处,并获得组合拟合线,matlab,curve-fitting,polynomial-math,line-intersection,linear-equation,Matlab,Curve Fitting,Polynomial Math,Line Intersection,Linear Equation,我试图从两侧(应相交)的两个线性多边形拟合得到组合拟合线,以下是拟合线的图片: 我正在尝试使两条拟合(蓝色)线相交,并生成一条组合拟合线,如下图所示: 请注意,波峰可以发生在任何地方,所以我不能假设它在中心 以下是创建第一个绘图的代码: xdatPart1 = R; zdatPart1 = z; n = 3000; ln = length(R); [sX,In] = sort(R,1); sZ = z(In); xdatP1 = sX(1:n,1); zdatP1 =

我试图从两侧(应相交)的两个线性多边形拟合得到组合拟合线,以下是拟合线的图片:

我正在尝试使两条拟合(蓝色)线相交,并生成一条组合拟合线,如下图所示:

请注意,波峰可以发生在任何地方,所以我不能假设它在中心

以下是创建第一个绘图的代码:

xdatPart1 = R;
zdatPart1 = z;

n = 3000;
ln = length(R);

[sX,In] = sort(R,1);

sZ = z(In);       

xdatP1 = sX(1:n,1);
zdatP1 = sZ(1:n,1);

n2 = ln - 3000;

xdatP2 = sX(n2:ln,1);
zdatP2 = sZ(n2:ln,1);

pp1 = polyfit(xdatP1,zdatP1,1);
pp2 = polyfit(xdatP2,zdatP2,1);

ff1 = polyval(pp1,xdatP1);
ff2 = polyval(pp2,xdatP2);

xDat = [xdatPart1];
zDat = [zdatPart1];

axes(handles.axes2);
cla(handles.axes2);
plot(xdatPart1,zdatPart1,'.r');
hold on
plot(xdatP1,ff1,'.b');
plot(xdatP2,ff2,'.b');
xlabel(['R ',units]);
ylabel(['Z ', units]);
grid on
hold off

下面是一个没有曲线拟合工具箱的粗略实现。虽然代码应该是不言自明的,但下面是算法的概要:

  • 我们生成一些数据
  • 我们通过平滑数据并找到最大值的位置来估计交点
  • 我们在估计交点的每一侧拟合一条线
  • 我们使用拟合方程计算拟合线的交点
  • 我们使用构造一个“可评估”分段多项式的函数句柄
  • 输出,
    ppfunc
    ,是一个1个变量的函数句柄,您可以像这样使用它
  • 现在,这个解决方案在任何意义上都不是最优的(如MMSE、LSQ等),但正如您将在与MATLAB工具箱的结果的比较中看到的,它并没有那么糟糕

    function ppfunc = q40160257
    %% Define the ground truth:
    center_x = 6 + randn(1);
    center_y = 78.15 + 0.01 * randn(1);
    % Define a couple of points for the left section
    leftmost_x = 0;
    leftmost_y = 78.015 + 0.01 * randn(1);
    % Define a couple of points for the right section
    rightmost_x = 14.8;
    rightmost_y = 78.02 + 0.01 * randn(1);
    % Find the line equations:
    m1 = (center_y-leftmost_y)/(center_x-leftmost_x);
    n1 = getN(leftmost_x,leftmost_y,m1);
    m2 = (rightmost_y-center_y)/(rightmost_x-center_x);
    n2 = getN(rightmost_x,rightmost_y,m2);
    % Print the ground truth:
    fprintf(1,'The line equations are: {y1=%f*x+%f} , {y2=%f*x+%f}\n',m1,n1,m2,n2)
    %% Generate some data:
    NOISE_MAGNITUDE = 0.002;
    N_POINTS_PER_SIDE = 1000;
    x1 = linspace(leftmost_x,center_x,N_POINTS_PER_SIDE);
    y1 = m1*x1+n1+NOISE_MAGNITUDE*randn(1,numel(x1));
    x2 = linspace(center_x,rightmost_x,N_POINTS_PER_SIDE);
    y2 = m2*x2+n2+NOISE_MAGNITUDE*randn(1,numel(x2));
    X = [x1 x2(2:end)]; Y = [y1 y2(2:end)];
    %% See what we have:
    figure(); plot(X,Y,'.r'); hold on;
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% Estimating the intersection point:
    MOVING_AVERAGE_PERIOD = 10; % Play around with this value.
    smoothed_data = conv(Y, ones(1,MOVING_AVERAGE_PERIOD)/MOVING_AVERAGE_PERIOD, 'same');
    plot(X, smoothed_data, '-b'); ylim([floor(leftmost_y*10) ceil(center_y*10)]/10);
    [~,centerInd] = max(smoothed_data);
    fprintf(1,'The real intersection is at index %d, the estimated is at %d.\n',...
               N_POINTS_PER_SIDE, centerInd);
    %% Fitting a polynomial to each side:
    p1 = polyfit(X(1:centerInd),Y(1:centerInd),1);
    p2 = polyfit(X(centerInd+1:end),Y(centerInd+1:end),1);
    [x_int,y_int] = getLineIntersection(p1,p2);
    plot(x_int,y_int,'sg');
    
    pp = mkpp([X(1) x_int X(end)],[p1; (p2 + [0 x_int*p2(1)])]);
    ppfunc = @(x)ppval(pp,x);
    plot(X, ppfunc(X),'-k','LineWidth',3)
    legend('Original data', 'Smoothed data', 'Computed intersection',...
           'Final piecewise-linear fit');
    grid on; grid minor;     
    
    %% Comparison with the curve-fitting toolbox:
    if license('test','Curve_Fitting_Toolbox')
      ft = fittype( '(x<=-(n2-n1)/(m2-m1))*(m1*x+n1)+(x>-(n2-n1)/(m2-m1))*(m2*x+n2)',...
                    'independent', 'x', 'dependent', 'y' );
      opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
      % Parameter order: m1, m2, n1, n2:
      opts.StartPoint = [0.02 -0.02 78 78];
      fitresult = fit( X(:), Y(:), ft, opts);
      % Comparison with what we did above:
      fprintf(1,[...
        'Our solution:\n'...
        '\tm1 = %-12f\n\tm2 = %-12f\n\tn1 = %-12f\n\tn2 = %-12f\n'...
        'Curve Fitting Toolbox'' solution:\n'...
        '\tm1 = %-12f\n\tm2 = %-12f\n\tn1 = %-12f\n\tn2 = %-12f\n'],...
        m1,m2,n1,n2,fitresult.m1,fitresult.m2,fitresult.n1,fitresult.n2);    
    end
    
    %% Helper functions:
    function n = getN(x0,y0,m)
    % y = m*x+n => n = y0-m*x0;
    n = y0-m*x0;
    
    function [x_int,y_int] = getLineIntersection(p1,p2)
    % m1*x+n1 = m2*x+n2 => x = -(n2-n1)/(m2-m1)
    x_int = -(p2(2)-p1(2))/(p2(1)-p1(1));
    y_int = p1(1)*x_int+p1(2);
    

    围绕交叉点放大:
    下面是一个没有曲线拟合工具箱的粗略实现。虽然代码应该是不言自明的,但下面是算法的概要:

  • 我们生成一些数据
  • 我们通过平滑数据并找到最大值的位置来估计交点
  • 我们在估计交点的每一侧拟合一条线
  • 我们使用拟合方程计算拟合线的交点
  • 我们使用构造一个“可评估”分段多项式的函数句柄
  • 输出,
    ppfunc
    ,是一个1个变量的函数句柄,您可以像这样使用它
  • 现在,这个解决方案在任何意义上都不是最优的(如MMSE、LSQ等),但正如您将在与MATLAB工具箱的结果的比较中看到的,它并没有那么糟糕

    function ppfunc = q40160257
    %% Define the ground truth:
    center_x = 6 + randn(1);
    center_y = 78.15 + 0.01 * randn(1);
    % Define a couple of points for the left section
    leftmost_x = 0;
    leftmost_y = 78.015 + 0.01 * randn(1);
    % Define a couple of points for the right section
    rightmost_x = 14.8;
    rightmost_y = 78.02 + 0.01 * randn(1);
    % Find the line equations:
    m1 = (center_y-leftmost_y)/(center_x-leftmost_x);
    n1 = getN(leftmost_x,leftmost_y,m1);
    m2 = (rightmost_y-center_y)/(rightmost_x-center_x);
    n2 = getN(rightmost_x,rightmost_y,m2);
    % Print the ground truth:
    fprintf(1,'The line equations are: {y1=%f*x+%f} , {y2=%f*x+%f}\n',m1,n1,m2,n2)
    %% Generate some data:
    NOISE_MAGNITUDE = 0.002;
    N_POINTS_PER_SIDE = 1000;
    x1 = linspace(leftmost_x,center_x,N_POINTS_PER_SIDE);
    y1 = m1*x1+n1+NOISE_MAGNITUDE*randn(1,numel(x1));
    x2 = linspace(center_x,rightmost_x,N_POINTS_PER_SIDE);
    y2 = m2*x2+n2+NOISE_MAGNITUDE*randn(1,numel(x2));
    X = [x1 x2(2:end)]; Y = [y1 y2(2:end)];
    %% See what we have:
    figure(); plot(X,Y,'.r'); hold on;
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% Estimating the intersection point:
    MOVING_AVERAGE_PERIOD = 10; % Play around with this value.
    smoothed_data = conv(Y, ones(1,MOVING_AVERAGE_PERIOD)/MOVING_AVERAGE_PERIOD, 'same');
    plot(X, smoothed_data, '-b'); ylim([floor(leftmost_y*10) ceil(center_y*10)]/10);
    [~,centerInd] = max(smoothed_data);
    fprintf(1,'The real intersection is at index %d, the estimated is at %d.\n',...
               N_POINTS_PER_SIDE, centerInd);
    %% Fitting a polynomial to each side:
    p1 = polyfit(X(1:centerInd),Y(1:centerInd),1);
    p2 = polyfit(X(centerInd+1:end),Y(centerInd+1:end),1);
    [x_int,y_int] = getLineIntersection(p1,p2);
    plot(x_int,y_int,'sg');
    
    pp = mkpp([X(1) x_int X(end)],[p1; (p2 + [0 x_int*p2(1)])]);
    ppfunc = @(x)ppval(pp,x);
    plot(X, ppfunc(X),'-k','LineWidth',3)
    legend('Original data', 'Smoothed data', 'Computed intersection',...
           'Final piecewise-linear fit');
    grid on; grid minor;     
    
    %% Comparison with the curve-fitting toolbox:
    if license('test','Curve_Fitting_Toolbox')
      ft = fittype( '(x<=-(n2-n1)/(m2-m1))*(m1*x+n1)+(x>-(n2-n1)/(m2-m1))*(m2*x+n2)',...
                    'independent', 'x', 'dependent', 'y' );
      opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
      % Parameter order: m1, m2, n1, n2:
      opts.StartPoint = [0.02 -0.02 78 78];
      fitresult = fit( X(:), Y(:), ft, opts);
      % Comparison with what we did above:
      fprintf(1,[...
        'Our solution:\n'...
        '\tm1 = %-12f\n\tm2 = %-12f\n\tn1 = %-12f\n\tn2 = %-12f\n'...
        'Curve Fitting Toolbox'' solution:\n'...
        '\tm1 = %-12f\n\tm2 = %-12f\n\tn1 = %-12f\n\tn2 = %-12f\n'],...
        m1,m2,n1,n2,fitresult.m1,fitresult.m2,fitresult.n1,fitresult.n2);    
    end
    
    %% Helper functions:
    function n = getN(x0,y0,m)
    % y = m*x+n => n = y0-m*x0;
    n = y0-m*x0;
    
    function [x_int,y_int] = getLineIntersection(p1,p2)
    % m1*x+n1 = m2*x+n2 => x = -(n2-n1)/(m2-m1)
    x_int = -(p2(2)-p1(2))/(p2(1)-p1(1));
    y_int = p1(1)*x_int+p1(2);
    

    围绕交叉点放大:

    做了一些编辑以使其清晰明了。您需要估计的结果有多好。。。?我可以想出一个解决方案,但它在最小二乘法(或任何其他)意义上都不是最优的。。。另外,你有曲线拟合工具箱吗?没有,我没有曲线拟合工具箱。你能给出一个没有工具箱的解决方案吗?你做了一些编辑来弄清楚。你需要估计值有多好。。。?我可以想出一个解决方案,但它在最小二乘法(或任何其他)意义上都不是最优的。。。另外,你有曲线拟合工具箱吗?没有,我没有曲线拟合工具箱,请你给出一个没有工具箱的解决方案好吗?谢谢,先生,我理解大部分代码,但我在理解基本事实方面有困难。在我的情况下,两边都有部分数据,如何计算基本事实或中心。@nman84在您的案例中不需要这些数据。请注意,在拟合多项式之后,我的代码只依赖于拟合的方程-您也有。只需跳到我做的部分
    getLineIntersection(p1,p2)但使用您的
    pp1
    pp2
    。我之所以这样做,是因为我必须自己生成数据,并将其分为两部分,这两部分都是有意义的。您的数据没有这样的问题。谢谢先生,我理解了大部分代码,但我在理解基本事实方面遇到了困难。在我的情况下,两边都有部分数据,如何计算基本事实或中心。@nman84在您的案例中不需要这些数据。请注意,在拟合多项式之后,我的代码只依赖于拟合的方程-您也有。只需跳到我做的部分
    getLineIntersection(p1,p2)但使用您的
    pp1
    pp2
    。我之所以这样做,是因为我必须自己生成数据,并将其分为两部分,这两部分都是有意义的。你的数据没有这样的问题。