~ubuntu-branches/ubuntu/trusty/rheolef/trusty-proposed

« back to all changes in this revision

Viewing changes to skit/lib/outml.cc

  • Committer: Bazaar Package Importer
  • Author(s): Christophe Prud'homme
  • Date: 2010-06-12 09:08:59 UTC
  • Revision ID: james.westby@ubuntu.com-20100612090859-8gpm2gc7j3ab43et
Tags: upstream-5.89
ImportĀ upstreamĀ versionĀ 5.89

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
///
 
2
/// This file is part of Rheolef.
 
3
///
 
4
/// Copyright (C) 2000-2009 Pierre Saramito <Pierre.Saramito@imag.fr>
 
5
///
 
6
/// Rheolef is free software; you can redistribute it and/or modify
 
7
/// it under the terms of the GNU General Public License as published by
 
8
/// the Free Software Foundation; either version 2 of the License, or
 
9
/// (at your option) any later version.
 
10
///
 
11
/// Rheolef is distributed in the hope that it will be useful,
 
12
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
/// GNU General Public License for more details.
 
15
///
 
16
/// You should have received a copy of the GNU General Public License
 
17
/// along with Rheolef; if not, write to the Free Software
 
18
/// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
/// 
 
20
/// =========================================================================
 
21
//
 
22
// OUT ML: Matrix and Vector Output
 
23
//            in a MatLab-like format
 
24
// 
 
25
// author: Pierre.Saramito@imag.fr
 
26
//
 
27
// date: 21 january 1997
 
28
//
 
29
// note: code inspired from octave-1.1.1
 
30
//       mail:jwe@che.utexas.edu (John W. Eaton)
 
31
//       ftp://ftp.che.utexas.edu:/pub/octave
 
32
//
 
33
# include "rheolef/csr.h"
 
34
# include "rheolef/outml.h"
 
35
# include "rheolef/vec.h"
 
36
# include "rheolef/avec.h"
 
37
# include "rheolef/iotrick.h" // TODO: delete it !
 
38
using namespace std;
 
39
 
 
40
// global var
 
41
ml_preferences ml_pref;
 
42
 
 
43
// circumvent bug in shared libraries :
 
44
// ml_pref cstor not called : force initialization
 
45
static void init_ml_pref() {
 
46
    static bool already_init = false;
 
47
    if (!already_init) {
 
48
        ml_pref.reset();
 
49
        already_init = true;
 
50
    }
 
51
}
 
52
int screenwidth = 80; // TODO: could use readline.
 
53
int
 
54
terminal_columns (void)
 
55
{
 
56
        extern int screenwidth;
 
57
        return screenwidth > 0 ? screenwidth : 80;
 
58
}
 
59
// Current format string for floats numbers
 
60
static char *curr_fmt = 0;
 
61
 
 
62
template <class T>
 
63
static
 
64
void
 
65
set_format (ostream& os, const T& a, int& fw)
 
