Natural logarithms, exponential growth and C++

Started by
17 comments, last by ReubenESTD 12 years, 11 months ago

[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.



It now reaches 2500 population, then stops, no matter how high the time value is. Argh so frustrating...
Current 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;
population();
currentyear = t+currentyear;
cout << "\nIt is now year " << currentyear << " and the population is now " << pop_at_start_of_periodint << ".\n";
}


void population(){
double k = (deaths/pop_at_start_of_periodint);

double P = (births/k)+(pop_at_start_of_periodint-(births/k))*exp(-k*t);

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.
}

Advertisement
White Dwarf. I commend your research. If you want any advice or help regarding this subject, please private message me. That said, please don't take the following comment personally...

Does everyone remember that thread from a few months ago about whether or not First Nations people would have ever "advanced" if Europeans hadn't come to the Americas?

Remember how I said it was nonsense, because First Nations people knew the logistic function like the back of their hand even though they didn't have the symbolic language to describe it?

You guys are nothing but a bunch of fancy rabbits with oversized egos. Have fun trying to figure this out! Bwahaha.
Well, first, k should not be a function of population. It should be a constant. It is the fraction of the population that dies every year. Say 1/10 people in the model die every year, then k = 0.1, not 0.1 * current population. Second, if we look at our equation for population as a function of time...

p(t) = (r/k) - (P_0 - (r/k))*exp(-k*t)

we see that the lim t->infinity p(t) = r/k, because the second term will go to zero. This means that if your constant birth rate is 1,000 births per year and your death rate is 10% then the population for any sufficiently large value of t will be near to 10,000 people.

Well, first, k should not be a function of population. It should be a constant. It is the fraction of the population that dies every year. Say 1/10 people in the model die every year, then k = 0.1, not 0.1 * current population. Second, if we look at our equation for population as a function of time...

p(t) = (r/k) - (P_0 - (r/k))*exp(-k*t)

we see that the lim t->infinity p(t) = r/k, because the second term will go to zero. This means that if your constant birth rate is 1,000 births per year and your death rate is 10% then the population for any sufficiently large value of t will be near to 10,000 people.


I commend your efforts too, which is why I rated you ++ up the wazoo. Good work man. You sir are a fancy rabbit with a normal sized ego. That's rare.

That said, I still find it highly disappointing that no one mentioned Malthus or Verhulst or Volterra or the logistic function once in this thread. Armed with that information, White Dwarf may now feel free to investigate the meaning of the parameters on their own, to verify/discredit what you are saying:

K represents what is known as the carrying capacity in all official documentation on the subject.

I wonder where all the self-declared experts from the AI board are? They use the logistic function as an activation function all the time, so this should have been a cakewalk for them. Perhaps they're still busy trying to figure out that people use Greek characters for constants in their manuscripts because it's an homage to the Greeks, and not a sign of elitism.

I wonder where all the self-declared experts from the AI board are? They use the logistic function as an activation function all the time, so this should have been a cakewalk for them. Perhaps they're still busy trying to figure out that people use Greek characters for constants in their manuscripts because it's an homage to the Greeks, and not a sign of elitism.

Please drop the attitude and try to stay on-topic -- posts like this achieve nothing other than potentially dragging the discussion off-topic. You can consider this an official warning. Should you wish to discuss the matter with me further please feel welcome to do so via private message rather than cluttering up the topic more.

- Jason Astle-Adams

I'm sorry but even with my best attempts at all the suggested solutions I still can't get a working formula. If anyone could muster up some working code for this I would be eternally grateful as it is really preventing me from moving on with the program.

Thanks in advance.

-EDIT:

This




int main()
{
double initpop=1000;
double births=24;
double deaths=19;
double birthdeathrate=(births-deaths)/initpop+1;
unsigned int population;
int t;


cout << "Enter year increment: ";
cin >> t;

population = initpop*(pow(birthdeathrate,t));

cout << population;
}




