Page 267 - Introduction to Programming with Java: A Problem Solving Approach
P. 267

                Figure 6.20 Method that implements step-with-midpoint algorithm
Add this method to the code in Figure 6.17 to improve simulation accuracy and efficiency.
6.13 Problem Solving with Simulation (Optional) 233
conditions there. Then go back to the beginning and use the condition(s) at the midpoint to determine what the change(s) will be in a full step forward.
At first, this might sound like a hard way to do an easy thing. Why not just cut the step size in half and take two small steps forward? The qualitative answer is: That still leaves a regular bias toward old data. The quantitative answer is: If you use a step-with-midpoint algorithm for your simulation, the size of the error is proportional to the square of the size of the time step. That means that if you reduce the full-step size by a factor of 100, the error goes down by a factor of 10,000. In other words, you can get an extra factor-of-100 accuracy by increasing the computer’s work by only a factor of 2.
But what about the work you do? How much harder is it to implement a step-with-midpoint algorithm? Not much. All you have to do is add one simple method. Specifically, to the Growth class in Figure 6.17, just add the getSizeIncrement2 method shown in Figure 6.20.
 public double getSizeIncrement2(double sizeCopy, double timeStep)
{
sizeCopy += getSizeIncrement(sizeCopy, 0.5 * timeStep);
return getSizeIncrement(sizeCopy, timeStep);
 } // end getSizeIncrement2
  No prefix necessary since getSizeIncrement and getSizeIncrement2 are in the same class.
Apago PDF Enhancer
How does this little method work? It simply calls the original getSizeIncrement method two times. Notice that the sizeCopy parameter in Figure 6.20 is just a copy of the size variable in the driver class. The first call to getSizeIncrement uses the size at the beginning of the time increment, and it goes only half a time step forward. Then, it uses the returned value to increment sizeCopy to the size at the midpoint. The second call to getSizeIncrement uses this computed midpoint size and a full time step to determine the change from the beginning to the end of the full time interval.
Within the getSizeIncrement2 method definition, note the calls to getSizeIncrement. There’s no reference variable dot prefix at the left of getSizeIncrement. Here’s why: If you call a method that’s in the same class as the current class, then you can call the method directly, with no reference variable dot prefix.
The work required to modify the driver is negligible. All you have to do is change the name of the method called to the name of the new method. In our case, all you have to do is change the last statement in the driver in Figure 6.18 to this:
size += entity.getSizeIncrement2(size, timeStep);
This appended ‘2’ is the only difference!
Figure 6.21 shows what the improved algorithm produces with a full step size equal to the step size used for Figure 6.19. This takes twice as much computer time as what’s in Figure 6.19, but it’s clearly much
   















































































   265   266   267   268   269