创建分段函数的关键是将if 条件替换为矢量化>。通过在某个数组x 上调用y = x > 1,输出y 将是一个与x 大小相同的数组,如果x 中的对应元素大于1,则为逻辑True,并且False 否则。例如
>> x = [1, 2, 4; 3, 1, 2];
>> y = x > 2
y =
2×3 logical array
0 0 1
1 0 0
您可以利用它来创建分段线性函数,如下所示:
>> fun = @(theta, xdata) theta(1) + ...
(xdata<=theta(2)) .* theta(3) .* xdata + ...
(xdata>theta(2)) .* (theta(3) * theta(2) + ...
theta(4) .* (xdata-theta(2)))
参数向量theta 将是 4 维的:第一个元素是从零开始的恒定偏移量,第二个元素是角点,第三个和第四个元素是两个斜率。
通过将theta(3).*xdata 与xdata<=theta(2) 的结果相乘,对于xdata 中小于theta(2) 的每个点,您将得到theta(3).*xdata,对于所有其他点,您将得到0。
那么,调用lsqcurvefit就这么简单
>> theta = lsqcurvefit(fun, [0; 15; 0; 1], xdata, ydata)
theta =
18.3793
17.9639
-0.0230
0.9943
lsqcurvefit 函数还允许您为要估计的变量指定下限lb 和上限ub。对于您不想指定界限的变量,您可以使用例如inf 绑定。为了确保您的a1 和a2,即theta(3) 和theta(4) 是正数,我们可以将下限指定为[-inf, -inf, 0, 0]。
但是,lsqcurvefit 函数不允许您添加约束 a2 > a1(或任何线性不等式约束)。在示例数据中,这个约束可能甚至没有必要,因为这从数据中很明显。否则,一个可能的解决方案是将a2 替换为a1 + da,并为da 使用0 的下限。这可以确保a2 >= a1。
>> fun = @(theta, xdata) theta(1) + ...
(xdata<=theta(2)) .* theta(3) .* xdata + ...
(xdata>theta(2)) .* (theta(3) * theta(2) + ...
(theta(3)+theta(4)) .* (xdata-theta(2)))
>> theta = lsqcurvefit(fun, [0; 15; 0; 1], xdata, ydata, [-Inf, -Inf, 0, 0], [])
theta =
18.1162
18.1159
0.0000
0.9944