~ubuntu-branches/ubuntu/wily/gnuplot-iostream/wily

« back to all changes in this revision

Viewing changes to example-data-1d.cc

  • Committer: Package Import Robot
  • Author(s): Anton Gladky
  • Date: 2013-05-08 21:09:45 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20130508210945-wrn68tn3pvcvd79r
Tags: 0~20130424.gita9d3e31-1
* [10be64a] Imported Upstream version 0~20130424.gita9d3e31
* [4454719] Enable some more tests.
* [d88265b] Add blitz, armadillo to BD to enable some more tests.
* [0603e0a] Minor update in rules and install files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 2013 Daniel Stahlke
 
3
 
 
4
Permission is hereby granted, free of charge, to any person obtaining a copy
 
5
of this software and associated documentation files (the "Software"), to deal
 
6
in the Software without restriction, including without limitation the rights
 
7
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
8
copies of the Software, and to permit persons to whom the Software is
 
9
furnished to do so, subject to the following conditions:
 
10
 
 
11
The above copyright notice and this permission notice shall be included in
 
12
all copies or substantial portions of the Software.
 
13
 
 
14
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
15
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
16
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
17
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
18
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
19
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
20
THE SOFTWARE.
 
21
*/
 
22
 
 
23
#if (__cplusplus >= 201103)
 
24
#define USE_CXX
 
25
#endif
 
26
 
 
27
#include <vector>
 
28
#include <complex>
 
29
#include <cmath>
 
30
 
 
31
#include <boost/tuple/tuple.hpp>
 
32
#include <boost/array.hpp>
 
33
#include <boost/range/adaptor/transformed.hpp>
 
34
#include <boost/range/irange.hpp>
 
35
#include <boost/bind.hpp>
 
36
 
 
37
#ifdef USE_ARMA
 
38
#include <armadillo>
 
39
#endif
 
40
 
 
41
#ifdef USE_BLITZ
 
42
#include <blitz/array.h>
 
43
#endif
 
44
 
 
45
#include "gnuplot-iostream.h"
 
46
 
 
47
#ifndef M_PI
 
48
#       define M_PI 3.14159265358979323846
 
49
#endif
 
50
 
 
51
const int num_steps = 100;
 
52
 
 
53
double get_x(int step, double shift) {
 
54
        double theta = 2.0*M_PI*step/(num_steps-1);
 
55
        return std::cos(theta) * (1 + 0.3*std::cos(3.0*theta+2.0*M_PI*shift));
 
56
}
 
57
 
 
58
double get_y(int step, double shift) {
 
59
        double theta = 2.0*M_PI*step/(num_steps-1);
 
60
        return std::sin(theta) * (1 + 0.3*std::cos(3.0*theta+2.0*M_PI*shift));
 
61
}
 
62
 
 
63
double get_z(int step, double shift) {
 
64
        double theta = 2.0*M_PI*step/(num_steps-1);
 
65
        return 0.3*std::sin(3.0*theta+2.0*M_PI*shift);
 
66
}
 
67
 
 
68
// This doesn't have to be a template.  It's just a template to show that such things are
 
69
// possible.
 
70
template <typename T>
 
71
struct MyTriple {
 
72
        MyTriple() : x(0), y(0), z(0) { }
 
73
        MyTriple(T _x, T _y, T _z) : x(_x), y(_y), z(_z) { }
 
74
 
 
75
        T x, y, z;
 
76
};
 
77
 
 
78
// Tells gnuplot-iostream how to print objects of class MyTriple.
 
