Natural logarithms, exponential growth and C++

Started by
17 comments, last by ReubenESTD 12 years, 11 months ago
Ok so I am currently working on a complex console game in which the player takes on the role of an all powerful AI which controls the subconscious of a humanoid population. Many factors will be simulated in this game which will directly or indirectly effect birth/death-rate. This humanoid population will start at 1000 and increase until it reaches 15 billion when the game ends.

I wish to create a function in which a user input time increment and a global variable that represents yearly population increase can define the exponential population growth.

Ok so here is my formula (written in purely mathematical syntax no c++)

P = Ip(e^-kt)

Where
P = population
Ip = initial population
k = exponential constant
t = time

So inputing my numbers into this I get:

15,000,000,000 = 1000(2.718281828^-kt)
Or
15,000,000 = 2.718281828^-kt

ln(15,000,000) = k.t (ln e)

ln e = 16.524...

So
t=(16.524/k)(ln 15,000,000)

What I need to know is
1. Is this formula correct?
2. How can I make it so that t is the subject?
3. How can I best write this in C++ as a function or class with k as a global variable?

Thankyou for any help in advance, I am 15 and this maths is way beyond what I do in school.
Advertisement

Ok so I am currently working on a complex console game in which the player takes on the role of an all powerful AI which controls the subconscious of a humanoid population. Many factors will be simulated in this game which will directly or indirectly effect birth/death-rate. This humanoid population will start at 1000 and increase until it reaches 15 billion when the game ends.

I wish to create a function in which a user input time increment and a global variable that represents yearly population increase can define the exponential population growth.

Ok so here is my formula (written in purely mathematical syntax no c++)

P = Ip(e^-kt)

Where
P = population
Ip = initial population
k = exponential constant
t = time

So inputing my numbers into this I get:

15,000,000,000 = 1000(2.718281828^-kt)
Or
15,000,000 = 2.718281828^-kt

ln(15,000,000) = k.t (ln e)

ln e = 16.524...

So
t=(16.524/k)(ln 15,000,000)

What I need to know is
1. Is this formula correct?
2. How can I make it so that t is the subject?
3. How can I best write this in C++ as a function or class with k as a global variable?

Thankyou for any help in advance, I am 15 and this maths is way beyond what I do in school.


That looks like pretty impressive maths considering your age. Good to see you getting into it early. We're only just doing that sort of stuff and I'm nearly 4 years older than you. The formula you have looks like a fairly standard exponential growth equation, I'm not sure why you have a minus sign on your power of e though, so we'll get rid of that.

ln e = 1 not 16.524

So rearranging for t, you'd get:
t = (ln 15,000,000)/k

And the c++ function for ln is called log(). You'll have to include the math header files. I know you might not understand what a logarithm is, but ln is just log to the base e. C++ defaults to base e. If you want a base 10 logarithm, normally written as log in maths, you'd use log10().

So written in c++ your formula for t would be.


double k = //insert your constant
double t = log(15000000)/k


That would work out the time taken for your population to reach your limit.

To work out the population number after a time interval, you can use this method:


double t = //insert your time
double k = //insert your constant
double kt = k*t
double e = 2.71828183;
double P = 1000*pow(e,kt)


I guess you'll just have to play around with values of k until you find one that works with your game.

Hope this helps!
std::pow(e,x) == std::exp(x)

That looks like pretty impressive maths considering your age. Good to see you getting into it early. We're only just doing that sort of stuff and I'm nearly 4 years older than you. The formula you have looks like a fairly standard exponential growth equation, I'm not sure why you have a minus sign on your power of e though, so we'll get rid of that.

ln e = 1 not 16.524

So rearranging for t, you'd get:
t = (ln 15,000,000)/k

And the c++ function for ln is called log(). You'll have to include the math header files. I know you might not understand what a logarithm is, but ln is just log to the base e. C++ defaults to base e. If you want a base 10 logarithm, normally written as log in maths, you'd use log10().

So written in c++ your formula for t would be.


double k = //insert your constant
double t = log(15000000)/k


That would work out the time taken for your population to reach your limit.

To work out the population number after a time interval, you can use this method:


double t = //insert your time
double k = //insert your constant
double kt = k*t
double e = 2.71828183;
double P = 1000*pow(e,kt)


I guess you'll just have to play around with values of k until you find one that works with your game.

Hope this helps!


Hey, your explanation has made it much clearer, so thankyou!

Anyway, I tried to incorporate it with my program and I keep getting the result 0.
Here is the code:


#include <iostream>
#include <cmath>
#include <math.h>
#include <stdio.h>

using namespace std;

void otherfactors(); //temporary function to effect births and deaths.
void population(); // natural logarithm for population growth.
void birthdeathrate(); //yearly birth and death rate
void timestepfoward(); //performs all neccasary proceedures to fast foward time

int births;//births over a year
int deaths;//deaths over a year
double popgrowth; // population growth over a year (percentage)
double t; //time in years
int currentyear=1; //current year
double pop_at_start_of_period=1000; //holds the population at the start of each period.


int main()
{
otherfactors();
timestepfoward();
return 0;
}


void timestepfoward(){
cout << "\n\nIt is currently year " << currentyear << " and the population is " << pop_at_start_of_period << ".\n";
cout << "How many years would you like to skip? ";
cin >> t;
birthdeathrate();
population();
currentyear = t+currentyear;
cout << "\nIt is now year " << currentyear << " and the population is now " << pop_at_start_of_period << ".\n";
}

void birthdeathrate(){
double increase = births-deaths;
popgrowth = pop_at_start_of_period-increase*100;
}

void population(){
double k = popgrowth/100;
double kt = k*t;
double e = 2.71828183;

double P = pop_at_start_of_period*pow(e,kt);

cout << P;

pop_at_start_of_period = P;
}

