/* Program to calculate ruin-theory approach to mortality. See "Applying survival models to pensioner mortality data", details of which can be found at http://www.richardsconsulting.co.uk/laws.html Copyright (c) 2008 Stephen Richards. All rights reserved. */ #include #include #include #define COMMAND 0 #define LAMBDA 1 #define MU 2 #define R 3 #define X 4 #define N 5 #define ARGC 6 #define AGE_LIMIT 120 /* Maximum age. */ int gidum = -1, // For random-number generators. giSeed = -1; // Copy of initial seed for random-number generators. /* Function to return minimum of two real values. */ double minimum(const double a, const double b) { if (a < b) return a; return b; } // Park and Miller's random-number generator with Bays-Durham shuffle // Implementation inspired by Press et al (2002) double U(void) { const int IA = 16807, IM = 2147483647, IQ = 127773, IR = 2836, MASK = 123459876; const double AM = 1.0 / (double)IM; int k; double ans; gidum ^= MASK; k = gidum / IQ; gidum = IA * (gidum - k * IQ) - IR * k; if (gidum < 0) gidum += IM; ans = AM * gidum; gidum ^= MASK; return ans; } int main(const int argc, const char * argv[]) { int rc = EXIT_FAILURE; if (argc != ARGC) fprintf(stderr, "Usage: ruin lambda mu r x n\n"); else { const double lambda = atof(argv[LAMBDA]), mu = atof(argv[MU ]), r = atof(argv[R ]), x = atof(argv[X ]); const unsigned long int n = atol(argv[N]); if (lambda <= 0.0) fprintf(stderr, "lambda must be greater than zero!\n"); else if (mu <= 0.0) fprintf(stderr, "mu must be greater than zero!\n"); else if (r < 0.0) fprintf(stderr, "r must be non-negative!\n"); else if (x <= 0.0) fprintf(stderr, "x must be greater than zero!\n"); else if (n <= 0) fprintf(stderr, "n must be greater than zero!\n"); else { double dLifetime, dLifeLived[AGE_LIMIT+1], ux, t, damage; unsigned long int i, j, Deaths[AGE_LIMIT+1], Lives[AGE_LIMIT+1], ageatend; int Dead; /* Initialise counters. */ for (i=0; i<=AGE_LIMIT; i++) { Deaths[i] = Lives [i] = 0; dLifeLived[i] = 0.0; } for (i=0; i 0.0) printf("%5.1f %7.5f %7d %7d %f\n", i+0.5, Deaths[i] / dLifeLived[i], Deaths[i], Lives[i], dLifeLived[i]); rc = EXIT_SUCCESS; } } return rc; }