Max a function wrt two variables
Afficher commentaires plus anciens
I have been asking this at another forum, and got nice help - but I still can't get it quite to work.
I have a function for calculating the utility of for working a certain number of hours (yearly) for a husband and wife in a family. I want to maximize the utility function, CalcUFamily, with respect to the number of working hours (1 to 3500) for the wife and husband, separately and give me the optimal work hours for the husband and wife.
I tried the code below, but can't get it to work properly. Can you help me?
function Test
global LocalTaxRate
global StateTax1Rate
global StateTax2Rate
LocalTaxRate = 0.3212; %Average 2017
StateTax1Rate = 0.25;
StateTax2Rate = 0.05;
h = [0 0]; % start value
lb = [0 0]; % lower bound of h
ub = [3500 3500]; % upper bound of h
myFun = @(h) -CalcUFamily(h(1), h(2)); % function to minimize with one input
Uoptimal = fmincon(myFun, [1000 1000], [], [], [], [], lb, ub)
end
function UFamily = CalcUFamily(hh,hw) %h = male, w = wife
(bunch of irrelevant code skipped)
else
Psa = 0;
Dw = 1;
YearlyWorkIncomeHusband = WageHH * hh;
C = YearlyWorkIncomeHusband + MonthlyTaxableTransfers * 12 - CalcTaxSwe(YearlyWorkIncomeHusband + MonthlyTaxableTransfers * 12, YearlyWorkIncomeHusband, Age) + MonthlyNonTaxableTransfers * 12; %Netincome husband
YearlyWorkIncomeWife = WageHW * hw;
C = C + YearlyWorkIncomeWife + MonthlyTaxableTransfers * 12 - CalcTaxSwe(YearlyWorkIncomeWife + MonthlyTaxableTransfers * 12, YearlyWorkIncomeWife, Age) + MonthlyNonTaxableTransfers * 12; %Netincome husband + wife
UFamily = alpha1 * log10(C/100000) + alpha11 * (log10(C/100000)^2) ...
+ alpha2 * (log10(T/1000-hh/1000)) + alpha22 * (log10(T/1000-hh/1000))^2 + alpha12 * log10(C/100000) * (log10(T/1000-hh/1000)) * 2 ... %husband
+ alpha3 * (log10(T/1000-hw/1000)) + alpha33 * (log10(T/1000-hw/1000))^2 + alpha13 * log10(C/100000) * (log10(T/1000-hw/1000)) * 2 ... %wife
+ alpha23 * (log10(T/1000-hh/1000)) * (log10(T/1000-hw/1000)) ... %common leisure parameter
- alpha4 * Psa - bfc * Dw; %Dummies
end
end
Réponses (2)
Image Analyst
le 28 Juil 2017
The code crashes at this point:
function UFamily = CalcUFamily(hh,hw) %h = male, w = wife
(bunch of irrelevant code skipped)
else
You need to start the else block off with an "if" statement. And the "(bunch..." needs to be in a comment - a line starting with %. So, try something like this:
function UFamily = CalcUFamily(hh,hw) %h = male, w = wife
% (bunch of irrelevant code skipped)
if someCondition
% whatever...
else
6 commentaires
Image Analyst
le 28 Juil 2017
Well, that pretty much stopped me in my tracks and I quit after that. I'll leave it up to you.
Walter Roberson
le 28 Juil 2017
What difficulty are you observing?
When I run your code, I get an exit flag of 1 from the fmincon, which is the exit flag that indicates success.
Walter Roberson
le 28 Juil 2017
Note that you coded 0 as your lower bounds, but your problem description gives 1 as the lower bounds. The difference is important in this case, as your function has a maxima at points arbitrarily close to 0 (and is undefined at (0,0))
Walter Roberson
le 29 Juil 2017
The maximum is at x1 = 1299.789403251401341605335676596 and x2 = 2993.8956914836407431811398740633 giving a maximum of 11.969999104694875886276737089086, compared to only 11.96200980280465830244970897474 for [1240, 2950]
syms x1 x2
F = CalcUFamily(x1,x2);
dx1 = diff(F,x1);
dx2 = diff(F,x2);
sol = vpasolve(dx1, dx2);
best_x1 = sol.x1; best_x2 = sol.x2;
However, there is a region close to 0 where in theory the function goes infinity, in pretty much a 1/x relationship (that is, the value at 10^-(N) is about 1/10th of the value at 10^-(N+1) ). It does not grow especially quickly -- at 10^-100000000 the value has only reached 22570000455447658.275295509433155 . None the less, it goes to infinity.
19 commentaires
KGB91
le 1 Août 2017
Walter Roberson
le 1 Août 2017
Do you have the symbolic toolbox? If you do then the code is what I posted.
KGB91
le 1 Août 2017
Walter Roberson
le 1 Août 2017
You could have the Symbolic toolbox in MATLAB R2014b; the latest version is not necessary, but installing the (licensed) toolbox would be.
KGB91
le 1 Août 2017
KGB91
le 1 Août 2017
Walter Roberson
le 2 Août 2017
The LocalTaxRate, StateTax1Rate, and StateTax2Rate that you assign there are not used in your CalcUFamily code. They are irrelevant. So you simply call
syms x1 x2
F = CalcUFamily(x1,x2);
dx1 = diff(F,x1);
dx2 = diff(F,x2);
sol = vpasolve(dx1, dx2);
best_x1 = sol.x1; best_x2 = sol.x2;
None of the code you show needs to test anything.
If it will make it easier for you to understand, then use
syms hh hw
F = CalcUFamily(hh,hw);
dhh = diff(F,hh);
dhw = diff(F,hw);
sol = vpasolve(dhh, dhw);
best_hh = sol.hh; best_hw = sol.hw;
KGB91
le 2 Août 2017
Walter Roberson
le 2 Août 2017
Really, your function should be using a different husband age than wife age.
Why do you not have something similar to alpha4 for the wife? It is understandable that the male and female constants might be different for welfare effects, but there is a complete expression that is missing for the wife.
If it is the case that only one of the husband or wife can make a particular claim, then it is not clear to an outsider that it must be the husband who makes it -- is there an actual asymmetry built into the tax laws, or is the couple not entitled to use whichever is the most advantageous ?
The husband / wife system with asymmetric coefficients does not account for same-sex marriage, which has been legal in Sweden for about 8 years.
I have been working on the code to use symbolic expressions to allow for the possibility of using an analytic optimizer. Unfortunately parts of it are pretty slow! The individual Swedish tax calculations for husband and wife are not bad at producing symbolic expressions in a reasonable time, but as soon as you add the two together to create your "C", then that is slow, as it works through all the combinations of circumstances. Then with the resulting C being quite long, the calculations of the various uFamily terms is pretty slow.
I have to go out for a while, so it may take some time to finish.
KGB91
le 2 Août 2017
Walter Roberson
le 3 Août 2017
Could you confirm that in the section
else %Older than 64 OTESTAD
the lines
elseif floor(YearlyIncome/1)*1<1.11*PBB
BasicTaxDeductionSwe = ceil(1.11*PBB/100)*100;
elseif floor(YearlyIncome/10)*10<2.72*PBB
BasicTaxDeductionSwe = ceil((0.834*PBB+0.249*YearlyIncome)/100)*100;
Other than those two clauses, everything else in that block and the main "if" use floor(YearlyIncome/100)*100 . The 1.11 line is the only place that you quantize to the nearest kronar, and the 2.72 line is the only place that you quantize to the nearest 10 kronar. It seems especially odd to quantize the income to 1 or 10 kronar but to quantize the deduction to the nearest 100 kronar.
(This is a section that turns out to be important to rewrite for efficiency, so I am reformulating how the calculations are done, and want to be sure that the current code is deliberate rather than a typo.)
KGB91
le 3 Août 2017
KGB91
le 3 Août 2017
KGB91
le 3 Août 2017
Walter Roberson
le 3 Août 2017
My symbolic work is still unacceptably slow :(
When I plot the C results, they are nearly planar, except for a small change around 180
Walter Roberson
le 3 Août 2017
My symbolic approach is taking more than an hour just to calculate what the function is, and then takes a while to calculate the result of the function for any one pair of values. I have not started algebraic optimization yet.
KGB91
le 3 Août 2017
Catégories
En savoir plus sur Startup and Shutdown dans Centre d'aide et File Exchange
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!