2
/// This file is part of Rheolef.
4
/// Copyright (C) 2000-2009 Pierre Saramito <Pierre.Saramito@imag.fr>
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.
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.
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
20
/// =========================================================================
22
// OUT ML: Matrix and Vector Output
23
// in a MatLab-like format
25
// author: Pierre.Saramito@imag.fr
27
// date: 21 january 1997
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
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 !
41
ml_preferences ml_pref;
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;
52
int screenwidth = 80; // TODO: could use readline.
54
terminal_columns (void)
56
extern int screenwidth;
57
return screenwidth > 0 ? screenwidth : 80;
59
// Current format string for floats numbers
60
static char *curr_fmt = 0;
65
set_format (ostream& os, const T& a, int& fw)
69
if (ml_pref.free_format) return;
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)));
79
int prec = os.precision();
81
ml_pref.output_max_field_width = os.width();
83
ml_pref.output_max_field_width = screenwidth;
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;
99
if (ml_pref.bank_format) {
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)
108
} else if (a.all_elements_are_int_or_inf_or_nan ()) {
110
int digits = x_max > x_min ? x_max : x_min;
111
fw = digits <= 0 ? 1 : digits;
112
if (inf_or_nan && fw < 3)
120
rd_max = prec - x_max;
124
rd_max = prec - x_max;
130
rd_min = prec - x_min;
134
rd_min = prec - x_min;
137
ld = ld_max > ld_min ? ld_max : ld_min;
138
rd = rd_max > rd_min ? rd_max : rd_min;
140
if (inf_or_nan && fw < 3)
144
if (! ml_pref.bank_format && (fw > ml_pref.output_max_field_width || ml_pref.print_e)) {
147
if (x_max > 100 || x_min > 100)
149
fw = 2 + prec + exp_field;
150
if (inf_or_nan && fw < 3)
153
if (ml_pref.print_big_e)
154
sprintf (fmt_buf, "%%%d.%dE", fw, prec - 1);
156
sprintf (fmt_buf, "%%%d.%de", fw, prec - 1);
159
sprintf (fmt_buf, "%%%d.%df", fw, rd);
161
curr_fmt = &fmt_buf[0];
166
pr_any_float (const char *fmt, ostream& os, Float d, int fw = 0)
168
if (d == Float(-0.)) d = 0;
178
skit_form2(os, "%*s", fw, s);
182
} else if (xisnan (d)) {
184
skit_form2(os, "%*s", fw, "NaN");
189
skit_form(os, fmt, double(d));
196
pr_float (ostream& os, Float d, int fw = 0)
198
pr_any_float (curr_fmt, os, d, fw);
201
print_empty_vector (ostream& os, int n)
204
assert_macro (n == 0, "empty vector expected, vec(" << n << ") found");
205
if (ml_pref.pr_as_read_syntax) {
209
if (ml_pref.print_empty_dimensions)
210
os << "(" << n << ")";
216
print_matlab_gen (ostream& os, const Vec& x)
222
print_empty_vector (os, n);
224
} else if (ml_pref.plus_format && ! ml_pref.pr_as_read_syntax) {
226
for (int i = 0; i < n; i++) {
228
if (x (i) == Float(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 ();
241
if (ml_pref.pr_as_read_syntax)
244
if (ml_pref.free_format) {
246
if (ml_pref.pr_as_read_syntax)
252
if (ml_pref.pr_as_read_syntax)
257
if (total_width > max_width && ml_pref.split_long_rows) {
259
inc = max_width / column_width;
263
if (ml_pref.pr_as_read_syntax) {
265
// x = [ 1; 2; 3; ...
271
int lim = col + inc < n ? col + inc : n;
272
for (int i = col; i < lim; i++) {
274
if (i > col) os << "; ";
278
if (col < n) os << "; ...\n";
282
for (int line = 0; line < n; line += inc) {
284
int lim = line + inc < n ? line + inc : n;
285
if (total_width > max_width && ml_pref.split_long_rows) {
290
int num_lines = lim - line;
292
os << " Index " << line + 1 << ":\n\n";
293
else if (num_lines == 2)
294
os << " Indexes " << line + 1 << " and " << lim << ":\n\n";
296
os << " Indexes " << line + 1 << " through " << lim << ":\n\n";
298
for (int i = line; i < lim; i++) {
301
pr_float (os, x(i), fw);
310
print_matlab (ostream& os, const vec<T>& x)
312
print_matlab_gen(os, x);
316
print_matlab (ostream& os, const avec<T>& x)
318
print_matlab_gen(os, x);
322
print_matlab (ostream& os, const csr<T>& a)
327
if (nr == 0 || nc == 0) {
329
os << "zeros (" << a.nrow() << ", " << a.ncol() << ")";
331
} else if (ml_pref.plus_format && ! ml_pref.pr_as_read_syntax) {
333
for (int i = 0; i < nr; i++) {
334
for (int j = 0; j < nc; j++) {
337
if (a (i, j) == Float(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 ();
351
if (ml_pref.pr_as_read_syntax)
354
if (ml_pref.free_format) {
356
if (ml_pref.pr_as_read_syntax)
362
if (ml_pref.pr_as_read_syntax)
367
if (total_width > max_width && ml_pref.split_long_rows) {
369
inc = max_width / column_width;
373
if (ml_pref.pr_as_read_syntax) {
375
for (int i = 0; i < nr; i++) {
380
int lim = col + inc < nc ? col + inc : nc;
381
for (int j = col; j < lim; j++) {
383
if (i == 0 && j == 0) {
386
if (j > col && j < lim)
391
pr_float (os, a(i, j));
407
for (int col = 0; col < nc; col += inc) {
409
int lim = col + inc < nc ? col + inc : nc;
410
if (total_width > max_width && ml_pref.split_long_rows) {
415
int num_cols = lim - col;
417
os << " Column " << col + 1 << ":\n\n";
418
else if (num_cols == 2)
419
os << " Columns " << col + 1 << " and " << lim << ":\n\n";
421
os << " Columns " << col + 1 << " through " << lim << ":\n\n";
423
for (int i = 0; i < nr; i++) {
424
for (int j = col; j < lim; j++) {
427
pr_float (os, a(i, j), fw);
435
// =====================[ INSTANCIATION IN LIBRARY ]=============================
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>&);