@Section @Title { Mathematical functions, loops, and tests } @Tag { functions } @Begin @PP @Code "@Graph" offers quite a large selection of mathematical functions, mathematical.functions @Index { mathematical functions in graphs } available everywhere that x and y coordinates are required: within the @Code xticks and @Code yticks options, within the points within the @Code "objects" option, and within the right parameter of the @Code "@Data" symbol. For example, @ID @OneRow @Code { "@Data" " pairs { solid }" "{" " 0 0 pi sin { pi/2 }" "}" } draws a solid line from @Eq {(0, 0)} to @Eq {(pi, sin(pi "/" 2))}. Section {@NumberOf grsummary} lists all the functions; they include the four arithmetical operators @Eq { non + }, @Eq { non - }, @Eq { non * }, and @Eq { "/" }, as well as {@Code "sin"}, {@Code "cos"}, {@Code "sqrt"}, and many others. Braces are used for grouping, never parentheses. @PP For plotting functions there are three looping symbols, {@Code "xloop"}, {@Code "yloop"}, and {@Code "zloop"}. For example, the following plots the two functions @Eq { y = 2 } and @Eq { y = sqrt { pi x "/" 4 } + 1 } for @Eq { x } from 10 to 500: @ID @OneRow @Code { "-2p @Font @Graph" " style { axes }" " xorigin { 0 }" " yorigin { 0 }" " width { 8 cm }" " xticks { 10@ 50@ 100@ 200@ 500@ }" " objects { @NE at { 300 2 } @I { Exponential }" " @SE at { 300 sqrt { pi*300/4 } + 1 } @I { Uniform } }" " belowcaption { @I n }" " belowgap { 0 cm }" " leftcaption { Right shell nodes }" "{" " @Data points { filledcircle }" " { 10 1.97 50 2.01 100 2.00 200 2.0 500 2.00 }" "" " @Data points { filledcircle }" " { 10 3.53 50 7.45 100 9.32 200 13.41 500 21.63 }" "" " @Data pairs { dashed }" " { 10 2 500 2 }" "" " @Data pairs { dashed }" " {" " xloop from { 10 } to { 500 } by { 20 } do" " {" " x sqrt { pi*x / 4 } + 1" " }" " }" "}" } The @Code "do" option of @Code xloop is replicated repeatedly with each occurrence of @Code x replaced by 10, 30, 50, ... up to 490. The result is @FootNote { Source: Jeffrey H. Kingston, Analysis of tree algorithms for the simulation event list. @I { Acta Informatica } {@B 22}, pp. 15--33 (1985). } @CD -2p @Font @Graph style { axes } xorigin { 0 } yorigin { 0 } width { 8 cm } xticks { 10@ 50@ 100@ 200@ 500@ } objects { @NE at { 300 2 } @I { Exponential } @SE at { 300 sqrt { pi*300/4 } + 1 } @I { Uniform } } belowcaption { @I n } belowgap { 0 cm } leftcaption { Right shell nodes } { @Data points { filledcircle } { 10 1.97 50 2.01 100 2.00 200 2.0 500 2.00 } @Data points { filledcircle } { 10 3.53 50 7.45 100 9.32 200 13.41 500 21.63 } @Data pairs { dashed } { 10 2 500 2 } @Data pairs { dashed } { xloop from { 10 } to { 500 } by { 20 } do { x sqrt { pi*x / 4 } + 1 } } } The points are connected by straight line segments as usual, but a smallish @Code "by" option of about one-twentieth of the range creates the illusion of a smooth curve quite well. @PP There is also an @Code "if" symbol which produces alternative results, depending on whether a condition evaluates to @Code "true" or {@Code"false"}: @ID @OneRow @Code { "xloop from { -5 } to { +5 } by { 0.2 } do" "{" " if cond { abs { x } > 0.1 } then { x 1/x } else {}" "}" } This plots the function @Eq { y = 1 "/" x }, skipping points near zero. Actually the @Code "else" part could be omitted since its default value is empty. @PP Adventurous users might enjoy nesting a @Code "yloop" or @Code "zloop" within an {@Code "xloop"}, or using loops to generate ticks, like this: @ID @OneRow @Code { "xticks {" " xloop from { 0 } to { 20 } do" " {" " x if cond { x mod 5 = 0 } then { @ }" " }" "}" } The missing @Code "by" option defaults to 1, so this produces x ticks at 0, 1, 2, ..., 20, with labels at 0, 5, 10, 15, and 20. It is quite all right to mix @Code "@" and even labels in with numbers, as long as the final result obeys the rules of Section {@NumberOf ticks}. @PP You can define your own functions using Lout definitions, placed in your @Code "mydefs" file as explained in Section {@NumberOf definitions}. Here is an example of a function definition: @ID @OneRow @Code { "import @Graph @Data" "def @Tan" " precedence 40" " right x" "{" " sin x / cos x" "}" } This defines a function called @Code "@Tan" which implements the trigonometric tangent function. It may then be used in expressions just like any other function: @ID @OneRow @Code { "@Data {" " yloop from { 0 } to { 0.95 } by { 0.05 } do" " {" " y @Tan { y / pi }" " }" "}" } Following is a detailed explanation. @PP The first line, {@Code "import @Graph @Data"}, is the import clause. Its function is to grant the definition access to the three previously defined functions (symbols) that it uses, namely {@Code "sin"}, {@Code "cos"}, and {@Code "/"}. These are found within the @Code "@Data" symbol within {@Code "@Graph"}. @PP After the import clause comes the @Code "def" keyword, meaning `define,' and then the name of the symbol being defined, in this case @Code "@Tan". We have chosen @Code "@Tan" rather than @Code "tan" because symbols defined by the user in this way are visible throughout the document, and we do not want the literal word @Code "tan" to be taken as a symbol. @PP Next comes the symbol's precedence, in this case the same as @Code "sin" and @Code "cos" (see Section {@NumberOf dia_summ} for the precedence of each symbol). Next is a list of the formal parameters, in this case just one, called {@Code "x"}, that is to be passed on the right. @PP Finally comes the body of the definition enclosed in braces. When @Code "@Tan" is invoked, its value will be this body with each occurrence of the formal parameter @Code "x" replaced by the object following the @Code "@Tan" symbol. For example, the @Code "do" option of the @Code "yloop" above becomes @ID @Code "y sin { y / pi } / cos { y / pi }" as you would expect. @End @Section