(************** Content-type: application/mathematica ************** CreatedBy='Mathematica 5.2' Mathematica-Compatible Notebook This notebook can be used with any Mathematica-compatible application, such as Mathematica, MathReader or Publicon. The data for the notebook starts with the line containing stars above. To get the notebook into a Mathematica-compatible application, do one of the following: * Save the data starting with the line of stars above into a file with a name ending in .nb, then open the file inside the application; * Copy the data starting with the line of stars above to the clipboard, then use the Paste menu command inside the application. Data for notebooks contains only printable 7-bit ASCII and can be sent directly in email or through ftp in text mode. Newlines can be CR, LF or CRLF (Unix, Macintosh or MS-DOS style). NOTE: If you modify the data for this notebook not in a Mathematica- compatible application, you must delete the line below containing the word CacheID, otherwise Mathematica-compatible applications may try to use invalid cache data. For more information on notebooks and Mathematica-compatible applications, contact Wolfram Research: web: http://www.wolfram.com email: info@wolfram.com phone: +1-217-398-0700 (U.S.) Notebook reader applications are available free of charge from Wolfram Research. *******************************************************************) (*CacheID: 232*) (*NotebookFileLineBreakTest NotebookFileLineBreakTest*) (*NotebookOptionsPosition[ 59426, 2129]*) (*NotebookOutlinePosition[ 60108, 2152]*) (* CellTagsIndexPosition[ 60064, 2148]*) (*WindowFrame->Normal*) Notebook[{ Cell[CellGroupData[{ Cell["Creating Functions", "Title"], Cell[TextData[{ "The ", StyleBox["Mathematica", FontSlant->"Italic"], " convention is to spell out all words, so that you don't have to memorize \ abbreviations, and to capitalize the first letter of each word. For your own \ functions, however, the first letter of the first word should be lower case \ to distinguish it from built-in functions." }], "Text"], Cell[CellGroupData[{ Cell["One-line functions", "Section"], Cell["You have already been creating one-line functions, such as,", "Text"], Cell[BoxData[ \(f[x_] = x\^2\)], "Input"], Cell["or", "Text"], Cell[BoxData[ \(f[x_, y_] = x\^2 + y\^2\)], "Input"], Cell[TextData[{ "When you create more complicated one-line functions, though, it is helpful \ to build it up in stages and then put it all together into one statement, \ similar to a composition of functions ", StyleBox["f[g[h[x]]]", FontFamily->"Courier"], ". Think about the steps that you would go through to accomplish the task. \ The first step would be the innermost function, and the last step would be \ the outermost function. You can set the function arguments to particular \ values until you figure out what the function should be." }], "Text"], Cell[TextData[{ "For example, suppose that I want to calculate the average of a list of \ numbers, but leaving out the largest ", StyleBox["n", FontSlant->"Italic"], " values and the smallest ", StyleBox["n", FontSlant->"Italic"], " values. First I'll create a test data set." }], "Text"], Cell[BoxData[ \(\(data = {3, 4, 1, 12, 5, 3, 8, 15, 21, 17, 2, 25, 16, 8};\)\)], "Input"], Cell[TextData[{ "My steps will be:\n1) sort the list,\n2) drop the ", StyleBox["n", FontSlant->"Italic"], " largest,\n3) drop the ", StyleBox["n", FontSlant->"Italic"], " smallest,\n4) calculate the average." }], "Text"], Cell["We start by sorting the list.", "Text"], Cell[BoxData[ \(dataSorted = Sort[data]\)], "Input"], Cell[TextData[{ "Now, let's assign a value to ", StyleBox["n", FontSlant->"Italic"], " until we have our function fully developed." }], "Text"], Cell[BoxData[ \(\(n = 3;\)\)], "Input"], Cell[TextData[{ "Now we need to drop the ", StyleBox["n", FontSlant->"Italic"], " largest values." }], "Text"], Cell[BoxData[ \(dataChopped = Drop[dataSorted, \(-n\)]\)], "Input"], Cell[TextData[{ "Now we drop the ", StyleBox["n", FontSlant->"Italic"], " lowest values." }], "Text"], Cell[BoxData[ \(dataChopped2 = Drop[dataChopped, n]\)], "Input"], Cell["Finally, we calcuate the average of this list.", "Text"], Cell[BoxData[ \(Mean[dataChopped2]\)], "Input"], Cell["\<\ See if you can put this together into one line, with each command \ nested inside of the next command.\ \>", "Text"], Cell["\<\ Now we can bundle all of this into a one-line function. Paste your \ nested command at the end of the following.\ \>", "Text"], Cell[BoxData[{ \(Clear[truncatedMean]\), "\[IndentingNewLine]", \(\(\(truncatedMean[data_, n_]\)\(:=\)\)\)}], "Input"], Cell["\<\ Now, let's test it to be sure that it works. First, test it with \ your original data set.\ \>", "Text"], Cell[BoxData[ \(truncatedMean[{3, 4, 1, 12, 5, 3, 8, 15, 21, 17, 2, 25, 16, 8}, 3]\)], "Input"], Cell["\<\ You should include some tests with data that we did not use in our \ development. Here are some tests that we might try.\ \>", "Text"], Cell[BoxData[ \(truncatedMean[{\(-5\), 2, 3.7, 1\/3, 3, \(-10\)}, 2]\)], "Input"], Cell[BoxData[ \(truncatedMean[{2, \(-4\), 5, \[Pi], \[ExponentialE]\^3, 0, 12\/7}, 2]\)], "Input"], Cell[TextData[{ "Oops, that was not the correct answer. The answer should involve \[Pi], \ since 5 and ", Cell[BoxData[ \(TraditionalForm\`\[ExponentialE]\^3\)]], "are both greater than \[Pi], \[Pi] should remain in the truncated list; \ and therefore, it should appear in our answer. We need to look at this more \ carefully. Let's retrace the individual steps for this data set. First we \ have to sort the data." }], "Text"], Cell[BoxData[ \(Sort[{2, \(-4\), 5, \[Pi], \[ExponentialE]\^3, 0, 12\/7}]\)], "Input"], Cell[TextData[{ "There is the problem. ", StyleBox["Sort", FontFamily->"Courier"], " claims that \[Pi] is the largest value in the list. So, we had better \ look up ", StyleBox["Sort", FontFamily->"Courier"], " in the Help Browser. The Help Browser says that ", StyleBox["Sort", FontFamily->"Courier"], " uses the sort order described in Section A.3.9 as its default. That \ section says that symbols appear after numbers. \[Pi] and \[ExponentialE] \ are both symbols. But ", StyleBox["Sort", FontFamily->"Courier"], " accepts a second argument that specifies the sort ordering test. If we \ use < instead of the default sort order, then we should be in good shape. ", StyleBox["Less", FontFamily->"Courier"], " knows that \[Pi] is less than 5." }], "Text"], Cell[BoxData[ \(\[Pi] < 5\)], "Input"], Cell[TextData[{ "So, we need to include ", StyleBox["Less", FontFamily->"Courier"], " as a second argument to ", StyleBox["Sort", FontFamily->"Courier"], "." }], "Text"], Cell[BoxData[ \(Sort[{2, \(-4\), 5, \[Pi], \[ExponentialE]\^3, 0, 12\/7}, Less]\)], "Input"], Cell["\<\ That's better. Now, go back and correct our truncatedMean function \ and test it again on the data sets.\ \>", "Text"], Cell[TextData[{ StyleBox["Exercise 11.1:", FontWeight->"Bold", FontColor->RGBColor[0, 0.500008, 0.250004]], " Create a function to find the total population of the ", StyleBox["n", FontSlant->"Italic"], " least populous countries. The number of countries and the full path to \ the input data file should be function arguments." }], "Text", Background->GrayLevel[0.750011]] }, Closed]], Cell[CellGroupData[{ Cell["Restricting function arguments", "Section"], Cell["\<\ You can use various tests to restrict the values of arguments to \ functions. You can do this to avoid weird and unexpected effects when people \ use your function with a type of argument that you did not anticipate. These \ restrictions also allow you to different formulas for a function with \ different subsets of its domain. For example, suppose that your function \ contained a square root, and you wanted to restrict its argument to a \ non-negative value.\ \>", "Text"], Cell[BoxData[{ \(Clear[f]\), "\[IndentingNewLine]", \(f[x_ /; x \[GreaterEqual] 0] = \@x - \@\(x + 1\)\)}], "Input"], Cell["You will get a value when you evaluate", "Text"], Cell[BoxData[ \(f[4]\)], "Input"], Cell["But you won't get a value when you try to evaluate", "Text"], Cell[BoxData[ \(f[\(-3\)]\)], "Input"], Cell[TextData[{ "You can restrict the function arguments to be of a particular type. \ Everything in ", StyleBox["Mathematica", FontSlant->"Italic"], " is represesented as a function, except for the atomic elements \ \[LongDash] variable names, symbols, and numbers. When we write ", StyleBox["x", FontSlant->"Italic"], " + ", StyleBox["y", FontSlant->"Italic"], ", ", StyleBox["Mathematica", FontSlant->"Italic"], " represents this as ", StyleBox["Plus[x,y]", FontFamily->"Courier"], ". The expression {a, b} is ", StyleBox["List[a, b]", FontFamily->"Courier"], ". If you want to see how something is represented internally in ", StyleBox["Mathematica", FontSlant->"Italic"], ", use FullForm" }], "Text"], Cell[BoxData[{ \(Clear[x, y]\), "\[IndentingNewLine]", \(FullForm[{x + 7, 2 y}]\)}], "Input"], Cell[TextData[{ "The name of the outermost function is called the ", StyleBox["Head", FontFamily->"Courier"], " of the expression." }], "Text"], Cell[BoxData[{ \(Clear[x, y]\), "\[IndentingNewLine]", \(Head[{x + 7, 2 y}]\)}], "Input"], Cell[TextData[{ StyleBox["Mathematica", FontSlant->"Italic"], " even assigns values of ", StyleBox["Head", FontFamily->"Courier"], " to atomic elements." }], "Text"], Cell[BoxData[ \(Head[4]\)], "Input"], Cell[BoxData[ \(Head[3.7]\)], "Input"], Cell[BoxData[{ \(x = 3\/4\), "\[IndentingNewLine]", \(Head[x]\)}], "Input"], Cell[BoxData[ \(Head[\[Pi]]\)], "Input"], Cell[BoxData[{ \(Clear[x]\), "\[IndentingNewLine]", \(Head[x]\)}], "Input"], Cell["\<\ You can restrict your function arguments to have specified Heads. \ For example, here is a factorial function defined for integer \ arguments.\ \>", "Text"], Cell[BoxData[ \(factorial[n_Integer] := \(n!\)\)], "Input"], Cell["Our function will calculate", "Text"], Cell[BoxData[ \(factorial[4]\)], "Input"], Cell["but not", "Text"], Cell[BoxData[ \(factorial[3.7]\)], "Input"], Cell["Oops, it will also calculate", "Text"], Cell[BoxData[ \(factorial[\(-8\)]\)], "Input"], Cell[TextData[{ "We can restrict ", StyleBox["factorial", FontFamily->"Courier"], "'s argument to have a head of ", StyleBox["Integer", FontFamily->"Courier"], " and to be non-negative." }], "Text"], Cell[BoxData[{ \(Clear[factorial]\), "\[IndentingNewLine]", \(factorial[n_Integer /; n \[GreaterEqual] 0] := \(n!\)\)}], "Input"], Cell[TextData[{ "Now ", StyleBox["factorial", FontFamily->"Courier"], " refuses to evaluate the following." }], "Text"], Cell[BoxData[ \(factorial[\(-8\)]\)], "Input"], Cell[TextData[{ "You can create more complex tests for your arguments by creating logical \ functions (which return ", StyleBox["True", FontFamily->"Courier"], " or ", StyleBox["False", FontFamily->"Courier"], ") or using one of ", StyleBox["Mathematica", FontSlant->"Italic"], "'s built in logical functions. Some of these logical functions are ", StyleBox["NumberQ", FontFamily->"Courier"], ", ", StyleBox["NumericQ", FontFamily->"Courier"], ", ", StyleBox["IntegerQ", FontFamily->"Courier"], ", ", StyleBox["EvenQ", FontFamily->"Courier"], ", ", StyleBox["OddQ", FontFamily->"Courier"], ", ", StyleBox["PrimeQ", FontFamily->"Courier"], ", ", StyleBox["VectorQ", FontFamily->"Courier"], ", ", StyleBox["MatrixQ", FontFamily->"Courier"], ", and ", StyleBox["PolynomialQ", FontFamily->"Courier"], ". ", StyleBox["NumberQ", FontFamily->"Courier"], " returns ", StyleBox["True", FontFamily->"Courier"], " if its argument is a number with head ", StyleBox["Complex", FontFamily->"Courier"], ", ", StyleBox["Real", FontFamily->"Courier"], ", ", StyleBox["Rational", FontFamily->"Courier"], ", or ", StyleBox["Integer", FontFamily->"Courier"], "." }], "Text"], Cell[BoxData[ \(NumberQ[4.7]\)], "Input"], Cell[BoxData[ \(NumberQ[3 + 2 \[ImaginaryI]]\)], "Input"], Cell[BoxData[{ \(Clear[x]\), "\[IndentingNewLine]", \(NumberQ[x + 2]\)}], "Input"], Cell[BoxData[ \(NumberQ[4 + \[Pi]]\)], "Input"], Cell[TextData[{ "Oops, that last result was unexpected. This is because the head of \[Pi] \ is ", StyleBox["Symbol", FontFamily->"Courier"], ". If you want to allow mathematical constants, then you have to use ", StyleBox["NumericQ", FontFamily->"Courier"], " instead of ", StyleBox["NumberQ", FontFamily->"Courier"], "." }], "Text"], Cell[BoxData[ \(NumericQ[4 + \[Pi]]\)], "Input"], Cell["\<\ This is how you use logical functions to restrict function \ arguments.\ \>", "Text"], Cell[BoxData[ \(distance[x_?NumericQ, y_?NumericQ] := Abs[x - y]\)], "Input"], Cell[BoxData[ \(distance[4, 2 + \[Pi]]\)], "Input"], Cell[BoxData[{ \(Clear[x]\), "\[IndentingNewLine]", \(distance[x, 4]\)}], "Input"], Cell["\<\ Here is a homemade logical function to test for numbers that are \ too large.\ \>", "Text"], Cell[BoxData[{ \(Clear[notTooBig]\), "\[IndentingNewLine]", \(notTooBig[x_] := x \[LessEqual] 100\)}], "Input"], Cell[BoxData[{ \(Clear[factorial]\), "\[IndentingNewLine]", \(factorial[n_?notTooBig] := \(n!\)\)}], "Input"], Cell[BoxData[ \(factorial[12]\)], "Input"], Cell[BoxData[ \(factorial[10000]\)], "Input"], Cell[TextData[{ StyleBox["Exercise 11.2:", FontWeight->"Bold", FontColor->RGBColor[0, 0.500008, 0.250004]], " Define the ", ButtonBox["Weierstrass function", ButtonData:>{ URL[ "http://mathworld.wolfram.com/WeierstrassFunction.html"], None}, ButtonStyle->"Hyperlink"], " for rational arguments and plot the function for 0 < ", StyleBox["x", FontSlant->"Italic"], " < 1. You cannot just use ", StyleBox["Plot", FontFamily->"Courier"], " to graph this function, because you have only defined its values for \ rational arguments. You must first create a list of ordered pairs, (", StyleBox["x", FontSlant->"Italic"], ", ", StyleBox["y", FontSlant->"Italic"], ") values at rational values of ", StyleBox["x", FontSlant->"Italic"], " for 0 < ", StyleBox["x", FontSlant->"Italic"], " <", " 1. Then use ", StyleBox["ListPlot", FontFamily->"Courier"], " to plot these points. Display a curve instead of just the data points by \ using the ", StyleBox["PlotJoined", FontFamily->"Courier"], " option." }], "Text", Background->GrayLevel[0.750011]] }, Closed]], Cell[CellGroupData[{ Cell["Multi-line functions", "Section"], Cell[TextData[{ "If a function requires more than one line of code, then you must enclose \ it in a ", StyleBox["Module", FontFamily->"Courier"], " command. The first argument to Module is a list of local varialble \ names \[LongDash] variables whose definitions should be confined to the \ internal scope of the function. The second argument is a list of commands \ separated by semicolons. The output of the function is the output of the \ last command within the function." }], "Text"], Cell["\<\ Here is a function to calculate the sample standard deviation, \ mimicking the built-in StandardDeviation function.\ \>", "Text"], Cell[BoxData[{ \(Clear[standardDeviation]\), "\[IndentingNewLine]", \(standardDeviation[data_List] := Module[\[IndentingNewLine]{n, mean}, \[IndentingNewLine]n = Length[data]; \[IndentingNewLine]mean = Mean[data]; \[IndentingNewLine]\@\(\(\[Sum]\+\(i = \ 1\)\%n\((data\_\(\(\[LeftDoubleBracket]\)\(i\)\(\[RightDoubleBracket]\)\) - \ mean)\)\^2\)\/\(n - 1\)\)\[IndentingNewLine]]\)}], "Input"], Cell["and here it is in action.", "Text"], Cell[BoxData[ \(standardDeviation[{3, 1, 6, 3}]\)], "Input"], Cell[TextData[{ "Notice the following in our example:\n1) ", StyleBox["Module", FontFamily->"Courier"], " has two arguments. The first argument is a list of local variables, ", StyleBox["{n, mean}", FontFamily->"Courier"], ". \n2) The list of local variables is followed by a comma, which \ separates ", StyleBox["Module", FontFamily->"Courier"], "'s two arguments.\n3) The second argument to ", StyleBox["Module", FontFamily->"Courier"], " is a list of commands, separated by semicolons.\n4) The output of the \ function is the output of it's last command. The last command does not have \ a semicolon after it. If it were followed by a semicolon, then it would not \ have any output. Then the function would go through all of that work, but \ would not return anything to us. ", StyleBox["\[SadSmiley]", FontSize->18] }], "Text"] }, Closed]], Cell[CellGroupData[{ Cell["Control structures", "Section"], Cell[TextData[{ StyleBox["Mathematica", FontSlant->"Italic"], " has control structures, ", StyleBox["If", FontFamily->"Courier"], ", ", StyleBox["Do", FontFamily->"Courier"], ", ", StyleBox["For", FontFamily->"Courier"], ", ", StyleBox["While", FontFamily->"Courier"], ", ", StyleBox["Which", FontFamily->"Courier"], ", ", StyleBox["Switch", FontFamily->"Courier"], ", and a variety of other less-used commands to control the order in which \ a function's commands are evaluated. Most of these commands exist in other \ programming languages, too, such as C++, Java, Perl, and PHP. Let's look at \ these one at a time. You might want to look up these commands in the Help \ Browser for additional information and examples. The ", StyleBox["Mathematica", FontSlant->"Italic"], " Book, Chapter 1.7 Functions and Programming, gives an introduction to \ programming." }], "Text"], Cell[CellGroupData[{ Cell["If", "Subsection"], Cell[TextData[{ "The syntax for ", StyleBox["Mathematica", FontSlant->"Italic"], "'s If statement is\n\n\t", StyleBox["If[", FontFamily->"Courier"], StyleBox["condition", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[", ", FontFamily->"Courier"], StyleBox["trueStatement", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[", ", FontFamily->"Courier"], StyleBox["falseStatement", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[", ", FontFamily->"Courier"], StyleBox["unknownStatement", FontFamily->"Courier", FontSlant->"Italic"], StyleBox["]", FontFamily->"Courier"], "\n\nThe third and fourth arguements are optional. ", StyleBox["Mathematica", FontSlant->"Italic"], " evaluates ", StyleBox["condition", FontSlant->"Italic"], ". If ", StyleBox["condition", FontSlant->"Italic"], " is true, then ", StyleBox["Mathematica", FontSlant->"Italic"], " evaluates ", StyleBox["trueStatement", FontSlant->"Italic"], ". If ", StyleBox["condition", FontSlant->"Italic"], " is false, then ", StyleBox["Mathematica", FontSlant->"Italic"], " evaluates ", StyleBox["falseStatement", FontSlant->"Italic"], ", unless ", StyleBox["falseStatement", FontSlant->"Italic"], " is missing in which case ", StyleBox["Mathematica", FontSlant->"Italic"], " will return ", StyleBox["Null", FontFamily->"Courier"], ". If ", StyleBox["Mathematica", FontSlant->"Italic"], " cannot determine whether or not ", StyleBox["condition", FontSlant->"Italic"], " is true or false, it will evaluate ", StyleBox["unknownStatement.", FontSlant->"Italic"], " Any of these statements can be compound statements \[LongDash] \ statements separated by semicolons. Often the ", StyleBox["trueStatement", FontSlant->"Italic"], " is called the \"then clause\" and ", StyleBox["falseStatement", FontSlant->"Italic"], " is called the \"else clause\", because if statements are often read as \ \"if ", StyleBox["condition", FontSlant->"Italic"], ", then ", StyleBox["trueStatement", FontSlant->"Italic"], ", else ", StyleBox["falseStatement", FontSlant->"Italic"], "." }], "Text"], Cell[TextData[{ "Here is a simple example. If ", StyleBox["x", FontSlant->"Italic"], " has the value 7, then the command returns ", StyleBox["a", FontSlant->"Italic"], "." }], "Text"], Cell[BoxData[{ \(Clear[a, b]\), "\[IndentingNewLine]", \(\(x = 7;\)\), "\[IndentingNewLine]", \(If[x \[Equal] 7, a, b]\)}], "Input"], Cell[TextData[{ "If ", StyleBox["x", FontSlant->"Italic"], " does some value other than 7, then the command returns ", StyleBox["b", FontSlant->"Italic"], "." }], "Text"], Cell[BoxData[{ \(Clear[a, b]\), "\[IndentingNewLine]", \(\(x = 9;\)\), "\[IndentingNewLine]", \(If[x \[Equal] 7, a, b]\)}], "Input"], Cell[TextData[{ "In the next version, if ", StyleBox["Mathematica", FontSlant->"Italic"], " cannot determine whether or not ", StyleBox["x", FontSlant->"Italic"], " is 7, then the command returns ", StyleBox["c", FontSlant->"Italic"], "." }], "Text"], Cell[BoxData[{ \(Clear[a, b, c, x]\), "\[IndentingNewLine]", \(If[x \[Equal] 7, a, b, c]\)}], "Input"], Cell[TextData[{ "In the next example we calculate a factorial for non-negative integer \ values of ", StyleBox["n", FontSlant->"Italic"], " and we calculate its generalization, the gamma function, for all other \ values. The else clause is a compound statement, consisting of ", StyleBox["Print", FontFamily->"Courier"], " and ", StyleBox["Gamma", FontFamily->"Courier"], ", separated by a semicolon. Notice that the \"then\" clause and the \ \"else\" clause are on new lines for better readability. As ", StyleBox["Mathematica", FontSlant->"Italic"], " reads an input cell, it will continue a command onto the next line, if it \ sees that the command on the present line is incomplete." }], "Text"], Cell[BoxData[{ \(\(n = 5;\)\), "\[IndentingNewLine]", \(If[IntegerQ[n]\ && \ n \[GreaterEqual] 0, \[IndentingNewLine]\(n!\), \[IndentingNewLine]Print["\"]; \[IndentingNewLine]Gamma[ n + 1]\[IndentingNewLine]]\)}], "Input"], Cell[BoxData[{ \(\(n = 5.01;\)\), "\[IndentingNewLine]", \(If[IntegerQ[n]\ && \ n \[GreaterEqual] 0, \[IndentingNewLine]\(n!\), \[IndentingNewLine]Print["\"]; \[IndentingNewLine]Gamma[ n + 1]\[IndentingNewLine]]\)}], "Input"], Cell[TextData[{ "If we create a function from this, we need to use ", StyleBox[":=", FontFamily->"Courier"], " instead of =, since we don't want ", StyleBox["Mathematica", FontSlant->"Italic"], " to evaluate the ", StyleBox["If", FontFamily->"Courier"], " statement until we supply a value for ", StyleBox["n", FontSlant->"Italic"], "." }], "Text"], Cell[BoxData[ \(generalizedFactorial[n_] := \[IndentingNewLine]If[ IntegerQ[n]\ && \ n \[GreaterEqual] 0, \[IndentingNewLine]\(n!\), \[IndentingNewLine]Print["\"]; \[IndentingNewLine]Gamma[ n + 1]\[IndentingNewLine]]\)], "Input"], Cell[BoxData[ \(generalizedFactorial[5]\)], "Input"], Cell[BoxData[ \(generalizedFactorial[4.99]\)], "Input"], Cell[TextData[{ StyleBox["Exercise 11.3:", FontWeight->"Bold", FontColor->RGBColor[0, 0.500008, 0.250004]], " Create the piecewise-defined function, ", StyleBox["f", FontSlant->"Italic"], "(", StyleBox["t", FontSlant->"Italic"], ") = ", Cell[BoxData[ FormBox[ TagBox[ StyleBox[ RowBox[{"{", StyleBox[GridBox[{ {\(sin(2 t), \ t < 5\)}, {\(sin(10 t), \ t \[GreaterEqual] 5\)} }], ShowAutoStyles->True]}], ShowAutoStyles->False], (#&)], TraditionalForm]]], " and graph it for 0 \[LessEqual] ", StyleBox["t", FontSlant->"Italic"], " \[LessEqual] 10." }], "Text", Background->GrayLevel[0.750011]] }, Closed]], Cell[CellGroupData[{ Cell["Do", "Subsection"], Cell[TextData[{ "The ", StyleBox["Do", FontFamily->"Courier"], " statement allows you to evaluate an expression repeatedly. It is \ equivalent to the do loop in the Fortran and Basic programming languages. \ The syntax for ", StyleBox["Mathematica", FontSlant->"Italic"], "'s Do statement can take any of the following forms\n\n\t", StyleBox["Do[", FontFamily->"Courier"], StyleBox["expression", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[", {", FontFamily->"Courier"], StyleBox["imax", FontFamily->"Courier", FontSlant->"Italic"], StyleBox["}]\n", FontFamily->"Courier"], "\t", StyleBox["Do[", FontFamily->"Courier"], StyleBox["expression", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[", {", FontFamily->"Courier"], StyleBox["i, imax", FontFamily->"Courier", FontSlant->"Italic"], StyleBox["}]\n", FontFamily->"Courier"], "\t", StyleBox["Do[", FontFamily->"Courier"], StyleBox["expression", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[", {", FontFamily->"Courier"], StyleBox["i, imin", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[", ", FontFamily->"Courier"], StyleBox["imax", FontFamily->"Courier", FontSlant->"Italic"], StyleBox["}]\n", FontFamily->"Courier"], "\t", StyleBox["Do[", FontFamily->"Courier"], StyleBox["expression", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[", {", FontFamily->"Courier"], StyleBox["i, imin", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[", ", FontFamily->"Courier"], StyleBox["imax", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[", ", FontFamily->"Courier"], StyleBox["di", FontFamily->"Courier", FontSlant->"Italic"], StyleBox["}]\n", FontFamily->"Courier"], "\t", StyleBox["Do[", FontFamily->"Courier"], StyleBox["expression", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[", {", FontFamily->"Courier"], StyleBox["i, imin", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[", ", FontFamily->"Courier"], StyleBox["imax", FontFamily->"Courier", FontSlant->"Italic"], StyleBox["}, {", FontFamily->"Courier"], StyleBox["j, jmin", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[", ", FontFamily->"Courier"], StyleBox["jmax", FontFamily->"Courier", FontSlant->"Italic"], StyleBox["}]\n\n", FontFamily->"Courier"], "{", StyleBox["imax", FontFamily->"Courier"], "} \[LongDash] ", StyleBox["Do", FontFamily->"Courier"], " evaluates ", StyleBox["expression", FontSlant->"Italic"], " ", StyleBox["imax", FontFamily->"Courier"], " times.\n{", StyleBox["i", FontFamily->"Courier"], ", ", StyleBox["imax", FontFamily->"Courier"], "} \[LongDash] ", StyleBox["Do", FontFamily->"Courier"], " evaluates ", StyleBox["expression", FontSlant->"Italic"], " ", StyleBox["imax", FontFamily->"Courier"], " times as ", StyleBox["i", FontFamily->"Courier"], " goes from 1 to ", StyleBox["imax", FontFamily->"Courier"], " in increments of 1.\n{", StyleBox["i", FontFamily->"Courier"], ", ", StyleBox["imin", FontFamily->"Courier"], ", ", StyleBox["imax", FontFamily->"Courier"], "} \[LongDash] ", StyleBox["Do", FontFamily->"Courier"], " evaluates ", StyleBox["expression", FontSlant->"Italic"], " as ", StyleBox["i", FontFamily->"Courier"], " goes from ", StyleBox["imin", FontFamily->"Courier"], " to ", StyleBox["imax", FontFamily->"Courier"], " in increments of 1.\n{", StyleBox["i", FontFamily->"Courier"], ", ", StyleBox["imin", FontFamily->"Courier"], ", ", StyleBox["imax", FontFamily->"Courier"], ", ", StyleBox["di", FontFamily->"Courier"], "} \[LongDash] ", StyleBox["Do", FontFamily->"Courier"], " evaluates ", StyleBox["expression", FontSlant->"Italic"], " as ", StyleBox["i", FontFamily->"Courier"], " goes from ", StyleBox["imin", FontFamily->"Courier"], " to ", StyleBox["imax", FontFamily->"Courier"], " in increments of ", StyleBox["di", FontFamily->"Courier"], ". ", StyleBox["di", FontFamily->"Courier"], " can be a negative number.\n{", StyleBox["i", FontFamily->"Courier"], ", ", StyleBox["imin", FontFamily->"Courier"], ", imax}, {", StyleBox["j", FontFamily->"Courier"], ", ", StyleBox["jmin", FontFamily->"Courier"], ", ", StyleBox["jmax", FontFamily->"Courier"], "} \[LongDash] ", StyleBox["Do", FontFamily->"Courier"], " evaluates ", StyleBox["expression", FontSlant->"Italic"], " as ", StyleBox["j", FontFamily->"Courier"], " goes from ", StyleBox["jmin", FontFamily->"Courier"], " to ", StyleBox["jmax", FontFamily->"Courier"], ", for each value of ", StyleBox["i", FontFamily->"Courier"], ".\n\n", StyleBox["Do", FontFamily->"Courier"], " is similar to ", StyleBox["Table", FontFamily->"Courier"], ", except that ", StyleBox["Table", FontFamily->"Courier"], " creates a list by evaluating ", StyleBox["expression", FontSlant->"Italic"], "." }], "Text"], Cell[TextData[{ "Here is the sum of integers from 1 to 100. We initialize ", StyleBox["sum", FontFamily->"Courier"], " to 0. Each time through the ", StyleBox["Do", FontFamily->"Courier"], " loop, the ", StyleBox["Do", FontFamily->"Courier"], " statement increments ", StyleBox["i", FontFamily->"Courier"], " and then we add this integer to ", StyleBox["sum", FontFamily->"Courier"], ". The last line in the example is included just to display the value of \ sum." }], "Text"], Cell[BoxData[{ \(\(sum = 0;\)\), "\[IndentingNewLine]", \(\(Do[sum = sum + i, {i, 100}];\)\), "\[IndentingNewLine]", \(sum\)}], "Input"], Cell["We can put this into a function.", "Text"], Cell[BoxData[{ \(Clear[integerSum]\), "\[IndentingNewLine]", \(integerSum[ n_Integer /; n \[GreaterEqual] 0] := \[IndentingNewLine]Module[{sum, i}, \[IndentingNewLine]sum = 0; \[IndentingNewLine]Do[ sum = sum + i, {i, n}]; \[IndentingNewLine]sum\[IndentingNewLine]]\)}], "Input"], Cell["Our new function works for non-negative integer arguments.", "Text"], Cell[BoxData[ \(integerSum[100]\)], "Input"], Cell[BoxData[ \(integerSum[0]\)], "Input"], Cell["but not for other arguments.", "Text"], Cell[BoxData[ \(integerSum[\(-10\)]\)], "Input"], Cell[BoxData[ \(integerSum[4.8]\)], "Input"], Cell[TextData[{ "How would you use a ", StyleBox["Do", FontFamily->"Courier"], " loop to calculate a factorial?" }], "Text"] }, Closed]], Cell[CellGroupData[{ Cell["For", "Subsection"], Cell[TextData[{ StyleBox["Mathematica", FontSlant->"Italic"], "'s For statement is similar to the ", StyleBox["Do", FontFamily->"Courier"], " statement, but it is more flexible. ", StyleBox["Do", FontFamily->"Courier"], " loops iterate a predetemrined number of times, but ", StyleBox["For", FontFamily->"Courier"], " loops can also iterate until some dynamically determined condition is \ met.\n\n\t", StyleBox["For[", FontFamily->"Courier"], StyleBox["start", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[", ", FontFamily->"Courier"], StyleBox["test", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[",", FontFamily->"Courier"], StyleBox[" increment, body", FontFamily->"Courier", FontSlant->"Italic"], StyleBox["]\n\n", FontFamily->"Courier"], StyleBox["Mathematica", FontFamily->"Times New Roman", FontSlant->"Italic"], StyleBox[" executes ", FontFamily->"Times New Roman"], StyleBox["start", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[", then repeatedly evaulates ", FontFamily->"Times New Roman"], StyleBox["body", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[" followed by ", FontFamily->"Times New Roman"], StyleBox["increment", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[" until ", FontFamily->"Times New Roman"], StyleBox["test", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[" is no longer ", FontFamily->"Times New Roman"], StyleBox["True.", FontFamily->"Courier"], StyleBox[" The ", FontFamily->"Times New Roman"], StyleBox["test", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[" is performed before the ", FontFamily->"Times New Roman"], StyleBox["body", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[" of the loop is evalauated. If you are already familiar with C, \ Java, Perl or almost any other language that implements a for loop, the most \ confusing aspect of ", FontFamily->"Times New Roman"], StyleBox["Mathematica", FontFamily->"Times New Roman", FontSlant->"Italic"], StyleBox["'s For loop is that the comma and semicolon's roles are reversed. \ In ", FontFamily->"Times New Roman"], StyleBox["Mathematica", FontFamily->"Times New Roman", FontSlant->"Italic"], StyleBox[", commas separate the four parts of the For loop and semicolons \ separate the parts of compound statements within each part. This is \ consistent with ", FontFamily->"Times New Roman"], StyleBox["Mathematica", FontFamily->"Times New Roman", FontSlant->"Italic"], StyleBox["'s syntax for other commands, but contrary to most other \ programming languages.", FontFamily->"Times New Roman"] }], "Text"], Cell[TextData[{ "Here is an example of a ", StyleBox["For", FontFamily->"Courier"], " loop that acts just like a ", StyleBox["Do", FontFamily->"Courier"], " loop. The statement, ", StyleBox["i++", FontFamily->"Courier"], ", means to increment ", StyleBox["i", FontFamily->"Courier"], " by 1." }], "Text"], Cell[BoxData[ \(For[i = 1, i \[LessEqual] 10, \(i++\), Print[i\^2]]\)], "Input"], Cell[TextData[{ "If you are a C programmer, then you might want to use ", StyleBox["Mathematica", FontSlant->"Italic"], "'s ", StyleBox["For", FontFamily->"Courier"], " loop, since you are already familiar with this structure. However, For \ loops are not necessary in ", StyleBox["Mathematica", FontSlant->"Italic"], ". You can write any ", StyleBox["For", FontFamily->"Courier"], " loop as a ", StyleBox["While", FontFamily->"Courier"], " loop, which we will examine next." }], "Text"] }, Closed]], Cell[CellGroupData[{ Cell["While", "Subsection"], Cell[TextData[{ "The While statement tests a condition at the beginning of each iteration. \ If the condition is ", StyleBox["False", FontFamily->"Courier"], ", ", StyleBox["Mathematica", FontSlant->"Italic"], " exits the loop. The syntax is\n\n\t", StyleBox["While[", FontFamily->"Courier"], StyleBox["test", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[",", FontFamily->"Courier"], StyleBox[" body", FontFamily->"Courier", FontSlant->"Italic"], StyleBox["]\n\n", FontFamily->"Courier"], StyleBox["The following are equivalent", FontFamily->"Times New Roman"], StyleBox["\n", FontFamily->"Courier"], "\n\t", StyleBox["For[", FontFamily->"Courier"], StyleBox["start", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[", ", FontFamily->"Courier"], StyleBox["test", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[",", FontFamily->"Courier"], StyleBox[" increment, body", FontFamily->"Courier", FontSlant->"Italic"], StyleBox["]\n", FontFamily->"Courier"], "\t", StyleBox["start", FontFamily->"Courier", FontSlant->"Italic"], "; ", StyleBox["While[", FontFamily->"Courier"], StyleBox["test", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[",", FontFamily->"Courier"], StyleBox[" body", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[";", FontFamily->"Courier"], StyleBox[" increment", FontFamily->"Courier", FontSlant->"Italic"], StyleBox["]\n", FontFamily->"Courier"] }], "Text"], Cell[TextData[{ "Let's find the largest prime number less than or equal to a given number. \ We begin by picking a number. Here I chose ", StyleBox["n ", FontFamily->"Courier"], "= 27. We will find the largest prime less than or equal to this number. \ We initially set ", StyleBox["largestPrime", FontFamily->"Courier"], " to ", StyleBox["n", FontFamily->"Courier"], ". We want to repeatedly decrease ", StyleBox["largestPrime", FontFamily->"Courier"], " by 1 and test it each time to see if the new number is a prime. We will \ continue this while ", StyleBox["largestPrime", FontFamily->"Courier"], " is not a prime number. We cannot implement this with a ", StyleBox["Do", FontFamily->"Courier"], " loop because we don't know the number of iterations in advance. We could \ use a ", StyleBox["For", FontFamily->"Courier"], " loop or a ", StyleBox["While", FontFamily->"Courier"], " loop. Our While loop implementation below uses the test,", StyleBox[" ", FontFamily->"Courier"], StyleBox["!PrimeQ[largestPrime", FontFamily->"Courier"], StyleBox["]", FontFamily->"Courier"], ". ", StyleBox["PrimeQ[largestPrime", FontFamily->"Courier"], StyleBox["]", FontFamily->"Courier"], " returns ", StyleBox["True", FontFamily->"Courier"], " if ", StyleBox["largestPrime", FontFamily->"Courier"], " is a prime number. The exclamation mark preceeding it negates the \ result; that is, it returns ", StyleBox["True", FontFamily->"Courier"], " if ", StyleBox["largestPrime", FontFamily->"Courier"], " ", "is ", StyleBox["not", FontSlant->"Italic"], " a prime number." }], "Text"], Cell[BoxData[{\(n = 27;\), "\[IndentingNewLine]", RowBox[{ RowBox[{ StyleBox["largestPrime", FontFamily->"Courier"], "=", "n"}], ";"}], "\[IndentingNewLine]", RowBox[{"While", "[", RowBox[{ RowBox[{"!", RowBox[{"PrimeQ", "[", StyleBox["largestPrime", FontFamily->"Courier"], "]"}]}], ",", "\[IndentingNewLine]", RowBox[{ StyleBox["largestPrime", FontFamily->"Courier"], "--"}]}], "\[IndentingNewLine]", "]"}], "\[IndentingNewLine]", StyleBox["largestPrime", FontFamily->"Courier"]}], "Input"], Cell[TextData[{ "We can encapsulate this into a function. Again, we have to use ", StyleBox[":=", FontFamily->"Courier"], " instead of = to define the function, so that the ", StyleBox["While", FontFamily->"Courier"], " loop is not evaluated until we use the function with a particular value \ of ", StyleBox["n", FontSlant->"Italic"], ". " }], "Text"], Cell[BoxData[{ \(Clear[largestPrime]\), "\[IndentingNewLine]", \(largestPrime[ n_Integer /; n > 1] := \[IndentingNewLine]Module[{prime = n}, \[IndentingNewLine]While[\(! PrimeQ[ prime]\), \ \[IndentingNewLine]\(\(prime--\);\)\[IndentingNewLine]]; \ \[IndentingNewLine]prime\[IndentingNewLine]]\)}], "Input"], Cell[BoxData[ \(largestPrime[36]\)], "Input"], Cell[TextData[{ "There are several minor items to note in the function above.\n\n1) The \ local variable, ", StyleBox["prime", FontFamily->"Courier"], ", replaces the variable ", StyleBox["largestPrime", FontFamily->"Courier"], " in the non-function version of our solution, so that it is not confused \ with the function name, ", StyleBox["largestPrime", FontFamily->"Courier"], ".\n2) We had to insert a semicolon at the end of the ", StyleBox["While", FontFamily->"Courier"], " statement, on line 6 of the above ", StyleBox["Input", FontFamily->"Courier"], " cell. Otherwise, ", StyleBox["Mathematica", FontSlant->"Italic"], " would have interpreted the carriage return like it would a space; that \ is, it would interpret it as a multiplication. So, it would have multiplied \ the result of the ", StyleBox["While", FontFamily->"Courier"], " loop by the value of prime in line 7. So, you always have to end your \ statements within functions with a semicolon, except for the last statement.\n\ 3) The value of ", StyleBox["prime", FontFamily->"Courier"], " is initialized within the first argument of ", StyleBox["Module", FontFamily->"Courier"], ", where it is declared to be a local variable. This saves a line in the \ program. Otherwise, we would have had to include another line in our \ function definition, as shown below." }], "Text"], Cell[BoxData[{ \(Clear[largestPrime]\), "\[IndentingNewLine]", \(largestPrime[ n_] := \[IndentingNewLine]Module[{prime}, \[IndentingNewLine]prime = n; \[IndentingNewLine]While[\(! PrimeQ[ prime]\), \ \[IndentingNewLine]\(\(prime--\);\)\[IndentingNewLine]]; \ \[IndentingNewLine]prime\[IndentingNewLine]]\)}], "Input"], Cell[TextData[{ StyleBox["Exercise 11.4:", FontWeight->"Bold", FontColor->RGBColor[0, 0.500008, 0.250004]], " Use ", StyleBox["Do", FontFamily->"Courier"], ", ", StyleBox["For", FontFamily->"Courier"], ", or ", StyleBox["While", FontFamily->"Courier"], " to implement Newton's method for finding the root of an equation. Print \ out the value of ", StyleBox["x", FontSlant->"Italic"], " at each iteration.", " Test your implementation with the function ", StyleBox["f", FontSlant->"Italic"], "(", StyleBox["x", FontSlant->"Italic"], ") = ", Cell[BoxData[ \(TraditionalForm\`\[ExponentialE]\^x - 4 x\)]], " with an initial guess of 1. Check your answer by using one of ", StyleBox["Mathematica", FontSlant->"Italic"], "'s built-in root-finding commands." }], "Text", Background->GrayLevel[0.750011]] }, Closed]], Cell[CellGroupData[{ Cell["Which", "Subsection"], Cell[TextData[{ "The ", StyleBox["Which", FontFamily->"Courier"], " statement is like an ", StyleBox["If", FontFamily->"Courier"], " statement on steroids. It allows you to test many conditions until you \ find one that is true, and then evaluate an expression. It is the same as a \ case statement in many other programming languages. The syntax is\n\n\t", StyleBox["Which[", FontFamily->"Courier"], Cell[BoxData[ \(TraditionalForm\`test\_1\)]], StyleBox[",", FontFamily->"Courier"], StyleBox[" ", FontFamily->"Courier", FontSlant->"Italic"], Cell[BoxData[ \(TraditionalForm\`expression\_1\)]], StyleBox[", ", FontFamily->"Courier"], Cell[BoxData[ \(TraditionalForm\`test\_2\)]], StyleBox[",", FontFamily->"Courier"], StyleBox[" ", FontFamily->"Courier", FontSlant->"Italic"], Cell[BoxData[ \(TraditionalForm\`expression\_2\)]], StyleBox[", ", FontFamily->"Courier"], StyleBox["...", FontFamily->"Courier", FontSlant->"Italic"], StyleBox[", ", FontFamily->"Courier"], Cell[BoxData[ \(TraditionalForm\`test\_n\)]], StyleBox[",", FontFamily->"Courier"], StyleBox[" ", FontFamily->"Courier", FontSlant->"Italic"], Cell[BoxData[ \(TraditionalForm\`expression\_n\)]], StyleBox["]\n\n", FontFamily->"Courier"], StyleBox["Which evaluates each of the tests until it finds one, ", FontFamily->"Times New Roman"], Cell[BoxData[ \(TraditionalForm\`test\_i\)]], ", that is true. Then it returns the value of ", Cell[BoxData[ \(TraditionalForm\`expression\_i\)]], ". If none of the tests are true, then ", StyleBox["Which", FontFamily->"Courier"], " returns ", StyleBox["Null", FontFamily->"Courier"], "." }], "Text"], Cell[TextData[{ "The ", StyleBox["Which", FontFamily->"Courier"], " command can be used to implement the bisection method for finding roots \ of equations. Suppose that you want to find a root of a continuous function, \ ", StyleBox["y", FontSlant->"Italic"], " = ", StyleBox["f", FontSlant->"Italic"], " (", StyleBox["x", FontSlant->"Italic"], "). If you know that ", StyleBox["f(a", FontSlant->"Italic"], ") and ", StyleBox["f", FontSlant->"Italic"], "(", StyleBox["b", FontSlant->"Italic"], ") have different signs (one positive and the other negative), then by the \ Intermediate Value Theorem, there must be a value of ", StyleBox["x", FontSlant->"Italic"], " between ", StyleBox["a", FontSlant->"Italic"], " and ", StyleBox["b", FontSlant->"Italic"], " at which ", StyleBox["f", FontSlant->"Italic"], "(", StyleBox["x", FontSlant->"Italic"], ") = 0. The easiest way to check this is to see if ", StyleBox["f", FontSlant->"Italic"], "(", StyleBox["a", FontSlant->"Italic"], ") ", StyleBox["f", FontSlant->"Italic"], "(", StyleBox["b", FontSlant->"Italic"], ") < 0. With the bisection method, you divide the interval [", StyleBox["a", FontSlant->"Italic"], ", ", StyleBox["b", FontSlant->"Italic"], "] in half, at ", StyleBox["c", FontSlant->"Italic"], " = ", Cell[BoxData[ \(TraditionalForm\`\(a + b\)\/2\)]], ". Then you check to see which interval, [", StyleBox["a", FontSlant->"Italic"], ", ", StyleBox["c", FontSlant->"Italic"], "] or [", StyleBox["c", FontSlant->"Italic"], ", ", StyleBox["b", FontSlant->"Italic"], "] has a change in sign of ", StyleBox["f", FontSlant->"Italic"], ". You repeatedly divide the root-bracketing interval in half until you \ reach the desired level of accuracy. Here is a ", StyleBox["Mathematica", FontSlant->"Italic"], " implementation of the bisection method. Comments are enclosed in ", StyleBox["(*", FontFamily->"Courier"], " ", StyleBox["*)", FontFamily->"Courier"], "." }], "Text"], Cell[BoxData[{ \(Clear[bisectionRoot]\), "\[IndentingNewLine]", \(\(bisectionRoot::"\" = "\";\)\), "\[IndentingNewLine]", \(bisectionRoot[f_, aa_?NumericQ, bb_?NumericQ, errorTolerance_?NumericQ /; errorTolerance > 0] := \[IndentingNewLine]Module[{a = N[aa], b = N[bb], c}, \[IndentingNewLine]If[f[a] \[Equal] 0, Return[a]]; \ \ (*\ root\ is\ at\ x\ = \ a\ *) \[IndentingNewLine]If[ f[b] \[Equal] 0, \ Return[b]]; \ (*\ root\ is\ at\ x\ = \ b\ *) \[IndentingNewLine]If[ f[a]\ f[b] > 0, \ \ (*\ root\ is\ not\ bracketed . \ \ Display\ an\ error\ messsage\ and\ \ \(\(quit\)\(.\)\)\ *) \[IndentingNewLine]Message[ bisectionRoot::"\", aa, bb]; \[IndentingNewLine]Return[];\[IndentingNewLine]]; \ \[IndentingNewLine]While[ Abs[b - a] > errorTolerance\ , \[IndentingNewLine]c = \(a + b\)\/2; \ \[IndentingNewLine]Which[\[IndentingNewLine]f[a]\ f[c] < 0, \ b = c, \[IndentingNewLine]f[c]\ f[b] < 0, a = c, \[IndentingNewLine]f[c] \[Equal] 0, Return[c]\[IndentingNewLine]]\[IndentingNewLine]]; \ \[IndentingNewLine]Return[c]\[IndentingNewLine]]\)}], "Input"], Cell["Let's take it for a test ride.", "Text"], Cell[BoxData[{ \(Clear[f]\), "\[IndentingNewLine]", \(\(f[x_] = x\^2 - 10;\)\), "\[IndentingNewLine]", \(root = bisectionRoot[f, 3, 4, 10\^\(-6\)]\)}], "Input"], Cell[TextData[{ "We need to confirm that this is an approximation to a root of ", StyleBox["f", FontSlant->"Italic"], "." }], "Text"], Cell[BoxData[ \(f[root]\)], "Input"], Cell[TextData[{ "Excellent. Now let's see if it handles special issues. First, let's make \ sure that it works when ", StyleBox["a", FontSlant->"Italic"], " > ", StyleBox["b", FontSlant->"Italic"], "." }], "Text"], Cell[BoxData[ \(root = bisectionRoot[f, 4, 3, 10\^\(-6\)]\)], "Input"], Cell[TextData[{ "Now let's see if it works when either ", StyleBox["a", FontSlant->"Italic"], " or ", StyleBox["b", FontSlant->"Italic"], " is a root." }], "Text"], Cell[BoxData[{ \(Clear[f]\), "\[IndentingNewLine]", \(\(f[x_] = x - 4;\)\), "\[IndentingNewLine]", \(root = bisectionRoot[f, 2, 4, 10\^\(-6\)]\)}], "Input"], Cell[BoxData[ \(root = bisectionRoot[f, 4, 8, 10\^\(-6\)]\)], "Input"], Cell["Let's see if our function works when the midpoint is a root.", "Text"], Cell[BoxData[ \(root = bisectionRoot[f, 1, 7, 10\^\(-6\)]\)], "Input"], Cell["\<\ And finally, does it give an error message when our initial \ interval does not bracket a root?\ \>", "Text"], Cell[BoxData[ \(root = bisectionRoot[f, 5, 8, 10\^\(-6\)]\)], "Input"], Cell["Works like a charm!", "Text"], Cell[TextData[{ StyleBox["Exercise 11.5:", FontWeight->"Bold", FontColor->RGBColor[0, 0.500008, 0.250004]], " Write a function that uses ", StyleBox["Which", FontFamily->"Courier"], " and/or ", StyleBox["If", FontFamily->"Courier"], " to return two people's names in alphabetical order. The two people's \ names should be the two arguments to the function. Each name should be a \ list of first name and last name. The function should return a list of the \ two names in alphabetical order. For example,\n\n\t\ alphabeticalNames[{\"George\", \"Washington\"},{\"John\" Adams\"}]\n\nshould \ return the value\n\n\t{{\"John\", \"Adams\"}, {\"George\", \"Washington\"}}\n\ \nYou can use ", StyleBox["OrderedQ", FontFamily->"Courier"], " or ", StyleBox["Order", FontFamily->"Courier"], " to determine if two strings are in alphabetical order." }], "Text", Background->GrayLevel[0.750011]] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["Default values", "Section"], Cell[TextData[{ "You can give default values to function arguments. Here is an \ implementation of ", StyleBox["Mathematica", FontSlant->"Italic"], "'s ", StyleBox["Norm", FontFamily->"Courier"], " function, used to measure the size of a vector." }], "Text"], Cell[BoxData[{ \(Clear[norm]\), "\[IndentingNewLine]", \(norm[x_List, p_: 2] := \((\[Sum]\+\(k = 1\)\%\(Length[x]\)Abs[x\_\(\(\ \[LeftDoubleBracket]\)\(k\)\(\[RightDoubleBracket]\)\)]\^p)\)\^\(1/p\)\)}], \ "Input"], Cell[TextData[{ "Here we use the default value of ", StyleBox["p", FontSlant->"Italic"], " = 2, which is the standard formula for the length of a vector." }], "Text"], Cell[BoxData[ \(norm[{1, 3, 5}]\)], "Input"], Cell[TextData[{ "And here we override the default value and use ", StyleBox["p", FontSlant->"Italic"], " = 3." }], "Text"], Cell[BoxData[ \(norm[{1, 3, 5}, 3]\)], "Input"], Cell[TextData[{ StyleBox["Exercise 11.6:", FontWeight->"Bold", FontColor->RGBColor[0, 0.500008, 0.250004]], " Modify truncatedMean so that by default, it will display the mean of the \ entire data set." }], "Text", Background->GrayLevel[0.750011]] }, Closed]], Cell[CellGroupData[{ Cell["Options", "Section"], Cell[TextData[{ "In many of ", StyleBox["Mathematica", FontSlant->"Italic"], "'s built in commands, we can use options to modify a command's \ functionality. For example, we have used numerous options with ", StyleBox["Plot", FontFamily->"Courier"], ", such as ", StyleBox["PlotStyle", FontFamily->"Courier"], ", ", StyleBox["DisplayFunction", FontFamily->"Courier"], ", ", StyleBox["PlotRange", FontFamily->"Courier"], ", ", StyleBox["AxesLabel", FontFamily->"Courier"], ", and ", StyleBox["PlotLabel", FontFamily->"Courier"], ". You can include options for your own functions, too." }], "Text"], Cell[TextData[{ "Let's add two options to truncatedMean. One option will calculate the \ geometric mean instead of the more commonly used arithmetic mean. A second \ option will allow us to calculate a weighted mean. Weighted means are only \ applicable to the arithmetic mean, not the geometric mean. So, we should \ display an error message if both options are used. We will call these \ options ", StyleBox["type", FontFamily->"Courier"], " and ", StyleBox["weights", FontFamily->"Courier"], ". Their default values will be ", StyleBox["arithmeticMean", FontFamily->"Courier"], " and ", StyleBox["Automatic", FontFamily->"Courier"], ", respectively. ", StyleBox["Automatic", FontFamily->"Courier"], " is a catch-all default value for many ", StyleBox["Mathematica", FontSlant->"Italic"], " options. We will take it to represent an unweighted mean, or \ equivalently, weights of 1." }], "Text"], Cell[BoxData[{ \(Clear[type, weights, arithmeticMean]\), "\[IndentingNewLine]", \(Options[truncatedMean] = {type \[Rule] arithmeticMean, weights \[Rule] Automatic}\)}], "Input"], Cell["\<\ Here is the truncatedMean function, with the options included. In \ the second line, there are three underscores between opts and Rule.\ \>", \ "Text"], Cell[BoxData[{ \(Clear[truncatedMean]\), "\[IndentingNewLine]", \(truncatedMean[data_List, n_, opts___Rule] := Module[\[IndentingNewLine]{typeOption, weightOption}, \[IndentingNewLine]typeOption = \(type /. {opts}\) /. Options[truncatedMean]; \[IndentingNewLine]weightOption = \ \(weights /. {opts}\) /. Options[truncatedMean]; \[IndentingNewLine]If[ weightOption === Automatic, weightOption = Table[1, {Length[data] - 2 n}]]; \ \[IndentingNewLine]Which[\[IndentingNewLine]typeOption === geometricMean, \[IndentingNewLine]\t Apply[Times, Drop[Drop[Sort[data, Less], \(-n\)], \ n]]\^\(1/\((Length[data] - 2 n)\)\), \[IndentingNewLine]typeOption === arithmeticMean, \[IndentingNewLine]\t weightOption . Drop[Drop[Sort[data, Less], \(-n\)], n]/\(\[Sum]\+\(k = 1\)\%\(Length[data] - 2 n\)weightOption\_\ \(\(\[LeftDoubleBracket]\)\(k\)\(\[RightDoubleBracket]\)\)\)\ \[IndentingNewLine]]\[IndentingNewLine]]\)}], "Input"], Cell["We first test the function with a standard example.", "Text"], Cell[BoxData[{ \(\(data = {3, 4, 1, 12, 5, 3, 8, 15, 21, 17, 2, 25, 16, 8};\)\), "\[IndentingNewLine]", \(truncatedMean[data, 3]\)}], "Input"], Cell["Secondly, let's try the truncated geometric mean.", "Text"], Cell[BoxData[ \(truncatedMean[data, 3, type \[Rule] geometricMean] // N\)], "Input"], Cell["Thirdly, let's calcuate a weighted mean.", "Text"], Cell[BoxData[ \(truncatedMean[data, 3, weights \[Rule] {2, 1, 3, 5, 1, 4, 1, 3}] // N\)], "Input"], Cell[TextData[{ "The option, ", StyleBox["typeOption", FontFamily->"Courier"], ", is assigned a value in the line,", StyleBox[" typeOption = type/.{opts}/.Options[truncatedMean]", FontFamily->"Courier"], ". If the type option is set in the fucntion call, as we did in our third \ test, then typeOption gets this value. Otherwise, ", StyleBox["typeOption", FontFamily->"Courier"], " will get the value specified in ", StyleBox["Options[truncatedMean]", FontFamily->"Courier"], "." }], "Text"], Cell["\<\ Here is the same function, but incorporating some error \ checks.\ \>", "Text"], Cell[BoxData[{ \(Clear[truncatedMean]\), "\[IndentingNewLine]", \(truncatedMean[data_List, n_, opts___Rule] := Module[\[IndentingNewLine]{typeOption, weightOption}, \[IndentingNewLine]truncatedMean::"\" \ = "\"; \ \[IndentingNewLine]truncatedMean::"\" = "\"; \ \[IndentingNewLine]truncatedMean::"\" = "\"; \ \[IndentingNewLine]typeOption = \(type /. {opts}\) /. Options[truncatedMean]; \[IndentingNewLine]weightOption = \ \(weights /. {opts}\) /. Options[truncatedMean]; \[IndentingNewLine]If[ Length[data] < 2 n, \[IndentingNewLine]Message[ truncatedMean::"\", n, data]; \[IndentingNewLine]Return[];\[IndentingNewLine]]; \ \[IndentingNewLine]If[ typeOption === geometricMean\ && weightOption =!= Automatic, \[IndentingNewLine]\(Message[ truncatedMean::"\", weightOption];\)\[IndentingNewLine]]; \[IndentingNewLine]If[ weightOption === Automatic, weightOption = Table[1, {Length[data] - 2 n}]]; \ \[IndentingNewLine]Which[\[IndentingNewLine]typeOption === geometricMean, \[IndentingNewLine]\t Apply[Times, Drop[Drop[Sort[data, Less], \(-n\)], \ n]]\^\(1/\((Length[data] - 2 n)\)\), \[IndentingNewLine]typeOption === arithmeticMean, \[IndentingNewLine]\t weightOption . Drop[Drop[Sort[data, Less], \(-n\)], n]/\((Length[data] - 2 n)\), \[IndentingNewLine]_, \[IndentingNewLine]\t\(Message[ truncatedMean::"\", typeOption];\)\[IndentingNewLine]]\[IndentingNewLine]]\)}], \ "Input"], Cell[TextData[{ StyleBox["Exercise 11.7:", FontWeight->"Bold", FontColor->RGBColor[0, 0.500008, 0.250004]], " Add an option, barChart\[Rule]True, to the function in Exercise 11.1 to \ display a bar chart of the populations of the ", StyleBox["n", FontSlant->"Italic"], " least populous countries." }], "Text", Background->GrayLevel[0.750011]], Cell["\<\ Later, we will see how to bundle a collection of related functions \ and options into a package. We will be able to control which symbols are \ local to the package and which are accessible to the package's users. We \ will also see how to add documentation for your functions and options.\ \>", \ "Text"] }, Closed]] }, Open ]] }, FrontEndVersion->"5.2 for Microsoft Windows", ScreenRectangle->{{0, 1280}, {0, 951}}, WindowSize->{1004, 860}, WindowMargins->{{0, Automatic}, {Automatic, 0}}, StyleDefinitions -> "PastelColor.nb" ] (******************************************************************* Cached data follows. If you edit this Notebook file directly, not using Mathematica, you must remove the line containing CacheID at the top of the file. The cache data will then be recreated when you save this file from within Mathematica. *******************************************************************) (*CellTagsOutline CellTagsIndex->{} *) (*CellTagsIndex CellTagsIndex->{} *) (*NotebookFileOutline Notebook[{ Cell[CellGroupData[{ Cell[1776, 53, 35, 0, 98, "Title"], Cell[1814, 55, 370, 8, 50, "Text"], Cell[CellGroupData[{ Cell[2209, 67, 37, 0, 51, "Section"], Cell[2249, 69, 75, 0, 29, "Text"], Cell[2327, 71, 45, 1, 38, "Input"], Cell[2375, 74, 18, 0, 29, "Text"], Cell[2396, 76, 56, 1, 38, "Input"], Cell[2455, 79, 569, 10, 71, "Text"], Cell[3027, 91, 307, 9, 29, "Text"], Cell[3337, 102, 93, 1, 38, "Input"], Cell[3433, 105, 238, 8, 113, "Text"], Cell[3674, 115, 45, 0, 29, "Text"], Cell[3722, 117, 56, 1, 38, "Input"], Cell[3781, 120, 153, 5, 29, "Text"], Cell[3937, 127, 43, 1, 38, "Input"], Cell[3983, 130, 120, 5, 29, "Text"], Cell[4106, 137, 71, 1, 38, "Input"], Cell[4180, 140, 111, 5, 29, "Text"], Cell[4294, 147, 68, 1, 38, "Input"], Cell[4365, 150, 62, 0, 29, "Text"], Cell[4430, 152, 51, 1, 38, "Input"], Cell[4484, 155, 126, 3, 29, "Text"], Cell[4613, 160, 137, 3, 29, "Text"], Cell[4753, 165, 127, 2, 58, "Input"], Cell[4883, 169, 115, 3, 29, "Text"], Cell[5001, 174, 106, 2, 38, "Input"], Cell[5110, 178, 145, 3, 29, "Text"], Cell[5258, 183, 85, 1, 50, "Input"], Cell[5346, 186, 109, 2, 50, "Input"], Cell[5458, 190, 443, 9, 50, "Text"], Cell[5904, 201, 90, 1, 50, "Input"], Cell[5997, 204, 807, 21, 71, "Text"], Cell[6807, 227, 42, 1, 38, "Input"], Cell[6852, 230, 187, 8, 29, "Text"], Cell[7042, 240, 103, 2, 50, "Input"], Cell[7148, 244, 129, 3, 29, "Text"], Cell[7280, 249, 396, 10, 56, "Text"] }, Closed]], Cell[CellGroupData[{ Cell[7713, 264, 49, 0, 35, "Section"], Cell[7765, 266, 490, 8, 71, "Text"], Cell[8258, 276, 125, 2, 60, "Input"], Cell[8386, 280, 54, 0, 29, "Text"], Cell[8443, 282, 37, 1, 38, "Input"], Cell[8483, 285, 66, 0, 29, "Text"], Cell[8552, 287, 42, 1, 38, "Input"], Cell[8597, 290, 766, 25, 71, "Text"], Cell[9366, 317, 103, 2, 58, "Input"], Cell[9472, 321, 153, 5, 29, "Text"], Cell[9628, 328, 99, 2, 58, "Input"], Cell[9730, 332, 181, 7, 29, "Text"], Cell[9914, 341, 40, 1, 38, "Input"], Cell[9957, 344, 42, 1, 38, "Input"], Cell[10002, 347, 84, 2, 71, "Input"], Cell[10089, 351, 44, 1, 38, "Input"], Cell[10136, 354, 84, 2, 58, "Input"], Cell[10223, 358, 167, 4, 29, "Text"], Cell[10393, 364, 63, 1, 38, "Input"], Cell[10459, 367, 43, 0, 29, "Text"], Cell[10505, 369, 45, 1, 38, "Input"], Cell[10553, 372, 23, 0, 29, "Text"], Cell[10579, 374, 47, 1, 38, "Input"], Cell[10629, 377, 44, 0, 29, "Text"], Cell[10676, 379, 50, 1, 38, "Input"], Cell[10729, 382, 216, 8, 29, "Text"], Cell[10948, 392, 138, 2, 58, "Input"], Cell[11089, 396, 129, 5, 29, "Text"], Cell[11221, 403, 50, 1, 38, "Input"], Cell[11274, 406, 1302, 57, 71, "Text"], Cell[12579, 465, 45, 1, 38, "Input"], Cell[12627, 468, 62, 1, 38, "Input"], Cell[12692, 471, 91, 2, 58, "Input"], Cell[12786, 475, 51, 1, 38, "Input"], Cell[12840, 478, 361, 12, 29, "Text"], Cell[13204, 492, 52, 1, 38, "Input"], Cell[13259, 495, 95, 3, 29, "Text"], Cell[13357, 500, 81, 1, 38, "Input"], Cell[13441, 503, 55, 1, 38, "Input"], Cell[13499, 506, 91, 2, 58, "Input"], Cell[13593, 510, 101, 3, 29, "Text"], Cell[13697, 515, 120, 2, 58, "Input"], Cell[13820, 519, 118, 2, 58, "Input"], Cell[13941, 523, 46, 1, 38, "Input"], Cell[13990, 526, 49, 1, 38, "Input"], Cell[14042, 529, 1139, 38, 77, "Text"] }, Closed]], Cell[CellGroupData[{ Cell[15218, 572, 39, 0, 35, "Section"], Cell[15260, 574, 502, 10, 71, "Text"], Cell[15765, 586, 139, 3, 29, "Text"], Cell[15907, 591, 430, 7, 185, "Input"], Cell[16340, 600, 41, 0, 29, "Text"], Cell[16384, 602, 64, 1, 38, "Input"], Cell[16451, 605, 877, 21, 139, "Text"] }, Closed]], Cell[CellGroupData[{ Cell[17365, 631, 37, 0, 35, "Section"], Cell[17405, 633, 943, 30, 71, "Text"], Cell[CellGroupData[{ Cell[18373, 667, 24, 0, 39, "Subsection"], Cell[18400, 669, 2288, 87, 198, "Text"], Cell[20691, 758, 202, 8, 29, "Text"], Cell[20896, 768, 146, 3, 78, "Input"], Cell[21045, 773, 188, 8, 29, "Text"], Cell[21236, 783, 146, 3, 78, "Input"], Cell[21385, 788, 276, 11, 29, "Text"], Cell[21664, 801, 111, 2, 58, "Input"], Cell[21778, 805, 736, 18, 71, "Text"], Cell[22517, 825, 361, 7, 138, "Input"], Cell[22881, 834, 364, 7, 138, "Input"], Cell[23248, 843, 382, 14, 29, "Text"], Cell[23633, 859, 377, 7, 138, "Input"], Cell[24013, 868, 56, 1, 38, "Input"], Cell[24072, 871, 59, 1, 38, "Input"], Cell[24134, 874, 785, 28, 45, "Text"] }, Closed]], Cell[CellGroupData[{ Cell[24956, 907, 24, 0, 25, "Subsection"], Cell[24983, 909, 5358, 240, 349, "Text"], Cell[30344, 1151, 522, 18, 50, "Text"], Cell[30869, 1171, 150, 3, 78, "Input"], Cell[31022, 1176, 48, 0, 29, "Text"], Cell[31073, 1178, 330, 6, 158, "Input"], Cell[31406, 1186, 74, 0, 29, "Text"], Cell[31483, 1188, 48, 1, 38, "Input"], Cell[31534, 1191, 46, 1, 38, "Input"], Cell[31583, 1194, 44, 0, 29, "Text"], Cell[31630, 1196, 52, 1, 38, "Input"], Cell[31685, 1199, 48, 1, 38, "Input"], Cell[31736, 1202, 134, 5, 29, "Text"] }, Closed]], Cell[CellGroupData[{ Cell[31907, 1212, 25, 0, 25, "Subsection"], Cell[31935, 1214, 2829, 91, 199, "Text"], Cell[34767, 1307, 339, 14, 29, "Text"], Cell[35109, 1323, 84, 1, 39, "Input"], Cell[35196, 1326, 531, 18, 50, "Text"] }, Closed]], Cell[CellGroupData[{ Cell[35764, 1349, 27, 0, 25, "Subsection"], Cell[35794, 1351, 1607, 65, 200, "Text"], Cell[37404, 1418, 1721, 59, 134, "Text"], Cell[39128, 1479, 628, 16, 138, "Input"], Cell[39759, 1497, 379, 12, 50, "Text"], Cell[40141, 1511, 362, 8, 178, "Input"], Cell[40506, 1521, 49, 1, 38, "Input"], Cell[40558, 1524, 1425, 37, 197, "Text"], Cell[41986, 1563, 359, 7, 198, "Input"], Cell[42348, 1572, 884, 32, 56, "Text"] }, Closed]], Cell[CellGroupData[{ Cell[43269, 1609, 27, 0, 25, "Subsection"], Cell[43299, 1611, 1806, 64, 135, "Text"], Cell[45108, 1677, 2167, 90, 115, "Text"], Cell[47278, 1769, 1333, 24, 436, "Input"], Cell[48614, 1795, 46, 0, 29, "Text"], Cell[48663, 1797, 174, 3, 79, "Input"], Cell[48840, 1802, 143, 5, 29, "Text"], Cell[48986, 1809, 40, 1, 38, "Input"], Cell[49029, 1812, 233, 9, 29, "Text"], Cell[49265, 1823, 74, 1, 39, "Input"], Cell[49342, 1826, 181, 8, 29, "Text"], Cell[49526, 1836, 170, 3, 79, "Input"], Cell[49699, 1841, 74, 1, 39, "Input"], Cell[49776, 1844, 76, 0, 29, "Text"], Cell[49855, 1846, 74, 1, 39, "Input"], Cell[49932, 1849, 119, 3, 29, "Text"], Cell[50054, 1854, 74, 1, 39, "Input"], Cell[50131, 1857, 35, 0, 29, "Text"], Cell[50169, 1859, 933, 24, 224, "Text"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[51151, 1889, 33, 0, 35, "Section"], Cell[51187, 1891, 277, 9, 29, "Text"], Cell[51467, 1902, 233, 5, 83, "Input"], Cell[51703, 1909, 176, 5, 29, "Text"], Cell[51882, 1916, 48, 1, 38, "Input"], Cell[51933, 1919, 132, 5, 29, "Text"], Cell[52068, 1926, 51, 1, 38, "Input"], Cell[52122, 1929, 261, 7, 35, "Text"] }, Closed]], Cell[CellGroupData[{ Cell[52420, 1941, 26, 0, 35, "Section"], Cell[52449, 1943, 656, 24, 50, "Text"], Cell[53108, 1969, 954, 26, 92, "Text"], Cell[54065, 1997, 195, 3, 58, "Input"], Cell[54263, 2002, 162, 4, 29, "Text"], Cell[54428, 2008, 1090, 20, 309, "Input"], Cell[55521, 2030, 67, 0, 29, "Text"], Cell[55591, 2032, 162, 3, 58, "Input"], Cell[55756, 2037, 65, 0, 29, "Text"], Cell[55824, 2039, 88, 1, 38, "Input"], Cell[55915, 2042, 56, 0, 29, "Text"], Cell[55974, 2044, 109, 2, 38, "Input"], Cell[56086, 2048, 527, 15, 50, "Text"], Cell[56616, 2065, 89, 3, 29, "Text"], Cell[56708, 2070, 2002, 35, 522, "Input"], Cell[58713, 2107, 365, 10, 35, "Text"], Cell[59081, 2119, 317, 6, 50, "Text"] }, Closed]] }, Open ]] } ] *) (******************************************************************* End of Mathematica Notebook file. *******************************************************************)