[Matlab]Life cycle model

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Eey,

Momenteel ben ik bezig met het schrijven van mijn scriptie en werk aan een life cycle model voor pensioen sparen en investeringen. Het probleem wat ik nu heb is het oplossen van dit model. Het model loopt voor een aantal jaar T en runt n keer. Op elke T en n moet een optimale waarde voor A en B gevonden worden. A is de hoogte van het sparen en B is de investeringsbeslissing. Ik heb het momenteel in een for loop staan echter wil het mij niet lukken om een uitkomst te krijgen. Ik moet voor elke T een optimale A en B vinden (dit wil zeggen waar mijn utility het maximaal zijn). Hoe kan ik het voor elkaar krijgen dat A en B zo gekozen worden dat ze op elke T de beste A en B terug geven zodat ik een vector met A en B waarden krijg.

Het idee dat ik zelf heb is dat dit met een for statement moet welke een restrictie heeft op het vasthouden van de beste A en B, maar hoe dit te doen?

Ik heb de code hieronder geplakt en hoop dat iemand hier dan ook een oplossing voor me heeft.

Groetjes,

Stefan

[ Voor 27% gewijzigd door Woy op 16-06-2009 15:19 ]


Acties:
  • 0 Henk 'm!

  • Sallin
  • Registratie: Mei 2004
  • Niet online
Lijkt me een debugprobleem. Zet break points op relevanten plekken en controleer de waardes van de variabelen tijdens je for loop. Of nog simpeler haal alle ";" weg zodat je alle output krijgt.

This too shall pass
Debian | VirtualBox (W7), Flickr


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Welkom op het forum,

Zou je je code minstens in een code blok kunnen zetten, en zorgen dat het goed uitgelijnd is ( Hoe post je code? / Hoe gebruik je de code tag? )

Verder zou ik graag wat meer informatie hebben wat je precies wil, wat je geprobeerd hebt en wat daar niet aan lukte.

Kun je het probleem bijvoorbeeld wel op papier oplossen? Als dat je lukt, hoef je het alleen nog maar naar code te vertalen. Of heb je problemen met het bedenken van een algoritme? Dan is het eerst nog niet zo interessant dat het in matlab moet gebeuren.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb nu in onderstaande code A en B in een loop geschreven. Het probleem is nu dat ik niet weet hoe ik tussendoor een functie kan krijgen die kijkt wanneer mijn utility maximaal is.

Op papier kan ik precies vertellen wat er moet gebeuren echter qua programmeren ben ik niet heel sterkt.

C(t,i) = A*W(t,i); geeft voor verschillende waarden van A een niveau van consumptie wanneer deze consumptie te hoog is raak je al je welvaart en heb je geen voordeel aan het sparen. Je nut in de volgende periode zal dan lager zijn. Wanneer A te laag is heb je wel veel welvaart maar je ontleend alleen nut aan consumeren dus dan ben je ook niet gelukkig

W(t+1,i) = (W(t,i) - C(t,i)+I(t,i))*(B*Rs(t+1,i) + (1-B)*rf); geeft de investeringsbeslissing. Je kan in aandelen en in een risico vrij fonds investeren. Het rendement op aandelen fluctueert en zal dus onzekerder zijn dan dat van een risico vrije investering. Afhankelijk van je risico aversie zal er een keuze gemaakt moeten worden voor het investeren. B dient nu zo gekozen te worden dat ook deze een optimaal nut geeft.

Het nut wordt elke T bepaald door de nutsfunctie: Utility(t,i) = d^t * power(C(t,i)); met power = @(x) (1/(1-gamma) * x^(1-gamma));

Ik wil nu eigenlijk A en B willekeurige waarden geven, dus van 0 tot 1 met intervallen van 0.01 waarbij na elk interval gekeken moet worden of het nut hoger of lager is dan in het vorige interval. Is het nut nu hoger dan moet deze waarde vastgehouden worden, maar gaan we wel door naar het volgende interval om te kijken of er nog een ander interval is met een hoger nut. Als alle intervallen geweest zijn gaan we naar T =2, dit dient dan ook te gebeuren op elk tijdstip. Op deze manier krijg ik dus 65 keer een waarde voor A en B. Deze waarden zou ik graag in een vector hebben.

Wat ik nu geprobeerd heb is dit te formuleren met een if statement, maar mijn programmeer kennis is dusdanig beperkt dat ik hier niet uitkom. Ik weet namelijk niet hoe ik alles moet definiëren in matlab. Ik hoop dan ook dat er hier iemand is die weet hoe dit wel moet.

