(*********************************************************************** Mathematica-Compatible Notebook This notebook can be used on any computer system with Mathematica 4.0, MathReader 4.0, or any compatible application. 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[ 11683, 477]*) (*NotebookOutlinePosition[ 12628, 507]*) (* CellTagsIndexPosition[ 12584, 503]*) (*WindowFrame->Normal*) Notebook[{ Cell[CellGroupData[{ Cell["Optional Arguments and Defaults", "Title", TextAlignment->Center, TextJustification->0, FontSize->18], Cell["\<\ In this notebook, we'll look at how to define functions with \ optional arguments and how to set defaults for those arguments.\ \>", "Text"], Cell[CellGroupData[{ Cell["Clear symbols", "Section", Evaluatable->False, AspectRatioFixed->True], Cell["\<\ In order to avoid interference from symbols defined in other \ notebooks, we first Clear and Remove all symbols. We assume that the \ relevant symbols are in the Global` context.\ \>", "Text", Evaluatable->False, AspectRatioFixed->True], Cell["Clear[\"Global`*\"]", "Input", AspectRatioFixed->True], Cell["Remove[\"Global`*\"]", "Input", AspectRatioFixed->True] }, Open ]], Cell[CellGroupData[{ Cell["References", "Section", Evaluatable->False, AspectRatioFixed->True], Cell[TextData[{ "Tam's book \"A Physicist's Guide to ", StyleBox["Mathematica", FontSlant->"Italic"], "\" has a nice discussion with a sophisticated example in Section 3.4.4." }], "Text"] }, Open ]], Cell[CellGroupData[{ Cell["Overview", "Section", Evaluatable->False, AspectRatioFixed->True], Cell[TextData[{ "There are two types of arguments to a ", StyleBox["Mathematica", FontSlant->"Italic"], " function: positional arguments and named optional arguments (also called \ options). Options are indicated by the syntax: ", StyleBox["option->value ", FontSlant->"Italic"], "in the argument list. You can include zero, one,\nor more of these \ options." }], "Text"], Cell["\<\ For example, the function Factor takes one positional argument and \ several possible optional arguments. Use ?Factor to see them or \ Options[Factor] to see the options only:\ \>", "Text"], Cell[CellGroupData[{ Cell[BoxData[ \(\(?Factor\)\)], "Input"], Cell[BoxData[ \("Factor[poly] factors a polynomial over the integers. Factor[poly, \ Modulus->p] factors a polynomial modulo a prime p. Factor[poly, \ Extension->{a1, a2, ... }] factors a polynomial allowing coefficients that \ are rational combinations of the algebraic numbers ai."\)], "Print"] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ \(Options[Factor]\)], "Input"], Cell[BoxData[ \({Extension \[Rule] None, GaussianIntegers \[Rule] False, Modulus \[Rule] 0, Trig \[Rule] False}\)], "Output"] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ \(Factor[x^2 + 1]\)], "Input"], Cell[BoxData[ \(1 + x\^2\)], "Output"] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ \(Factor[x^2 + 1, GaussianIntegers \[Rule] True]\)], "Input"], Cell[BoxData[ \(\((\(-\[ImaginaryI]\) + x)\)\ \((\[ImaginaryI] + x)\)\)], "Output"] }, Open ]], Cell["\<\ The function Solve takes two positional arguments (each of which \ may be a list):\ \>", "Text"], Cell[CellGroupData[{ Cell[BoxData[ \(\(?Solve\)\)], "Input"], Cell[BoxData[ \("Solve[eqns, vars] attempts to solve an equation or set of equations \ for the variables vars. Solve[eqns, vars, elims] attempts to solve the \ equations for vars, eliminating the variables elims."\)], "Print"] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ \(Solve[x^2 \[Equal] 1, x]\)], "Input"], Cell[BoxData[ \({{x \[Rule] \(-1\)}, {x \[Rule] 1}}\)], "Output"] }, Open ]], Cell["Solve has many options (mostly obscure here!):", "Text"], Cell[CellGroupData[{ Cell[BoxData[ \(Options[Solve]\)], "Input"], Cell[BoxData[ RowBox[{"{", RowBox[{\(InverseFunctions \[Rule] Automatic\), ",", \(MakeRules \[Rule] False\), ",", \(Method \[Rule] 3\), ",", \(Mode \[Rule] Generic\), ",", \(Sort \[Rule] True\), ",", \(VerifySolutions \[Rule] Automatic\), ",", RowBox[{"WorkingPrecision", "\[Rule]", InterpretationBox["\[Infinity]", DirectedInfinity[ 1]]}]}], "}"}]], "Output"] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell["\<\ Simple Function Definitions with Optional Positional Arguments \ (with Defaults)\ \>", "Section", Evaluatable->False, AspectRatioFixed->True], Cell[TextData[{ "If you define a function f[x_,y_] and only give the first argument, ", StyleBox["Mathematica", FontSlant->"Italic"], " simply returns the function name:" }], "Text"], Cell[BoxData[ \(Clear[f]\)], "Input"], Cell[BoxData[ \(f[x_, y_]\ := \ x^2\ + \ y^2\)], "Input"], Cell[CellGroupData[{ Cell[BoxData[ \(f[a, b]\)], "Input"], Cell[BoxData[ \(a\^2 + b\^2\)], "Output"] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ \(f[a]\)], "Input"], Cell[BoxData[ \(f[a]\)], "Output"] }, Open ]], Cell["\<\ Suppose we want to define a function f that takes two (positional) \ arguments x and y and returns x^2+y^2, but if y is not given, it assumes y=c. \ Here's how to do it:\ \>", "Text"], Cell[BoxData[ \(Clear[f]\)], "Input"], Cell[BoxData[ \(f[x_, Optional[y_, c]]\ := \ x^2\ + \ y^2\)], "Input"], Cell[CellGroupData[{ Cell[BoxData[ \(f[a, b]\)], "Input"], Cell[BoxData[ \(a\^2 + b\^2\)], "Output"] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ \(f[a]\)], "Input"], Cell[BoxData[ \(a\^2 + c\^2\)], "Output"] }, Open ]], Cell["\<\ A shorthand notation for Optional[y_,c] is y_:c, so the function g \ is the same as f:\ \>", "Text"], Cell[BoxData[ \(g[x_, y_: c]\ := \ x^2\ + \ y^2\)], "Input"], Cell[CellGroupData[{ Cell[BoxData[ \(g[a, b]\)], "Input"], Cell[BoxData[ \(a\^2 + b\^2\)], "Output"] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ \(g[a]\)], "Input"], Cell[BoxData[ \(a\^2 + c\^2\)], "Output"] }, Open ]], Cell["Suppose I add a second optional argument:", "Text"], Cell[BoxData[ \(h[x_, y_: c, z_: d]\ := \ x^2\ + \ y^2\ + \ z^2\)], "Input"], Cell[CellGroupData[{ Cell[BoxData[ \(h[x, y, z]\)], "Input"], Cell[BoxData[ \(x\^2 + y\^2 + z\^2\)], "Output"] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ \(h[x, y]\)], "Input"], Cell[BoxData[ \(d\^2 + x\^2 + y\^2\)], "Output"] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ \(h[x]\)], "Input"], Cell[BoxData[ \(c\^2 + d\^2 + x\^2\)], "Output"] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell["\<\ Simple Function Definitions with Optional Arguments (Options)\ \>", \ "Section", Evaluatable->False, AspectRatioFixed->True], Cell["\<\ Suppose you wanted to define your own version of Sin, called mySin, \ that took an option called \"angle\" that can be either \"radians\" or \ \"degrees\", with \"radians\" the default. \ \>", "Text"], Cell["\<\ First specify the options using Options and give the default value. \ To generalize to more options, simply add to the list on the right side in \ the {}'s.\ \>", "Text"], Cell[CellGroupData[{ Cell[BoxData[ \(Options[mySin]\ = \ {angle \[Rule] radians}\)], "Input"], Cell[BoxData[ \({angle \[Rule] radians}\)], "Output"] }, Open ]], Cell[TextData[{ "Now we write the function itself. We'll use a Module, which lets us \ define the local variable \"units\" without worrying about any external \ (global) variables of the same name. Module has the form Module[{", StyleBox["local variables", FontSlant->"Italic"], "},", StyleBox["body", FontSlant->"Italic"], "], so we\ndefine \"units\" in the local variables section and then the \ body has the actual function. We use Which to change the return based on the \ value of \"units\"." }], "Text"], Cell[BoxData[ \(mySin[x_, \ opts___Rule]\ := \ \[IndentingNewLine]\ \ \ \ \ \ Module[\ {units\ \ = \ \(angle /. {opts}\) /. Options[mySin]}, \[IndentingNewLine]\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Which[units === radians, \ Sin[x], \[IndentingNewLine]\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ units === degrees, \ Sin[x\ Degree], \[IndentingNewLine]\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ True, \ Return["\"]\[IndentingNewLine]\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ]\[IndentingNewLine]\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ]\)], \ "Input"], Cell["Check it out:", "Text"], Cell[CellGroupData[{ Cell[BoxData[ \(mySin[Pi/2]\)], "Input"], Cell[BoxData[ \(1\)], "Output"] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ \(mySin[Pi/2, angle \[Rule] radians]\)], "Input"], Cell[BoxData[ \(1\)], "Output"] }, Open ]], Cell[CellGroupData[{ Cell[BoxData[ \(mySin[90, angle \[Rule] degrees]\)], "Input"], Cell[BoxData[ \(1\)], "Output"] }, Open ]], Cell["Some additional comments:", "Text"], Cell[TextData[{ "* The argument \"opts___Rule\" has three underscores. This allows any \ number of ", StyleBox["option->value", FontSlant->"Italic"], " Rules. The \"Rule\" at the end simply tells ", StyleBox["Mathematica", FontSlant->"Italic"], " that the opts objects are, in fact, rules of the type ", StyleBox["option->value", FontSlant->"Italic"], ". " }], "Text"], Cell["\<\ * Note that we included a \"True\" at the end of our list of pairs \ in the Which statement. This is to handle the case that an invalid option \ was used: \ \>", "Text"], Cell[CellGroupData[{ Cell[BoxData[ \(mySin[90, angle \[Rule] feet]\)], "Input"], Cell[BoxData[ \("The value of the option angle must be either radians or degrees."\)], \ "Output"] }, Open ]], Cell["If an irrelevant option is specified, it is simply ignored:", "Text"], Cell[CellGroupData[{ Cell[BoxData[ \(mySin[Pi/2, myname \[Rule] Bill]\)], "Input"], Cell[BoxData[ \(1\)], "Output"] }, Open ]], Cell["* Note that we can check what options are defined for mySin:", "Text"], Cell[CellGroupData[{ Cell[BoxData[ \(Options[mySin]\)], "Input"], Cell[BoxData[ \({angle \[Rule] radians}\)], "Output"] }, Open ]] }, Open ]] }, Open ]] }, FrontEndVersion->"4.0 for X", ScreenRectangle->{{0, 1280}, {0, 1024}}, WindowSize->{691, 889}, WindowMargins->{{104, Automatic}, {Automatic, 41}}, PrintingPageRange->{Automatic, Automatic}, PrintingOptions->{"PaperSize"->{612, 792}, "PaperOrientation"->"Portrait", "PostScriptOutputFile":>FrontEnd`FileName[{$RootDirectory, "home", \ "furnstah", "public_html", "reu", "nbs"}, "options.nb.ps", CharacterEncoding \ -> "ISO8859-1"], "Magnification"->1} ] (*********************************************************************** 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[1739, 51, 113, 3, 93, "Title"], Cell[1855, 56, 150, 3, 32, "Text"], Cell[CellGroupData[{ Cell[2030, 63, 80, 2, 60, "Section", Evaluatable->False], Cell[2113, 67, 251, 6, 50, "Text", Evaluatable->False], Cell[2367, 75, 62, 1, 27, "Input"], Cell[2432, 78, 63, 1, 27, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[2532, 84, 77, 2, 60, "Section", Evaluatable->False], Cell[2612, 88, 197, 5, 32, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[2846, 98, 75, 2, 60, "Section", Evaluatable->False], Cell[2924, 102, 393, 10, 68, "Text"], Cell[3320, 114, 200, 4, 50, "Text"], Cell[CellGroupData[{ Cell[3545, 122, 44, 1, 27, "Input"], Cell[3592, 125, 300, 4, 71, "Print"] }, Open ]], Cell[CellGroupData[{ Cell[3929, 134, 48, 1, 27, "Input"], Cell[3980, 137, 136, 2, 27, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[4153, 144, 48, 1, 27, "Input"], Cell[4204, 147, 42, 1, 29, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[4283, 153, 79, 1, 27, "Input"], Cell[4365, 156, 87, 1, 27, "Output"] }, Open ]], Cell[4467, 160, 106, 3, 32, "Text"], Cell[CellGroupData[{ Cell[4598, 167, 43, 1, 27, "Input"], Cell[4644, 170, 230, 3, 55, "Print"] }, Open ]], Cell[CellGroupData[{ Cell[4911, 178, 57, 1, 27, "Input"], Cell[4971, 181, 69, 1, 27, "Output"] }, Open ]], Cell[5055, 185, 62, 0, 32, "Text"], Cell[CellGroupData[{ Cell[5142, 189, 47, 1, 27, "Input"], Cell[5192, 192, 430, 8, 43, "Output"] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell[5671, 206, 155, 5, 88, "Section", Evaluatable->False], Cell[5829, 213, 192, 5, 32, "Text"], Cell[6024, 220, 41, 1, 27, "Input"], Cell[6068, 223, 63, 1, 27, "Input"], Cell[CellGroupData[{ Cell[6156, 228, 40, 1, 27, "Input"], Cell[6199, 231, 45, 1, 29, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[6281, 237, 37, 1, 27, "Input"], Cell[6321, 240, 38, 1, 27, "Output"] }, Open ]], Cell[6374, 244, 194, 4, 50, "Text"], Cell[6571, 250, 41, 1, 27, "Input"], Cell[6615, 253, 76, 1, 27, "Input"], Cell[CellGroupData[{ Cell[6716, 258, 40, 1, 27, "Input"], Cell[6759, 261, 45, 1, 29, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[6841, 267, 37, 1, 27, "Input"], Cell[6881, 270, 45, 1, 29, "Output"] }, Open ]], Cell[6941, 274, 110, 3, 32, "Text"], Cell[7054, 279, 67, 1, 27, "Input"], Cell[CellGroupData[{ Cell[7146, 284, 40, 1, 27, "Input"], Cell[7189, 287, 45, 1, 29, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[7271, 293, 37, 1, 27, "Input"], Cell[7311, 296, 45, 1, 29, "Output"] }, Open ]], Cell[7371, 300, 57, 0, 32, "Text"], Cell[7431, 302, 85, 1, 27, "Input"], Cell[CellGroupData[{ Cell[7541, 307, 43, 1, 27, "Input"], Cell[7587, 310, 52, 1, 29, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[7676, 316, 40, 1, 27, "Input"], Cell[7719, 319, 52, 1, 29, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[7808, 325, 37, 1, 27, "Input"], Cell[7848, 328, 52, 1, 29, "Output"] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell[7949, 335, 138, 5, 60, "Section", Evaluatable->False], Cell[8090, 342, 211, 4, 50, "Text"], Cell[8304, 348, 181, 4, 50, "Text"], Cell[CellGroupData[{ Cell[8510, 356, 77, 1, 27, "Input"], Cell[8590, 359, 57, 1, 27, "Output"] }, Open ]], Cell[8662, 363, 530, 12, 86, "Text"], Cell[9195, 377, 754, 13, 139, "Input"], Cell[9952, 392, 29, 0, 32, "Text"], Cell[CellGroupData[{ Cell[10006, 396, 44, 1, 27, "Input"], Cell[10053, 399, 35, 1, 27, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[10125, 405, 67, 1, 27, "Input"], Cell[10195, 408, 35, 1, 27, "Output"] }, Open ]], Cell[CellGroupData[{ Cell[10267, 414, 65, 1, 27, "Input"], Cell[10335, 417, 35, 1, 27, "Output"] }, Open ]], Cell[10385, 421, 41, 0, 32, "Text"], Cell[10429, 423, 398, 12, 50, "Text"], Cell[10830, 437, 180, 4, 50, "Text"], Cell[CellGroupData[{ Cell[11035, 445, 62, 1, 27, "Input"], Cell[11100, 448, 102, 2, 27, "Output"] }, Open ]], Cell[11217, 453, 75, 0, 32, "Text"], Cell[CellGroupData[{ Cell[11317, 457, 65, 1, 27, "Input"], Cell[11385, 460, 35, 1, 27, "Output"] }, Open ]], Cell[11435, 464, 76, 0, 32, "Text"], Cell[CellGroupData[{ Cell[11536, 468, 47, 1, 27, "Input"], Cell[11586, 471, 57, 1, 27, "Output"] }, Open ]] }, Open ]] }, Open ]] } ] *) (*********************************************************************** End of Mathematica Notebook file. ***********************************************************************)