I have a function that uses 9 inputs (cts(1) to cts (9)) and provides 1 value as result. The function needs 4 parameters (c(1) to c(4)). The code of the function is:
fun = @(c,cts) ((c(1) .* (4-c(4))) ./ (c(2)+c(3) .* 4)) *cts(1,:) +...
((c(1) .* (5-c(4))) ./ (c(2)+c(3) .* 5)) *cts(2,:)+ ...
((c(1) .* (6-c(4))) ./ (c(2)+c(3) .* 6)) *cts(3,:) + ...
((c(1) .* (7-c(4))) ./ (c(2)+c(3) .* 7)) *cts(4,:) + ...
((c(1) .* (8-c(4))) ./ (c(2)+c(3) .* 8)) *cts(5,:) + ...
((c(1) .* (9-c(4))) ./ (c(2)+c(3) .* 9)) *cts(6,:) + ...
((c(1) .* (10-c(4))) ./ (c(2)+c(3) .* 10)) *cts(7,:) + ...
((c(1) .* (11-c(4))) ./ (c(2)+c(3) .* 11)) *cts(8,:) + ...
((c(1) .* (12-c(4))) ./ (c(2)+c(3) .* 12)) *cts(9,:)
I have 11 measured values with each 9 inputs. From this data set I want to fit the parameters c. A condition that applies for only the first row of the input is that
((c(1) .* (4-c(4))) ./ (c(2)+c(3) .* 4)) *cts(1,1) must be greater than ((c(1) .* (5-c(4))) ./ (c(2)+c(3) .* 5)) *cts(2,1). Is there an algorithm which can do that? I already tried lsqcurvefit without this constraint, but the fitted parameters do not follow the condition.
Thank you for your time.

 採用された回答

Matt J
Matt J 2019 年 12 月 12 日
編集済み: Matt J 2019 年 12 月 12 日

0 投票

You would have to use fmincon, which will let you specify non-linear constraints.

3 件のコメント

Marco Knobloch
Marco Knobloch 2019 年 12 月 13 日
編集済み: Marco Knobloch 2019 年 12 月 13 日
I tried to use fmincon, but I realized that I have to pass parameters from the optimization to my non linear constraint and it is not obvious to me how I can pass them. In detail, I have my function and inputs from above. The objective to minimize and the constraints function:
fun = @(c) ((c(1) .* (4-c(4))) ./ (c(2)+c(3) .* 4)) *cts(1,:) +...
((c(1) .* (5-c(4))) ./ (c(2)+c(3) .* 5)) *cts(2,:)+ ...
((c(1) .* (6-c(4))) ./ (c(2)+c(3) .* 6)) *cts(3,:) + ...
((c(1) .* (7-c(4))) ./ (c(2)+c(3) .* 7)) *cts(4,:) + ...
((c(1) .* (8-c(4))) ./ (c(2)+c(3) .* 8)) *cts(5,:) + ...
((c(1) .* (9-c(4))) ./ (c(2)+c(3) .* 9)) *cts(6,:) + ...
((c(1) .* (10-c(4))) ./ (c(2)+c(3) .* 10)) *cts(7,:) + ...
((c(1) .* (11-c(4))) ./ (c(2)+c(3) .* 11)) *cts(8,:) + ...
((c(1) .* (12-c(4))) ./ (c(2)+c(3) .* 12)) *cts(9,:)
objective = @(c) sum(((fun(c)-y) ./ y).^2); % To minimize
The constraint is that the first term (c(1) .* (4-c(4))) ./ (c(2)+c(3) .* 4)) *cts(1,1) must be greater than the second term (c(1) .* (5-c(4))) ./ (c(2)+c(3) .* 5)) *cts(2,1), but only in the first row.
function [a, ceq] = nonlcon(m,c,cts)
a = (c(1) .* (5-c(4))) ./ (c(2)+c(3) .* 5)) *cts(2,1) - ...
(c(1) .* (4-c(4))) ./ (c(2)+c(3) .* 4)) *cts(1,1) ;
ceq= [];
end
The fmincon line looks like this
A_opt = fmincon(objective,[1 1 1 1],[],[],[],[],[],[],@(c,cts)nonlcon(m,c,cts)
Obviously there is an error because I gave fmincon not enough input arguments. But the additional input arguments c are the parameters which fmincon should fit. Is there a way to pass nonlcon the current values of the optimization for the parameters?
Matt J
Matt J 2019 年 12 月 13 日
編集済み: Matt J 2019 年 12 月 13 日
Obviously there is an error because I gave fmincon not enough input arguments.
It would be more obvious if you copy/pasted the exact error messages, but my guess is that this will fix it,
c_opt = fmincon(objective,[1 1 1 1],[],[],[],[],[],[],@(c)nonlcon(m,c,cts) )
Marco Knobloch
Marco Knobloch 2019 年 12 月 13 日
That worked. Many thanks

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

ヘルプ センター および File ExchangeLinear and Nonlinear Regression についてさらに検索

製品

リリース

R2019b

質問済み:

2019 年 12 月 12 日

コメント済み:

2019 年 12 月 13 日

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by