66
{
 
67
        init_ml_pref();
 
68
        curr_fmt = 0;
 
69
        if (ml_pref.free_format) return;
 
70
 
 
71
        static char fmt_buf[128];
 
72
        int sign       = a.any_element_is_negative ();
 
73
        int inf_or_nan = a.any_element_is_inf_or_nan ();
 
74
        Float max_abs_  = a.max_abs ();
 
75
        Float min_abs_  = a.min_abs ();
 
76
        int x_max = ((max_abs_ == Float(0)) ? 0 : ((int) floor (log10 (max_abs_) + 1.0)));
 
77
        int x_min = ((min_abs_ == Float(0)) ? 0 : ((int) floor (log10 (min_abs_) + 1.0)));
 
78
 
 
79
        int prec = os.precision();
 
80
        if (os.width() != 0)
 
81
            ml_pref.output_max_field_width = os.width();
 
82
        else
 
83
            ml_pref.output_max_field_width = screenwidth;
 
84
 
 
85
        bool has_fixed = ((cout.flags() & ios::floatfield) == ios::fixed);
 
86
        bool has_scien = ((cout.flags() & ios::floatfield) == ios::scientific);
 
87
        if (!has_fixed && !has_scien) {
 
88
            ml_pref.bank_format = false;
 
89
            ml_pref.print_e     = false;
 
90
        } else if (has_scien) {
 
91
            ml_pref.bank_format = false;
 
92
            ml_pref.print_e     = true;
 
93
        } else if (has_fixed) {
 
94
            ml_pref.bank_format = true;
 
95
            ml_pref.print_e     = false;
 
96
        }
 
97
        int ld, rd;
 
98
 
 
99
        if (ml_pref.bank_format) {
 
100
      
 
101
            int digits = x_max > x_min ? x_max : x_min;
 
102
            fw = digits <= 0 ? 4 : digits + 3;
 
103
            if (inf_or_nan && fw < 3)
 
104
                fw = 3;
 
105
            fw += sign;
 
106
            rd = 2;
 
107
 
 
108
        } else if (a.all_elements_are_int_or_inf_or_nan ()) {
 
109
      
 
110
            int digits = x_max > x_min ? x_max : x_min;
 
111
            fw = digits <= 0 ? 1 : digits;
 
112
            if (inf_or_nan && fw < 3)
 
113
                fw = 3;
 
114
            fw += sign;
 
115
            rd = 0;
 
116
        } else {
 
117
            int ld_max, rd_max;
 
118
            if (x_max > 0) {
 
119
                ld_max = x_max;
 
120
                rd_max = prec - x_max;
 
121
                x_max++;
 
122
            } else {
 
123
                ld_max = 1;
 
124
                rd_max = prec - x_max;
 
125
                x_max = -x_max + 1;
 
126
            }
 
127
            int ld_min, rd_min;
 
128
            if (x_min > 0) {
 
129
                ld_min = x_min;
 
130
                rd_min = prec - x_min;
 
131
                x_min++;
 
132
            } else {
 
133
                ld_min = 1;
 
134
                rd_min = prec - x_min;
 
135
                x_min = -x_min + 1;
 
136
            }
 
137
            ld = ld_max > ld_min ? ld_max : ld_min;
 
138
            rd = rd_max > rd_min ? rd_max : rd_min;
 
139
            fw = ld + 1 + rd;
 
140
            if (inf_or_nan && fw < 3)
 
141
                fw = 3;
 
142
            fw += sign;
 
143
        }
 
144
        if (! ml_pref.bank_format && (fw > ml_pref.output_max_field_width || ml_pref.print_e)) {
 
145
      
 
146
            int exp_field = 4;
 
147
            if (x_max > 100 || x_min > 100)
 
148
                exp_field++;
 
149
            fw = 2 + prec + exp_field;
 
150
            if (inf_or_nan && fw < 3)
 
151
                fw = 3;
 
152
            fw += sign;
 
153
            if (ml_pref.print_big_e)
 
154
                sprintf (fmt_buf, "%%%d.%dE", fw, prec - 1);
 
155
            else
 
156
                sprintf (fmt_buf, "%%%d.%de", fw, prec - 1);
 
157
        } else {
 
158
      
 
159
                sprintf (fmt_buf, "%%%d.%df", fw, rd);
 
160
        }
 
161
        curr_fmt = &fmt_buf[0];
 
162
}
 
163
static
 
164
inline
 
165
void
 
166
pr_any_float (const char *fmt, ostream& os, Float d, int fw = 0)
 
167
{
 
168
        if (d == Float(-0.)) d = 0;
 
169
        if (fmt) {
 
170
            if (xisinf (d)) {
 
171
                const char *s;
 
172
                if (d < Float(0.))
 
173
                    s = "-Inf";
 
174
                else
 
175
                    s = "Inf";
 
176
 
 
177
                if (fw > 0) {
 
178
                    skit_form2(os, "%*s", fw, s);
 
179
                } else {
 
180
                    os << s;
 
181
                }
 
182
            } else if (xisnan (d)) {
 
183
                if (fw > 0) {
 
184
                    skit_form2(os, "%*s", fw, "NaN");
 
185
                } else {
 
186
                    os << "NaN";
 
187
                }
 
188
            } else {
 
189
                    skit_form(os, fmt, double(d));
 
190
            }
 
191
        } else {
 
192
                    os << double(d);
 
193
        }
 
194
}
 
195
static inline void
 
196
pr_float (ostream& os, Float d, int fw = 0)
 
197
{
 
198
        pr_any_float (curr_fmt, os, d, fw);
 
199
}
 
200
static void
 
201
print_empty_vector (ostream& os, int n)
 
