By the end of this module, for simple programs with real numbers, you will be able to:
In this and the next few sections, we'll use simple for-loops to compute some of the most famous constants in mathematics, and explore a few mathematical ideas (no background needed).
One key idea in mathematics is the notion of a limit:
x1 = 1 x2 = 3 x3 = 5 x4 = 7 ... (and so on)
x1 = 1/1 = 1 x2 = 1/2 = 0.5 x3 = 1/3 = 0.3333 x4 = 1/4 = 0.25 x5 = 1/5 = 0.20 ... (skipping a few) ... x10 = 1/10 = 0.1 ... (skipping a few) ... x100 = 1/10 = 0.01 ... (skipping many) ... x10000 = 1/10000 = 0.00001
Next, let's explore some reasoning related to sequences (of numbers):
x1 = 3/4 x2 = (3/4)2 = 0.5625 x3 = (3/4)3 = 0.4218 x4 = (3/4)4 = 0.3164 ... (and so on)
x1 = (3/4) = 0.75 x2 = (3/4)2 = 0.5625 (less than 0.75)
x1 = (3/4) = 0.75 x2 = (3/4)2 = 0.5625 x3 = (3/4)3 = 0.4218 (less than 0.5625)
Let's write a program to verify:
public class TestSequence { public static void main (String[] argv) { // Remember: 3/4 = 0 because it'll be integer division. // We need to make this 3.0 / 4.0. double x = 3.0 / 4.0; for (int n=2; n<=20; n++) { System.out.println (x); // The next term is 3/4 times the previous. x = (3.0/4.0) * x; } } }
8.1 Exercise: Write up the above program and verify that successive powers of 3/4 are getting smaller. Now try another number that's less than 1, like 0.95 and examine its successive powers.
Next, let's look at a number that's larger than 1, like 4/3.
8.2 Exercise: Change the code above to verify. Now try another number that's bigger than 1, like 1.05, and examine its successive powers.
We can generalize this:
A small tweak will make this more interesting:
x1 = 1 x2 = 3 x3 = 5 x4 = 7 ... (and so on)
for (int n=1; n<=20; n++) { // Compute the n-th odd number: double x = 2*n-1; // Use a for-loop to compute xn double power = 1; for (int j=1; j<=n; j++) { power = power * x; } System.out.println ("n-th power of xn=" + power); }
8.3 Exercise: Write up the above code in OddSequence.java.
x1 = 1 + 1/1 = 2 x2 = 1 + 1/2 = 1.5 x3 = 1 + 1/3 = 1.333 x4 = 1 + 1/4 = 1.25 ... (and so on)
(x1)1 = (1 + 1/1)1 = ? (x2)2 = (1 + 1/2)2 = ? (x3)3 = (1 + 1/3)3 = ? (x4)4 = (1 + 1/4)4 = ? ... where is this headed?
for (int n=1; n<=20; n++) { // Compute the n-th term: double x = 1.0 + 1.0/n; // Use a for-loop to compute xn double power = 1; for (int j=1; j<=n; j++) { power = power * x; } System.out.println ("n-th power of xn=" + power); }
8.4 Exercise: Edit, compile and execute the program, writing your code in StrangeSequence.java. Try much larger values of n. What does the limit of the sequence appear to be?
The limit of the above sequence is the celebrated and important mathematical constant e:
About e:
Now that we've mentioned π, let's look at a sequence that computes it.
sum = 0 for i=1 to k { sum = sum + 1.0/(2*i-1) }
sum = 0 sign = 1 for i=1 to k { sum = sum + sign/(2*i-1) sign = -sign; }
8.5 Exercise: Edit, compile and execute the program. Try larger values of n to see how quickly it converges to π. When k=4 in the outerloop, trace through the execution inside the outerloop in (module8.pdf).
8.6 Video:
Let's look at a third famous constant: Φ, the golden ratio.
8.7 Exercise: In GoldenRatio.java modify the above program to compute this ratio. What does it appear to converge to?
Zeno's paradox:
8.8 Exercise: What does the series appear to converge to? Write your code in Zeno.java.
8.9 Audio:
Thus, we see that even though a series appears to add up an infinite number of numbers, the resulting sum can be finite. And a small number too.
This sort of strangeness with respect to numbers befuddled the Greeks and others to follow, until rigorous mathematics in later centuries built a firm theoretical and axiomatic foundation.
We'll now explore some data analysis with words:
8.10 Exercise: Write code in WordAnalysis.java with a for-loop that calls WordTool.getRandomVerb() and assigns to a String variable. Then, extract its length and accumulate into a variable called total. Continue from there to compute and print the average verb length. Use 1000 such verbs. Then repeat for nouns. You will need to download into the same directory: WordTool.java and wordsWithPOSAndPron.txt. What is the difference between the average lengths? Are other parts of speech shorter or longer on average?
Let's start by plotting a simple function:
0 0.5 1.0 1.5 ... (20 equally spaced values along x-axis) 9.5 10.0
f(0) = sin(0) = 0 f(0.5) = sin(0.5) = 0.48 f(1.0) = sin(1.0) = 0.84 f(1.5) = sin(1.5) = 0.997 ... f(9.5) = sin(9.5) = -0.075 f(10.0) = sin(10.0) = -0.54
// 20 points along the x-axis int N = 20; double xSpacing = (10.0 - 0.0) / N; for (double x=0; x<=10; x+=xSpacing) { // Compute f at the x-value of x double f = Math.sin(x); // Plot the point x, f(x) DrawTool.drawPoint (x, f); }
8.12 Exercise: Download DrawTool.java and FunctionExample.java Then, compile and execute FunctionExample.java. Edit the file FunctionExample.java to increase to 100 the number of points (N) at which the function is computed - this should produce a smoother curve.
Next, let's work with some real data
x | f(x) |
8.33 | 1666.67 |
22.22 | 3666.67 |
23.61 | 4833.33 |
30.55 | 5000 |
36.81 | 5166.67 |
47.22 | 8000 |
69.44 | 11333.33 |
105.56 | 19666.67 |
public class FunctionData { public static void main (String[] argv) { DrawTool.display (); DrawTool.setXYRange (0, 110, 0, 20000); double x = 8.33; double f = 1666.67; DrawTool.drawPoint (x,f); x = 22.2; f = 3666.67; DrawTool.drawPoint (x,f); x = 23.61; f = 4833.33; DrawTool.drawPoint (x,f); x = 30.55; f = 5000; DrawTool.drawPoint (x,f); x = 36.81; f = 5166.67; DrawTool.drawPoint (x,f); x = 47.22; f = 8000; DrawTool.drawPoint (x,f); x = 69.44; f = 11333.33; DrawTool.drawPoint (x,f); x = 105.56; f = 19666.67; DrawTool.drawPoint (x,f); } }
8.13 Exercise: Edit, compile and execute FunctionData.java. Then, try to estimate the slope of a line that would approximately "fit" the points. Use the DrawTool.drawLine method to draw a line with your estimated slope. For example, if your estimated slope is m, you would add this to your program:
DrawTool.drawLine (0,0, 110, m*110);
8.14 Exercise: The data is from a world-changing paper published in 1929. Use a websearch to discover what the data is and why it changed the world.
Let's introduce some programming terminology first:
That said, let's look at one very useful part of Java's library, with math functions. Here's an example:
public class MathExamples { public static void main (String[] argv) { // Compute the square root of a number: double x = 2; double y = Math.sqrt (2); System.out.println (y); // The package has many trig functions, e.g. double angle = 3.14159; double sinOfAngle = Math.sin (angle); System.out.println (sinOfAngle); // Power, exponent, logarithm etc, for example: double fourthPowerOf3 = Math.pow (3.0, 4.0); System.out.println (fourthPowerOf3); // Generate random numbers between 0 and 1. double randomValue = Math.random (); System.out.println (randomValue); } }What's important to know:
8.16 Exercise: Do a web search for "Java API". The follow the link to merely "check out" the API and get a feel for how impossibly large it is. One the lower-left menu, look for the Math collection and casually browse through the various functions. If you were not able to find the link, use this one.
About the Java library:
We will explore the use of visualization for problems in motion:
public class MotionExample { public static void main (String[] argv) { DrawTool.display (); DrawTool.setXYRange (0,100, 0,100); DrawTool.startAnimationMode (); double v = 10; for (double t=0; t<=10; t+=0.1) { double d = v*t; double h = 100 - 0.5*9.8*t*t; DrawTool.writeTopValue (t); DrawTool.setPointColor ("blue"); DrawTool.drawPoint (d, 0); DrawTool.setPointColor ("red"); DrawTool.drawPoint (70, h); DrawTool.animationPause (100); } DrawTool.endAnimationMode (); } }
8.17 Exercise: Edit, compile and execute the above program. Make sure DrawTool.java is in the same directory. Guess at the velocity v needed to create a collision between the two objects by changing v in the program. At what time would this occur?
Now that we can draw, let's go back in time to draw what Archimedes (circa 250BC) drew in his quest to compute π
8.18 Exercise: Download Archimedes.java, compile and run. You already have DrawTool in your directory.
What you see is:
Archimedes' idea:
Turns out: this gives π = 3.09
Turns out: this gives π = 3.12 (not bad)
Turns out: this gives π = 3.14107 (pretty good)
Now let's examine some of the details (a loop, really):
// Set DrawTool up so that the circle's // center is at the origin: DrawTool.display (); DrawTool.setXYRange (-10, 10, -10, 10); DrawTool.drawMiddleAxes (true); // Radius: double r = 8; // Draw the circle DrawTool.drawCircle (0, 0, r);
8.19 Exercise: Download ArchimedesSteps.java, compile and run. Then examine the code.
Note:
... // Interior angle of each triangle. double angle = 2*Math.PI / N; // Initialize the variable that will accumulate the lengths // of edges that comprise the perimeter. double perimeter = 0; for (int i=0; i<N; i++) { // One corner of the triangle on the circumference: double x1 = r * Math.cos (i*angle); double y1 = r * Math.sin (i*angle); // The second corner: double x2 = r * Math.cos ((i+1)*angle); double y2 = r * Math.sin ((i+1)*angle); // Distance between the two: double dist = Math.sqrt ((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); // Accumulate: perimeter = perimeter + dist; // Draw the i-th triangle: DrawTool.drawLine (0,0, x1, y1); DrawTool.drawLine (0,0, x2, y2); DrawTool.drawLine (x1,y1, x2, y2); } // The estimate of π is the perimeter divided by the diameter. double piEstimate = perimeter / (2*r); System.out.println ("pi=" + piEstimate);Note: Ignore the trigonometry for the moment and just pay attention to:
8.20 Exercise: Uncomment the main loop in ArchimedesSteps.java to see the rest.
Lastly, we would be remiss if we did not point out a faster way of achieving the same result:
// Radius: double r = 8; // Number of triangles to inscribe: int N = 100; // Interior angle of each: double angle = 2*Math.PI / N; // The corner of the triangle touching the x-axis: double x1 = r; double y1 = 0; // The second corner: double x2 = r * Math.cos (angle); double y2 = r * Math.sin (angle); // Distance between the two: double dist = Math.sqrt ((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); // Multiply by N: double perimeter = N * dist; // The estimate of is the perimeter divided by the diameter: double piEstimate = perimeter / (2*r); System.out.println ("pi=" + piEstimate);
8.21 Exercise: Download ArchimedesFast.java, compile and run. Increase N for higher accuracy.
8.22 Audio: