I was looking through my Github projects from last year and I stumbled across a program I started writing when I was first learning Java. It’s goal was to approximate the area under the quadratic equation f(x) =x^2 by summing the area of an arbitrary number of rectangles that fit under the curve between two points; this method for calculating the area is called a Riemann Sum.
I was taking a Calculus 1 at the time and wanted to try my hand at simulating it in Java.
Just doing some basic testing on my original file I got these results:
For these parameters it seems like my code is working well.
However when I try different ranges the answer became wildly wrong
This cannot be the case since there is less area between [2,10] than between [0,10].
I started looking at the code and boy was it a mess. There was only one class file that had all the methods. I think I was trying to express it as a combination of negative areas and positive areas.
I think I was trying to create an array of the base of each of the rectangles.
I ran into some problems since this was overly complicated and I was pretty sure there was a simpler way to do it.
In the year since I started this project I’ve learned a lot more about how to get rid of code smells and generally write cleaner code. So I gave myself a couple of goals and branched the repository on GitHub. You can see the repository here.
Make sure that the answers are correct
Refactor the code into more methods so that each method does one thing and that one thing well.
Use an organizational structure to make the code more modular
Right now all of the methods are in a single java file that also has main() in it.
I can move several of the different methods to other classes so that it is easier to understand.
Add a feature that uses the simplified integral to determine the true area and compare it to my approximation.
Remember that the area under a curve is:
If you want a more visual appreciation for Riemann Sums Wolfram Alpha has a nice demonstration of the concept.
You can solve the integral to get:
Where a is the starting point and b is the end point.
As a roadmap I planned on breaking up the code into the following classes:
A class to do the math.
This would need to calculate the xValues, yValues, width, area approximation and true area.
A class to get the parameters from the user.
A Main() to stitch everything together.
I first started working on a class to do the math.
Instead of trying to calculate how many rectangles should be on the negative side of the x axis and expressing it as a sum of those products it seemed easier to code (and more intuitive) to
create an array of X values and an array of Y values.
I decided that each rectangle would have its top left corner be on the line.
That would make the array look like:
[start, start +1* width, start + 2*width ... start + numberOfRectangles*width]
From this I can take each of those X values and plug them into f(X) to get the associated Y value, which is the height of each rectangle.
Now I have an array of Y Values where each is the height of a different rectangle. .
The width of each rectangle is the total distance between the start and end divided by the number of rectangles.
Now to find the area simply add up the area of all those rectangles.
I stitched it all together in the main like so
In the end I got a some sample run that looks like this:
Just like is expected as you use more rectangles the sum of their areas approaches the area under the curve. In practice, there is a limit to the preciseness since java is not built to handle an infinite number of anything, let alone infinite rectangles.
It now works for negative values. Important to note here is that when you are summing areas of negative X values the area approaches from the positive side while on the right hand side they are approaching from the negative side.
When part of the range is negative and part is positive it will approach from the positive side if more rectangles are on the left and from the negative side if more rectangles are on the right.
To improve the organizational structure I separated the math functions, the user input functions and the main into different files.
You can see the whole project here under “RienmannSumCalculator”.