Jump to content

stackOverflowError. Calculating 3 sequential expressions that are linked

Claryn

Hi.

 

I am trying to make a program that does some calculations for me.

Here are the three expressions that I need the first 200 numbers for.

 

 

n = 0 and increases by 1 for every iteration.

h = 1.

i(0) = 0,00000019.

s(0) = 1.

r(0) = 0.

 

i(n+1) = i(n) + ((1/2) * 1 * s(n) * i(n) ) - ((1/10) * 1 * i(n) )

s(n+1) = s(n) - ((1/2) * 1 * s(n) * i(n) )

r(n+1) = r(n) + ((1/10) * 1 * i(n) )

 

Here is the program I am working on at the moment, but sadly it gives me a stackOverflowError at line 42.

package amina;public class amina {		public static void main (String args[])	{						double s [] = new double [300];		double i [] = new double [300];		double r [] = new double [300];		//int h = 1;				i[0] = 0.00000019;		s[0] = 1;		r[0] = 0;				System.out.println("n\ti\ts\tr");		for (int n = 0; n<200; n++)		{			i[n] = i(n+1);			s[n] = s(n+1); 			r[n] = r(n+1);		}				output(s, i, r);	}		public static void output(double s [], double i [], double r []) 	{		for (int j = 0; j<200; j++)		{			System.out.println(j + "\t" + i[j] + "\t" + s[j] + "\t" + r[j]);		}			}		public static double i(int n)	{			double i;		i = i(n) + ((1/2) * 1 * s(n) * i(n) ) - ((1/10) * 1 * i(n) );		//System.out.println("i");		return i;	}	public static double s(int n)	{					double s;		s = s(n) - ((1/2) * 1 * s(n) * i(n) );			//System.out.println("s");		return s;	}		public static double r(int n)	{			double r;		r = r(n) + ((1/10) * 1 * i(n) );		//System.out.println("r");		return r;	}}

.. and the pastebin: http://pastebin.com/kMXhKC6K

Running Arch with i3-gaps on a Thinkpad X1 Extreme
Data Science Postgrad

 

Link to comment
Share on other sites

Link to post
Share on other sites

 
public static double i(int n)    {            double i;        i = i(n) + ((1/2) * 1 * s(n) * i(n) ) - ((1/10) * 1 * i(n) );        //System.out.println("i");        return i;    }

The following also applies to the function s() and r(). You are trying to program a recursive function so you should do the following:

 

  • Check if you reached the base case (in this case n=0) if so return the answer
  • Otherwise calculate the answer using the formula (this step should get you closer to the base case)

 

You don't do the first one so your code will not terminate.

You tried to do the second one but forgot to lower the value of n before inserting it in the function, this way you never reach the base case.

 

It might be easier to use the rewritten form and go on from there:

i(n) = i(n-1) + ((1/2) * 1 * s(n-1) * i(n-1) ) - ((1/10) * 1 * i(n-1) )

On a side note it would be easier to calculate your number using the numbers you already have:

i[n] = i[n-1] + ((1/2) * s[n-1]  * i[n-1]  ) - ((1/10) * i[n-1] )

This way the program does not continously recalculate parts it already solved.

Link to comment
Share on other sites

Link to post
Share on other sites

This is caused by deep recursion. Here are some strategies for tackling it in Java. Another option is to switch your recursive functions to iterative ones.

 

edit: voldelord got it right. Somehow I missed the infinite recursion.

Link to comment
Share on other sites

Link to post
Share on other sites

 

snip

Alright, I tried this out.

 

I changed every method to the following format:

	public static double i(int n)	{			double i = 0;		if (n==0)			return 0.00000019;;		i = i(n-1) + ((1/2) * 1 * s(n-1) * i(n-1) ) - ((1/10) * 1 * i(n-1) );		//System.out.println("i");		return i;	}

Where s returns it's initial value of 1 when n=0, r returns it's initial value of 0 when n=0. 

 

However, this doesn't work either. I don't get an error anymore, but all values of n gives the initial value of s,r and i.

 

Also, if I let the main loop do more than 10 iterations, it just sits there and doesn't output anything.

Running Arch with i3-gaps on a Thinkpad X1 Extreme
Data Science Postgrad

 

Link to comment
Share on other sites

Link to post
Share on other sites

That your program doesn't output anything (or takes a very long time) with more than 10 iterations is not surprising.

 

Only talking about i(n):

i(0) immediately returns the answer

For i(1) you need to rerun i(0) 3 times and run s(0) and perform calculations with those

for i(2) you need to run i(1) 3 times so you run i(0) 9 times. But you also need to run s(1) which needs s(0) and s(1)

 

This goes up exponentially with more iterations, and since you do not print the results between iteration but only when you have all the answer it can seem to get stuck.

 

Having said that I corrected to program using your tactic:

package amina;public class amina {		public static void main (String args[])	{						double s [] = new double [300];		double i [] = new double [300];		double r [] = new double [300];		//int h = 1;				i[0] = 0.00000019;		s[0] = 1;		r[0] = 0;				System.out.println("n\ti\ts\tr");		for (int n = 1; n<200; n++)		{			i[n] = i(n);			s[n] = s(n); 			r[n] = r(n);			System.out.println(n);		}				output(s, i, r);	}		public static void output(double s [], double i [], double r []) 	{		for (int j = 0; j<200; j++)		{			System.out.println(j + "\t" + i[j] + "\t" + s[j] + "\t" + r[j]);		}			}		public static double i(int n)	{			double i = 0;		if (n==0)			return 0.00000019;;		i = i(n-1) + (s(n-1) * i(n-1)/2) - (i(n-1)/10 );		//System.out.println("i");		return i;	}	public static double s(int n)	{					double s;		if (n==0)			return 1;;		s = s(n-1) - (s(n-1) * i(n-1)/2 );			//System.out.println("s");		return s;	}		public static double r(int n)	{			double r;		if (n==0)			return 0;;		r = r(n-1) + (i(n-1)/10 );		//System.out.println("r");		return r;	}}

I rewrote the formula to include less operators

so instead of i(n)= i(n-1) + ((1/2) * 1 * s(n-1) * i(n-1) ) - ((1/10) * 1 * i(n-1) ) 

I used i(n) = i(n-1) + (s(n-1) * i(n-1)/2 ) - i(n-1)/10

 

As far as I now the calculations are done correctly (haven't checked by hand) but the program calculates the numbers means it is not feasible for a high number if iterations.

It took about 10 minutes to do the first 20 iterations and it will only get worse.

 

 

My advice would be to think of a way to use previously calculated or given values to calculate the next value.

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×