# Riskyasset (portfolio-choice) now much faster with refine

**URL:** https://discourse.vfitoolkit.com/t/riskyasset-portfolio-choice-now-much-faster-with-refine/355
**Category:** Uncategorized
**Created:** [January 23, 2025, 5:17am UTC](https://discourse.vfitoolkit.com/t/riskyasset-portfolio-choice-now-much-faster-with-refine/355 "2025-01-23T05:17:45Z")
**Posts on this page:** 10
**Page:** 2

<div class="post-metadata">

### Author: ![robertdkirkby](https://discourse.vfitoolkit.com/user_avatar/discourse.vfitoolkit.com/robertdkirkby/32/287_2.png) [@robertdkirkby](https://discourse.vfitoolkit.com/u/robertdkirkby)
#### Post date: [April 16, 2025, 10:22am UTC](https://discourse.vfitoolkit.com/t/riskyasset-portfolio-choice-now-much-faster-with-refine/355/21 "2025-04-16T10:22:01Z")

</div>

Oops, sorry, should be fixed now.

[I was doing some internal cleaning about two weeks ago so all the riskyasset codes did that bit of figuring out which decision variable is which using same few lines of code, clearly didn’t fully clean up.]

---

<div class="post-metadata">

### Author: ![bob\_rb](https://discourse.vfitoolkit.com/letter_avatar_proxy/v4/letter/b/5fc32e/32.png) [@bob\_rb](https://discourse.vfitoolkit.com/u/bob_rb)
#### Post date: [April 16, 2025, 12:39pm UTC](https://discourse.vfitoolkit.com/t/riskyasset-portfolio-choice-now-much-faster-with-refine/355/22 "2025-04-16T12:39:45Z")

</div>

Thanks. But now the following error appears:

```auto
> Unrecognized function or variable 'l_a'.
> 
> Error in StationaryDist_FHorz_Case1_RiskyAsset (line 111)
> if l_a==1 % just riskyasset
> 
> Error in StationaryDist_FHorz_Case1 (line 147)
> StationaryDist=StationaryDist_FHorz_Case1_RiskyAsset(jequaloneDist,AgeWeightParamNames,Policy,n_d,n_a,n_z,N_j,pi_z_J,Parameters,simoptions);
> 
> Error in LifeCycleModel35 (line 299)
> StationaryDist=StationaryDist_FHorz_Case1(jequaloneDist,AgeWeightsParamNames,Policy,n_d,n_a,n_z,N_j,pi_z,Params,simoptions);

```

---

<div class="post-metadata">

### Author: ![robertdkirkby](https://discourse.vfitoolkit.com/user_avatar/discourse.vfitoolkit.com/robertdkirkby/32/287_2.png) [@robertdkirkby](https://discourse.vfitoolkit.com/u/robertdkirkby)
#### Post date: [April 16, 2025, 1:42pm UTC](https://discourse.vfitoolkit.com/t/riskyasset-portfolio-choice-now-much-faster-with-refine/355/23 "2025-04-16T13:42:16Z")

</div>

Should be fixed.

I cannot test as I am away (so no gpu). Let me know if there is another issue.

---

<div class="post-metadata">

### Author: ![bob\_rb](https://discourse.vfitoolkit.com/letter_avatar_proxy/v4/letter/b/5fc32e/32.png) [@bob\_rb](https://discourse.vfitoolkit.com/u/bob_rb)
#### Post date: [April 16, 2025, 6:31pm UTC](https://discourse.vfitoolkit.com/t/riskyasset-portfolio-choice-now-much-faster-with-refine/355/24 "2025-04-16T18:31:17Z")

</div>

Now it goes through without errors. Thank you!

---

<div class="post-metadata">

### Author: ![MichaelTiemann](https://discourse.vfitoolkit.com/user_avatar/discourse.vfitoolkit.com/michaeltiemann/32/220_2.png) [@MichaelTiemann](https://discourse.vfitoolkit.com/u/MichaelTiemann)
#### Post date: [June 23, 2026, 5:07am UTC](https://discourse.vfitoolkit.com/t/riskyasset-portfolio-choice-now-much-faster-with-refine/355/25 "2026-06-23T05:07:14Z")

</div>

I am trying to model a Mandatory Savings problem (loosely based on KiwiSaver). Agents earn money before they retire, and contribute a percentage of their employment income to the scheme. Employers match to some amount. Every year the balance increases by the rate of return applied to the balance. Agents cannot withdraw until they retire.

This is classic `experienceasset` behavior, so I wrote an `aprimeFn` to calculate the contributions made during employment, and to calculate the balance when pensioners decide they want to liquidate some (or all) of it. In the contribution phase, we need to know how much is being earned (a function of labor hours) so we can calculate the contribution. The two decision variables are thus `h` and `ks_out`.

In the retirement phase, pensioners can supplement their income by deciding to liquidate a fraction of their balance. The `aprimeFn` tells us the post-liquidation value of the experience asset, as it should. But the `ReturnFn` also needs to work with the liquidation decision variable (I think), so it can add the liquidated value to the consumption function. The return function also has `h` and `ks_out` as decision variables.

Because they both have the same two decision variables, then by this comment, d1 and d2 are 0 and all the action is in d3.

```auto
% tell the code how many d1, d2, and d3 there are
% Idea is to distinguish three categories of decision variable:
% d1: decision is in the ReturnFn but not in aprimeFn
% d2: decision is in the aprimeFn but not in ReturnFn
% d3: decision is in both ReturnFn and in aprimeFn
% Note: ReturnFn must use inputs (d1,d3,..) 
% aprimeFn must use inputs (d2,d3,..)
% n_d must be set up as n_d=[n_d1, n_d2, n_d3]
% d_grid must be set up as d_grid=[d1_grid; d2_grid; d3_grid];
vfoptions.refine_d=[0,0,2];

```

But this creates a problem when calling into creating the ReturnFnParamNames. But that function doesn’t look through the two zero-valued decision variables to see that there are two decision variables in position 3.

Am I setting this up wrong, or do I need to fix `ReturnFnParamNames`?

…Partially answering my own question, I see that `refine_d` should not be used when everything is just `d3`. Fair enough. So I deleted that and now I’m stuck because the `aprimeFnParamNames` calculation proclaims that the first parameters will be (d2,a2), despite the fact that I need d1.

```auto
    aprimeFnParamNames={temp{l_d2+l_a2+(l_a2>=2)+1:end}}; % the first inputs will always be (d2,a2)

```

---

<div class="post-metadata">

### Author: ![MichaelTiemann](https://discourse.vfitoolkit.com/user_avatar/discourse.vfitoolkit.com/michaeltiemann/32/220_2.png) [@MichaelTiemann](https://discourse.vfitoolkit.com/u/MichaelTiemann)
#### Post date: [June 23, 2026, 8:19pm UTC](https://discourse.vfitoolkit.com/t/riskyasset-portfolio-choice-now-much-faster-with-refine/355/26 "2026-06-23T20:19:38Z")

</div>

Making changes to:

```auto
aprimeFnMatrix\CreateaprimePolicyExperienceAssetz.m
ValueFnIter\FHorz\ExperienceAsset\ValueFnIter_FHorz_ExpAsset.m
StationaryDist\FHorz\ExpAssetz\StationaryDist_FHorz_ExpAssetz.m
ValueFnIter\FHorz\ExperienceAssetz\ValueFnIter_FHorz_ExpAssetz.m
ValueFnIter\FHorz\ExperienceAssetz\ValueFnIter_FHorz_ExpAssetz_raw.m

```

I was able to run my program. Needless to say, having to accommodate n\_d1 alongside n\_d2 (and consequently d\_grid instead of d2\_grid) makes things get big fast. Happily, my experiments with single-precision value functions speed things up 4x in this case, which is the difference between one hour and four. It also required some special lowmemory handling to enable it to run with 26 of 32GB GPU RAM using the following:

```auto
% Grid sizes to use
n_d=[21,11]; % Endogenous labour choice (fraction of time worked); and kiwisaver redemption percentage
n_a=[51,21,11]; % Endogenous asset holdings: assets, pv, kiwisaver
n_z=[2,9]; % Exogenous labor productivity units shock; energy price shocks

```

But my agents can now choose to invest in solar capacity vs. retirement scheme to achieve optimal results in the case of a variety of shocks. A small up-front investment in energy cost reduction is a winner compared to an all-in approach to saving for retirement. Who knew?

---

<div class="post-metadata">

### Author: ![aledinola](https://discourse.vfitoolkit.com/letter_avatar_proxy/v4/letter/a/3ec8ea/32.png) [@aledinola](https://discourse.vfitoolkit.com/u/aledinola)
#### Post date: [June 23, 2026, 9:14pm UTC](https://discourse.vfitoolkit.com/t/riskyasset-portfolio-choice-now-much-faster-with-refine/355/27 "2026-06-23T21:14:54Z")

</div>

I look forward to using the single-precision value function!  
Do you currently use single precision only for value function iteration or also in other routines? In my experience the distribution is always very fast (so need there), but sometimes the calculation of model statistics (mean, variances, percentiles, etc) can be slow, especially if one has many “functions to evaluate” and/or "conditional restrictions.

---

<div class="post-metadata">

### Author: ![MichaelTiemann](https://discourse.vfitoolkit.com/user_avatar/discourse.vfitoolkit.com/michaeltiemann/32/220_2.png) [@MichaelTiemann](https://discourse.vfitoolkit.com/u/MichaelTiemann)
#### Post date: [June 23, 2026, 9:25pm UTC](https://discourse.vfitoolkit.com/t/riskyasset-portfolio-choice-now-much-faster-with-refine/355/28 "2026-06-23T21:25:16Z")

</div>

Right now I’ve only focused on the value functions, but I’ll look at doing the statistics if there’s a win to be had there. The statistics code is all in one place, whereas I modified around 1300 files (!) across all the value-related functions.

---

<div class="post-metadata">

### Author: ![MichaelTiemann](https://discourse.vfitoolkit.com/user_avatar/discourse.vfitoolkit.com/michaeltiemann/32/220_2.png) [@MichaelTiemann](https://discourse.vfitoolkit.com/u/MichaelTiemann)
#### Post date: [July 5, 2026, 8:12am UTC](https://discourse.vfitoolkit.com/t/riskyasset-portfolio-choice-now-much-faster-with-refine/355/29 "2026-07-05T08:12:51Z")

</div>

Another update: I remembered that I can cleverly use the same d variable for two jobs: fraction of hours worked before retirement and fraction of retirement savings liquidated after retirement.

Thus, I don’t need special handling to pass an extra d-variable to the aprime function. I’m sure somebody will need that at some point, but not me, and not after today (for this model).

---

<div class="post-metadata">

### Author: ![MichaelTiemann](https://discourse.vfitoolkit.com/user_avatar/discourse.vfitoolkit.com/michaeltiemann/32/220_2.png) [@MichaelTiemann](https://discourse.vfitoolkit.com/u/MichaelTiemann)
#### Post date: [July 5, 2026, 11:39pm UTC](https://discourse.vfitoolkit.com/t/riskyasset-portfolio-choice-now-much-faster-with-refine/355/30 "2026-07-05T23:39:01Z")

</div>

Yet another update: while `refine_d` may be relegated to only Risky Assets, a new variable cropped up that I had missed: `vfoptions.l_dexperienceasset`. That, truly, was what I was looking for. That, with other `l_d...` options, likely gives me everything I need for the toolkit to decide which decision variables need to be passed to what return, aprime, and other such functions.

[Previous page](https://discourse.vfitoolkit.com/t/riskyasset-portfolio-choice-now-much-faster-with-refine/355.md?page=1)