works fine for me.
Your form is close. I added the exponential growth formula to your code, its the one that prints 2nd.

Notice the difference when you input something like 500 years (and then work each formula with that t value to see why its different)

Enter year increment: 500
12106
12182
[/quote]
Your form does something like this (using the provided values in your code)
1.005 to the power of t (number of years) multiplied by the initial population equals the new population.

The exponential form does the following.
Initial population multiplied by: 'e' to the power of (0.005 * t) equals the new population.

I think your form is more intuitive, but since everything else uses newPop=initPop*e^(rate*time), I suggest that you use that.

The 0.005 is your 'k' value above. It represents a percent as a decimal, that is 1% is the number 0.01. Your (birth-death)/initpop results in (24-19)/1000 = 0.005 so this is your k value, a population increase of 0.5% per year (t).

Google up "Exponential Growth" to see more detail about it. This formula is used often enough that it is pretty handy to have memorized and understood.



int main(void)
{
double initpop=1000;
double births=24;
double deaths=19;
double birthdeathrate=(births-deaths)/initpop+1;
unsigned int population;
int t;


cout << "Enter year increment: ";
cin >> t;

population = initpop*(pow(birthdeathrate,t));

cout << population << endl;

population = initpop*exp( (births-deaths)/initpop * t );

cout << population << endl;

return 0;
}



Hope this helps!
By the way, you can solve for k or t if you know both the initialPopulation and newPopulation along with one or the other of k or t.

k = ln( newPopulation / initialPopulation ) / t;

t = ln( newPopulation / initialPopulation ) / k;

The function "ln(...)" is in the C++ header <cmath>.

If the initial population is 6 billion, and we wonder how long it will take to reach 15 billion at a growth rate of 1.2% then we are solving for t.
t = ln ( 15,000,000,000 / 6,000,000,000 ) / 0.012
t = ln ( 2.5 ) / 0.012
t = 0.91629... / 0.012
t = 76.358 years

If the initial population is 6 billion, and someone tells us that it will be 10 billion 50 years from now, what is the growth rate? Solving for k.
k = ln ( 10,000,000,000 / 6,000,000,000 ) / 50
k = ln ( 1.666~ ) / 50
k = 0.5108... / 50
k = 0.0102
The growth rate would be 1.02%.

Your form is close. I added the exponential growth formula to your code, its the one that prints 2nd.

Notice the difference when you input something like 500 years (and then work each formula with that t value to see why its different)

Enter year increment: 500
12106
12182

Your form does something like this (using the provided values in your code)
1.005 to the power of t (number of years) multiplied by the initial population equals the new population.

The exponential form does the following.
Initial population multiplied by: 'e' to the power of (0.005 * t) equals the new population.

I think your form is more intuitive, but since everything else uses newPop=initPop*e^(rate*time), I suggest that you use that.

The 0.005 is your 'k' value above. It represents a percent as a decimal, that is 1% is the number 0.01. Your (birth-death)/initpop results in (24-19)/1000 = 0.005 so this is your k value, a population increase of 0.5% per year (t).

Google up "Exponential Growth" to see more detail about it. This formula is used often enough that it is pretty handy to have memorized and understood.



int main(void)
{
double initpop=1000;
double births=24;
double deaths=19;
double birthdeathrate=(births-deaths)/initpop+1;
unsigned int population;
int t;


cout << "Enter year increment: ";
cin >> t;

population = initpop*(pow(birthdeathrate,t));

cout << population << endl;

population = initpop*exp( (births-deaths)/initpop * t );

cout << population << endl;

return 0;
}




Hope this helps!
[/quote]



Thank you, this was the exact explanation I was hoping to receive. Perfectly explained, helpful and accurate. And thanks for elaborating on the rearranging of the formula, it helped me understand better and should come in handy when completing this program. +rep biggrin.gif

This topic is closed to new replies.

Advertisement