@Section @Title { Mathematical functions, loops, and tests } @Tag { functions } @Begin @PP @Code "@Graph" offers quite a large selection of mathematical functions, graphs. @RawIndex { graphs (statistical) } graphs.mathematical @SubIndex { 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 @Verbatim { @Data pairs { solid } { 0 0 pi sin { pi/2 } } } draws a solid line from @M {(0, 0)} to @M {(pi, sin(pi "/" 2))}. Section {@NumberOf grsummary} lists all the functions; they include the four arithmetical operators @M { non + }, @M { non - }, @M { non * }, and @M { "/" }, 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 @M { y = 2 } and @M { y = sqrt { pi x "/" 4 } + 1 } for @M { x } from 10 to 500: @ID -1px @Break @OneRow @Code @Verbatim { -2p @Font @Graph style { axes } xorigin { 0 } yorigin { 0 } width { 8c } 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 { 0c } 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 @CD -2p @Font @Graph style { axes } xorigin { 0 } yorigin { 0 } width { 8c } 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 { 0c } 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 } } } (Jeffrey H. Kingston, Analysis of tree algorithms for the simulation event list. @I { Acta Informatica } {@B 22}, pp. 15--33 1985). 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 @Verbatim { xloop from { -5 } to { +5 } by { 0.2 } do { if cond { abs { x } > 0.1 } then { x 1/x } else {} } } This plots the function @M { 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 @Verbatim { 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 @Verbatim { 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 @Verbatim { @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 grsummary} 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