Series Summation With Function Handles
3 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
I am performing a Monte Caro simulation with non-linear optimization inside using fmincon. Fmincon requires the use of function handles. However, I want to perform a series summation, as attempted when defining Elife with symsum. Since symsum only takes symbolic variables, how would I perform this summation using function handles? To simplify the code, everything before the for loop is just setting up the distributions and inside the for loop is where I define a couple functions and where I set up and perform the optimization.
clear all
m_tlife = 33;
std_tlife = 11;
dist_tlife = makedist('Normal', m_tlife, std_tlife);
a_drate = 2;
b_drate = 0.006;
dist_drate = makedist('Gamma', a_drate, b_drate);
m_Ee = 4.56;
std_Ee = 0.27;
dist_Ee = makedist('Normal', m_Ee, std_Ee);
m = 34;
Asp = 40.1; % m^2
em = 0.162;
Np = 10;
for i = 1:Np
tlife = random(dist_tlife);
sigma = random(dist_drate);
Ee = random(dist_Ee);
Ep = Asp*em*Ee*365/m;
Elife = @(x)symsum(Ep*(m - x(2))*(1 - sigma)^x(1) + Ep*x(2)*(1 - sigma)^(tlife - x(1)), x(1), 1, tlife);
fun = @(x)Elife(x)*x(2)/(1 + x(1))
x0 = [0,0];
lb = [0,0];
up = [tlife m];
A = [];
b = [];
Aeq = [];
beq = [];
x(i,:) = fmincon(fun, x0, A, b, Aeq, beq, lb, up);
L(i) = fun(x)*10^2;
end
0 Commenti
Risposte (1)
Andrew Newell
il 27 Apr 2017
In principle, you can use matlabFunction to get around this difficulty. However, I noticed a couple of issues. First, the summation is over a variable tlife that is generally not an integer, which is an invalid choice for the last parameter in symsum. So you may have to round it off.
Second, to define Elife, you need symbolic variables to stand in for x(2) and x(1). I tried the following (for reproducibility, I hard coded the parameter values in):
tlife = 28.2305;
sigma = 0.0712;
Ee = 5.3077;
Ep = 370.1550;
syms x1 x2
Elife = symsum(Ep*(m - x2)*(1 - sigma)^x1 + Ep*x2*(1 - sigma)^(tlife - x1), x1, 1, round(tlife));
This gave the result
(375669370696008546723677936360824844289937144399794339030368775708855024128885589600699801*1161^(461/2000)*1250^(1539/2000)*x2)/103397576569128459358926086508745356695726513862609863281250000000000000000000000000000000 - (436152139378065922746190084114917644220617024648161227614258148597980683013636169526412468961*x2)/103397576569128459358926086508745356695726513862609863281250000000000000000000000000000000 + 7414586369427120686685231429953599951750489419018740869442388526165671611231814881949011972337/51698788284564229679463043254372678347863256931304931640625000000000000000000000000000000
which is surprising because x1 has disappeared. Thus, in applying matlabFunction, I get a function only of the second component:
Elife = matlabFunction(symsum(Ep*(m - x2)*(1 - sigma)^x1 + Ep*x2*(1 - sigma)^(tlife - x1), x1, 1, round(tlife)));
disp(Elife)
@(x2)x2.*(-4.218204660594419e3)+5.086790208514118.*2.415862736086788e2.*x2.*3.633251214982273+1.434189584602102e5
Given this result, the only way I could find to define the function fun that didn't give an error called the second component explicitly:
fun = @(x) Elife(x(2))*x(2)/(1+x(1));
This does get minimized without error, hitting one of the constraints.
In summary, I ran the whole loop successfully using the following block of code instead of your definition of fun:
syms x1 x2
Elife = matlabFunction(symsum(Ep*(m - x2)*(1 - sigma)^x1 + Ep*x2*(1 - sigma)^(tlife - x1), x1, 1, round(tlife)));
fun = @(x) Elife(x(2))*x(2)/(1+x(1));
But if I were you, I'd try to understand why x1 is disappearing from Elife.
3 Commenti
Walter Roberson
il 27 Apr 2017
I agree, after the symsum the index variable would be expected to disappear.
Vedere anche
Categorie
Scopri di più su Loops and Conditional Statements in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!