Code

5a74d62c0f4faccadd12a7bf3c05aa193a35512f
[pkg-rrdtool.git] / doc / rpntutorial.1
1 .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.14
2 .\"
3 .\" Standard preamble:
4 .\" ========================================================================
5 .de Sh \" Subsection heading
6 .br
7 .if t .Sp
8 .ne 5
9 .PP
10 \fB\\$1\fR
11 .PP
12 ..
13 .de Sp \" Vertical space (when we can't use .PP)
14 .if t .sp .5v
15 .if n .sp
16 ..
17 .de Vb \" Begin verbatim text
18 .ft CW
19 .nf
20 .ne \\$1
21 ..
22 .de Ve \" End verbatim text
23 .ft R
24 .fi
25 ..
26 .\" Set up some character translations and predefined strings.  \*(-- will
27 .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
28 .\" double quote, and \*(R" will give a right double quote.  | will give a
29 .\" real vertical bar.  \*(C+ will give a nicer C++.  Capital omega is used to
30 .\" do unbreakable dashes and therefore won't be available.  \*(C` and \*(C'
31 .\" expand to `' in nroff, nothing in troff, for use with C<>.
32 .tr \(*W-|\(bv\*(Tr
33 .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
34 .ie n \{\
35 .    ds -- \(*W-
36 .    ds PI pi
37 .    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
38 .    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
39 .    ds L" ""
40 .    ds R" ""
41 .    ds C` ""
42 .    ds C' ""
43 'br\}
44 .el\{\
45 .    ds -- \|\(em\|
46 .    ds PI \(*p
47 .    ds L" ``
48 .    ds R" ''
49 'br\}
50 .\"
51 .\" If the F register is turned on, we'll generate index entries on stderr for
52 .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
53 .\" entries marked with X<> in POD.  Of course, you'll have to process the
54 .\" output yourself in some meaningful fashion.
55 .if \nF \{\
56 .    de IX
57 .    tm Index:\\$1\t\\n%\t"\\$2"
58 ..
59 .    nr % 0
60 .    rr F
61 .\}
62 .\"
63 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
64 .\" way too many mistakes in technical documents.
65 .hy 0
66 .if n .na
67 .\"
68 .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
69 .\" Fear.  Run.  Save yourself.  No user-serviceable parts.
70 .    \" fudge factors for nroff and troff
71 .if n \{\
72 .    ds #H 0
73 .    ds #V .8m
74 .    ds #F .3m
75 .    ds #[ \f1
76 .    ds #] \fP
77 .\}
78 .if t \{\
79 .    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
80 .    ds #V .6m
81 .    ds #F 0
82 .    ds #[ \&
83 .    ds #] \&
84 .\}
85 .    \" simple accents for nroff and troff
86 .if n \{\
87 .    ds ' \&
88 .    ds ` \&
89 .    ds ^ \&
90 .    ds , \&
91 .    ds ~ ~
92 .    ds /
93 .\}
94 .if t \{\
95 .    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
96 .    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
97 .    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
98 .    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
99 .    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
100 .    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
101 .\}
102 .    \" troff and (daisy-wheel) nroff accents
103 .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
104 .ds 8 \h'\*(#H'\(*b\h'-\*(#H'
105 .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
106 .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
107 .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
108 .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
109 .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
110 .ds ae a\h'-(\w'a'u*4/10)'e
111 .ds Ae A\h'-(\w'A'u*4/10)'E
112 .    \" corrections for vroff
113 .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
114 .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
115 .    \" for low resolution devices (crt and lpr)
116 .if \n(.H>23 .if \n(.V>19 \
117 \{\
118 .    ds : e
119 .    ds 8 ss
120 .    ds o a
121 .    ds d- d\h'-1'\(ga
122 .    ds D- D\h'-1'\(hy
123 .    ds th \o'bp'
124 .    ds Th \o'LP'
125 .    ds ae ae
126 .    ds Ae AE
127 .\}
128 .rm #[ #] #H #V #F C
129 .\" ========================================================================
130 .\"
131 .IX Title "RPNTUTORIAL 1"
132 .TH RPNTUTORIAL 1 "2008-12-22" "1.3.99909060808" "rrdtool"
133 .SH "NAME"
134 rpntutorial \- Reading RRDtool RPN Expressions by Steve Rader
135 .SH "DESCRIPTION"
136 .IX Header "DESCRIPTION"
137 This tutorial should help you get to grips with RRDtool \s-1RPN\s0 expressions
138 as seen in \s-1CDEF\s0 arguments of RRDtool graph.
139 .SH "Reading Comparison Operators"
140 .IX Header "Reading Comparison Operators"
141 The \s-1LT\s0, \s-1LE\s0, \s-1GT\s0, \s-1GE\s0 and \s-1EQ\s0 \s-1RPN\s0 logic operators are not as tricky as
142 they appear.  These operators act on the two values on the stack
143 preceding them (to the left).  Read these two values on the stack
144 from left to right inserting the operator in the middle.  If the
145 resulting statement is true, then replace the three values from the
146 stack with \*(L"1\*(R".  If the statement if false, replace the three values
147 with \*(L"0\*(R".
148 .PP
149 For example, think about \*(L"2,1,GT\*(R".  This \s-1RPN\s0 expression could be
150 read as \*(L"is two greater than one?\*(R"  The answer to that question is
151 \&\*(L"true\*(R".  So the three values should be replaced with \*(L"1\*(R".  Thus the
152 \&\s-1RPN\s0 expression 2,1,GT evaluates to 1.
153 .PP
154 Now consider \*(L"2,1,LE\*(R".  This \s-1RPN\s0 expression could be read as \*(L"is
155 two less than or equal to one?\*(R".   The natural response is \*(L"no\*(R"
156 and thus the \s-1RPN\s0 expression 2,1,LE evaluates to 0.
157 .SH "Reading the IF Operator"
158 .IX Header "Reading the IF Operator"
159 The \s-1IF\s0 \s-1RPN\s0 logic operator can be straightforward also.  The key
160 to reading \s-1IF\s0 operators is to understand that the condition part
161 of the traditional \*(L"if X than Y else Z\*(R" notation has *already*
162 been evaluated.  So the \s-1IF\s0 operator acts on only one value on the
163 stack: the third value to the left of the \s-1IF\s0 value.  The second
164 value to the left of the \s-1IF\s0 corresponds to the true (\*(L"Y\*(R") branch.
165 And the first value to the left of the \s-1IF\s0 corresponds to the false
166 (\*(L"Z\*(R") branch.  Read the \s-1RPN\s0 expression \*(L"X,Y,Z,IF\*(R" from left to
167 right like so: \*(L"if X then Y else Z\*(R".
168 .PP
169 For example, consider \*(L"1,10,100,IF\*(R".  It looks bizarre to me.
170 But when I read \*(L"if 1 then 10 else 100\*(R" it's crystal clear: 1 is true
171 so the answer is 10.  Note that only zero is false; all other values
172 are true.  \*(L"2,20,200,IF\*(R" (\*(L"if 2 then 20 else 200\*(R") evaluates to 20.
173 And \*(L"0,1,2,IF\*(R" ("if 0 then 1 else 2) evaluates to 2.
174 .PP
175 Notice that none of the above examples really simulate the whole
176 \&\*(L"if X then Y else Z\*(R" statement.  This is because computer programmers
177 read this statement as \*(L"if Some Condition then Y else Z\*(R".  So it's
178 important to be able to read \s-1IF\s0 operators along with the \s-1LT\s0, \s-1LE\s0,
179 \&\s-1GT\s0, \s-1GE\s0 and \s-1EQ\s0 operators.
180 .SH "Some Examples"
181 .IX Header "Some Examples"
182 While compound expressions can look overly complex, they can be
183 considered elegantly simple.  To quickly comprehend \s-1RPN\s0 expressions,
184 you must know the algorithm for evaluating \s-1RPN\s0 expressions:
185 iterate searches from the left to the right looking for an operator.
186 When it's found, apply that operator by popping the operator and some
187 number of values (and by definition, not operators) off the stack.
188 .PP
189 For example, the stack \*(L"1,2,3,+,+\*(R" gets \*(L"2,3,+\*(R" evaluated (as \*(L"2+3\*(R")
190 during the first iteration and is replaced by 5.  This results in
191 the stack \*(L"1,5,+\*(R".  Finally, \*(L"1,5,+\*(R" is evaluated resulting in the
192 answer 6.  For convenience, it's useful to write this set of
193 operations as:
194 .PP
195 .Vb 3
196 \& 1) 1,2,3,+,+    eval is 2,3,+ = 5    result is 1,5,+
197 \& 2) 1,5,+        eval is 1,5,+ = 6    result is 6
198 \& 3) 6
199 .Ve
200 .PP
201 Let's use that notation to conveniently solve some complex \s-1RPN\s0 expressions
202 with multiple logic operators:
203 .PP
204 .Vb 1
205 \& 1) 20,10,GT,10,20,IF  eval is 20,10,GT = 1     result is 1,10,20,IF
206 .Ve
207 .PP
208 read the eval as pop \*(L"20 is greater than 10\*(R" so push 1
209 .PP
210 .Vb 1
211 \& 2) 1,10,20,IF         eval is 1,10,20,IF = 10  result is 10
212 .Ve
213 .PP
214 read pop \*(L"if 1 then 10 else 20\*(R" so push 10.  Only 10 is left so
215 10 is the answer.
216 .PP
217 Let's read a complex \s-1RPN\s0 expression that also has the traditional
218 multiplication operator:
219 .PP
220 .Vb 4
221 \& 1) 128,8,*,7000,GT,7000,128,8,*,IF  eval 128,8,*       result is 1024
222 \& 2) 1024,7000,GT,7000,128,8,*,IF     eval 1024,7000,GT  result is 0
223 \& 3) 0,128,8,*,IF                     eval 128,8,*       result is 1024
224 \& 4) 0,7000,1024,IF                                      result is 1024
225 .Ve
226 .PP
227 Now let's go back to the first example of multiple logic operators,
228 but replace the value 20 with the variable \*(L"input\*(R":
229 .PP
230 .Vb 1
231 \& 1) input,10,GT,10,input,IF  eval is input,10,GT  ( lets call this A )
232 .Ve
233 .PP
234 Read eval as \*(L"if input > 10 then true\*(R" and replace \*(L"input,10,GT\*(R"
235 with \*(L"A\*(R":
236 .PP
237 .Vb 1
238 \& 2) A,10,input,IF            eval is A,10,input,IF
239 .Ve
240 .PP
241 read \*(L"if A then 10 else input\*(R".  Now replace A with it's verbose
242 description again and\*(--voila!\-\-you have a easily readable description
243 of the expression:
244 .PP
245 .Vb 1
246 \& if input > 10 then 10 else input
247 .Ve
248 .PP
249 Finally, let's go back to the first most complex example and replace
250 the value 128 with \*(L"input\*(R":
251 .PP
252 .Vb 1
253 \& 1) input,8,*,7000,GT,7000,input,8,*,IF  eval input,8,*     result is A
254 .Ve
255 .PP
256 where A is \*(L"input * 8\*(R"
257 .PP
258 .Vb 1
259 \& 2) A,7000,GT,7000,input,8,*,IF          eval is A,7000,GT  result is B
260 .Ve
261 .PP
262 where B is \*(L"if ((input * 8) > 7000) then true\*(R"
263 .PP
264 .Vb 1
265 \& 3) B,7000,input,8,*,IF                  eval is input,8,*  result is C
266 .Ve
267 .PP
268 where C is \*(L"input * 8\*(R"
269 .PP
270 .Vb 1
271 \& 4) B,7000,C,IF
272 .Ve
273 .PP
274 At last we have a readable decoding of the complex \s-1RPN\s0 expression with
275 a variable:
276 .PP
277 .Vb 1
278 \& if ((input * 8) > 7000) then 7000 else (input * 8)
279 .Ve
280 .SH "Exercises"
281 .IX Header "Exercises"
282 Exercise 1:
283 .PP
284 Compute \*(L"3,2,*,1,+ and \*(R"3,2,1,+,*" by hand.  Rewrite them in
285 traditional notation.  Explain why they have different answers.
286 .PP
287 Answer 1:
288 .PP
289 .Vb 3
290 \&    3*2+1 = 7 and 3*(2+1) = 9.  These expressions have
291 \&    different answers because the altering of the plus and
292 \&    times operators alter the order of their evaluation.
293 .Ve
294 .PP
295 Exercise 2:
296 .PP
297 One may be tempted to shorten the expression
298 .PP
299 .Vb 1
300 \& input,8,*,56000,GT,56000,input,*,8,IF
301 .Ve
302 .PP
303 by removing the redundant use of \*(L"input,8,*\*(R" like so:
304 .PP
305 .Vb 1
306 \& input,56000,GT,56000,input,IF,8,*
307 .Ve
308 .PP
309 Use traditional notation to show these expressions are not the same.
310 Write an expression that's equivalent to the first expression, but
311 uses the \s-1LE\s0 and \s-1DIV\s0 operators.
312 .PP
313 Answer 2:
314 .PP
315 .Vb 2
316 \&    if (input <= 56000/8 ) { input*8 } else { 56000 }
317 \&    input,56000,8,DIV,LT,input,8,*,56000,IF
318 .Ve
319 .PP
320 Exercise 3:
321 .PP
322 Briefly explain why traditional mathematic notation requires the
323 use of parentheses.  Explain why \s-1RPN\s0 notation does not require
324 the use of parentheses.
325 .PP
326 Answer 3:
327 .PP
328 .Vb 6
329 \&    Traditional mathematic expressions are evaluated by
330 \&    doing multiplication and division first, then addition and
331 \&    subtraction.  Parentheses are used to force the evaluation of
332 \&    addition before multiplication (etc).  RPN does not require
333 \&    parentheses because the ordering of objects on the stack
334 \&    can force the evaluation of addition before multiplication.
335 .Ve
336 .PP
337 Exercise 4:
338 .PP
339 Explain why it was desirable for the RRDtool developers to implement
340 \&\s-1RPN\s0 notation instead of traditional mathematical notation.
341 .PP
342 Answer 4:
343 .PP
344 .Vb 5
345 \&    The algorithm that implements traditional mathematical
346 \&    notation is more complex then algorithm used for RPN.
347 \&    So implementing RPN allowed Tobias Oetiker to write less
348 \&    code!  (The code is also less complex and therefore less
349 \&    likely to have bugs.)
350 .Ve
351 .SH "AUTHOR"
352 .IX Header "AUTHOR"
353 Steve Rader <rader@wiscnet.net>