79
namespace gnuplotio {
 
80
        template<typename T>
 
81
        struct BinfmtSender<MyTriple<T> > {
 
82
                static void send(std::ostream &stream) {
 
83
                        BinfmtSender<T>::send(stream);
 
84
                        BinfmtSender<T>::send(stream);
 
85
                        BinfmtSender<T>::send(stream);
 
86
                }
 
87
        };
 
88
 
 
89
        template <typename T>
 
90
        struct BinarySender<MyTriple<T> > {
 
91
                static void send(std::ostream &stream, const MyTriple<T> &v) {
 
92
                        BinarySender<T>::send(stream, v.x);
 
93
                        BinarySender<T>::send(stream, v.y);
 
94
                        BinarySender<T>::send(stream, v.z);
 
95
                }
 
96
        };
 
97
 
 
98
        // We don't use text mode in this demo.  This is just here to show how it would go.
 
99
        template<typename T>
 
100
        struct TextSender<MyTriple<T> > {
 
101
                static void send(std::ostream &stream, const MyTriple<T> &v) {
 
102
                        TextSender<T>::send(stream, v.x);
 
103
                        stream << " ";
 
104
                        TextSender<T>::send(stream, v.y);
 
105
                        stream << " ";
 
106
                        TextSender<T>::send(stream, v.z);
 
107
                }
 
108
        };
 
109
}
 