202
{
 
203
    init_ml_pref();
 
204
    assert_macro (n == 0, "empty vector expected, vec(" << n << ") found");
 
205
    if (ml_pref.pr_as_read_syntax) {
 
206
        os << "[]";
 
207
    } else {
 
208
        os << "[]";
 
209
        if (ml_pref.print_empty_dimensions)
 
210
            os << "(" << n << ")";
 
211
        os << "\n";
 
212
    }
 
213
}
 
214
template <class Vec>
 
215
static void
 
216
print_matlab_gen (ostream& os, const Vec& x)
 
217
{
 
218
        init_ml_pref();
 
219
        int n = x.n();
 
220
        if (n == 0) {
 
221
 
 
222
            print_empty_vector (os, n);
 
223
 
 
224
        } else if (ml_pref.plus_format && ! ml_pref.pr_as_read_syntax) {
 
225
 
 
226
             for (int i = 0; i < n; i++) {
 
227
                 os << "  ";
 
228
                 if (x (i) == Float(0.))
 
229
                     os << " ";
 
230
                 else
 
231
                     os << "+";
 
232
                 os << "\n";
 
233
             }
 
234
        } else {
 
235
            int fw = 0;
 
236
            set_format (os, x, fw);
 
237
            int column_width = fw + 2;
 
238
            int total_width = n * column_width;
 
239
            int max_width = terminal_columns ();
 
240
 
 
241
            if (ml_pref.pr_as_read_syntax)
 
242
                max_width -= 4;
 
243
 
 
244
            if (ml_pref.free_format) {
 
245
 
 
246
                if (ml_pref.pr_as_read_syntax)
 
247
                    os << "[\n";
 
248
 
 
249
                // default: dump
 
250
                os << x;
 
251
 
 
252
                if (ml_pref.pr_as_read_syntax)
 
253
                    os << "]";
 
254
                return;
 
255
            }
 
256
            int inc = n;
 
257
            if (total_width > max_width && ml_pref.split_long_rows) {
 
258
          
 
259
                inc = max_width / column_width;
 
260
                if (inc == 0)
 
261
                    inc++;
 
262
            }
 
263
            if (ml_pref.pr_as_read_syntax) {
 
264
 
 
265
                // x = [ 1; 2; 3; ...
 
266
                //       4; 5]
 
267
                int col = 0;
 
268
                os << "[ ";
 
269
                while (col < n) {
 
270
                  
 
271
                    int lim = col + inc < n ? col + inc : n;
 
272
                    for (int i = col; i < lim; i++) {
 
273
                      
 
274
                        if (i > col) os << "; ";
 
275
                        pr_float (os, x(i));
 
276
                   }
 
277
                   col += inc;
 
278
                   if (col < n) os << "; ...\n";
 
279
                }
 
280
                os << " ]";
 
281
            } else {
 
282
                for (int line = 0; line < n; line += inc) {
 
283
              
 
284
                    int lim = line + inc < n ? line + inc : n;
 
285
                    if (total_width > max_width && ml_pref.split_long_rows) {
 
286
                  
 
287
                        if (line != 0)
 
288
                            os << "\n";
 
289
 
 
290
                        int num_lines = lim - line;
 
291
                        if (num_lines == 1)
 
292
                            os << " Index " << line + 1 << ":\n\n";
 
293
                        else if (num_lines == 2)
 
294
                            os << " Indexes " << line + 1 << " and " << lim << ":\n\n";
 
295
                        else
 
296
                            os << " Indexes " << line + 1 << " through " << lim << ":\n\n";
 
297
                    }
 
298
                    for (int i = line; i < lim; i++) {
 
299
                      
 
300
                        os << "  ";
 
301
                        pr_float (os, x(i), fw);
 
302
                    }
 
303
                }
 
304
                os << "\n";
 
305
            }
 
306
        }
 
307
}
 
308
template <class T>
 
309
void
 
310
print_matlab (ostream& os, const vec<T>& x)
 
311
{
 
312
    print_matlab_gen(os, x);
 
313
}
 
314
template <class T>
 
315
void
 
316
print_matlab (ostream& os, const avec<T>& x)
 
317
{
 
318
    print_matlab_gen(os, x);
 
319
}
 
320
template <class T>
 
321
void
 
322
print_matlab (ostream& os, const csr<T>& a)
 