void otherfactors(){
births = 50;
deaths = 20; // will be more complex when taking other variables into account.
}




What is it that I'm doing wrong?
Thanks.

Oh and I don't really understand this:
[color="#1C2837"]std::pow(e,x) == std::exp(x)[/quote]

What is it that I'm doing wrong?
Thanks.

Oh and I don't really understand this:
std::pow(e,x) == std::exp(x)

[/quote]

If you haven't yet practised with a debugger. I suggest you give it a go. That'd really help you out in this situation. I'll compile your code in a bit and see if I can see what's wrong with it. I probably overlooked something when I was posting late last night.

Alvaro was just saying you can replace:

pow(e,kt)

With:

exp(kt)


It does the same thing, just simpler because you can remove the e variable from your code. It's a minor point, I'd just forgotten that the function existed. I'll get back to you once I've had a play with your code.

EDIT:

So, I had a play around with it and it does actually seem to be working. The population just grows towards zero. It turns out that this line is turning your k value negative which shouldn't happen for a population growth:

popgrowth = pop_at_start_of_period-increase*100;


Did you get your order of precedence right? Should it not have been this?

popgrowth = (pop_at_start_of_period-increase)*100;


Even so, your population grows very very quickly. If you try that line above without the *100 on the end and put in 0.1 as the number of years you want to skip you should see it working :)
Fixed post below.
win_crook, on 14 April 2011 - 01:23 PM, said:
EDIT:

So, I had a play around with it and it does actually seem to be working. The population just grows towards zero. It turns out that this line is turning your k value negative which shouldn't happen for a population growth:
popgrowth = pop_at_start_of_period-increase*100;


Did you get your order of precedence right? Should it not have been this?
popgrowth = (pop_at_start_of_period-increase)*100;


Even so, your population grows very very quickly. If you try that line above without the *100 on the end and put in 0.1 as the number of years you want to skip you should see it working



Okay so I changed the code as you suggested:

 popgrowth=(pop_at_start_of_period-increase);

and entered 0.1 as the amount of years to be skipped and it produced the result: 2637. This seemed too rapid, so I experimented abit and the following code yielded results which were more similar to what I expected.

popgrowth=(pop_at_start_of_period-increase)*0.01

when entering 1 as the amount of years to be skipped the result was: 1101. However when I entered a year increment of more than 71 I would get: 1.079232e+006 (for 72) or something similar.
When I reshuffled to code as such:


void timestepfoward(){
cout << "\n\nIt is currently year " << currentyear << " and the population is " << pop_at_start_of_periodint << ".\n";
cout << "How many years would you like to skip? ";
cin >> t;
t=t/100;
birthdeathrate();
population();
currentyear = t+currentyear;
cout << "\nIt is now year " << currentyear << " and the population is now " << pop_at_start_of_periodint << ".\n"
}
void birthdeathrate(){
double increase = births-deaths;
popgrowth = (pop_at_start_of_periodint-increase);
}

It yielded the same results as the previous code.

Assuming this code is correct, how can I avoid the result being a number like this 1.079232e+006.
Assuming it is incorrect, where have I gone wrong and what can I do to put it right.

Thanks in advance.
Your problem is that for a fixed growth rate r = births - deaths, if r > 0 the system explodes (diverges at t = infinity). If r < 0 then the system dies (converges to 0 at t = infinity).

To make the system stable you need to model as a differential equation.

Consider a population with initial population p_0, and every year there are r births and k% of the population dies.

Our differential equation is p' = r - kp.

The solution to this system with initial condition p(0) = p_0 is

p(t) = r/k + (p_0 - r/k)*exp(-kt)

This system is stable and for any initial condition p_0 will converge to p(infinity) = r/k.

Your problem is that for a fixed growth rate r = births - deaths, if r > 0 the system explodes (diverges at t = infinity). If r < 0 then the system dies (converges to 0 at t = infinity).

To make the system stable you need to model as a differential equation.

Consider a population with initial population p_0, and every year there are r births and k% of the population dies.

Our differential equation is p' = r - kp.

The solution to this system with initial condition p(0) = p_0 is

p(t) = r/k + (p_0 - r/k)*exp(-kt)

This system is stable and for any initial condition p_0 will converge to p(infinity) = r/k.


Hey jper, I don't really understand what you mean by p_0. It would be great if you could represent this formula in terms of my code:


void timestepfoward(){
cout << "\n\nIt is currently year " << currentyear << " and the population is " << pop_at_start_of_periodint << ".\n";
cout << "How many years would you like to skip? ";
cin >> t;
birthdeathrate();
population();
currentyear = t+currentyear;
cout << "\nIt is now year " << currentyear << " and the population is now " << pop_at_start_of_periodint << ".\n";
}

void birthdeathrate(){
double increase = births-deaths;
popgrowth = (pop_at_start_of_periodint-increase)*0.01;
}

void population(){
double k = popgrowth/100;
double kt = k*t;

double P = pop_at_start_of_periodint*exp(kt);

int pint = P;
pop_at_start_of_periodint = pint;
}


void otherfactors(){
births = 50;
deaths = 20; // will be more complex when taking other variables into account.
}



Many thanks.
[font="Arial"]p_0 is your population at time = 0, from your code it looks like you call it 'pop_at_start_of_periodint'.

So what I would do is remove the birthdeathrate() function and change your population() function to look like...

double r = constant population increase per year (for example 1000 births per year)
double k = percentage of population killed per year (for example 0.30 -> 30% of the population dies every year)

then double P = (r/k) + [/font](pop_at_start_of_periodint- (r/k)) *exp(-k*t)

should give you a stable system.

This topic is closed to new replies.

Advertisement