File: spiel.html

package info (click to toggle)
lg-issue71 1-2
  • links: PTS
  • area: main
  • in suites: woody
  • size: 2,104 kB
  • ctags: 218
  • sloc: perl: 89; makefile: 58; sh: 45; tcl: 14
file content (1412 lines) | stat: -rw-r--r-- 49,720 bytes parent folder | download
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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
<!--startcut  ==============================================-->
<!-- *** BEGIN HTML header *** -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML><HEAD>
<title>Numerical Workbenches, part III LG #71</title>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#0000AF"
ALINK="#FF0000">
<!-- *** END HTML header *** -->

<CENTER>
<A HREF="http://www.linuxgazette.com/">
<IMG ALT="LINUX GAZETTE" SRC="../gx/lglogo.png" 
	WIDTH="600" HEIGHT="124" border="0"></A> 
<BR>

<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="qubism.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="lg_toc71.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../lg_frontpage.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue71/spiel.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><A HREF="../lg_faq.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="lg_backpage71.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
<!-- *** END navbar *** -->
<P>
</CENTER>

<!--endcut ============================================================-->

<H4 ALIGN="center">
"Linux Gazette...<I>making Linux just a little more fun!</I>"
</H4>

<P> <HR> <P> 
<!--===================================================================-->

<center>
<H1><font color="maroon">Numerical Workbenches, part III</font></H1>
<H4>By <a href="mailto:cspiel@hammersmith-consulting.com">Christoph Spiel</a></H4>
</center>
<P> <HR> <P>  

<!-- END header -->




<p>Parts&nbsp;I and II of this little series on numerical math workbenches on
GNU/Linux have covered rather dry subjects like matrix manipulations and <em>
for</em>-loops. This part brings more color to the screens as it turns to the
graphical capabilities of GNU/Octave, Scilab, and Tela. It will deviate from
the previous way of presenting the three applications, because the differences
of the graphical backends are far too big to allow for a uniform treatment
with only a few explanations on the differences.</p>

<p>The article starts with an introduction applicable to all programs. To give
the reader maximum benefit, all applications have to solve the same three real
life <a href="#problems">problems</a>. This simplifies the comparison despite
the differences of the implementations. In the last part, <a href="#octave">
Octave</a>, <a href="#scilab">Scilab</a>, and <a href="#tela">Tela</a> have to
tackle the given tasks.</p>

<h2><a name="introduction">Introduction</a></h2>

<dl>
<dt><strong><a name="item_Discrete_Data_Only">Discrete Data
Only</a></strong><br>
</dt>

<dd>As all three applications are designed to work with vectors and matrices,
their graphics backends only understand this kind of data. Doh! For the user
this means that the graph of a mathematical function like 

