的關鍵在於創造分段功能是通過向量化>
更換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維的參數:所述第一元件是一個常數偏離零,第二個元素是角點,第三個和第四個元素是兩個斜坡。
通過與xdata<=theta(2)
結果乘以theta(3).*xdata
,你theta(3).*xdata
在xdata
每個點比theta(2)
小,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
非常感謝您的回答,並給出了詳盡的解釋! – Alemex