Mochten er nog vragen zijn dan hoor ik dit graag.


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
randn('state',0);
d=0.96;                                     % discount rate 
N = 1;                                      % aantal simulaties
n = 19                                      % bepaling stappen van A en B
T=65;                                       % aantal jaren dat je leeft

W = zeros(T,N);                             % matrix welvaart
C = zeros(T,N);                             % matrix consumptie
I = ones(T,N) * 30000;                      % matrix inkomen
I(41:end,:) = 0;                            % inkomen is nul na 40 jaar (pensioen)

Rs = 1.08 + 0.16*randn(T,N);                % return op aandelen
rf = 1.04;                                  % risco vrij return

Utility = zeros(T,N);                       % matrix nut

gamma = 2;                                  % risico aversie

power = @(x) (1/(1-gamma) * x^(1-gamma));   % nuts functie (power utility)

for i=1:N

    for t=1:T-1

        for h=1:n

            A = 0.0+(h*0.05);

            for j=1:n

             B = 0.0+(j*0.05);

                 if t==1
                     C(t,i) = 0.5*I(t,i);
                 else
                     C(t,i) = A*W(t,i);
                 end

                    W(t+1,i) = (W(t,i) - C(t,i)+I(t,i))*(B*Rs(t+1,i) + (1-B)*rf);
                    Utility(t,i) = d^t * power(C(t,i));

            end
        end
    end
end

Rs';
C';
W';
y = mean(mean(Utility));

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Ik heb uit je startpost even de code weggehaald, aangezien die hier een stuk beter te lezen is.

Verder ben ik niet erg bekend met matlab, maar je wilt dus eigenlijk een maximum berekenen?

In pseudo code zou je dan zo iets moeten doen

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var maxUtility = 0;
var iMaxUtility;
var tMaxUtility;
for( i = 1 to i = n)
{
   for( t = 1 to t = T )
   {
       var utility = CalculateUtility( i, t )
       if( utility > maxUtility )
       {
           maxUtility = utility;
           iMaxUtility = i;
           tMaxUtility = t;
       }
   }
}
//Hier bevatten iMaxUtility en tMaxUtility de waardes die bij de hoogste utility horen

Je kunt er zoveel loopjes bij maken als je wilt, en CalculateUtility kun je vervangen voor de berekening die de juiste utility oplevert.

Als dit niet is wat je bedoeld moet je misschien wat duidelijker aangeven op welke regel je wat zou willen doen in code.

