Code

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