323
{
 
324
        init_ml_pref();
 
325
        int nr = a.nrow ();
 
326
        int nc = a.ncol ();
 
327
        if (nr == 0 || nc == 0) {
 
328
 
 
329
            os << "zeros (" << a.nrow() << ", " << a.ncol() << ")";
 
330
 
 
331
        } else if (ml_pref.plus_format && ! ml_pref.pr_as_read_syntax) {
 
332
      
 
333
             for (int i = 0; i < nr; i++) {
 
334
                 for (int j = 0; j < nc; j++) {
 
335
                     if (j == 0)
 
336
                        os << "  ";
 
337
                     if (a (i, j) == Float(0))
 
338
                        os << " ";
 
339
                     else
 
340
                        os << "+";
 
341
                 }
 
342
                 os << "\n";
 
343
             }
 
344
        } else {
 
345
            int fw = 0;
 
346
            set_format (os, a, fw);
 
347
            int column_width = fw + 2;
 
348
            int total_width = nc * column_width;
 
349
            int max_width = terminal_columns ();
 
350
 
 
351
            if (ml_pref.pr_as_read_syntax)
 
352
                max_width -= 4;
 
353
 
 
354
            if (ml_pref.free_format) {
 
355
 
 
356
                if (ml_pref.pr_as_read_syntax)
 
357
                    os << "[\n";
 
358
 
 
359
                // default: dump
 
360
                os << a;
 
361
 
 
362
                if (ml_pref.pr_as_read_syntax)
 
363
                    os << "]";
 
364
                return;
 
365
            }
 
366
            int inc = nc;
 
367
            if (total_width > max_width && ml_pref.split_long_rows) {
 
368
          
 
369
                inc = max_width / column_width;
 
370
                if (inc == 0)
 
371
                    inc++;
 
372
            }
 
373
            if (ml_pref.pr_as_read_syntax) {
 
374
 
 
375
                for (int i = 0; i < nr; i++) {
 
376
              
 
377
                    int col = 0;
 
378
                    while (col < nc) {
 
379
                  
 
380
                        int lim = col + inc < nc ? col + inc : nc;
 
381
                        for (int j = col; j < lim; j++) {
 
382
                      
 
383
                            if (i == 0 && j == 0) {
 
384
                                os << "[ ";
 
385
                            } else {
 
386
                                if (j > col && j < lim)
 
387
                                    os << ", ";
 
388
                                else
 
389
                                    os << "  ";
 
390
                            }
 
391
                            pr_float (os, a(i, j));
 
392
                        }
 
393
                        col += inc;
 
394
                        if (col >= nc) {
 
395
                      
 
396
                            if (i == nr - 1)
 
397
                                os << " ]";
 
398
                            else
 
399
                                os << ";\n";
 
400
                        } else {
 
401
                                os << " ...\n";
 
402
                        }
 
403
                    }
 
404
                }
 
405
            } else {
 
406
 
 
407
                for (int col = 0; col < nc; col += inc) {
 
408
              
 
409
                    int lim = col + inc < nc ? col + inc : nc;
 
410
                    if (total_width > max_width && ml_pref.split_long_rows) {
 
411
                  
 
412
                        if (col != 0)
 
413
                            os << "\n";
 
414
 
 
415
                        int num_cols = lim - col;
 
416
                        if (num_cols == 1)
 
417
                            os << " Column " << col + 1 << ":\n\n";
 
418
                        else if (num_cols == 2)
 
419
                            os << " Columns " << col + 1 << " and " << lim << ":\n\n";
 
420
                        else
 
421
                            os << " Columns " << col + 1 << " through " << lim << ":\n\n";
 
422
                    }
 
423
                    for (int i = 0; i < nr; i++) {
 
424
                        for (int j = col; j < lim; j++) {
 
425
                      
 
426
                            os << "  ";
 
427
                            pr_float (os, a(i, j), fw);
 
428
                        }
 
429
                        os << "\n";
 
430
                    }
 
431
                }
 
432
            }
 
433
        }
 
434
}
 
435
// =====================[ INSTANCIATION IN LIBRARY ]=============================
 
436
 
 
437
template void print_matlab (ostream&, const vec<Float>&);
 
438
template void print_matlab (ostream&, const avec<Float>&);
 
439
template void print_matlab (ostream&, const csr<Float>&);
 
440