1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
@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
|