[ Voor 8% gewijzigd door Woy op 16-06-2009 15:30 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dank je, ik ga dit morgen in ieder geval even proberen, mocht het lukken dan laat ik het je zeker even weten.

Acties:
  • 0 Henk 'm!

  • Noordvogel
  • Registratie: Juli 2007
  • Laatst online: 19-07-2024

Noordvogel

DPC @ DC-vault

Als je arrays van A en B wil overhouden, waarbij voor elke i en t de combinatie A en B met het hoogste nut bewaard wordt, dien je natuurlijk de A- en B-waarden over te houden, in plaats van de i- en t-waarden. Dus in plaats van iMaxUtility en tMaxUtility in bovenstaande pseudo-code:


Matlab:
12
13
maxA(t,i) = A;
maxB(t,i) = B;


Verder lijkt er iets niet te kloppen aan je nutsfunctie (power utility function). Als ik je code in Matlab run, krijg ik alleen maar negatieve waarden voor Utility; dat lijkt me niet de bedoeling, toch?

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Bovenstaande code blijkt nog niet helemaal te werken. Ik zal hem hieronder posten en misschien zien jullie wat ik fout doe. Verder klopt het dat me nutsfunctie heel negatief is, ik moet dan ook een maximale waarde verkrijgen en dit zal dan de waarde zijn die het dichtst bij nul ligt.

Terugkomend op het probleem voor elke h en j dien ik te controleren of de A en B waarden die op dat moment gegenereerd zijn optimaal zijn. Op elke tijdstip t zal ik A van 0 tot 1 laten lopen en dit geldt ook voor B. Dit doe ik met intervallen van 0.01, wat mij 100 A waardes en 100 B waardes oplevert. Een gezamenlijke combinatie van deze twee dus bijvoorbeeld A = 0.71 B = 0.82 levert mij een bepaald nut op. Ik dien nu al deze combinaties langs te gaan en dan te kijken welke het hoogste nut heeft op tijdstip t.

Dit komt er dus op neer dat ik voor elk tijdstip (100*100) = 10000 combinaties heb waarvan ik de beste moet kiezen en deze dien ik in een vector te plaatsen. In het huidige model zijn de intervallen 0.05 maar dit is gedaan voor de rekentijd.

code:
1
2
3
4
5
6
7
8
9
   t     A       B
   1     0.75    0.82
   2     0.73    0.81
   3     0.68    0.83
   4     .       .
   5     .       .
   6     .       . 
   7     .       .
   8     .       .


zo dient het er dus ongeveer uit te zien.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
maxUtility = -100000000000000000000000000000000000;
maxA = zeros(T,N); 
maxB = zeros(T,N);

randn('state',0);
d=0.96;
N = 10;
n = 10;
T=65;
W = zeros(T,N);
C = zeros(T,N);
I = ones(T,N) * 30000;
I(41:end,:) = 0;
Rs = 1.08 + 0.16*randn(T,N);
rf = 1.04;
Utility = zeros(T,N);
gamma = 2;
power = @(x) (1/(1-gamma) * x^(1-gamma));
for i=1:N

    for t=1:T-1

        for h=1:n

            A = 0.0+(h*0.05);

            for j=1:n

             B = 0.0+(j*0.05);

                 if t==1
                     C(t,i) = 0.5*I(t,i);
                 else
                     C(t,i) = A*W(t,i);
                 end

                    W(t+1,i) = (W(t,i) - C(t,i)+I(t,i))*(B*Rs(t+1,i) + (1-B)*rf);
                    utility(t,i) = d^t * power(C(t,i));
                    
                if( utility(t,i) > maxUtility )
                   
                        maxUtility = utility(t,i);
                        maxA(t,i) = A;
                        maxB(t,i) = B;
                    
                end
            end
        end
    end
end


Rs';
C';
W';
y = mean(mean(Utility));


Waar ik nu tegen aanloop is dat ik niet alle waardes voor A en B krijg maar ook dat de gegeven waardes van A en B allemaal 0.05 zijn. Dit komt waarschijnlijk omdat je in het doorzoeken van de loop geen h en j gebruikt maar alleen t en i hoe kan je dit aanpassen?

Acties:
  • 0 Henk 'm!

  • Noordvogel
  • Registratie: Juli 2007
  • Laatst online: 19-07-2024

Noordvogel

DPC @ DC-vault

Wat je als laatste zegt, klopt niet. Je loopt in de diepst-geneste loop (de loop met for j = ) voor verschillende waarden van B (en indirect met de daarboven gelegen loop ook alle waarden van A) alle uitkomsten voor W en utility door voor het tijdstip t(+1) en simulatie i. Je overschrijft wel steeds de waarden van W(t+1,i) en utility(t,i) voor nieuwe waarden van A en B. Maar daarom heb je ook in je diepst-geneste loop het if-statement wat controleert of de utility op dat moment groter is dan de maxUtility. Je slaat in de maxA en maxB arrays dan ook de waarden van A en B van dat moment op (aangezien je voor A en B de waarden ook steeds overschrijft voor elke stap h en j).

Wat ik verder zo snel zag toen ik je scriptje runde, was dat de utility altijd negatief is en voor grotere t's alleen maar negatiever wordt. Je W-functie neemt toe tot het pensioen (I == 0); hetzelfde beeld geldt voor C.

Verder lijkt de optimale waarde van A en B altijd als volgt te zijn: 0.95 voor A en 0.05 voor B. Gezien je functies zou dat geen gekke uitkomst kunnen zijn, omdat er blijkbaar geen lokale maxima zijn.

Tenslotte heb ik nog wat Matlab-tips:
  • Matlab is relatief traag met loops (for en while loops). Dit ga je merken aan de snelheid van het script als je kleinere intervallen neemt voor A en B. Matlab kan wel goed met vectoren rekenen, dus bijvoorbeeld voor alle waarden van A ( A = 1:0.01:0.999 ) en B de uitkomsten tegelijk doorrekenen. Dit vereist wel dat je je script drastisch aanpast. Mochten bepaalde berekeningen niet werken voor matrices, dan zou je eens naar de functie 'arrayfun' in Matlab kunnen kijken.
  • Door de manier waarop je A, B en n definieert, kun je niet makkelijk de stapgrootte aanpassen.
Succes ermee!

[ Voor 0% gewijzigd door Noordvogel op 18-06-2009 09:30 . Reden: typo ]

Pagina: 1