/* this file: endowment.c * author: Ulf Hermjakob * to compile this file (in UNIX): gcc -lm endowment.c * to move compiled file into proper location: mv a.out endowment * to call program: endowment */ #include #include #define one_over_sqrt_2_pi 0.3989422804014327 double gauss(double x) { return(one_over_sqrt_2_pi * exp(-0.5 * x * x)); } double core_gauss_integral(double from, double to) { double s = 0.0; double granularity = 0.00001; double x; for (x=from; x from) s -= 0.5 * granularity * gauss(from); return (s); } double gauss_integral(double x) { if (x >= 5) return (1.0); if (x >= 4) return (0.9999683 + core_gauss_integral(4.0, x)); if (x >= 3) return (0.9986501 + core_gauss_integral(3.0, x)); if (x >= 2) return (0.9772 + core_gauss_integral(2.0, x)); if (x >= 1) return (0.8413 + core_gauss_integral(1.0, x)); if (x >= 0) return (0.5 + core_gauss_integral(0.0, x)); return (1.0 - gauss_integral(-1 * x)); } double gauss_smoothing (double raw_rate, double target_rate, double deviation_radius_rate, double s) { return (target_rate - deviation_radius_rate + (2 * deviation_radius_rate * gauss_integral(s * (raw_rate - target_rate)))); } double endowment_grant (double endowment_total, double last_endowment_distr, double inflation_rate, double new_endowment_money, int verbose_type, double deviation_radius_rate) { double target_rate = 0.045; double kick_up_rate = 0.005; double old_endowment_money = 0.0; double raw_endowment_distr = 0.0; double raw_endowment_rate = 0.0; double adj_endowment_rate = 0.0; double adj_endowment_distr = 0.0; old_endowment_money = endowment_total - new_endowment_money; raw_endowment_distr = last_endowment_distr * (1.0 + inflation_rate + kick_up_rate); if (old_endowment_money > 0.0) raw_endowment_rate = raw_endowment_distr / old_endowment_money; if (deviation_radius_rate <= 0.0) adj_endowment_rate = raw_endowment_rate; else adj_endowment_rate = gauss_smoothing(raw_endowment_rate, target_rate, deviation_radius_rate, 1.0 / deviation_radius_rate); adj_endowment_distr = adj_endowment_rate * old_endowment_money + target_rate * new_endowment_money; if (verbose_type == 2) { printf("\n"); printf("Endowment total: $%9.2f\n", endowment_total); printf("Last endowment distribution: $%9.2f\n", last_endowment_distr); printf("New endowment donations: $%9.2f\n", new_endowment_money); printf("Endowment w/o new donations: $%9.2f\n", old_endowment_money); printf("Inflation rate: %6.2f%%\n", 100 * inflation_rate); printf("Kick-up rate: %6.2f%%\n", 100 * kick_up_rate); printf("Raw endowment distribution: $%9.2f (which is $%.2f plus %.2f%% plus %.2f%%)\n", raw_endowment_distr, last_endowment_distr, 100 * inflation_rate, 100 * kick_up_rate); printf("Raw endowment rate: %6.2f%% (which is $%.2f out of $%.2f)\n", 100 * raw_endowment_rate, raw_endowment_distr, old_endowment_money); printf("Adjusted endowment rate: %6.2f%% ", 100 * adj_endowment_rate); printf("(centering inside interval [%3.1f%% ... %3.1f%%])\n", 100 * (target_rate - deviation_radius_rate), 100 * (target_rate + deviation_radius_rate)); printf("New endowment distribution: $%9.2f (which is %.2f%% of $%.2f", adj_endowment_distr, 100 * adj_endowment_rate, old_endowment_money); if (new_endowment_money > 0.0) printf(" plus %.2f%% of $%.2f", 100 * target_rate, new_endowment_money); printf(")\n"); } return (adj_endowment_distr); } void print_gauss_smoothing_table() { double x; for (x=0.0; x<=0.10001; x=x+0.001) printf ("%4.1f%% %6.4f%%\n", 100 * x, 100 * gauss_smoothing(x, 0.045, 0.01, 100)); } /* static int market_perf[11] = {0, 9, -15, 25, 26, 5, 10, -2, 14, 5, 8}; */ static int market_perf[11] = {0, 9, 25, 26, -15, 5, 10, -2, 14, 5, 9}; void endowment_scenario(double init_endowment, double infl_rate, int n_years, int *end_perf, int grant_proc, double deviation_radius_rate) { int i; double endowment_total = init_endowment; double new_endowment = init_endowment; double last_grant = 0.0; double grant, grant_growth; printf("Year perf. endowment grant growth\n"); for (i=0; i<=n_years; i++) { endowment_total *= 1.0 + (end_perf[i] / 100.0); if (grant_proc == 1) grant = endowment_grant(endowment_total, last_grant, infl_rate, new_endowment, 0, deviation_radius_rate); else grant = endowment_total * 0.045; if (last_grant > 0.0) grant_growth = (grant - last_grant) / last_grant * 100; else grant_growth = 999.9; printf("%3d %4d%% $%9.2f $%8.2f %5.1f%%\n", i, end_perf[i], endowment_total, grant, grant_growth); new_endowment = 0.0; last_grant = grant; endowment_total -= grant; } } void single_comp() { double endowment_total, last_endowment_distr, inflation_percentage, inflation_rate, new_endowment_money, new_endowment_distr; printf("Please enter endowment total: "); scanf("%lf", &endowment_total); printf("Please enter last year's endowment distribution: "); scanf("%lf", &last_endowment_distr); printf("Please enter last year's inflation (in percent): "); scanf("%lf", &inflation_percentage); inflation_rate = inflation_percentage / 100; printf("Please enter last year's new endowment donations: "); scanf("%lf", &new_endowment_money); endowment_grant(endowment_total, last_endowment_distr, inflation_rate, new_endowment_money, 2, 0.01); } main() { single_comp(); /* printf("Both scenarios assume a new initial endowmend of $200,000 and inflation of 3%% every year.\n\n"); printf("\nScenario 1: without smoothing adjustment\n"); endowment_scenario(200000.0, 0.03, 10, market_perf, 0, 0.01); printf("Scenario 2: with smoothing adjustment\n"); endowment_scenario(200000.0, 0.03, 10, market_perf, 1, 0.01); printf("Scenario 3: with double smoothing adjustment\n"); endowment_scenario(200000.0, 0.03, 10, market_perf, 1, 0.02); */ /* print_gauss_smoothing_table(); */ }