<pre>
                { sin(x)/x  for x &lt;&gt; 0
    y := f(x) = {
                {    1      for x == 0
</pre>

<p>cannot be drawn from the above expression, but the function has to be
transformed into discrete pairs&nbsp;(<em>x(i)</em>,&nbsp;<em>y(i)</em>). This
transformation is called sampling. To sample <em>f(x)</em>, we pick
values&nbsp;<em>x</em> where we are interested in <em>f(x)</em> and compute
<em>f</em> for the given <em>x</em>. Any reader who has followed the earlier
parts, will immediately recognize that this involves a vector operation.</p>

<pre>
    ### GNU/Octave code
</pre>

<pre>
    function y = f(x)
        if x == 0.0
            y = 1.0;
        else
            y = sin(x) ./ x;
        endif
    endfunction
</pre>

<pre>
    x = linspace(0.0, 4*pi, 50);
    y = f(x);
</pre>

<p><em>linspace(start, end, n)</em> returns a vector from <em>start</em> to
<em>end</em>, whose <em>n</em>&nbsp;elements are evenly spaced. The
vectors&nbsp;<em>x</em> and <em>y</em> can be passed to an appropriate
plotting function.</p>

<p>If data already are in vectorized form, they can be displayed
immediately.</p>
</dd>

<dt><strong><a name="item_Complexity_at_Large">Complexity at
Large</a></strong><br>
</dt>

<dd>How do we actually display a graph? This question leads us to the
fundamental problem all applications run into when it comes to graphical
output of data: either complicated or many simple function calls! Let us first
consider the complexity for the user of a call to solve a system of linear
equations 

<pre>
    x = a \ b             # Octave, Scilab
</pre>

<p>or</p>

<pre>
    x = linsolve(a, b)    // Tela
</pre>

<p>Even if we try hard to artificially complicate the calls (yet leaving them
useful), we hit the end of the road at</p>

<pre>
    x = linsolve(a, b, "CompletePivoting", "DoIterativeRefinement")
</pre>

<p>This is, with the two additional parameters -- pivoting strategy and
iterative refinement of the solution -- the user completely controls <em>
linsolve()</em>. All other ``decisions'' can reasonably be taken by the
workbench itself, for example, what algorithm to use if matrix&nbsp;<em>a</em>
has a special form.</p>

<p>Contrast this with the 2d-graph of</p>

<pre>
    x = [2.25,  2.27,  2.42,  ...]
    y = [0.363, 0.360, 0.337, ...]
</pre>

<p>What options can we think of?</p>

<ul>
<li>Draw isolated data points or connect data points with straight lines.</li>

<li>Which symbol to draw at each data point? A dot, star, circle, or asterisk?
What color should the data points be?</li>

<li>Which kind of line to draw between the data points? Continuous, dashed,
dotted, or dash-dotted? What line thickness and what color is the line?</li>

<li>Scale the plot to fit within the plotting window?</li>

<li>Draw coordinate axes? Linear or logarithmic <em>x</em> or <em>y</em> axis?
Both axes logarithmic?</li>

<li>Graduate or annotate the axes?</li>

<li>...</li>
</ul>

<p>Many more reasonable options are conceivable. The point is: we cannot
expect plotting to be as simple to use as is for example solving a system of
linear equations -- not because the applications are badly written, but
because the topic is inherently more complicated on the user's side. Hence,
nobody should be surprised if she ever needs 20 or more lines to define a
publication quality plot in Octave, Scilab, or Tela.</p>
</dd>
</dl>

<h2><a name="problems">Problems</a></h2>

<p>To make the competition interesting, I put up problems, which are not too
far away from the Real World(tm). Each of the three applications will have to
cope with three different types of plots:</p>

<ol>
<li><strong><a name="item_2D_Plot_of_Discrete_Data">2D Plot of Discrete
Data</a></strong><br>
 

<p>Display three sets of data (<a href="misc/spiel/l1.ascii">l1.ascii</a>, <a
href="misc/spiel/l2.ascii">l2.ascii</a>, <a href="misc/spiel/l3.ascii">
l3.ascii</a>) on a single page. The sets have a different number of data
points.</p>

<p>The data are stored as two columns, column&nbsp;1 holds the <em>
x</em>-value, and column&nbsp;2 the <em>y</em>-value:</p>

<pre>
    0.2808  3.419E-07
    0.3711  3.459E-07
    0.4882  3.488E-07
    ...
</pre>

<p>The graph must show title, axes captions, and legend. The <em>x</em> and
<em>y</em> ranges are supplied by the user.</p>
</li>

<li><strong><a name="item_3D_Plot_of_a_Function">3D Plot of a
Function</a></strong><br>
 Plot Rosenbrock's function (in two dimensions) 

<pre>
    f(u, v) = 100*(v - u^2)^2 + (1 - u)^2
</pre>

<p>as a 3d-surface in the parameter ranges -3&nbsp;&lt;=&nbsp;<em>
u</em>&nbsp;&lt;=&nbsp;3 and -2&nbsp;&lt;=&nbsp;<em>
v</em>&nbsp;&lt;=&nbsp;4.</p>

<p>Annotate the plot with title and axes captions.</p>
</li>

<li><strong><a name="item_Contour_Plot_of_a_Function">Contour Plot of a
Function</a></strong><br>
 Plot function 

<pre>
    g(u, v) = exp(u) * (4*u^2 + 2*v^2 + 4*u*v + 2*v + 1)
</pre>

<p>with contours, this is, <em>f(u, v) = z</em> for given <em>z</em> in the
parameter ranges -4.5&nbsp;&lt;=&nbsp;<em>u</em>&nbsp;&lt;=&nbsp;-0.5 and
-1&nbsp;&lt;=&nbsp;<em>v</em> &lt;=&nbsp;3.</p>

<p>The iso-lines are defined by a user-specified ``weight'' function.</p>

<pre>
                          (  z - z_0  ) 3
    z_iso = (z_1 - z_0) * ( --------- )   + z_0
                          ( z_1 - z_0 )
</pre>

<p>where <em>z_0</em> and <em>z_1</em> are the minimum and maximum values of
<em>g(u, v)</em> in the plot's range.</p>

<p>Again, annotate the plot with title and axes captions.</p>
</li>
</ol>

<p>All graphics must be rendered for two devices,</p>

<ul>
<li>X11 terminal and</li>

<li>Postscript printer.</li>
</ul>

<h2><a name="octave">Octave</a></h2>

<p>You know Gnuplot? Then learning to use GNU/Octave's plot functions will be
a piece of cake. All you need to do is precede the Gnuplot commands with a
``<code>g</code>'' to reach at the Octave equivalent. -- Oh, you haven't tried
Gnuplot yet? Then I will guide you through the examples. However, having a
Gnuplot manual (online or dead-tree edition) ready may be helpful.</p>

If you do not want to download Gnuplot's manual, you can use one of the <a
href= 
"http://pi3.informatik.uni-mannheim.de/staff/mitarbeiter/westmann/gnuplot.html">
publicly accessible versions</a>.

<h3><a name="octave: 2d discrete data plot">Octave: 2D Discrete Data
Plot</a></h3>

<p>For an easier discussion, I have split the code into blocks. Each block
gathers commands that belong together. The blocks are labeled with numbers in
square brackets, to allow for referencing them in the text.</p>

<pre>
    ### [1] Read data set_i into N_i-times-2 matrices
    set1 = load("l1.ascii");
    set2 = load("l2.ascii");
    set3 = load("l3.ascii");
</pre>

<pre>
    ### [2] Reset Gnuplot
    graw("reset;");
    clearplot;
</pre>

<pre>
    ### [3] Define decorations and plot area
    gset title "Comparison of sets L1, L2, and L3";
    gset xlabel "Temperature / K";
    gset ylabel "Voltage / V";
    gset key top left;
    gset xrange [0 : 100];
    gset yrange [8e-8 : 2e-6];
</pre>

<pre>
    ### [4] Plot data
    hold on;
    gplot set1 title "Set L1" with points;
    gplot set2 title "Set L2" with points;
    gplot set3 title "Set L3" with points;
    hold off;
</pre>

<pre>
    ### [5] Switch to PostScript output and plot into file
    gset terminal push;
    gset terminal postscript;
    gset output "oct1.eps";
    replot;
    gset terminal pop;
    gset output;
</pre>

<p><img height="450" alt=
"[Graphics: The Gnuplot window that has been opened by Octave's graphics commands shows the three data sets. The data points are drawn with blue, green, and red markers. The markers themselves have different shape. The plot has a title. Both axes show the annotations as defined by the gset-commands.]"
 src="misc/spiel/oct1.png" width="600"> The output to the Postscript terminal,
block&nbsp;[6], produced a <a href="misc/spiel/oct1.eps">printable version
(eps)</a> of the graphics.</p>

<p>Block&nbsp;[1] should be clear from the previous articles. The first
interaction with Gnuplot happens in [2], where Gnuplot is reset to a known
state and the X11-plot window gets cleared. A known state is helpful when
still experimenting with Gnuplot's options. In our case reseting is
unnecessary, but it does not hurt.</p>

<p>The block of <code>gset</code> commands, [3] is self explaining except</p>

<pre>
    gset key top left
</pre>

<p>which means: ``put the legend (or key) inside the plotting area at the
north-west corner''. <code>xrange</code> and <code>yrange</code> with their
special interval syntax set the width and height of the plot range.</p>

<p>Now, the actual data can be rendered into the plot window [4]. Because the
data sets have different sizes, they cannot be gathered in a single matrix.
Hence, each data set must be plotted by itself, and Gnuplot must be told --
with <code>hold on</code> -- that it should collect all <code>
gplot</code>&nbsp;commands until the last plot of the set is completed and
<code>hold off</code> is called. The calls to <em>gplot</em> essentially
contain the data matrix</p>

<pre>
    gplot set1
</pre>

<p>The title, which shows up in the plot's legend, is assigned in the call to
<code>gplot</code>, too.</p>

<p>Block&nbsp;[5] is specific to the way Gnuplot works. For each plot it uses
a <em>terminal</em> and an <em>output</em> file (remember that in UN*X
everything is a file, as for example is the console). When Gnuplot is running
under X, the terminal type defaults to X11 and output file defaults to
Gnuplot's X11-graphic window. Both, <em>terminal</em> and <em>
output</em>&nbsp;file can be changed independently with <code>gset</code>
commands. Thus, to get the same graphics in a different format, we switch from
the current terminal to Postscript, and put an ordinary file's name at the
output. Function&nbsp;<code>replot</code> replays all plot commands for us, we
do not have to write them again. After that the terminal and output settings
are undone, which is optional, but helpful if the user wants to twiddle some
more <code>gset</code>'s and repeatedly check their influence on the graph's
appearance.</p>

<h3><a name="octave: 3d function plot">Octave: 3D Function Plot</a></h3>

<pre>
    ### [1] Define function
    function z = f(u, v)
        ## truncated Rosenbrock function
        z = 100.0*(v - u.^2).^2 + (1.0 - u).^2;
        zv = z(:);
        zv(find(zv &gt; 100.0)) = 100.0;
        z = reshape(zv, size(z));
    endfunction
</pre>

<pre>
    ### [2] Sample function f()
    x = linspace(-3, 3, 40);
    y = linspace(-2, 4, 40);
    [xx, yy] = meshgrid(x, y);
    z_splot = splice_mat(xx, yy, f(xx, yy));
</pre>

<pre>
    ### [3] Reset Gnuplot
    graw("reset;");
    clearplot;
</pre>

<pre>
    ### [4] Define decorations and viewing direction
    gset data style line;
    gset title "Rosenbrock Function";
    gset xlabel "u";
    gset ylabel "v";
    gset view 30, 160;
    gset hidden;
    gset nokey
    gset parametric;
</pre>

<pre>
    ### [5] Plot
    gsplot z_splot;
</pre>

<pre>
    ### [6] Switch to PostScript output and plot into file
    gset terminal push;
    gset terminal postscript;
    gset output "oct2.eps";
    replot;
    gset terminal pop;
    gset output;
    gset noparametric;
</pre>

<pre>
    system("gzip --best --force oct2.eps");
</pre>

<p><img height="450" alt=
"[Graphics: The Gnuplot window shows a red-mesh that is 'deformed' according to function f(u, v). The whole plot looks like the imprint of a boomerang.]"
 src="misc/spiel/oct2.png" width="600"> A <a href="misc/spiel/oct2.eps.gz">
printer-ready version</a> (eps.gz) is available, too.</p>

<p>Again the first block, [1], should be easy to understand for anyone who has
read Part&nbsp;1 and 2 of this series for it only uses known functions. In
contrast, [2] introduces two new functions. Out friend <em>linspace()</em>
quickly generates two vectors which will define where <em>f(u, v)</em> will be
evaluated: from vectors&nbsp;<em>x</em> and <em>y</em>, a grid is constructed,
this is, two matrices&nbsp;<em>xx</em> and <em>yy</em>, where each pair of
matrix elements <em>(xx(i,&nbsp;j),&nbsp;yy(i,&nbsp;j))</em>,
1&nbsp;&lt;=&nbsp;<em>i</em>,&nbsp;<em>j</em> &lt;=&nbsp;40, define a (grid-)
point at which function&nbsp;<em>z&nbsp;=&nbsp;f(u, v)</em> will be evaluated.
The matrix of all <em>z</em>-values at the grid points then simply is <code>zz
= f(xx, yy)</code>. However, we are not done at this point, because Octave
requires to pass a specially formatted matrix to the 3d-plot
function&nbsp;<em>gsplot</em>.</p>

<p>The user-defined function <a href="misc/spiel/splice_mat.m">
splice_mat()</a> does exactly the needed operation: collect the grid data <em>
xx</em> and <em>yy</em> along with the <em>z</em>-values in matrix&nbsp;<em>
z_plot</em>. Matrix&nbsp;<em>z_plot</em> can be handed over to <em>gsplot</em>
without further ado (given Gnuplot is in parametric mode. (we will be in
parametric mode and for the given kind of problem parametric mode is the only
way to go (and I don't want to introduce another level of parenthesis
(really!))))</p>

<p>Block&nbsp;[4], a collection of <code>gset</code>s, looks almost familiar.
Some new settings are</p>

<ul>
<li><strong><a name="item_gset_data_style_line">gset data style
line</a></strong><br>
 Join adjacent mesh-points with (by default: red) lines.</li>

<li><strong><a name="item_gset_view_x_angle%2C_z_angle">gset view x_angle,
z_angle</a></strong><br>
 Rotate the view point around the <em>x</em>-axis by <em>x_angle</em> degrees,
then rotate around the new <em>z</em>-axis by <em>z_angle</em> degrees.</li>

<li><strong><a name="item_gset_hidden">gset hidden</a></strong><br>
 Suppress invisible mesh lines. The back side of the mesh is drawn differently
(green in the X11-window and with dashed black lines in the
Postscript&nbsp;terminal).</li>

<li><strong><a name="item_gset_nokey">gset nokey</a></strong><br>
 Suppress any legend.</li>

<li><strong><a name="item_gset_parametric">gset parametric</a></strong><br>
 See GNU/Octave's documentation. (<code>help -i gsplot</code> from Octave, or
<code>info octave --node='Three-Dimensional Plotting'</code> from the
shell.)</li>
</ul>

<p>After so much preparation, the actual plot command, <code>gsplot
z_splot</code> in [5] looks trivial.</p>

<p>The Postscript block&nbsp;[6] is similar to [5] in Section <a href= 
"#octave: 2d discrete data plot">``Octave: 2d discrete data plot''</a>. The
only additional job [6] does is gzipping the eps-file. In general <em>
system(``shell-commands'')</em> executes <em>shell-commands</em> in a
sub-shell. Obviously, this is extremely useful when interacting with an
external application, like gzip(1).</p>

<h3><a name="octave: contour function plot">Octave: Contour Function
Plot</a></h3>

<pre>
    ### [1] Define function
    function z = g(u, v)
        z = exp(u) .* (4.0*u.^2 + 2.0*v.^2 + 4.0*u.*v + 2.0*v + 1.0);
    endfunction
</pre>

<pre>
    ### [2] Define weight function for iso-line distances
    function y = pow_weight(x, n)
        ## Map interval X onto itself, weight with N-th power.
        d = max(x) - min(x);
        y = d*((x - min(x))/d).^n + min(x);
    endfunction
</pre>

<pre>
    ### [3] Sample function g()
    x = linspace(-4.5, -0.5, 40);
    y = linspace(-1.0, 3.0, 40);
    [xx, yy] = meshgrid(x, y);
    zz = g(xx, yy);
    z_splot = splice_mat(xx, yy, zz);
</pre>

<pre>
    ### [4] Compute iso-line distances
    iso_levels = pow_weight(linspace(min(min(zz))*1.01, ...
                                     max(max(zz))*0.99, 12), 3.0);
    il_str = sprintf("%f,", iso_levels);
    il_str = il_str(1 : length(il_str)-1);    # remove last ","
</pre>

<pre>
    ### [5] Reset Gnuplot
    graw("reset;");
    clearplot;
</pre>

<pre>
    ### [6] Define decorations and viewing direction
    gset data style line;
    gset title "Contour Plot of g(u, v)";
    gset xlabel "u";
    gset ylabel "v";
    gset contour base;
    gset nosurface;
    gset view 0, 0;
    eval(sprintf("gset cntrparam levels discrete %s", il_str));
    gset parametric;
</pre>

<pre>
    ### [7] Plot
    gsplot z_splot;
</pre>

<pre>
    ### [8] Switch to PostScript output and plot into file
    gset terminal push;
    gset terminal postscript;
    gset output "oct3.eps";
    replot;
    gset terminal pop;
    gset output;
    gset noparametric;
</pre>

<p><img height="450" alt=
"[Graphics: The Gnuplot window shows 12 iso-lines each with a different color. The plot exhibits a saddle point of g(u, v) in the right third of the image.]"
 src="misc/spiel/oct3.png" width="600"> A <a href="misc/spiel/oct3.eps">
printable version (eps)</a> is available, too.</p>

<p>After working through the 2d discrete and the 3d function plot examples,
the top three blocks&nbsp;[1-3] of the contour function script should not
raise many questions. In block&nbsp;[4] however, I have to prepare a trick,
which I must play at the end of block&nbsp;[6]. The job is to plot contour
lines with a user-defined function. The values of this function and therefore
the positions of the iso-lines are not known in advance.</p>

<p>Gnuplot offers several ways to define iso-lines, for example, automatic
computation of a given number of (linearly spaced) contours or defining a
minimum and a maximum contour value with a fixed increment between two
adjacent contours. Our problem requires a more general solution because the
iso-lines are not equally spaced along the <em>z</em>-axis. For completely
arbitrary iso-line values, as the third way if specifying contour lines,
Gnuplot has the following <code>gset</code> command</p>

<pre>
    gset cntrparam discrete z1, z2, ..., zN
</pre>

<p>where <em>z1</em>, <em>z2</em>, ..., <em>zN</em> are the <em>z</em>-values
of the iso-lines given as <em>floating point literals</em>. Thus,</p>

<pre>
    gset cntrparam discrete 0.2, 0.4, 0.8
</pre>

<p>is a perfect call, whereas</p>

<pre>
    z1 = 0.2
    z2 = 0.4
    z3 = 0.8
    gset cntrparam discrete z1, z2, z3
</pre>

<p>is nothing but a syntax error as would be</p>

<pre>
    gset cntrparam discrete iso_levels
</pre>

<p>Remember, <code>gset</code> needs floating point literals!</p>

<p>We are stuck unless we apply a bit of magic. If we present a complete
<code>gset</code> line to Octave, one where the values of vector <em>
iso_levels</em> are ``interpolated'' into (Perl programmers do this all day
long), the race is won. Here is how the trick is played:</p>

<pre>
    # Convert iso_levels to comma-separated string.  Octave reuses
    # the format specifier list if there are more items to print than
    # there are format specifiers.  Don't try this with C's printf :-)
    il_string = sprintf("%f,", iso_levels)
</pre>

<pre>
    # Remove comma past last contour value in the string.
    il_string = il_string(1 : length(il_string)-1)
</pre>

<pre>
    # Play interpolation trick a second time
    gset_string = sprintf("gset cntrparam levels discrete %s", il_string);
</pre>

<pre>
    # Execute the command which is stored in the variable gset_string
    eval(gset_string);
</pre>

<p>For readers who do not like abstract descriptions, this is a transcript of
a session (where long lines have been edited to fit):</p>

<pre>
    octave:10&gt; il_string = sprintf("%f,", iso_levels)
    il_string = 0.583444,0.592029,0.652120,0.815224,1.132847,1.656497, \
                2.437679,3.527900,4.978667,6.841486,9.167864,12.009307,
    octave:11&gt; il_string = il_string(1 : length(il_string)-1)
    il_string = 0.583444,0.592029,0.652120,0.815224,1.132847,1.656497, \
                2.437679,3.527900,4.978667,6.841486,9.167864,12.009307
    octave:12&gt; gset_string = sprintf("gset cntrparam levels discrete %s", \
                                     il_string)
    gset_string = gset cntrparam levels discrete 0.583444,0.592029, \
                0.652120,0.815224,1.132847,1.656497,2.437679,3.527900, \
                4.978667,6.841486,9.167864,12.009307
</pre>

<p>In the script, no temporary variable&nbsp;<em>gset_string</em> has been
introduced, but <em>sprintf()</em> sends its output directly to <em>
eval()</em>.</p>

<p>Block&nbsp;[6]: Gnuplot does not excel in plotting contours. In fact the
GNuplot user-manual suggests not to use it directly. Anyhow, we proceed,
because the out approach is easier to understand. The following three <code>
gset</code>s switch Gnuplot into contour-mode:</p>

<pre>
    gset contour base    # draw contours in the xy-plane
    gset nosurface       # do not draw the surface's mesh
    gset view 0, 0       # view the xy-plane from above
</pre>

<p>Blocks&nbsp;[7] and [8] closely resemble those we have already seen in
Section <a href="#octave: 2d discrete data plot">``Octave: 2D Discrete Data
Plot''</a> and <a href="#octave: 3d function plot">``Octave: 3D Function
Plot''</a>.</p>

<p>More demo plots of Gnuplot can be found at <a href= 
"http://www.gnuplot.org/gnuplot/gpdocs/all2.htm">
http://www.gnuplot.org/gnuplot/gpdocs/all2.htm</a></p>

<h2><a name="scilab">Scilab</a></h2>

<p>And now for a rather different approach ...</p>

<p>Scilab goes a different way to cope with the complexity, which we have
discussed in Section <a href="#complexity at large">Complexity at Large</a>.
In contrary to Gnuplot, Scilab does not strictly separate plotting and
setting, but offers a plethora (buckle up, then try: <code>apropos
plot</code>) of different plot commands to produce different kinds of plots.
Furthermore, the plot functions themselves take many arguments that change the
plots' appearances. Some of the arguments are so cryptic that you almost
certainly will want to have the appropriate man-page within sight.</p>

<p>For the reader who wants to look at the on-line help, but does not have
Scilab installed, the <a href= 
"http://www.num.uni-sb.de/~ehrhardt/Ue_PraMa/scilab/doc/html/manual/docu023.html">
Scilab manual</a> is available online.</p>

<h3><a name="scilab: 2d discrete data plot">Scilab: 2D Discrete Data
Plot</a></h3>

<pre>
    // [1] Read data set_i into N_i-times-2 matrices
    set1 = read("l1.ascii", -1, 2);
    set2 = read("l2.ascii", -1, 2);
    set3 = read("l3.ascii", -1, 2);
</pre>

<pre>
    // [2] Clear plot window's contents
    xbasc();
</pre>

<pre>
    // [3] Plot data; 1st plot command defines plot area
    plot2d(set1(:, 1), set1(:, 2), -1, "011", ..
           rect = [0, 8e-8, 100, 2e-6]);
    plot2d(set2(:, 1), set2(:, 2), -2, "000");
    plot2d(set3(:, 1), set3(:, 2), -3, "000");
</pre>

<pre>
    // [4] Define decorations
    xtitle(["Comparison of sets", "L1, L2, and L3"], ..
           "Temperature / K", "Voltage / V");
    legends(["Set L1   ", "Set L2   ", "Set L3   "], [-1, -2, -3], 2);
</pre>

<pre>
    // [5] Save plot window's contents to file; convert file to PostScript
    xbasimp(0, "sci1.xps");
    unix("scilab -save_p sci1.xps.0 Postscript");
</pre>

<p><img height="447" alt=
"[Graphics: Please see the image caption of '2D Discrete Data Plot' in the Octave section.]"
 src="misc/spiel/sci1.png" width="600"> The <a href="misc/spiel/sci1.eps">
Encapsulated Postscript output</a> is available, too.</p>

<p>Block&nbsp;[1] reads the data from disk-files into matrices.</p>

<p>Block&nbsp;[2] clears the graphics window (if it exists). Even more
important, <em>xbasc()</em> deletes all graphics commands that have been
recorded for the window. The mnemonic for <em>xbasc()</em> is x-bas-c for
<strong>x</strong>11-function, <strong>bas</strong>ic level, <strong>
c</strong>lear.</p>

<p>Tip: When playing with Scilab's plot functions, preceding the plot function
call with a clear command often saves keystrokes</p>

<pre>
    xbasc(); plot2d(...);
</pre>

<p>in one line can be recalled for editing with a single C-p and replayed with
a single hit of the return-key.</p>

<p>In Block&nbsp;[3] the enigma raises its head! What in the world does</p>

<pre>
   plot2d(set1(:, 1),                      // vector of x-values
          set1(:, 2),                      // vector of y-values
          -1,                              // style index
          "011",                           // decoration control
          rect = [0, 8e-8, 100, 2e-6]);    // plot dimensions
</pre>

<p>do? I have added a comment for each argument, yet, to what does a ``style
index'' of -1 refer to? A badly dressed hacker? And what does the string in
``decoration control'' mean?</p>

<dl>
<dt><strong><a name="item_Style_index">Style index</a></strong><br>
</dt>

<dd>controls the kind of marker to draw for each data point or the color of
the line that joins the data points. A positive value&nbsp;<em>i</em> means:
draw a line with color&nbsp;<em>i</em>, a negative value means: use marker
type&nbsp;<em>abs(i)</em>. Note that <em>plot2d()</em> draws either markers or
lines, never both. If markers and lines are required for the same data set,
two plots with different style indices are necessary.</dd>

<dt><strong><a name="item_Decoration_control">Decoration
control</a></strong><br>
</dt>

<dd>always is a string of length&nbsp;3. Each character of the string controls
a certain aspect of the plot's decorations. 

<dl>
<dt><strong><a name="item_Character_1">Character 1</a></strong><br>
</dt>

<dd>Toggle display of the plot caption. '<code>0</code>' is no caption,
'<code>1</code>' tells Scilab to display a caption.</dd>

<dt><strong><a name="item_Character_2">Character 2</a></strong><br>
</dt>

<dd>Control how the size of the plot is computed. Valid characters range from
'<code>0</code>' to '<code>8</code>'. Please see <em>plot2d()</em>
documentation for details. 

<p>Here, we use '<code>1</code>' for the first plot and '<code>0</code>' for
all others. '<code>1</code>' lets the user explicitely specify the plot range
in the <code>rect</code>&nbsp;argument to <em>plot2d()</em>. If <em>
plot2d()</em> is called with '<code>0</code>', the size of a previous plot is
used and no size computation is done.</p>
</dd>

<dt><strong><a name="item_Character_3">Character 3</a></strong><br>
</dt>

<dd>Set the type of axes drawn around the plot. The user can choose from six
different values. We choose '<code>1</code>' for the first plot, which gives
axes on the bottom and the left hand side. The following plots use
'<code>0</code>', which means nothing is drawn around the plot.</dd>
</dl>
</dd>
</dl>

<p>Gee, that is quite a mouthful! Block&nbsp;[4] will give us some rest.</p>

<pre>
    xtitle([title_line1; title_line2; ...], x_label, y_label)
</pre>

<p>Puts a possibly multi-line title into an existing plot and optionally
decorates the <em>x</em> and <em>y</em>-axis with labels.</p>

<pre>
    legends([legend_1, legend_2, ...], [style_1, style_2, ...], position)
</pre>

<p>Places a legend in a plot where the position is given by <em>position</em>.
<em>position = 1</em> refers to the north east corner. The remaining corners
are enumerated counter-clockwise, this is, <em>position = 2</em> will put the
legend in the north west corner. The <em>style_i</em> parameters refer to the
same numbers that we have used as style indices in the <em>plot2d()</em>
calls. They determine which kind of marker or line is drawn right next to the
legend's text. The text is given by <em>legend_i</em>.</p>

<p>Finally, Block&nbsp;[5] converts the data in the graphics window to a
Postscript file.</p>

<pre>
    xbasimp(0, "sci1.xps")
</pre>

<p>Replays all graphics commands for window&nbsp;0 (our only graphics window)
into <em>sci1.xps</em>. The function's name has nothing to do with a
X11-daemon named ``bas'', but has its stem from <strong>x</strong>11 and
<strong>bas</strong>ic level as <em>xbasc()</em>. The ``<strong>imp</strong>''
comes from the French word ``imprimer'', which means ``to print''. From which
language does ``fsck'' come from? N vcls, I guess.</p>

<p>File&nbsp;<em>sci1.xps</em> almost contains valid Postscript, but not
quite. The contents must be processed by Scilab</p>

<pre>
    scilab -save_p sci1.xps.0 Postscript
</pre>

<p>adding the correct Postscript header and repositioning the graphics on the
page. The external Scilab is called by the <em>
unix(``shell-commands'')</em>&nbsp;function.</p>

<h3><a name="scilab: 3d function plot">Scilab: 3D Function Plot</a></h3>

<pre>
    // [1] Define function
    function z = f(u, v)
        // truncated Rosenbrock function
        z = 100.0*(v - u.^2).^2 + (1.0 - u).^2
        z(find(z &gt; 100)) = 100;
    endfunction
</pre>

<pre>
    // [2] Define sampling grid for f()
    x = linspace(-3, 3, 40);
    y = linspace(-2, 4, 40);
</pre>

<pre>
    // [3] Clear plot window's contents
    xbasc();
</pre>

<pre>
    // [4] Plot
    fplot3d(x, y, f, 65, 1.5);
</pre>

<pre>
    // [5] Define decoration
    xtitle("Rosenbrock Function", "u", "v");
</pre>

<pre>
    // [6] Save plot window's contents to file; convert file to PostScript
    xbasimp(0, "sci2.xps");
    unix("scilab -save_p sci2.xps.0 Postscript; " ..
         + "gzip  --best --force sci2.eps");
</pre>

<p><img height="447" alt=
"[Graphics: Please see the image caption of '3D Function Plot' in the Octave section.]"
 src="misc/spiel/sci2.png" width="600"> Here is the gzipped <a href= 
"misc/spiel/sci2.eps.gz">Encapsulated Postscript version</a> (eps.gz) of the
graphics.</p>

<p>After so much new stuff in Section <a href="#scilab: 2d discrete data
plot">Scilab: 2D Discrete Data Plot</a> the only unknown here hides in
Block&nbsp;[4]:</p>

<pre>
    fplot3d(x_vector, y_vector, function_of_x_and_y, alpha, theta)
</pre>

<p>The vectors&nbsp;<em>x_vector</em> and <em>y_vector</em> define the grid on
which <em>function_of_x_and_y</em> is evaluated. Comparing <em>fplot3d()</em>
with Octave's <em>gsplot</em> we notice, that Scilab generates the grid for
us. Function&nbsp;<em>fplot3d()</em> is a convenience function, built on top
of</p>

<pre>
    plot3d(x_vector, y_vector, z_matrix, alpha, theta)
</pre>

<p>which resembles <em>gsplot</em> (and Tela's <em>mesh()</em>).</p>

<p>The parameters <em>theta</em> and <em>alpha</em>, define the elevation of
the view point and the rotation around the <em>z</em>-axis respectively.</p>

<h3><a name="scilab: contour function plot">Scilab: Contour Function
Plot</a></h3>

<pre>
    // [1] Define function
    function z = g(u, v)
        z = exp(u) .* (4.0*u.^2 + 2.0*v.^2 + 4.0*u.*v + 2.0*v + 1.0)
    endfunction
</pre>

<pre>
    // [2] Define weight function for iso-line distances
    function y = pow_weight(x, n)
        // Map interval X onto itself, weight with N-th power.
        d = max(x) - min(x)
        y = d*((x - min(x))/d).^n + min(x)
    endfunction
</pre>

<pre>
    // [3] Define sampling grid for g()
    x = linspace(-4.5, -0.5, 40);
    y = linspace(-1.0, 3.0, 40);
</pre>

<pre>
    // [4] Evaluate g() at points defined by X and Y
    z = eval3d(g, x, y);
</pre>

<pre>
    // [5] Compute iso-line distances
    iso_levels = pow_weight(linspace(min(z)*1.01, max(z)*0.99, 12), 3.0);
</pre>

<pre>
    // [6] Clear plot window's contents
    xbasc();
</pre>

<pre>
    // [7] Set format of iso-line annotation and plot
    xset("fpf", "%.2f");
    contour2d(x, y, z, iso_levels);
</pre>

<pre>
    // [8] Define decoration
    xtitle("Contour Plot of g(u, v)", "u", "v");
</pre>

<pre>
    // [9] Save plot window's contents to file; convert file to PostScript
    xbasimp(0, "sci3.xps");
    unix("scilab -save_p sci3.xps.0 Postscript");
</pre>

<p><img height="447" alt=
"[Graphics: Please see the image caption of 'Contour Function Plot' in the Octave section for the image's description.]"
 src="misc/spiel/sci3.png" width="600"> The output is available as <a href= 
"misc/spiel/sci3.eps">printer-ready version</a> (eps), too.</p>

<p>Remember the difficulties we had with the user-defined iso-lines in
Octave/Gnuplot? The problem can be solved in Scilab without any tricks, magic,
or bribery. As with <em>plot3d()</em>, Scilab defines a convenience
function</p>

<pre>
    fcontour2d(x_vector, y_vector, function_of_x_and_y, levels)
</pre>

<p>as a wrapper around</p>

<pre>
    contour2d(x_vector, y_vector, z_matrix, levels)
</pre>

<p>However, as we must know the maximum and minimum value of <em>g(u, v)</em>
on the grid, <em>fcontour2d()</em> would not save us anything. Thus, Block [4]
computes <em>g(u, v)</em> on the grid defined by <em>x</em> and <em>
y</em>:</p>

<pre>
    z = eval3d(g, x, y)
</pre>

<p>In Block&nbsp;[7], we use <em>z</em> and <em>iso_levels</em> from
Block&nbsp;[5]. The <em>xset()</em> call sets the <strong>f</strong>loating
<strong>p</strong>oint <strong>f</strong>ormat (``fpf'') to
``<code>%.2f</code>'', which is a C-printf format specifier that forces all
contour line numbers to have two digits after the decimal point.</p>

<p>All other blocks only use functions already discussed in the other
plots.</p>

<p>More demo plots of Scilab are found at <a href= 
"http://www-rocq.inria.fr/scilab/doc/demos_html/node183.html">INRIA's Scilab
site</a>.</p>

<p>Scilab has much more to offer than the functions we have seen right above.
For example, it supplies</p>

<ul>
<li>Low-level functions to draw points, lines, polygons, etc.</li>

<li>
<p>Surface facets which are the building blocks for 3d-environments. (See for
example Enrico Segre's amazing <a href= 
"http://www.polito.it/~segre/scigallery.html">Scigallery</a>)</p>
</li>

<li>High-level GUI-interface for rapid development of tailor-made Scilab
applications.</li>

<li>Feedback functions that allow passing back information from any graphics
window to Scilab.</li>
</ul>

<h2><a name="tela">Tela</a></h2>

<p>In the sections on <a href="#octave">Octave</a> and <a href="#scilab">
Scilab</a>, we have seen that both applications save auxiliary ``state'' of
the plot window. Gnuplot does so to the max: <code>gplot</code> or <code>
gsplot</code> have almost no parameters. The state is controlled by <code>
gset</code> commands. Scilab stores some state of the plot window as, for
example, the legend and title.</p>

<p>Tela uses the external application PlotMTV to display graphs. With PlotMTV,
Tela is located on the other side of the spectrum: its plots have no state,
and all information about the plot has to go into the call to the actual
plotting function. The advantage of Tela's approach is that multiple plots do
not interfere (unless we force them to do so by calling <code>hold(on)</code>
or <code>hold(off)</code> as we will see soon). The downside is that the calls
to plotting functions can get rather long.</p>

<p>As has been in the discussions of the other plotting applications, it is
helpful to have a PlotMTV manual within reach.</p>

<h3><a name="tela: 2d discrete data plot">Tela: 2D Discrete Data Plot</a></h3>

<pre>
    // [1] Read data set_i into N_i-times-2 matrices
    set1 = import1("l1.ascii");
    set2 = import1("l2.ascii");
    set3 = import1("l3.ascii");
</pre>

<pre>
    // [2] Define plotting function
    function do_plot(d1, d2, d3)
    {
         hold(on);    // postpone actual plotting until hold(off)
</pre>

<pre>
         // render set 1
         plot(d1[:, 1], d1[:, 2],
              "linestyle",  0,
              "markertype", 2,
              "linelabel",  "Set L1",
              // Define decorations
              "toplabel",   "Comparison of sets",
              "subtitle",   "L1, L2, and L3",
              "xlabel",     "Temperature / K",
              "ylabel",     "Voltage / V",
              // Define plot area
              "xmin",       0,
              "xmax",       100,
              "ymin",       8e-8,
              "ymax",       2e-6);
         // render set 2
         plot(d2[:, 1], d2[:, 2],
              "linestyle",  0,
              "markertype", 3,
              "linelabel",  "Set L2");
         // render set 3
         plot(d3[:, 1], d3[:, 2],
              "linestyle",  0,
              "markertype", 4,
              "linelabel",  "Set L3");
</pre>

<pre>
         hold(off);    // plot!
    };
</pre>

<pre>
    // [3] Plot to X11 window
    do_plot(set1, set2, set3);
</pre>

<pre>
    // [4] Plot into a postscript file
    plotopt("-o tela1.eps -printcmd 'cat' -noxplot -print");
    do_plot(set1, set2, set3);
</pre>

<p>Hmm, this script looks differently! It does -- because I have to play
another trick that has to do with the statelessness plot functions. As Tela
``forgets'' the parameters after displaying graphics in an X11-window, I would
have to retype everything with output redirected to a Postscript file. Well,
code duplication is known to be the root of many (not all) evil. Thus, the
Tela plots are wrapped into a function. The further strategy is displaying the
plot in an X11 window, changing the output file and type, which is somewhat
analogous to Gnuplot, and then plotting again into an eps-file:</p>

<pre>
    do_plot(...);    // display plot in X11 window
    plotopt("-o foo.eps -printcmd 'cat' -noxplot -print");  // redirect output
    do_plot(...);    // render plot in Encapsulated Postscript file foo.eps
</pre>

<p><img height="800" alt=
"[Graphics: Please see the image caption of '2D Discrete Data Plot' in the Octave section.]"
 src="misc/spiel/tela1.png" width="600"> <a href="misc/spiel/tela1.eps">
Encapsulated Postscript version</a> of the graphics.</p>

<p>Function&nbsp;<em>do_plot</em> in Block&nbsp;[2] takes care of all output
by using function&nbsp;<em>plot()</em>. The general structure of Tela's <em>
plot()</em>, in fact all Tela plot functions, is first passing the mandatory
data arguments as vectors or matrices followed by optional key-value
strings.</p>

<pre>
    plot(x_vector, y_vector                 // data
         "option_key1", "option_value1",    // option 1
         "option_key2", "option_value2",    // option 2
         ...
         "option_keyN", "option_valueN");   // option N
</pre>

<p>Note that putting one key-value pair per line enhances the readability of
the whole call.</p>

<p>The key-value strings themselves are self-explaining. Non-obvious
associations like linestyle&nbsp;=&gt;&nbsp;0 (= invisible line) or
markertype&nbsp;=&gt;&nbsp;2 (= plus sign) must be looked up in the manual or
in a reference plot which shows all available line styles.</p>

<h3><a name="tela: 3d function plot">Tela: 3D Function Plot</a></h3>

<pre>
    function v = linspace(a, b; n)
    {
        if (isdefined(n)) nn = n else nn = 100;
        v = a + (0 : nn - 1) * (b - a) / (nn - 1) 
    };
</pre>

<pre>
    // [1] Define function
    function z = f(u, v)
    {
        // truncated Rosenbrock function
        z = 100.0*(v - u^2)^2 + (1.0 - u)^2;
        z[find(z &gt; 100.0)] = 100.0;
    };
</pre>

<pre>
    // [2] Sample function f()
    x = linspace(-3.0, 3.0, 40);
    y = linspace(-2.0, 4.0, 40);
    [xx, yy] = grid(x, y);
    zz = f(xx, yy);
</pre>

<pre>
    // [3] Define plot function
    function do_plot(x, y, zz)
    {
        mesh(zz,
             "xgrid",       x,
             "ygrid",       y,
             "toplabel",    "Rosenbrock Function",
             "xlabel",      "u",
             "ylabel",      "v",
             "hiddenline",  "true",
             "eyepos.z",    2.0)
    };
</pre>

<pre>
    // [4] Render plot into X11 window
    do_plot(x, y, zz);
</pre>

<pre>
    // [5] Plot into a postscript file
    plotopt("-o tela2.eps -printcmd 'cat' -noxplot -print");
    do_plot(x, y, zz);
    system("gzip --best --force tela2.eps");
</pre>

<p><img height="800" alt=
"[Graphics: Please see the image caption of '3D Function Plot' in the Octave section.]"
 src="misc/spiel/tela2.png" width="600"> An gzipped <a href= 
"misc/spiel/tela2.eps.gz">Encapsulated Postscript version</a> (eps.gz) of the
plot is available, too.</p>

<p>Tela has no built in <em>linspace()</em>&nbsp;function, so I quickly define
one.</p>

<p>Block&nbsp;[2] resembles Block&nbsp;[2] in Section <a href="#octave: 3d 
function plot">``Octave: 3D Function Plot''</a>, where Octave's <em>
meshgrid()</em> has been replaced by Tela's <em>grid()</em>.</p>

<p>The 3d-mesh plotting function <em>mesh()</em> takes a matrix of <em>
z</em>-values as its first argument; the grid-specification is given in the
options:</p>

<pre>
        mesh(z_matrix,
             "xgrid", x_vector,
             "ygrid", y_vector);
</pre>

<p>Of course, the sizes of <em>z_matrix</em>, <em>x_vector</em>, and <em>
y_vector</em> must be compatible.</p>

<h3><a name="tela: contour function plot">Tela: Contour Function Plot</a></h3>

<pre>
    function v = linspace(a, b; n)
    {
        if (isdefined(n)) nn = n else nn = 100;
        v = a + (0 : nn - 1) * (b - a) / (nn - 1) 
    };
</pre>

<pre>
    // [1] Define function
    function z = g(u, v)
    {
        z = exp(u) * (4.0*u^2 + 2.0*v^2 + 4.0*u*v + 2.0*v + 1.0)
    };
</pre>

<pre>
    // [2] Define weight function for iso-line distances
    function y = pow_weight(x, n)
    {
        // Map interval X onto itself, weight with N-th power.
        d = max(x) - min(x);
        y = d*((x - min(x))/d)^n + min(x)
    };
</pre>

<pre>
    // [3] Sample function f()
    x = linspace(-4.5, -0.5, 40);
    y = linspace(-1.0, 3.0, 40);
    [xx, yy] = grid(x, y);
    zz = g(xx, yy);
</pre>

<pre>
    // [4] Compute iso-line distances
    iso_levels = pow_weight(linspace(min(zz)*1.01, max(zz)*0.99, 12), 3.0);
    il_str = sformat("``", iso_levels);
    il_str = il_str[2 : length(il_str)];
</pre>

<pre>
    // [5] Define plot function
    function do_plot(x, y, zz, iso_levels_str)
    {
        contour(zz,
                "xgrid",    x,
                "ygrid",    y,
                "toplabel", "Contour Plot of g(u, v)",
                "xlabel",   "u",
                "ylabel",   "v",
                "contours", iso_levels_str)
    };
</pre>

<pre>
    // [6] Render plot into X11 window
    do_plot(x, y, zz, il_str);
</pre>

<pre>
    // [7] Plot into a postscript file
    plotopt("-o tela3.eps -printcmd 'cat' -noxplot -print");
    do_plot(x, y, zz, il_str);
</pre>

<p><img height="800" alt=
"[Graphics: Please see the image caption of 'Contour Function Plot' in the Octave section for the image's description.]"
 src="misc/spiel/tela3.png" width="600"> Also available is an Encapsulated
Postscript <a href="misc/spiel/tela3.eps">printer version</a>.</p>

<p>Tela requires us to play a similar trick on PlotMTV as we had to when
convincing Octave to pass the contours' values to Gnuplot. However, the trick
in Block&nbsp;[4] is not as involved. Again, the first step is to compute the
vector&nbsp;<em>iso_levels</em>. Function&nbsp;<em>sformat()</em> works
analogously to Octave's <em>sprintf()</em>, though the vectors are differently
formatted as the transcript shows (<em>il_str</em> has been edited to fit the
line).</p>

<pre>
    &gt;il_str = sformat("``", iso_levels);
    &gt;il_str
    "#(0.583444, 0.592029, 0.65212, 0.815224, 1.13285, 1.6565, \
    2.43768, 3.5279, 4.97867, 6.84149, 9.16786, 12.0093)"
</pre>

<p>PlotMTV does understand a vector that is enclosed in parenthesis, but the
leading sharp-sign must go</p>

<pre>
    il_str = il_str[2 : length(il_str)];
</pre>

<p>In this form, <em>il_string</em> can be passed as value to the option key
<code>contours</code> in function&nbsp;<em>contour()</em>.</p>

<p>More demo plots of PlotMTV can be found at <a href= 
"http://csep1.phy.ornl.gov/cornell_proceedings/tutorials/Plotmtv/overview.html">
ORNL</a> and at <a href= 
"http://www.hammersmith-consulting.com/plotmtv-us-g.html">HSC</a>.</p>

<p>By the way, PlotMTV suits perfectly as graphical backend for home grown
scripts and programs. The PlotMTV manual consistently helps the reader to
develop programmatic interfaces for her own applications.</p>

<h2><a name="closing comments on graphics">Closing Comments on
Graphics</a></h2>

<p>We have seen how to get publication ready data and function plots from
GNU/Octave, Scilab, and Tela. Sometimes the solutions have been intricate,
because of implementations' restrictions. However, all <a href="#problems">
problems</a> could be solved.</p>

<p>The effort in creating pleasantly looking graphs appears to be high and
almost independent of the chosen application.</p>





<!-- *** BEGIN bio *** -->
<SPACER TYPE="vertical" SIZE="30">
<P> 
<H4><IMG ALIGN=BOTTOM ALT="" SRC="../gx/note.gif">Christoph Spiel</H4>
Chris runs an Open Source Software consulting company in Upper Bavaria/Germany.
<EM>Despite being trained as a physicist -- he holds a PhD in physics from Munich
University of Technology -- his main interests revolve around numerics,
heterogenous programming environments, and software engineering.  He can be
reached at 
<A HREF="mailto:cspiel@hammersmith-consulting.com">cspiel@hammersmith-consulting.com</A>.</EM>

<!-- *** END bio *** -->

<!-- *** BEGIN copyright *** -->
<P> <hr> <!-- P --> 
<H5 ALIGN=center>

Copyright &copy; 2001, Christoph Spiel.<BR>
Copying license <A HREF="../copying.html">http://www.linuxgazette.com/copying.html</A><BR> 
Published in Issue 71 of <i>Linux Gazette</i>, October 2001</H5>
<!-- *** END copyright *** -->

<!--startcut ==========================================================-->
<HR><P>
<CENTER>
<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="qubism.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="lg_toc71.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../lg_frontpage.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue71/spiel.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><A HREF="../lg_faq.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="lg_backpage71.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
<!-- *** END navbar *** -->
</CENTER>
</BODY></HTML>
<!--endcut ============================================================-->