Jump to content
  • Advertisement
Sign in to follow this  
ReubenESTD

Natural logarithms, exponential growth and C++

This topic is 2669 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites

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]

Share this post


Link to post
Share on other sites

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 :)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
[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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!