Matrix Optimization, optimizing a 336 by 2 matrix, x
古いコメントを表示
Hello,
I'm working on , with certain constraints as specified in the code. Unfortunately I'm encountering a bunch of warnings that i'm just not able to get rid of despite multiple code edits, mentioned below. Any advise would be help full.
CODE
%global variables
global Tch Pch Mch Ad C1Tin Ocd mw1 mw2 mtw SpP ncd OEn NEn C1w C2w Tow EnvAirP PolyCompEff IsenExpo PolyCompExpo CompRatio MaxCP Cp_air HxEff WaterIn WaterOut Cp_water IFChP IChT R PolyTurbEff PolyTurbExpo Pexp Vch C1P C2P C1Tout C2Tin C2Tout HXout;
EnvAirP = 101;
PolyCompEff = 0.85;
IsenExpo = 1.4;
PolyCompExpo = 1.503;
CompRatio = 8;
MaxCP = 18.6;
Cp_air = 1;
HxEff = 0.8;
WaterIn = 293.15;
WaterOut = 368.15;
Cp_water = 4.184;
IFChP = 2000;
IChT = 400;
R = 0.287;
PolyTurbEff = 0.8;
PolyTurbExpo = 1.297;
Pexp = 700;
Vch = 10;
Pch = 0;
%Matrix input variables
%C1Tin - Compressor 1 Inlet air temp
%Amd - Company air mass flow Demand
%Ocd - Overall Old Company Power Demand
%Ad - Air Density
x0 = [0,0];
lb = [0,0];
ub = [];
x = patternsearch(@fun,x0,[],[],[],[],lb,ub,@nlinconst);
C1P = EnvAirP*CompRatio;
C2P = C1P*CompRatio;
C1Tout(:,1) = C1Tin(:,1)*(CompRatio^(PolyCompExpo/(PolyCompExpo - 1)));
C2Tin(:,1) = WaterIn + HxEff*(WaterIn - C1Tout(:,1));
C2Tout(:,1) = C2Tin(:,1)*CompRatio^(PolyCompExpo/(PolyCompExpo - 1));
HXout(:,1) = WaterIn + HxEff*(WaterIn - C2Tout(:,1));
mw1(:,1) = x(:,1).*Cp_air.*(C1Tout(:,1) - C2Tin(:,1))./(Cp_air*(WaterOut - WaterIn));
mw2(:,1) = x(:,1).*Cp_air.*(C2Tout(:,1) - HXout(:,1))./(Cp_air*(WaterOut - WaterIn));
mtw(:,1) = mw1(:,1) + mw2(:,1);
SpP(:,1) = (PolyCompEff^(-1))*Cp_air.*C1Tin(:,1).*(CompRatio^(PolyCompExpo/(PolyCompExpo - 1)));
ncd(:,1) = C1w(:,1) + C2w(:,1) - Tow(:,1) + Ocd(:,1) - SpP(:,1).*x(:,2)./Ad(:,1).*2118.9;
OEn = sum(Ocd(:,1),'all')*0.5;
NEn = sum(ncd(:,1),'all')*0.5;
for i = 1:336
Tch(i+1,3) = Tch(i,3) + (Mch(i,1)^-1).*(1-IsenExpo^-1).*(x(i,1).*HXout(i,1) - x(i,2).*Tch(i+1,1)).*1800;
end
function [c,ceq] = nlinconst(x)
c(:,1) = OEn - NEn;
c(:,2) = 700 - Pch(:,1);
c(:,3) = x(:,1) - 0.2;
c(:,4) = x(:,2) - 0.2;
c(:,5) = Pch(:,1) - 6464;
c(:,6) = C1w(:,1) - 18.6;
c(:,7) = C2w(:,1) - 18.6;
c(:,8) = Mch(:,1) - 350;
ceq(1,1) = Tch(1,1) - IChT;
ceq(1,2) = Pch(1,1) - IFChP;
ceq(336,2) = Pch(336,1) - IFChP;
ceq(:,3) = C1w(:,1) - (PolyCompEff^-1).*x(:,1).*Cp_air.*C2Tin.*(CompRatio^(PolyCompExpo/(PolyCompExpo - 1)) - 1);
ceq(:,4) = Pch(:,1).*Vch./(R.*Tch(:,1)) - Mch(:,1);
ceq(:,6) = PolyTurbEff.*x(:,2).*Cp_air.*Tch(:,1).*(1-(Pch(:,1)./Pexp).^((PolyTurbExpo - 1)./PolyTurbExpo));
ceq(:,7) = EnvAirP.*CompRatio - C1P ;
ceq(:,8) = C1P(:,1).*CompRatio - C2P;
ceq(:,9) = C1Tin(:,1).*CompRatio^(PolyCompExpo./(PolyCompExpo - 1)) - C1Tout(:,1) ;
ceq(:,10) = WaterIn + HxEff.*(WaterIn - C1Tout(:,1)) - C2Tin(:,1);
ceq(:,11) = C2Tin(:,1).*CompRatio^(PolyCompExpo./(PolyCompExpo - 1)) - C2Tout(:,1) ;
ceq(:,12) = WaterIn + HxEff.*(WaterIn - C2Tout(:,1)) - HXout(:,1);
ceq(:,13) = x(:,1).*Cp_air.*( C1Tout(:,1) - C2Tin(:,1))./(Cp_water.*(WaterOut - WaterIn)) - mw1(:,1) ;
ceq(:,14) = x(:,1).*Cp_air.*(C2Tout(:,14) - HXout(:,1))./(Cp_air.*(WaterOut - WaterIn)) - mw2(:,1) ;
ceq(:,15) = mw1(:,1) + mw2(:,1) - mtw(:,1) ;
ceq(:,16) = (Mch(:,1) + (x(:,1) - x(:,2) ).*1800).*R.*x(:,1)./Vch - Pch(:,1);
end
function y = fun(x)
ncd(:,1) = C1w(:,1) + C2w(:,1) - Tow(:,1) + Ocd(:,1) - SpP(:,1).*x(:,2)./Ad(:,1).*2118.9;
y = max( ncd(:,1));
end
Errors and Warnings
Warning: The value of local variables may have been changed to match the globals. Future versions of MATLAB will require that you declare a variable to be
global before you use that variable.
> In test_4 (line 3)
Warning: The value of local variables may have been changed to match the globals. Future versions of MATLAB will require that you declare a variable to be
global before you use that variable.
> In test_4 (line 3)
Warning: The value of local variables may have been changed to match the globals. Future versions of MATLAB will require that you declare a variable to be
global before you use that variable.
> In test_4 (line 3)
Warning: The value of local variables may have been changed to match the globals. Future versions of MATLAB will require that you declare a variable to be
global before you use that variable.
> In test_4 (line 3)
Unrecognized function or variable 'EnvAirP'.
Error in test_4>fun (line 91)
C1P = EnvAirP*CompRatio;
Error in funevaluate (line 54)
f = feval(FUN,reshapeinput(Xin,X),varargin{:});
Error in poptimfcnchk (line 23)
[y,count,cache] = funevaluate(FUN,Xin,X,'init',cache,[],[],objFcnArg{:});
Error in patternsearch (line 262)
[Iterate,OUTPUT.funccount] = poptimfcnchk(FUN,nonlcon,X0,Iterate, ...
Error in test_4 (line 39)
x = patternsearch(@fun,x0,[],[],[],[],lb,ub,@nlinconst);
Caused by:
Failure in initial user-supplied objective function evaluation. PATTERNSEARCH cannot continue.
7 件のコメント
Sargondjani
2020 年 6 月 30 日
You only assign values to variables like C1P after calling patternsearch, so basically C1P has no vlue when you start optimization. You need to put the block below patternsearch above it.
Furthermore, I would recommend against using global variables. I usually put all my parameter in a structure, with each variable being a field:
par.C1P = EnvAirP*CompRatio;
etc. and then pass "par' as an argument in your functions.
Ebin Daniel
2020 年 6 月 30 日
編集済み: Ebin Daniel
2020 年 6 月 30 日
Walter Roberson
2020 年 7 月 1 日
x0 = [0,0];
That is a vector of length 2.
x = patternsearch(@fun,x0,[],[],[],[],lb,ub,@nlinconst);
and that vector of length 2 is being used as the initial location for searching, so that tells patternsearch() that there are two variables being optimized over.
ceq(336,2) = x(336,8) - x(:,9);
That line tells us that your nonlinear constraints think that you have at least 336*8 = 2688 variables rather than just 2 variables.
When you pass in a row vector of length 2 as your x0, then that row vector will not be automatically copied as often as needed to act as initial conditions for the optimization. You need to provide an x0 that has exactly as many elements as you are optimizing over.
c(:,1) = 700 - x(:,8);
Your code is expecting a 2D array with at least 8 columns. However:
Initial point, specified as a real vector. patternsearch uses the number of elements in x0 to determine the number of variables that fun accepts.
So what your objective function will receive and what your nonlinear constraint function will receive, will be a vector, not an array.
ceq(1,1) = x(1,6) - x(:,7);
If you did have an array of x (perhaps you reshape() into an array as the first step in the routine, which is absolutely a valid thing to do), then x(:,7) would be a vector of length 336, and subtracting that from x(1,6) would give a vector of length 336... which you are trying to store inside the scalar location ceq(1,1)
ceq(1,2) = x(1,8) - x(:,9);
Assuming you changed that to
ceq(:,2) = x(1,8) - x(:,9);
then because those are equality constraints, that forces all members of x(:,9) to be exactly equal to x(1,8) . But that is a linear equality constraint that you should express through the Aeq, beq matrix rather than through the nonlinear constraint function.
c(:,1) = 700 - x(:,8);
c(:,2) = x(:,1) - 0.2;
Those are linear inequalities that should be expressed through the A, b matrix rather than through the nonlinear constraints function.
Linear constraints are much more efficient than nonlinear constraints.
Ebin Daniel
2020 年 7 月 4 日
Walter Roberson
2020 年 7 月 4 日
To force 2000 use lb / ub. As a general rule, lb/ub is the most efficient, then linear inequality, then linear equality, and nonlinear inequality is much less efficient, with nonlinear equality being expensive. For efficiency, you should code any given constraint for fastest execution.
Ebin Daniel
2020 年 7 月 5 日
編集済み: Ebin Daniel
2020 年 7 月 5 日
Walter Roberson
2020 年 7 月 6 日
I recommend against doing that through the nonlinear constraints.
x0 = zeros(336, 8);
lb = zeros(336,8);
ub = inf(336,8);
lb(:,8) = 700;
lb(1,8) = 2000;
lb(336,8) = 2000;
ub(:,8) = 6464;
ub(1,8) = 2000;
ub(336,8) = 2000;
A = []; b = [];
Aeq = []; beq = [];
x = patternsearch(@fun, x0(:), A, b, Aeq, beq, lb(:), ub(:), @nlinconst);
and leave out those linear constraints such as 700-Pch(:,10 from your nonlinear constraint function.
回答 (1 件)
Ebin Daniel
2020 年 7 月 6 日
6 件のコメント
Walter Roberson
2020 年 7 月 6 日
x = patternsearch(@fun, x0, [], [],[],[], lb, ub, @(T1cin) nlinconst(T1Cin, x0));
However, your nlconst function ignores T1Cin, and I am having difficulty coming up with a reason why you would want to pass in the initial values x0 to your nonlinear constraints.
Ebin Daniel
2020 年 7 月 6 日
Ebin Daniel
2020 年 7 月 12 日
Walter Roberson
2020 年 7 月 12 日
Put in a conditional breakpoint on the end statement of the const function. Make the condition
~all(isfinite(c)) || ~all(isfinite(ceq)) || any(imag(c) ~= 0) || any(imag(ceq) ~= 0)
Ebin Daniel
2020 年 7 月 12 日
Walter Roberson
2020 年 7 月 17 日
No, you would not have to use a seperate function. Inside your const function, your last line of code is
ceq(336,2) = 2000 - Pch(336,1);
and the "end" statement that is after that is considered to be part of the same function. In the editor, right-click on the circle that is between the line number and the text area and select Set Conditional Breakpoint . In the box that comes up, put in
~all(isfinite(c)) || ~all(isfinite(ceq)) || any(imag(c) ~= 0) || any(imag(ceq) ~= 0)
and then click OK. Then run your code. If you still get the error without the breakpoint firing, then my analysis of your code is not correct.
You are calling the nonlinear constraint function correctly.
カテゴリ
ヘルプ センター および File Exchange で Write Constraints についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!