110
 
 
111
int main() {
 
112
        Gnuplot gp;
 
113
        // for debugging, prints to console
 
114
        //Gnuplot gp(stdout);
 
115
 
 
116
        int num_examples = 11;
 
117
#ifdef USE_ARMA
 
118
        num_examples += 4;
 
119
#endif
 
120
#ifdef USE_BLITZ
 
121
        num_examples += 3;
 
122
#endif
 
123
#ifdef USE_CXX
 
124
        num_examples += 3;
 
125
#endif
 
126
 
 
127
        double shift = 0;
 
128
 
 
129
        gp << "set zrange [-1:1]\n";
 
130
 
 
131
        // I use temporary files rather than stdin because the syntax ends up being easier when
 
132
        // plotting several datasets.  With the stdin method you have to give the full plot
 
133
        // command, then all the data.  But I would rather give the portion of the plot command for
 
134
        // the first dataset, then give the data, then the command for the second dataset, then the
 
135
        // data, etc.
 
136
 
 
137
        gp << "splot ";
 
138
 
 
139
        {
 
140
                std::vector<std::pair<std::pair<double, double>, double> > pts;
 
141
                for(int i=0; i<num_steps; i++) {
 
142
                        pts.push_back(std::make_pair(std::make_pair(get_x(i, shift), get_y(i, shift)), get_z(i, shift)));
 
143
                }
 
144
                gp << gp.binFile1d(pts, "record") << "with lines title 'vector of nested std::pair'";
 
145
        }
 
146
 
 
147
        gp << ", ";
 
148
        shift += 1.0/num_examples;
 
149
 
 
150
        {
 
151
                // complex is treated as if it were a pair
 
152
                std::vector<std::pair<std::complex<double>, double> > pts;
 
153
                for(int i=0; i<num_steps; i++) {
 
154
                        pts.push_back(std::make_pair(std::complex<double>(get_x(i, shift), get_y(i, shift)), get_z(i, shift)));
 
155
                }
 
156
                gp << gp.binFile1d(pts, "record") << "with lines title 'vector of pair of cplx and double'";
 
157
        }
 
158
 
 
159
        gp << ", ";
 
160
        shift += 1.0/num_examples;
 
161
 
 
162
        {
 
163
                std::vector<boost::tuple<double, double, double> > pts;
 
164
                for(int i=0; i<num_steps; i++) {
 
165
                        pts.push_back(boost::make_tuple(get_x(i, shift), get_y(i, shift), get_z(i, shift)));
 
166
                }
 
167
                gp << gp.binFile1d(pts, "record") << "with lines title 'vector of boost::tuple'";
 
168
        }
 
169
 
 
170
        gp << ", ";
 
171
        shift += 1.0/num_examples;
 
172
 
 
173
        {
 
174
                std::vector<double> x_pts, y_pts, z_pts;
 
175
                for(int i=0; i<num_steps; i++) {
 
176
                        x_pts.push_back(get_x(i, shift));
 
177
                        y_pts.push_back(get_y(i, shift));
 
178
                        z_pts.push_back(get_z(i, shift));
 
179
                }
 
180
                gp << gp.binFile1d(boost::make_tuple(x_pts, y_pts, z_pts), "record") << "with lines title 'boost::tuple of vector'";
 
181
        }
 
182
 
 
183
        gp << ", ";
 
184
        shift += 1.0/num_examples;
 
185
 
 
186
        {
 
187
                std::vector<boost::array<double, 3> > pts(num_steps);
 
188
                for(int i=0; i<num_steps; i++) {
 
189
                        pts[i][0] = get_x(i, shift);
 
190
                        pts[i][1] = get_y(i, shift);
 
191
                        pts[i][2] = get_z(i, shift);
 
192
                }
 
193
                gp << gp.binFile1d(pts, "record") << "with lines title 'vector of boost::array'";
 
194
        }
 
195
 
 
196
        gp << ", ";
 
197
        shift += 1.0/num_examples;
 
198
 
 
199
        {
 
200
                std::vector<std::vector<double> > pts(num_steps);
 
201
                for(int i=0; i<num_steps; i++) {
 
202
                        pts[i].push_back(get_x(i, shift));
 
203
                        pts[i].push_back(get_y(i, shift));
 
204
                        pts[i].push_back(get_z(i, shift));
 
205
                }
 
206
                gp << gp.binFile1d(pts, "record") << "with lines title 'vector of vector'";
 
207
        }
 
208
 
 
209
        gp << ", ";
 
210
        shift += 1.0/num_examples;
 
211
 
 
212
        {
 
213
                std::vector<std::vector<double> > pts(3);
 
214
                for(int i=0; i<num_steps; i++) {
 
215
                        pts[0].push_back(get_x(i, shift));
 
216
                        pts[1].push_back(get_y(i, shift));
 
217
                        pts[2].push_back(get_z(i, shift));
 
218
                }
 
219
                gp << gp.binFile1d_colmajor(pts, "record") << "with lines title 'vector of vector (colmajor)'";
 
220
        }
 
221
 
 
222
        gp << ", ";
 
223
        shift += 1.0/num_examples;
 
224
 
 
225
        {
 
226
                std::vector<MyTriple<double> > pts;
 
227
                for(int i=0; i<num_steps; i++) {
 
228
                        pts.push_back(MyTriple<double>(get_x(i, shift), get_y(i, shift), get_z(i, shift)));
 
229
                }
 
230
                gp << gp.binFile1d(pts, "record") << "with lines title 'vector of MyTriple'";
 
231
        }
 
232
 
 
233
        gp << ", ";
 
234
        shift += 1.0/num_examples;
 
235
 
 
236
        {
 
237
                // Note: C style arrays seem to work, but are a bit fragile since they easily decay to
 
238
                // pointers, causing them to forget their lengths.  It is highly recommended that you
 
239
                // use boost::array or std::array instead.  These have the same size and efficiency of
 
240
                // C style arrays, but act like STL containers.
 
241
                double pts[num_steps][3];
 
242
                for(int i=0; i<num_steps; i++) {
 
243
                        pts[i][0] = get_x(i, shift);
 
244
                        pts[i][1] = get_y(i, shift);
 
245
                        pts[i][2] = get_z(i, shift);
 
246
                }
 
247
                gp << gp.binFile1d(pts, "record") << "with lines title 'double[N][3]'";
 
248
        }
 
249
 
 
250
        gp << ", ";
 
251
        shift += 1.0/num_examples;
 
252
 
 
253
        {
 
254
                // Note: C style arrays seem to work, but are a bit fragile since they easily decay to
 
255
                // pointers, causing them to forget their lengths.  It is highly recommended that you
 
256
                // use boost::array or std::array instead.  These have the same size and efficiency of
 
257
                // C style arrays, but act like STL containers.
 
258
                double pts[3][num_steps];
 
259
                for(int i=0; i<num_steps; i++) {
 
260
                        pts[0][i] = get_x(i, shift);
 
261
                        pts[1][i] = get_y(i, shift);
 
262
                        pts[2][i] = get_z(i, shift);
 
263
                }
 
264
                gp << gp.binFile1d_colmajor(pts, "record") << "with lines title 'double[N][3] (colmajor)'";
 
265
        }
 
266
 
 
267
        gp << ", ";
 
268
        shift += 1.0/num_examples;
 
269
 
 
270
        {
 
271
                // Note: C style arrays seem to work, but are a bit fragile since they easily decay to
 
272
                // pointers, causing them to forget their lengths.  It is highly recommended that you
 
273
                // use boost::array or std::array instead.  These have the same size and efficiency of
 
274
                // C style arrays, but act like STL containers.
 
275
                double x_pts[num_steps];
 
276
                double y_pts[num_steps];
 
277
                double z_pts[num_steps];
 
278
                for(int i=0; i<num_steps; i++) {
 
279
                        x_pts[i] = get_x(i, shift);
 
280
                        y_pts[i] = get_y(i, shift);
 
281
                        z_pts[i] = get_z(i, shift);
 
282
                }
 
283
                gp << gp.binFile1d(boost::make_tuple(x_pts, y_pts, z_pts), "record") <<
 
284
                        "with lines title 'boost::tuple of double[N]'";
 
285
        }
 
286
 
 
287
#ifdef USE_ARMA
 
288
        gp << ", ";
 
289
        shift += 1.0/num_examples;
 
290
 
 
291
        {
 
292
                arma::mat pts(num_steps, 3);
 
293
                for(int i=0; i<num_steps; i++) {
 
294
                        pts(i, 0) = get_x(i, shift);
 
295
                        pts(i, 1) = get_y(i, shift);
 
296
                        pts(i, 2) = get_z(i, shift);
 
297
                }
 
298
                gp << gp.binFile1d(pts, "record") << "with lines title 'armadillo N*3'";
 
299
        }
 
300
 
 
301
        gp << ", ";
 
302
        shift += 1.0/num_examples;
 
303
 
 
304
        {
 
305
                arma::mat pts(3, num_steps);
 
306
                for(int i=0; i<num_steps; i++) {
 
307
                        pts(0, i) = get_x(i, shift);
 
308
                        pts(1, i) = get_y(i, shift);
 
309
                        pts(2, i) = get_z(i, shift);
 
310
                }
 
311
                gp << gp.binFile1d_colmajor(pts, "record") << "with lines title 'armadillo 3*N (colmajor)'";
 
312
        }
 
313
 
 
314
        gp << ", ";
 
315
        shift += 1.0/num_examples;
 
316
 
 
317
        {
 
318
                arma::Row<double> x_pts(num_steps);
 
319
                arma::Col<double> y_pts(num_steps);
 
320
                arma::Col<double> z_pts(num_steps);
 
321
                for(int i=0; i<num_steps; i++) {
 
322
                        x_pts(i) = get_x(i, shift);
 
323
                        y_pts(i) = get_y(i, shift);
 
324
                        z_pts(i) = get_z(i, shift);
 
325
                }
 
326
                gp << gp.binFile1d(boost::make_tuple(x_pts, y_pts, z_pts), "record")
 
327
                        << "with lines title 'boost tuple of arma Row,Col,Col'";
 
328
        }
 
329
 
 
330
        gp << ", ";
 
331
        shift += 1.0/num_examples;
 
332
 
 
333
        {
 
334
                arma::field<boost::tuple<double,double,double> > pts(num_steps);
 
335
                for(int i=0; i<num_steps; i++) {
 
336
                        pts(i) = boost::make_tuple(
 
337
                                get_x(i, shift),
 
338
                                get_y(i, shift),
 
339
                                get_z(i, shift)
 
340
                        );
 
341
                }
 
342
                gp << gp.binFile1d(pts, "record") << "with lines title 'armadillo field of boost tuple'";
 
343
        }
 
344
#endif
 
345
 
 
346
#ifdef USE_BLITZ
 
347
        gp << ", ";
 
348
        shift += 1.0/num_examples;
 
349
 
 
350
        {
 
351
                blitz::Array<blitz::TinyVector<double, 3>, 1> pts(num_steps);
 
352
                for(int i=0; i<num_steps; i++) {
 
353
                        pts(i)[0] = get_x(i, shift);
 
354
                        pts(i)[1] = get_y(i, shift);
 
355
                        pts(i)[2] = get_z(i, shift);
 
356
                }
 
357
                gp << gp.binFile1d(pts, "record") << "with lines title 'blitz::Array<blitz::TinyVector<double, 3>, 1>'";
 
358
        }
 
359
 
 
360
        gp << ", ";
 
361
        shift += 1.0/num_examples;
 
362
 
 
363
        {
 
364
                blitz::Array<double, 2> pts(num_steps, 3);
 
365
                for(int i=0; i<num_steps; i++) {
 
366
                        pts(i, 0) = get_x(i, shift);
 
367
                        pts(i, 1) = get_y(i, shift);
 
368
                        pts(i, 2) = get_z(i, shift);
 
369
                }
 
370
                gp << gp.binFile1d(pts, "record") << "with lines title 'blitz<double>(N*3)'";
 
371
        }
 
372
 
 
373
        gp << ", ";
 
374
        shift += 1.0/num_examples;
 
375
 
 
376
        {
 
377
                blitz::Array<double, 2> pts(3, num_steps);
 
378
                for(int i=0; i<num_steps; i++) {
 
379
                        pts(0, i) = get_x(i, shift);
 
380
                        pts(1, i) = get_y(i, shift);
 
381
                        pts(2, i) = get_z(i, shift);
 
382
                }
 
383
                gp << gp.binFile1d_colmajor(pts, "record") << "with lines title 'blitz<double>(3*N) (colmajor)'";
 
384
        }
 
385
#endif
 
386
 
 
387
#ifdef USE_CXX
 
388
        gp << ", ";
 
389
        shift += 1.0/num_examples;
 
390
 
 
391
        {
 
392
                std::function<boost::tuple<double,double,double>(int)> f = [&shift](int i) {
 
393
                        return boost::make_tuple(get_x(i, shift), get_y(i, shift), get_z(i, shift)); };
 
394
 
 
395
                auto pts = boost::irange(0, num_steps) | boost::adaptors::transformed(f);
 
396
 
 
397
                gp << gp.binFile1d(pts, "record") << "with lines title 'boost transform to tuple'";
 
398
        }
 
399
 
 
400
        gp << ", ";
 
401
        shift += 1.0/num_examples;
 
402
 
 
403
        {
 
404
                auto steps = boost::irange(0, num_steps);
 
405
 
 
406
                gp << gp.binFile1d(boost::make_tuple(
 
407
                                steps | boost::adaptors::transformed(boost::bind(get_x, _1, shift)),
 
408
                                steps | boost::adaptors::transformed(boost::bind(get_y, _1, shift)),
 
409
                                steps | boost::adaptors::transformed(boost::bind(get_z, _1, shift))
 
410
                        ), "record") << "with lines title 'tuple of boost transform'";
 
411
        }
 
412
 
 
413
        gp << ", ";
 
414
        shift += 1.0/num_examples;
 
415
 
 
416
        {
 
417
                // Note: C style arrays seem to work, but are a bit fragile since they easily decay to
 
418
                // pointers, causing them to forget their lengths.  It is highly recommended that you
 
419
                // use boost::array or std::array instead.  These have the same size and efficiency of
 
420
                // C style arrays, but act like STL containers.
 
421
                double x_pts[num_steps];
 
422
                double y_pts[num_steps];
 
423
                double z_pts[num_steps];
 
424
                for(int i=0; i<num_steps; i++) {
 
425
                        x_pts[i] = get_x(i, shift);
 
426
                        y_pts[i] = get_y(i, shift);
 
427
                        z_pts[i] = get_z(i, shift);
 
428
                }
 
429
                // Note: std::make_tuple doesn't work here since it makes the arrays decay to pointers,
 
430
                // and as a result they forget their lengths.
 
431
                gp << gp.binFile1d(std::tie(x_pts, y_pts, z_pts), "record") <<
 
432
                        "with lines title 'std::tie of double[N]'";
 
433
        }
 
434
#endif
 
435
 
 
436
        gp << std::endl;
 
437
 
 
438
        shift += 1.0/num_examples;
 
439
        //std::cout << shift << std::endl;
 
440
        assert(std::fabs(shift - 1.0) < 1e-12);
 
441
 
 
442
#ifdef _WIN32
 
443
        // For Windows, prompt for a keystroke before the Gnuplot object goes out of scope so that
 
444
        // the gnuplot window doesn't get closed.
 
445
        std::cout << "Press enter to exit." << std::endl;
 
446
        std::cin.get();
 
447
#endif
 
448
 
 
449
        return 0;
 
450
}