Mercurial > octave
comparison libinterp/corefcn/pr-output.cc @ 16892:68fc671a9339
maint: Collapse interpfcn and interpfcn-core directories into corefcn directory.
* libgui/src/module.mk: Remove -I references to interp-core, interpfcn, add
reference to corefcn.
* libinterp/Makefile.am: Remove -I references to interp-core, interpfcn, add
reference to corefcn.
* libinterp/corefcn/module.mk: Add files from interp-core, interpfcn to
build system. Copy over special rules from module.mk files in interp-core
andd interpfcn.
* src/Makefile.am: Replace references to interp-core, interpfcn with those
to corefcn.
* libinterp/corefcn/Cell.cc, libinterp/corefcn/Cell.h,
libinterp/corefcn/action-container.h, libinterp/corefcn/c-file-ptr-stream.cc,
libinterp/corefcn/c-file-ptr-stream.h, libinterp/corefcn/comment-list.cc,
libinterp/corefcn/comment-list.h, libinterp/corefcn/cutils.c,
libinterp/corefcn/cutils.h, libinterp/corefcn/data.cc,
libinterp/corefcn/data.h, libinterp/corefcn/debug.cc,
libinterp/corefcn/debug.h, libinterp/corefcn/defaults.cc,
libinterp/corefcn/defaults.in.h, libinterp/corefcn/defun-dld.h,
libinterp/corefcn/defun-int.h, libinterp/corefcn/defun.cc,
libinterp/corefcn/defun.h, libinterp/corefcn/dirfns.cc,
libinterp/corefcn/dirfns.h, libinterp/corefcn/display.cc,
libinterp/corefcn/display.h, libinterp/corefcn/dynamic-ld.cc,
libinterp/corefcn/dynamic-ld.h, libinterp/corefcn/error.cc,
libinterp/corefcn/error.h, libinterp/corefcn/event-queue.h,
libinterp/corefcn/file-io.cc, libinterp/corefcn/file-io.h,
libinterp/corefcn/gl-render.cc, libinterp/corefcn/gl-render.h,
libinterp/corefcn/gl2ps-renderer.cc, libinterp/corefcn/gl2ps-renderer.h,
libinterp/corefcn/gl2ps.c, libinterp/corefcn/gl2ps.h,
libinterp/corefcn/graphics.cc, libinterp/corefcn/graphics.in.h,
libinterp/corefcn/gripes.cc, libinterp/corefcn/gripes.h,
libinterp/corefcn/help.cc, libinterp/corefcn/help.h,
libinterp/corefcn/hook-fcn.cc, libinterp/corefcn/hook-fcn.h,
libinterp/corefcn/input.cc, libinterp/corefcn/input.h,
libinterp/corefcn/jit-ir.cc, libinterp/corefcn/jit-ir.h,
libinterp/corefcn/jit-typeinfo.cc, libinterp/corefcn/jit-typeinfo.h,
libinterp/corefcn/jit-util.cc, libinterp/corefcn/jit-util.h,
libinterp/corefcn/load-path.cc, libinterp/corefcn/load-path.h,
libinterp/corefcn/load-save.cc, libinterp/corefcn/load-save.h,
libinterp/corefcn/ls-ascii-helper.cc, libinterp/corefcn/ls-ascii-helper.h,
libinterp/corefcn/ls-hdf5.cc, libinterp/corefcn/ls-hdf5.h,
libinterp/corefcn/ls-mat-ascii.cc, libinterp/corefcn/ls-mat-ascii.h,
libinterp/corefcn/ls-mat4.cc, libinterp/corefcn/ls-mat4.h,
libinterp/corefcn/ls-mat5.cc, libinterp/corefcn/ls-mat5.h,
libinterp/corefcn/ls-oct-ascii.cc, libinterp/corefcn/ls-oct-ascii.h,
libinterp/corefcn/ls-oct-binary.cc, libinterp/corefcn/ls-oct-binary.h,
libinterp/corefcn/ls-utils.cc, libinterp/corefcn/ls-utils.h,
libinterp/corefcn/matherr.c, libinterp/corefcn/mex.cc, libinterp/corefcn/mex.h,
libinterp/corefcn/mexproto.h, libinterp/corefcn/mxarray.in.h,
libinterp/corefcn/oct-errno.h, libinterp/corefcn/oct-errno.in.cc,
libinterp/corefcn/oct-fstrm.cc, libinterp/corefcn/oct-fstrm.h,
libinterp/corefcn/oct-hdf5.h, libinterp/corefcn/oct-hist.cc,
libinterp/corefcn/oct-hist.h, libinterp/corefcn/oct-iostrm.cc,
libinterp/corefcn/oct-iostrm.h, libinterp/corefcn/oct-lvalue.cc,
libinterp/corefcn/oct-lvalue.h, libinterp/corefcn/oct-map.cc,
libinterp/corefcn/oct-map.h, libinterp/corefcn/oct-obj.cc,
libinterp/corefcn/oct-obj.h, libinterp/corefcn/oct-prcstrm.cc,
libinterp/corefcn/oct-prcstrm.h, libinterp/corefcn/oct-procbuf.cc,
libinterp/corefcn/oct-procbuf.h, libinterp/corefcn/oct-stdstrm.h,
libinterp/corefcn/oct-stream.cc, libinterp/corefcn/oct-stream.h,
libinterp/corefcn/oct-strstrm.cc, libinterp/corefcn/oct-strstrm.h,
libinterp/corefcn/oct.h, libinterp/corefcn/octave-link.cc,
libinterp/corefcn/octave-link.h, libinterp/corefcn/pager.cc,
libinterp/corefcn/pager.h, libinterp/corefcn/pr-output.cc,
libinterp/corefcn/pr-output.h, libinterp/corefcn/procstream.cc,
libinterp/corefcn/procstream.h, libinterp/corefcn/profiler.cc,
libinterp/corefcn/profiler.h, libinterp/corefcn/pt-jit.cc,
libinterp/corefcn/pt-jit.h, libinterp/corefcn/sighandlers.cc,
libinterp/corefcn/sighandlers.h, libinterp/corefcn/siglist.c,
libinterp/corefcn/siglist.h, libinterp/corefcn/sparse-xdiv.cc,
libinterp/corefcn/sparse-xdiv.h, libinterp/corefcn/sparse-xpow.cc,
libinterp/corefcn/sparse-xpow.h, libinterp/corefcn/symtab.cc,
libinterp/corefcn/symtab.h, libinterp/corefcn/sysdep.cc,
libinterp/corefcn/sysdep.h, libinterp/corefcn/toplev.cc,
libinterp/corefcn/toplev.h, libinterp/corefcn/txt-eng-ft.cc,
libinterp/corefcn/txt-eng-ft.h, libinterp/corefcn/txt-eng.h,
libinterp/corefcn/unwind-prot.cc, libinterp/corefcn/unwind-prot.h,
libinterp/corefcn/utils.cc, libinterp/corefcn/utils.h,
libinterp/corefcn/variables.cc, libinterp/corefcn/variables.h,
libinterp/corefcn/workspace-element.h, libinterp/corefcn/xdiv.cc,
libinterp/corefcn/xdiv.h, libinterp/corefcn/xgl2ps.c,
libinterp/corefcn/xnorm.cc, libinterp/corefcn/xnorm.h,
libinterp/corefcn/xpow.cc, libinterp/corefcn/xpow.h,
libinterp/corefcn/zfstream.cc, libinterp/corefcn/zfstream.h:
Files moved from interp-core and interpfcn directories.
* libinterp/interp-core/Cell.cc, libinterp/interp-core/Cell.h,
libinterp/interp-core/action-container.h,
libinterp/interp-core/c-file-ptr-stream.cc,
libinterp/interp-core/c-file-ptr-stream.h,
libinterp/interp-core/comment-list.cc, libinterp/interp-core/comment-list.h,
libinterp/interp-core/cutils.c, libinterp/interp-core/cutils.h,
libinterp/interp-core/defun-dld.h, libinterp/interp-core/defun-int.h,
libinterp/interp-core/display.cc, libinterp/interp-core/display.h,
libinterp/interp-core/dynamic-ld.cc, libinterp/interp-core/dynamic-ld.h,
libinterp/interp-core/event-queue.h, libinterp/interp-core/gl-render.cc,
libinterp/interp-core/gl-render.h, libinterp/interp-core/gl2ps-renderer.cc,
libinterp/interp-core/gl2ps-renderer.h, libinterp/interp-core/gl2ps.c,
libinterp/interp-core/gl2ps.h, libinterp/interp-core/gripes.cc,
libinterp/interp-core/gripes.h, libinterp/interp-core/jit-ir.cc,
libinterp/interp-core/jit-ir.h, libinterp/interp-core/jit-typeinfo.cc,
libinterp/interp-core/jit-typeinfo.h, libinterp/interp-core/jit-util.cc,
libinterp/interp-core/jit-util.h, libinterp/interp-core/ls-ascii-helper.cc,
libinterp/interp-core/ls-ascii-helper.h, libinterp/interp-core/ls-hdf5.cc,
libinterp/interp-core/ls-hdf5.h, libinterp/interp-core/ls-mat-ascii.cc,
libinterp/interp-core/ls-mat-ascii.h, libinterp/interp-core/ls-mat4.cc,
libinterp/interp-core/ls-mat4.h, libinterp/interp-core/ls-mat5.cc,
libinterp/interp-core/ls-mat5.h, libinterp/interp-core/ls-oct-binary.cc,
libinterp/interp-core/ls-oct-binary.h, libinterp/interp-core/ls-utils.cc,
libinterp/interp-core/ls-utils.h, libinterp/interp-core/matherr.c,
libinterp/interp-core/mex.cc, libinterp/interp-core/mex.h,
libinterp/interp-core/mexproto.h, libinterp/interp-core/module.mk,
libinterp/interp-core/mxarray.in.h, libinterp/interp-core/oct-errno.h,
libinterp/interp-core/oct-errno.in.cc, libinterp/interp-core/oct-fstrm.cc,
libinterp/interp-core/oct-fstrm.h, libinterp/interp-core/oct-hdf5.h,
libinterp/interp-core/oct-iostrm.cc, libinterp/interp-core/oct-iostrm.h,
libinterp/interp-core/oct-lvalue.cc, libinterp/interp-core/oct-lvalue.h,
libinterp/interp-core/oct-map.cc, libinterp/interp-core/oct-map.h,
libinterp/interp-core/oct-obj.cc, libinterp/interp-core/oct-obj.h,
libinterp/interp-core/oct-prcstrm.cc, libinterp/interp-core/oct-prcstrm.h,
libinterp/interp-core/oct-procbuf.cc, libinterp/interp-core/oct-procbuf.h,
libinterp/interp-core/oct-stdstrm.h, libinterp/interp-core/oct-stream.cc,
libinterp/interp-core/oct-stream.h, libinterp/interp-core/oct-strstrm.cc,
libinterp/interp-core/oct-strstrm.h, libinterp/interp-core/oct.h,
libinterp/interp-core/procstream.cc, libinterp/interp-core/procstream.h,
libinterp/interp-core/pt-jit.cc, libinterp/interp-core/pt-jit.h,
libinterp/interp-core/siglist.c, libinterp/interp-core/siglist.h,
libinterp/interp-core/sparse-xdiv.cc, libinterp/interp-core/sparse-xdiv.h,
libinterp/interp-core/sparse-xpow.cc, libinterp/interp-core/sparse-xpow.h,
libinterp/interp-core/txt-eng-ft.cc, libinterp/interp-core/txt-eng-ft.h,
libinterp/interp-core/txt-eng.h, libinterp/interp-core/unwind-prot.cc,
libinterp/interp-core/unwind-prot.h, libinterp/interp-core/xdiv.cc,
libinterp/interp-core/xdiv.h, libinterp/interp-core/xgl2ps.c,
libinterp/interp-core/xnorm.cc, libinterp/interp-core/xnorm.h,
libinterp/interp-core/xpow.cc, libinterp/interp-core/xpow.h,
libinterp/interp-core/zfstream.cc, libinterp/interp-core/zfstream.h,
libinterp/interpfcn/data.cc, libinterp/interpfcn/data.h,
libinterp/interpfcn/debug.cc, libinterp/interpfcn/debug.h,
libinterp/interpfcn/defaults.cc, libinterp/interpfcn/defaults.in.h,
libinterp/interpfcn/defun.cc, libinterp/interpfcn/defun.h,
libinterp/interpfcn/dirfns.cc, libinterp/interpfcn/dirfns.h,
libinterp/interpfcn/error.cc, libinterp/interpfcn/error.h,
libinterp/interpfcn/file-io.cc, libinterp/interpfcn/file-io.h,
libinterp/interpfcn/graphics.cc, libinterp/interpfcn/graphics.in.h,
libinterp/interpfcn/help.cc, libinterp/interpfcn/help.h,
libinterp/interpfcn/hook-fcn.cc, libinterp/interpfcn/hook-fcn.h,
libinterp/interpfcn/input.cc, libinterp/interpfcn/input.h,
libinterp/interpfcn/load-path.cc, libinterp/interpfcn/load-path.h,
libinterp/interpfcn/load-save.cc, libinterp/interpfcn/load-save.h,
libinterp/interpfcn/ls-oct-ascii.cc, libinterp/interpfcn/ls-oct-ascii.h,
libinterp/interpfcn/module.mk, libinterp/interpfcn/oct-hist.cc,
libinterp/interpfcn/oct-hist.h, libinterp/interpfcn/octave-link.cc,
libinterp/interpfcn/octave-link.h, libinterp/interpfcn/pager.cc,
libinterp/interpfcn/pager.h, libinterp/interpfcn/pr-output.cc,
libinterp/interpfcn/pr-output.h, libinterp/interpfcn/profiler.cc,
libinterp/interpfcn/profiler.h, libinterp/interpfcn/sighandlers.cc,
libinterp/interpfcn/sighandlers.h, libinterp/interpfcn/symtab.cc,
libinterp/interpfcn/symtab.h, libinterp/interpfcn/sysdep.cc,
libinterp/interpfcn/sysdep.h, libinterp/interpfcn/toplev.cc,
libinterp/interpfcn/toplev.h, libinterp/interpfcn/utils.cc,
libinterp/interpfcn/utils.h, libinterp/interpfcn/variables.cc,
libinterp/interpfcn/variables.h, libinterp/interpfcn/workspace-element.h:
deleted files.
author | Rik <rik@octave.org> |
---|---|
date | Wed, 03 Jul 2013 17:43:48 -0700 |
parents | libinterp/interpfcn/pr-output.cc@0c340bf413d7 |
children | 259c1f295a1e |
comparison
equal
deleted
inserted
replaced
16891:486c3e2731ff | 16892:68fc671a9339 |
---|---|
1 /* | |
2 | |
3 Copyright (C) 1993-2012 John W. Eaton | |
4 | |
5 This file is part of Octave. | |
6 | |
7 Octave is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
9 Free Software Foundation; either version 3 of the License, or (at your | |
10 option) any later version. | |
11 | |
12 Octave is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with Octave; see the file COPYING. If not, see | |
19 <http://www.gnu.org/licenses/>. | |
20 | |
21 */ | |
22 | |
23 #ifdef HAVE_CONFIG_H | |
24 #include <config.h> | |
25 #endif | |
26 | |
27 #include <cfloat> | |
28 #include <cstdio> | |
29 #include <cstring> | |
30 | |
31 #include <iomanip> | |
32 #include <iostream> | |
33 #include <sstream> | |
34 #include <string> | |
35 | |
36 #include "Array-util.h" | |
37 #include "CMatrix.h" | |
38 #include "Range.h" | |
39 #include "cmd-edit.h" | |
40 #include "dMatrix.h" | |
41 #include "lo-mappers.h" | |
42 #include "lo-math.h" | |
43 #include "mach-info.h" | |
44 #include "oct-cmplx.h" | |
45 #include "quit.h" | |
46 #include "str-vec.h" | |
47 | |
48 #include "Cell.h" | |
49 #include "defun.h" | |
50 #include "error.h" | |
51 #include "gripes.h" | |
52 #include "oct-obj.h" | |
53 #include "oct-stream.h" | |
54 #include "pager.h" | |
55 #include "pr-output.h" | |
56 #include "sysdep.h" | |
57 #include "unwind-prot.h" | |
58 #include "utils.h" | |
59 #include "variables.h" | |
60 | |
61 // TRUE means use a scaled fixed point format for 'format long' and | |
62 // 'format short'. | |
63 static bool Vfixed_point_format = false; | |
64 | |
65 // The maximum field width for a number printed by the default output | |
66 // routines. | |
67 static int Voutput_max_field_width = 10; | |
68 | |
69 // The precision of the numbers printed by the default output | |
70 // routines. | |
71 static int Voutput_precision = 5; | |
72 | |
73 // TRUE means that the dimensions of empty objects should be printed | |
74 // like this: x = [](2x0). | |
75 bool Vprint_empty_dimensions = true; | |
76 | |
77 // TRUE means that the rows of big matrices should be split into | |
78 // smaller slices that fit on the screen. | |
79 static bool Vsplit_long_rows = true; | |
80 | |
81 // TRUE means don't do any fancy formatting. | |
82 static bool free_format = false; | |
83 | |
84 // TRUE means print plus sign for nonzero, blank for zero. | |
85 static bool plus_format = false; | |
86 | |
87 // First char for > 0, second for < 0, third for == 0. | |
88 static std::string plus_format_chars = "+ "; | |
89 | |
90 // TRUE means always print in a rational approximation | |
91 static bool rat_format = false; | |
92 | |
93 // Used to force the length of the rational approximation string for Frats | |
94 static int rat_string_len = -1; | |
95 | |
96 // TRUE means always print like dollars and cents. | |
97 static bool bank_format = false; | |
98 | |
99 // TRUE means print data in hexadecimal format. | |
100 static int hex_format = 0; | |
101 | |
102 // TRUE means print data in binary-bit-pattern format. | |
103 static int bit_format = 0; | |
104 | |
105 // TRUE means don't put newlines around the column number headers. | |
106 bool Vcompact_format = false; | |
107 | |
108 // TRUE means use an e format. | |
109 static bool print_e = false; | |
110 | |
111 // TRUE means use a g format. | |
112 static bool print_g = false; | |
113 | |
114 // TRUE means print E instead of e for exponent field. | |
115 static bool print_big_e = false; | |
116 | |
117 // TRUE means use an engineering format. | |
118 static bool print_eng = false; | |
119 | |
120 class pr_engineering_float; | |
121 class pr_formatted_float; | |
122 class pr_rational_float; | |
123 | |
124 static int | |
125 current_output_max_field_width (void) | |
126 { | |
127 return Voutput_max_field_width; | |
128 } | |
129 | |
130 static int | |
131 current_output_precision (void) | |
132 { | |
133 return Voutput_precision; | |
134 } | |
135 | |
136 class | |
137 float_format | |
138 { | |
139 public: | |
140 | |
141 float_format (int w = current_output_max_field_width (), | |
142 int p = current_output_precision (), int f = 0) | |
143 : fw (w), ex (0), prec (p), fmt (f), up (0), sp (0) { } | |
144 | |
145 float_format (int w, int e, int p, int f) | |
146 : fw (w), ex (e), prec (p), fmt (f), up (0), sp (0) { } | |
147 | |
148 float_format (const float_format& ff) | |
149 : fw (ff.fw), ex (ff.ex), prec (ff.prec), fmt (ff.fmt), up (ff.up), sp (ff.sp) { } | |
150 | |
151 float_format& operator = (const float_format& ff) | |
152 { | |
153 if (&ff != this) | |
154 { | |
155 fw = ff.fw; | |
156 ex = ff.ex; | |
157 prec = ff.prec; | |
158 fmt = ff.fmt; | |
159 up = ff.up; | |
160 sp = ff.sp; | |
161 } | |
162 | |
163 return *this; | |
164 } | |
165 | |
166 ~float_format (void) { } | |
167 | |
168 float_format& scientific (void) { fmt = std::ios::scientific; return *this; } | |
169 float_format& fixed (void) { fmt = std::ios::fixed; return *this; } | |
170 float_format& general (void) { fmt = 0; return *this; } | |
171 | |
172 float_format& uppercase (void) { up = std::ios::uppercase; return *this; } | |
173 float_format& lowercase (void) { up = 0; return *this; } | |
174 | |
175 float_format& precision (int p) { prec = p; return *this; } | |
176 | |
177 float_format& width (int w) { fw = w; return *this; } | |
178 | |
179 float_format& trailing_zeros (bool tz = true) | |
180 { sp = tz ? std::ios::showpoint : 0; return *this; } | |
181 | |
182 friend std::ostream& operator << (std::ostream& os, | |
183 const pr_engineering_float& pef); | |
184 | |
185 friend std::ostream& operator << (std::ostream& os, | |
186 const pr_formatted_float& pff); | |
187 | |
188 friend std::ostream& operator << (std::ostream& os, | |
189 const pr_rational_float& prf); | |
190 | |
191 private: | |
192 | |
193 // Field width. Zero means as wide as necessary. | |
194 int fw; | |
195 | |
196 // Exponent Field width. Zero means as wide as necessary. | |
197 int ex; | |
198 | |
199 // Precision. | |
200 int prec; | |
201 | |
202 // Format. | |
203 int fmt; | |
204 | |
205 // E or e. | |
206 int up; | |
207 | |
208 // Show trailing zeros. | |
209 int sp; | |
210 }; | |
211 | |
212 static int | |
213 calc_scale_exp (const int& x) | |
214 { | |
215 if (! print_eng) | |
216 return x; | |
217 else | |
218 return x - 3*static_cast<int> (x/3); | |
219 /* The expression above is equivalent to x - (x % 3). | |
220 * According to the ISO specification for C++ the modulo operator is | |
221 * compiler dependent if any of the arguments are negative. Since this | |
222 * function will need to work on negative arguments, and we want to avoid | |
223 * portability issues, we re-implement the modulo function to the desired | |
224 * behavior (truncation). There may be a gnulib replacement. | |
225 * | |
226 * ISO/IEC 14882:2003 : Programming languages -- C++. 5.6.4: ISO, IEC. 2003 . | |
227 * "the binary % operator yields the remainder from the division of the first | |
228 * expression by the second. .... If both operands are nonnegative then the | |
229 * remainder is nonnegative; if not, the sign of the remainder is | |
230 * implementation-defined". */ | |
231 } | |
232 | |
233 static int | |
234 engineering_exponent (const double& x) | |
235 { | |
236 int ex = 0; | |
237 if (x != 0) | |
238 { | |
239 double absval = (x < 0.0 ? -x : x); | |
240 int logabsval = static_cast<int> (gnulib::floor (log10 (absval))); | |
241 /* Avoid using modulo function with negative arguments for portability. | |
242 * See extended comment at calc_scale_exp */ | |
243 if (logabsval < 0.0) | |
244 ex = logabsval - 2 + ((-logabsval + 2) % 3); | |
245 else | |
246 ex = logabsval - (logabsval % 3); | |
247 } | |
248 return ex; | |
249 } | |
250 | |
251 static int | |
252 num_digits (const double& x) | |
253 { | |
254 return 1 + (print_eng | |
255 ? engineering_exponent (x) | |
256 : static_cast<int> (gnulib::floor (log10 (x)))); | |
257 } | |
258 | |
259 class | |
260 pr_engineering_float | |
261 { | |
262 public: | |
263 | |
264 const float_format& f; | |
265 | |
266 double val; | |
267 | |
268 int exponent (void) const | |
269 { | |
270 return engineering_exponent (val); | |
271 } | |
272 | |
273 double mantissa (void) const | |
274 { | |
275 return val / std::pow (10.0, exponent ()); | |
276 } | |
277 | |
278 pr_engineering_float (const float_format& f_arg, double val_arg) | |
279 : f (f_arg), val (val_arg) { } | |
280 }; | |
281 | |
282 std::ostream& | |
283 operator << (std::ostream& os, const pr_engineering_float& pef) | |
284 { | |
285 if (pef.f.fw >= 0) | |
286 os << std::setw (pef.f.fw - pef.f.ex); | |
287 | |
288 if (pef.f.prec >= 0) | |
289 os << std::setprecision (pef.f.prec); | |
290 | |
291 std::ios::fmtflags oflags = | |
292 os.flags (static_cast<std::ios::fmtflags> | |
293 (pef.f.fmt | pef.f.up | pef.f.sp)); | |
294 | |
295 os << pef.mantissa (); | |
296 | |
297 int ex = pef.exponent (); | |
298 if (ex < 0) | |
299 { | |
300 os << std::setw (0) << "e-"; | |
301 ex = -ex; | |
302 } | |
303 else | |
304 os << std::setw (0) << "e+"; | |
305 | |
306 os << std::setw (pef.f.ex - 2) << std::setfill ('0') << ex | |
307 << std::setfill (' '); | |
308 | |
309 os.flags (oflags); | |
310 | |
311 return os; | |
312 } | |
313 | |
314 class | |
315 pr_formatted_float | |
316 { | |
317 public: | |
318 | |
319 const float_format& f; | |
320 | |
321 double val; | |
322 | |
323 pr_formatted_float (const float_format& f_arg, double val_arg) | |
324 : f (f_arg), val (val_arg) { } | |
325 }; | |
326 | |
327 std::ostream& | |
328 operator << (std::ostream& os, const pr_formatted_float& pff) | |
329 { | |
330 if (pff.f.fw >= 0) | |
331 os << std::setw (pff.f.fw); | |
332 | |
333 if (pff.f.prec >= 0) | |
334 os << std::setprecision (pff.f.prec); | |
335 | |
336 std::ios::fmtflags oflags = | |
337 os.flags (static_cast<std::ios::fmtflags> | |
338 (pff.f.fmt | pff.f.up | pff.f.sp)); | |
339 | |
340 os << pff.val; | |
341 | |
342 os.flags (oflags); | |
343 | |
344 return os; | |
345 } | |
346 | |
347 static inline std::string | |
348 rational_approx (double val, int len) | |
349 { | |
350 std::string s; | |
351 | |
352 if (len <= 0) | |
353 len = 10; | |
354 | |
355 if (xisinf (val)) | |
356 s = "1/0"; | |
357 else if (xisnan (val)) | |
358 s = "0/0"; | |
359 else if (val < std::numeric_limits<int>::min () | |
360 || val > std::numeric_limits<int>::max () | |
361 || D_NINT (val) == val) | |
362 { | |
363 std::ostringstream buf; | |
364 buf.flags (std::ios::fixed); | |
365 buf << std::setprecision (0) << xround (val); | |
366 s = buf.str (); | |
367 } | |
368 else | |
369 { | |
370 double lastn = 1.; | |
371 double lastd = 0.; | |
372 double n = xround (val); | |
373 double d = 1.; | |
374 double frac = val - n; | |
375 int m = 0; | |
376 | |
377 std::ostringstream buf2; | |
378 buf2.flags (std::ios::fixed); | |
379 buf2 << std::setprecision (0) << static_cast<int>(n); | |
380 s = buf2.str (); | |
381 | |
382 while (1) | |
383 { | |
384 double flip = 1. / frac; | |
385 double step = xround (flip); | |
386 double nextn = n; | |
387 double nextd = d; | |
388 | |
389 // Have we converged to 1/intmax ? | |
390 if (m > 100 || fabs (frac) < 1 / static_cast<double> (std::numeric_limits<int>::max ())) | |
391 { | |
392 lastn = n; | |
393 lastd = d; | |
394 break; | |
395 } | |
396 | |
397 frac = flip - step; | |
398 n = n * step + lastn; | |
399 d = d * step + lastd; | |
400 lastn = nextn; | |
401 lastd = nextd; | |
402 | |
403 std::ostringstream buf; | |
404 buf.flags (std::ios::fixed); | |
405 buf << std::setprecision (0) << static_cast<int>(n) | |
406 << "/" << static_cast<int>(d); | |
407 m++; | |
408 | |
409 if (n < 0 && d < 0) | |
410 { | |
411 // Double negative, string can be two characters longer.. | |
412 if (buf.str ().length () > static_cast<unsigned int>(len + 2) && | |
413 m > 1) | |
414 break; | |
415 } | |
416 else if (buf.str ().length () > static_cast<unsigned int>(len) && | |
417 m > 1) | |
418 break; | |
419 | |
420 s = buf.str (); | |
421 } | |
422 | |
423 if (lastd < 0.) | |
424 { | |
425 // Move sign to the top | |
426 lastd = - lastd; | |
427 lastn = - lastn; | |
428 std::ostringstream buf; | |
429 buf.flags (std::ios::fixed); | |
430 buf << std::setprecision (0) << static_cast<int>(lastn) | |
431 << "/" << static_cast<int>(lastd); | |
432 s = buf.str (); | |
433 } | |
434 } | |
435 | |
436 return s; | |
437 } | |
438 | |
439 class | |
440 pr_rational_float | |
441 { | |
442 public: | |
443 | |
444 const float_format& f; | |
445 | |
446 double val; | |
447 | |
448 pr_rational_float (const float_format& f_arg, double val_arg) | |
449 : f (f_arg), val (val_arg) { } | |
450 }; | |
451 | |
452 std::ostream& | |
453 operator << (std::ostream& os, const pr_rational_float& prf) | |
454 { | |
455 int fw = (rat_string_len > 0 ? rat_string_len : prf.f.fw); | |
456 std::string s = rational_approx (prf.val, fw); | |
457 | |
458 if (fw >= 0) | |
459 os << std::setw (fw); | |
460 | |
461 std::ios::fmtflags oflags = | |
462 os.flags (static_cast<std::ios::fmtflags> | |
463 (prf.f.fmt | prf.f.up | prf.f.sp)); | |
464 | |
465 if (fw > 0 && s.length () > static_cast<unsigned int>(fw)) | |
466 os << "*"; | |
467 else | |
468 os << s; | |
469 | |
470 os.flags (oflags); | |
471 | |
472 return os; | |
473 } | |
474 | |
475 // Current format for real numbers and the real part of complex | |
476 // numbers. | |
477 static float_format *curr_real_fmt = 0; | |
478 | |
479 // Current format for the imaginary part of complex numbers. | |
480 static float_format *curr_imag_fmt = 0; | |
481 | |
482 static double | |
483 pr_max_internal (const Matrix& m) | |
484 { | |
485 octave_idx_type nr = m.rows (); | |
486 octave_idx_type nc = m.columns (); | |
487 | |
488 double result = -std::numeric_limits<double>::max (); | |
489 | |
490 bool all_inf_or_nan = true; | |
491 | |
492 for (octave_idx_type j = 0; j < nc; j++) | |
493 for (octave_idx_type i = 0; i < nr; i++) | |
494 { | |
495 double val = m(i,j); | |
496 if (xisinf (val) || xisnan (val)) | |
497 continue; | |
498 | |
499 all_inf_or_nan = false; | |
500 | |
501 if (val > result) | |
502 result = val; | |
503 } | |
504 | |
505 if (all_inf_or_nan) | |
506 result = 0.0; | |
507 | |
508 return result; | |
509 } | |
510 | |
511 static double | |
512 pr_min_internal (const Matrix& m) | |
513 { | |
514 octave_idx_type nr = m.rows (); | |
515 octave_idx_type nc = m.columns (); | |
516 | |
517 double result = std::numeric_limits<double>::max (); | |
518 | |
519 bool all_inf_or_nan = true; | |
520 | |
521 for (octave_idx_type j = 0; j < nc; j++) | |
522 for (octave_idx_type i = 0; i < nr; i++) | |
523 { | |
524 double val = m(i,j); | |
525 if (xisinf (val) || xisnan (val)) | |
526 continue; | |
527 | |
528 all_inf_or_nan = false; | |
529 | |
530 if (val < result) | |
531 result = val; | |
532 } | |
533 | |
534 if (all_inf_or_nan) | |
535 result = 0.0; | |
536 | |
537 return result; | |
538 } | |
539 | |
540 // FIXME -- it would be nice to share more code among these | |
541 // functions,.. | |
542 | |
543 static void | |
544 set_real_format (int digits, bool inf_or_nan, bool int_only, int &fw) | |
545 { | |
546 static float_format fmt; | |
547 | |
548 int prec = Voutput_precision; | |
549 | |
550 int ld, rd; | |
551 | |
552 if (rat_format) | |
553 { | |
554 fw = 0; | |
555 rd = 0; | |
556 } | |
557 else if (bank_format) | |
558 { | |
559 fw = digits < 0 ? 4 : digits + 3; | |
560 if (inf_or_nan && fw < 4) | |
561 fw = 4; | |
562 rd = 2; | |
563 } | |
564 else if (hex_format) | |
565 { | |
566 fw = 2 * sizeof (double); | |
567 rd = 0; | |
568 } | |
569 else if (bit_format) | |
570 { | |
571 fw = 8 * sizeof (double); | |
572 rd = 0; | |
573 } | |
574 else if (inf_or_nan || int_only) | |
575 { | |
576 fw = 1 + digits; | |
577 if (inf_or_nan && fw < 4) | |
578 fw = 4; | |
579 rd = fw; | |
580 } | |
581 else | |
582 { | |
583 if (digits > 0) | |
584 { | |
585 ld = digits; | |
586 rd = prec > digits ? prec - digits : prec; | |
587 digits++; | |
588 } | |
589 else | |
590 { | |
591 ld = 1; | |
592 rd = prec > digits ? prec - digits : prec; | |
593 digits = -digits + 1; | |
594 } | |
595 | |
596 fw = 1 + ld + 1 + rd; | |
597 if (inf_or_nan && fw < 4) | |
598 fw = 4; | |
599 } | |
600 | |
601 if (! (rat_format || bank_format || hex_format || bit_format) | |
602 && (fw > Voutput_max_field_width || print_e || print_g || print_eng)) | |
603 { | |
604 if (print_g) | |
605 fmt = float_format (); | |
606 else | |
607 { | |
608 // e+ddd | |
609 int ex = 5; | |
610 | |
611 if (print_eng) | |
612 { | |
613 // -ddd. | |
614 fw = 5 + prec + ex; | |
615 if (inf_or_nan && fw < 6) | |
616 fw = 6; | |
617 fmt = float_format (fw, ex, prec - 1, std::ios::fixed); | |
618 } | |
619 else | |
620 { | |
621 // -d. | |
622 fw = 3 + prec + ex; | |
623 if (inf_or_nan && fw < 4) | |
624 fw = 4; | |
625 fmt = float_format (fw, ex, prec - 1, std::ios::scientific); | |
626 } | |
627 } | |
628 | |
629 if (print_big_e) | |
630 fmt.uppercase (); | |
631 } | |
632 else if (! bank_format && (inf_or_nan || int_only)) | |
633 fmt = float_format (fw, rd); | |
634 else | |
635 fmt = float_format (fw, rd, std::ios::fixed); | |
636 | |
637 curr_real_fmt = &fmt; | |
638 } | |
639 | |
640 static void | |
641 set_format (double d, int& fw) | |
642 { | |
643 curr_real_fmt = 0; | |
644 curr_imag_fmt = 0; | |
645 | |
646 if (free_format) | |
647 return; | |
648 | |
649 bool inf_or_nan = (xisinf (d) || xisnan (d)); | |
650 | |
651 bool int_only = (! inf_or_nan && D_NINT (d) == d); | |
652 | |
653 double d_abs = d < 0.0 ? -d : d; | |
654 | |
655 int digits = (inf_or_nan || d_abs == 0.0) | |
656 ? 0 : num_digits (d_abs); | |
657 | |
658 set_real_format (digits, inf_or_nan, int_only, fw); | |
659 } | |
660 | |
661 static inline void | |
662 set_format (double d) | |
663 { | |
664 int fw; | |
665 set_format (d, fw); | |
666 } | |
667 | |
668 static void | |
669 set_real_matrix_format (int x_max, int x_min, bool inf_or_nan, | |
670 int int_or_inf_or_nan, int& fw) | |
671 { | |
672 static float_format fmt; | |
673 | |
674 int prec = Voutput_precision; | |
675 | |
676 int ld, rd; | |
677 | |
678 if (rat_format) | |
679 { | |
680 fw = 9; | |
681 rd = 0; | |
682 } | |
683 else if (bank_format) | |
684 { | |
685 int digits = x_max > x_min ? x_max : x_min; | |
686 fw = digits <= 0 ? 4 : digits + 3; | |
687 if (inf_or_nan && fw < 4) | |
688 fw = 4; | |
689 rd = 2; | |
690 } | |
691 else if (hex_format) | |
692 { | |
693 fw = 2 * sizeof (double); | |
694 rd = 0; | |
695 } | |
696 else if (bit_format) | |
697 { | |
698 fw = 8 * sizeof (double); | |
699 rd = 0; | |
700 } | |
701 else if (Vfixed_point_format && ! print_g) | |
702 { | |
703 rd = prec; | |
704 fw = rd + 2; | |
705 if (inf_or_nan && fw < 4) | |
706 fw = 4; | |
707 } | |
708 else if (int_or_inf_or_nan) | |
709 { | |
710 int digits = x_max > x_min ? x_max : x_min; | |
711 fw = digits <= 0 ? 2 : digits + 1; | |
712 if (inf_or_nan && fw < 4) | |
713 fw = 4; | |
714 rd = fw; | |
715 } | |
716 else | |
717 { | |
718 int ld_max, rd_max; | |
719 if (x_max > 0) | |
720 { | |
721 ld_max = x_max; | |
722 rd_max = prec > x_max ? prec - x_max : prec; | |
723 x_max++; | |
724 } | |
725 else | |
726 { | |
727 ld_max = 1; | |
728 rd_max = prec > x_max ? prec - x_max : prec; | |
729 x_max = -x_max + 1; | |
730 } | |
731 | |
732 int ld_min, rd_min; | |
733 if (x_min > 0) | |
734 { | |
735 ld_min = x_min; | |
736 rd_min = prec > x_min ? prec - x_min : prec; | |
737 x_min++; | |
738 } | |
739 else | |
740 { | |
741 ld_min = 1; | |
742 rd_min = prec > x_min ? prec - x_min : prec; | |
743 x_min = -x_min + 1; | |
744 } | |
745 | |
746 ld = ld_max > ld_min ? ld_max : ld_min; | |
747 rd = rd_max > rd_min ? rd_max : rd_min; | |
748 | |
749 fw = 1 + ld + 1 + rd; | |
750 if (inf_or_nan && fw < 4) | |
751 fw = 4; | |
752 } | |
753 | |
754 if (! (rat_format || bank_format || hex_format || bit_format) | |
755 && (print_e | |
756 || print_eng || print_g | |
757 || (! Vfixed_point_format && fw > Voutput_max_field_width))) | |
758 { | |
759 if (print_g) | |
760 fmt = float_format (); | |
761 else | |
762 { | |
763 int ex = 4; | |
764 if (x_max > 100 || x_min > 100) | |
765 ex++; | |
766 | |
767 if (print_eng) | |
768 { | |
769 fw = 4 + prec + ex; | |
770 if (inf_or_nan && fw < 6) | |
771 fw = 6; | |
772 fmt = float_format (fw, ex, prec - 1, std::ios::fixed); | |
773 } | |
774 else | |
775 { | |
776 fw = 2 + prec + ex; | |
777 if (inf_or_nan && fw < 4) | |
778 fw = 4; | |
779 fmt = float_format (fw, prec - 1, std::ios::scientific); | |
780 } | |
781 } | |
782 | |
783 if (print_big_e) | |
784 fmt.uppercase (); | |
785 } | |
786 else if (! bank_format && int_or_inf_or_nan) | |
787 fmt = float_format (fw, rd); | |
788 else | |
789 fmt = float_format (fw, rd, std::ios::fixed); | |
790 | |
791 curr_real_fmt = &fmt; | |
792 } | |
793 | |
794 static void | |
795 set_format (const Matrix& m, int& fw, double& scale) | |
796 { | |
797 curr_real_fmt = 0; | |
798 curr_imag_fmt = 0; | |
799 | |
800 if (free_format) | |
801 return; | |
802 | |
803 bool inf_or_nan = m.any_element_is_inf_or_nan (); | |
804 | |
805 bool int_or_inf_or_nan = m.all_elements_are_int_or_inf_or_nan (); | |
806 | |
807 Matrix m_abs = m.abs (); | |
808 double max_abs = pr_max_internal (m_abs); | |
809 double min_abs = pr_min_internal (m_abs); | |
810 | |
811 int x_max = max_abs == 0.0 ? 0 : num_digits (max_abs); | |
812 | |
813 int x_min = min_abs == 0.0 ? 0 : num_digits (min_abs); | |
814 | |
815 scale = (x_max == 0 || int_or_inf_or_nan) ? 1.0 | |
816 : std::pow (10.0, calc_scale_exp (x_max - 1)); | |
817 | |
818 set_real_matrix_format (x_max, x_min, inf_or_nan, int_or_inf_or_nan, fw); | |
819 } | |
820 | |
821 static inline void | |
822 set_format (const Matrix& m) | |
823 { | |
824 int fw; | |
825 double scale; | |
826 set_format (m, fw, scale); | |
827 } | |
828 | |
829 static void | |
830 set_complex_format (int x_max, int x_min, int r_x, bool inf_or_nan, | |
831 int int_only, int& r_fw, int& i_fw) | |
832 { | |
833 static float_format r_fmt; | |
834 static float_format i_fmt; | |
835 | |
836 int prec = Voutput_precision; | |
837 | |
838 int ld, rd; | |
839 | |
840 if (rat_format) | |
841 { | |
842 i_fw = 0; | |
843 r_fw = 0; | |
844 rd = 0; | |
845 } | |
846 else if (bank_format) | |
847 { | |
848 int digits = r_x; | |
849 i_fw = 0; | |
850 r_fw = digits <= 0 ? 4 : digits + 3; | |
851 if (inf_or_nan && r_fw < 4) | |
852 r_fw = 4; | |
853 rd = 2; | |
854 } | |
855 else if (hex_format) | |
856 { | |
857 r_fw = 2 * sizeof (double); | |
858 i_fw = 2 * sizeof (double); | |
859 rd = 0; | |
860 } | |
861 else if (bit_format) | |
862 { | |
863 r_fw = 8 * sizeof (double); | |
864 i_fw = 8 * sizeof (double); | |
865 rd = 0; | |
866 } | |
867 else if (inf_or_nan || int_only) | |
868 { | |
869 int digits = x_max > x_min ? x_max : x_min; | |
870 i_fw = digits <= 0 ? 1 : digits; | |
871 r_fw = i_fw + 1; | |
872 if (inf_or_nan && i_fw < 3) | |
873 { | |
874 i_fw = 3; | |
875 r_fw = 4; | |
876 } | |
877 rd = r_fw; | |
878 } | |
879 else | |
880 { | |
881 int ld_max, rd_max; | |
882 if (x_max > 0) | |
883 { | |
884 ld_max = x_max; | |
885 rd_max = prec > x_max ? prec - x_max : prec; | |
886 x_max++; | |
887 } | |
888 else | |
889 { | |
890 ld_max = 1; | |
891 rd_max = prec > x_max ? prec - x_max : prec; | |
892 x_max = -x_max + 1; | |
893 } | |
894 | |
895 int ld_min, rd_min; | |
896 if (x_min > 0) | |
897 { | |
898 ld_min = x_min; | |
899 rd_min = prec > x_min ? prec - x_min : prec; | |
900 x_min++; | |
901 } | |
902 else | |
903 { | |
904 ld_min = 1; | |
905 rd_min = prec > x_min ? prec - x_min : prec; | |
906 x_min = -x_min + 1; | |
907 } | |
908 | |
909 ld = ld_max > ld_min ? ld_max : ld_min; | |
910 rd = rd_max > rd_min ? rd_max : rd_min; | |
911 | |
912 i_fw = ld + 1 + rd; | |
913 r_fw = i_fw + 1; | |
914 if (inf_or_nan && i_fw < 3) | |
915 { | |
916 i_fw = 3; | |
917 r_fw = 4; | |
918 } | |
919 } | |
920 | |
921 if (! (rat_format || bank_format || hex_format || bit_format) | |
922 && (r_fw > Voutput_max_field_width || print_e || print_eng || print_g)) | |
923 { | |
924 if (print_g) | |
925 { | |
926 r_fmt = float_format (); | |
927 i_fmt = float_format (); | |
928 } | |
929 else | |
930 { | |
931 int ex = 4; | |
932 if (x_max > 100 || x_min > 100) | |
933 ex++; | |
934 | |
935 if (print_eng) | |
936 { | |
937 i_fw = 3 + prec + ex; | |
938 r_fw = i_fw + 1; | |
939 if (inf_or_nan && i_fw < 5) | |
940 { | |
941 i_fw = 5; | |
942 r_fw = 6; | |
943 } | |
944 r_fmt = float_format (r_fw, ex, prec - 1, std::ios::fixed); | |
945 i_fmt = float_format (i_fw, ex, prec - 1, std::ios::fixed); | |
946 } | |
947 else | |
948 { | |
949 i_fw = 1 + prec + ex; | |
950 r_fw = i_fw + 1; | |
951 if (inf_or_nan && i_fw < 3) | |
952 { | |
953 i_fw = 3; | |
954 r_fw = 4; | |
955 } | |
956 r_fmt = float_format (r_fw, prec - 1, std::ios::scientific); | |
957 i_fmt = float_format (i_fw, prec - 1, std::ios::scientific); | |
958 } | |
959 } | |
960 | |
961 if (print_big_e) | |
962 { | |
963 r_fmt.uppercase (); | |
964 i_fmt.uppercase (); | |
965 } | |
966 } | |
967 else if (! bank_format && (inf_or_nan || int_only)) | |
968 { | |
969 r_fmt = float_format (r_fw, rd); | |
970 i_fmt = float_format (i_fw, rd); | |
971 } | |
972 else | |
973 { | |
974 r_fmt = float_format (r_fw, rd, std::ios::fixed); | |
975 i_fmt = float_format (i_fw, rd, std::ios::fixed); | |
976 } | |
977 | |
978 curr_real_fmt = &r_fmt; | |
979 curr_imag_fmt = &i_fmt; | |
980 } | |
981 | |
982 static void | |
983 set_format (const Complex& c, int& r_fw, int& i_fw) | |
984 { | |
985 curr_real_fmt = 0; | |
986 curr_imag_fmt = 0; | |
987 | |
988 if (free_format) | |
989 return; | |
990 | |
991 double rp = c.real (); | |
992 double ip = c.imag (); | |
993 | |
994 bool inf_or_nan = (xisinf (c) || xisnan (c)); | |
995 | |
996 bool int_only = (D_NINT (rp) == rp && D_NINT (ip) == ip); | |
997 | |
998 double r_abs = rp < 0.0 ? -rp : rp; | |
999 double i_abs = ip < 0.0 ? -ip : ip; | |
1000 | |
1001 int r_x = (xisinf (rp) || xisnan (rp) || r_abs == 0.0) | |
1002 ? 0 : num_digits (r_abs); | |
1003 | |
1004 int i_x = (xisinf (ip) || xisnan (ip) || i_abs == 0.0) | |
1005 ? 0 : num_digits (i_abs); | |
1006 | |
1007 int x_max, x_min; | |
1008 | |
1009 if (r_x > i_x) | |
1010 { | |
1011 x_max = r_x; | |
1012 x_min = i_x; | |
1013 } | |
1014 else | |
1015 { | |
1016 x_max = i_x; | |
1017 x_min = r_x; | |
1018 } | |
1019 | |
1020 set_complex_format (x_max, x_min, r_x, inf_or_nan, int_only, r_fw, i_fw); | |
1021 } | |
1022 | |
1023 static inline void | |
1024 set_format (const Complex& c) | |
1025 { | |
1026 int r_fw, i_fw; | |
1027 set_format (c, r_fw, i_fw); | |
1028 } | |
1029 | |
1030 static void | |
1031 set_complex_matrix_format (int x_max, int x_min, int r_x_max, | |
1032 int r_x_min, bool inf_or_nan, | |
1033 int int_or_inf_or_nan, int& r_fw, int& i_fw) | |
1034 { | |
1035 static float_format r_fmt; | |
1036 static float_format i_fmt; | |
1037 | |
1038 int prec = Voutput_precision; | |
1039 | |
1040 int ld, rd; | |
1041 | |
1042 if (rat_format) | |
1043 { | |
1044 i_fw = 9; | |
1045 r_fw = 9; | |
1046 rd = 0; | |
1047 } | |
1048 else if (bank_format) | |
1049 { | |
1050 int digits = r_x_max > r_x_min ? r_x_max : r_x_min; | |
1051 i_fw = 0; | |
1052 r_fw = digits <= 0 ? 4 : digits + 3; | |
1053 if (inf_or_nan && r_fw < 4) | |
1054 r_fw = 4; | |
1055 rd = 2; | |
1056 } | |
1057 else if (hex_format) | |
1058 { | |
1059 r_fw = 2 * sizeof (double); | |
1060 i_fw = 2 * sizeof (double); | |
1061 rd = 0; | |
1062 } | |
1063 else if (bit_format) | |
1064 { | |
1065 r_fw = 8 * sizeof (double); | |
1066 i_fw = 8 * sizeof (double); | |
1067 rd = 0; | |
1068 } | |
1069 else if (Vfixed_point_format && ! print_g) | |
1070 { | |
1071 rd = prec; | |
1072 i_fw = rd + 1; | |
1073 r_fw = i_fw + 1; | |
1074 if (inf_or_nan && i_fw < 3) | |
1075 { | |
1076 i_fw = 3; | |
1077 r_fw = 4; | |
1078 } | |
1079 } | |
1080 else if (int_or_inf_or_nan) | |
1081 { | |
1082 int digits = x_max > x_min ? x_max : x_min; | |
1083 i_fw = digits <= 0 ? 1 : digits; | |
1084 r_fw = i_fw + 1; | |
1085 if (inf_or_nan && i_fw < 3) | |
1086 { | |
1087 i_fw = 3; | |
1088 r_fw = 4; | |
1089 } | |
1090 rd = r_fw; | |
1091 } | |
1092 else | |
1093 { | |
1094 int ld_max, rd_max; | |
1095 if (x_max > 0) | |
1096 { | |
1097 ld_max = x_max; | |
1098 rd_max = prec > x_max ? prec - x_max : prec; | |
1099 x_max++; | |
1100 } | |
1101 else | |
1102 { | |
1103 ld_max = 1; | |
1104 rd_max = prec > x_max ? prec - x_max : prec; | |
1105 x_max = -x_max + 1; | |
1106 } | |
1107 | |
1108 int ld_min, rd_min; | |
1109 if (x_min > 0) | |
1110 { | |
1111 ld_min = x_min; | |
1112 rd_min = prec > x_min ? prec - x_min : prec; | |
1113 x_min++; | |
1114 } | |
1115 else | |
1116 { | |
1117 ld_min = 1; | |
1118 rd_min = prec > x_min ? prec - x_min : prec; | |
1119 x_min = -x_min + 1; | |
1120 } | |
1121 | |
1122 ld = ld_max > ld_min ? ld_max : ld_min; | |
1123 rd = rd_max > rd_min ? rd_max : rd_min; | |
1124 | |
1125 i_fw = ld + 1 + rd; | |
1126 r_fw = i_fw + 1; | |
1127 if (inf_or_nan && i_fw < 3) | |
1128 { | |
1129 i_fw = 3; | |
1130 r_fw = 4; | |
1131 } | |
1132 } | |
1133 | |
1134 if (! (rat_format || bank_format || hex_format || bit_format) | |
1135 && (print_e | |
1136 || print_eng || print_g | |
1137 || (! Vfixed_point_format && r_fw > Voutput_max_field_width))) | |
1138 { | |
1139 if (print_g) | |
1140 { | |
1141 r_fmt = float_format (); | |
1142 i_fmt = float_format (); | |
1143 } | |
1144 else | |
1145 { | |
1146 int ex = 4; | |
1147 if (x_max > 100 || x_min > 100) | |
1148 ex++; | |
1149 | |
1150 if (print_eng) | |
1151 { | |
1152 i_fw = 3 + prec + ex; | |
1153 r_fw = i_fw + 1; | |
1154 if (inf_or_nan && i_fw < 5) | |
1155 { | |
1156 i_fw = 5; | |
1157 r_fw = 6; | |
1158 } | |
1159 r_fmt = float_format (r_fw, ex, prec - 1, std::ios::fixed); | |
1160 i_fmt = float_format (i_fw, ex, prec - 1, std::ios::fixed); | |
1161 } | |
1162 else | |
1163 { | |
1164 i_fw = 1 + prec + ex; | |
1165 r_fw = i_fw + 1; | |
1166 if (inf_or_nan && i_fw < 3) | |
1167 { | |
1168 i_fw = 3; | |
1169 r_fw = 4; | |
1170 } | |
1171 r_fmt = float_format (r_fw, prec - 1, std::ios::scientific); | |
1172 i_fmt = float_format (i_fw, prec - 1, std::ios::scientific); | |
1173 } | |
1174 } | |
1175 | |
1176 if (print_big_e) | |
1177 { | |
1178 r_fmt.uppercase (); | |
1179 i_fmt.uppercase (); | |
1180 } | |
1181 } | |
1182 else if (! bank_format && int_or_inf_or_nan) | |
1183 { | |
1184 r_fmt = float_format (r_fw, rd); | |
1185 i_fmt = float_format (i_fw, rd); | |
1186 } | |
1187 else | |
1188 { | |
1189 r_fmt = float_format (r_fw, rd, std::ios::fixed); | |
1190 i_fmt = float_format (i_fw, rd, std::ios::fixed); | |
1191 } | |
1192 | |
1193 curr_real_fmt = &r_fmt; | |
1194 curr_imag_fmt = &i_fmt; | |
1195 } | |
1196 | |
1197 static void | |
1198 set_format (const ComplexMatrix& cm, int& r_fw, int& i_fw, double& scale) | |
1199 { | |
1200 curr_real_fmt = 0; | |
1201 curr_imag_fmt = 0; | |
1202 | |
1203 if (free_format) | |
1204 return; | |
1205 | |
1206 Matrix rp = real (cm); | |
1207 Matrix ip = imag (cm); | |
1208 | |
1209 bool inf_or_nan = cm.any_element_is_inf_or_nan (); | |
1210 | |
1211 bool int_or_inf_or_nan = (rp.all_elements_are_int_or_inf_or_nan () | |
1212 && ip.all_elements_are_int_or_inf_or_nan ()); | |
1213 | |
1214 Matrix r_m_abs = rp.abs (); | |
1215 double r_max_abs = pr_max_internal (r_m_abs); | |
1216 double r_min_abs = pr_min_internal (r_m_abs); | |
1217 | |
1218 Matrix i_m_abs = ip.abs (); | |
1219 double i_max_abs = pr_max_internal (i_m_abs); | |
1220 double i_min_abs = pr_min_internal (i_m_abs); | |
1221 | |
1222 int r_x_max = r_max_abs == 0.0 ? 0 : num_digits (r_max_abs); | |
1223 | |
1224 int r_x_min = r_min_abs == 0.0 ? 0 : num_digits (r_min_abs); | |
1225 | |
1226 int i_x_max = i_max_abs == 0.0 ? 0 : num_digits (i_max_abs); | |
1227 | |
1228 int i_x_min = i_min_abs == 0.0 ? 0 : num_digits (i_min_abs); | |
1229 | |
1230 int x_max = r_x_max > i_x_max ? r_x_max : i_x_max; | |
1231 int x_min = r_x_min > i_x_min ? r_x_min : i_x_min; | |
1232 | |
1233 scale = (x_max == 0 || int_or_inf_or_nan) ? 1.0 | |
1234 : std::pow (10.0, calc_scale_exp (x_max - 1)); | |
1235 | |
1236 set_complex_matrix_format (x_max, x_min, r_x_max, r_x_min, inf_or_nan, | |
1237 int_or_inf_or_nan, r_fw, i_fw); | |
1238 } | |
1239 | |
1240 static inline void | |
1241 set_format (const ComplexMatrix& cm) | |
1242 { | |
1243 int r_fw, i_fw; | |
1244 double scale; | |
1245 set_format (cm, r_fw, i_fw, scale); | |
1246 } | |
1247 | |
1248 static void | |
1249 set_range_format (int x_max, int x_min, int all_ints, int& fw) | |
1250 { | |
1251 static float_format fmt; | |
1252 | |
1253 int prec = Voutput_precision; | |
1254 | |
1255 int ld, rd; | |
1256 | |
1257 if (rat_format) | |
1258 { | |
1259 fw = 9; | |
1260 rd = 0; | |
1261 } | |
1262 else if (bank_format) | |
1263 { | |
1264 int digits = x_max > x_min ? x_max : x_min; | |
1265 fw = digits < 0 ? 5 : digits + 4; | |
1266 rd = 2; | |
1267 } | |
1268 else if (hex_format) | |
1269 { | |
1270 fw = 2 * sizeof (double); | |
1271 rd = 0; | |
1272 } | |
1273 else if (bit_format) | |
1274 { | |
1275 fw = 8 * sizeof (double); | |
1276 rd = 0; | |
1277 } | |
1278 else if (all_ints) | |
1279 { | |
1280 int digits = x_max > x_min ? x_max : x_min; | |
1281 fw = digits + 1; | |
1282 rd = fw; | |
1283 } | |
1284 else if (Vfixed_point_format && ! print_g) | |
1285 { | |
1286 rd = prec; | |
1287 fw = rd + 3; | |
1288 } | |
1289 else | |
1290 { | |
1291 int ld_max, rd_max; | |
1292 if (x_max > 0) | |
1293 { | |
1294 ld_max = x_max; | |
1295 rd_max = prec > x_max ? prec - x_max : prec; | |
1296 x_max++; | |
1297 } | |
1298 else | |
1299 { | |
1300 ld_max = 1; | |
1301 rd_max = prec > x_max ? prec - x_max : prec; | |
1302 x_max = -x_max + 1; | |
1303 } | |
1304 | |
1305 int ld_min, rd_min; | |
1306 if (x_min > 0) | |
1307 { | |
1308 ld_min = x_min; | |
1309 rd_min = prec > x_min ? prec - x_min : prec; | |
1310 x_min++; | |
1311 } | |
1312 else | |
1313 { | |
1314 ld_min = 1; | |
1315 rd_min = prec > x_min ? prec - x_min : prec; | |
1316 x_min = -x_min + 1; | |
1317 } | |
1318 | |
1319 ld = ld_max > ld_min ? ld_max : ld_min; | |
1320 rd = rd_max > rd_min ? rd_max : rd_min; | |
1321 | |
1322 fw = ld + rd + 3; | |
1323 } | |
1324 | |
1325 if (! (rat_format || bank_format || hex_format || bit_format) | |
1326 && (print_e | |
1327 || print_eng || print_g | |
1328 || (! Vfixed_point_format && fw > Voutput_max_field_width))) | |
1329 { | |
1330 if (print_g) | |
1331 fmt = float_format (); | |
1332 else | |
1333 { | |
1334 int ex = 4; | |
1335 if (x_max > 100 || x_min > 100) | |
1336 ex++; | |
1337 | |
1338 if (print_eng) | |
1339 { | |
1340 fw = 5 + prec + ex; | |
1341 fmt = float_format (fw, ex, prec - 1, std::ios::fixed); | |
1342 } | |
1343 else | |
1344 { | |
1345 fw = 3 + prec + ex; | |
1346 fmt = float_format (fw, prec - 1, std::ios::scientific); | |
1347 } | |
1348 } | |
1349 | |
1350 if (print_big_e) | |
1351 fmt.uppercase (); | |
1352 } | |
1353 else if (! bank_format && all_ints) | |
1354 fmt = float_format (fw, rd); | |
1355 else | |
1356 fmt = float_format (fw, rd, std::ios::fixed); | |
1357 | |
1358 curr_real_fmt = &fmt; | |
1359 } | |
1360 | |
1361 static void | |
1362 set_format (const Range& r, int& fw, double& scale) | |
1363 { | |
1364 curr_real_fmt = 0; | |
1365 curr_imag_fmt = 0; | |
1366 | |
1367 if (free_format) | |
1368 return; | |
1369 | |
1370 double r_min = r.base (); | |
1371 double r_max = r.limit (); | |
1372 | |
1373 if (r_max < r_min) | |
1374 { | |
1375 double tmp = r_max; | |
1376 r_max = r_min; | |
1377 r_min = tmp; | |
1378 } | |
1379 | |
1380 bool all_ints = r.all_elements_are_ints (); | |
1381 | |
1382 double max_abs = r_max < 0.0 ? -r_max : r_max; | |
1383 double min_abs = r_min < 0.0 ? -r_min : r_min; | |
1384 | |
1385 int x_max = max_abs == 0.0 ? 0 : num_digits (max_abs); | |
1386 | |
1387 int x_min = min_abs == 0.0 ? 0 : num_digits (min_abs); | |
1388 | |
1389 scale = (x_max == 0 || all_ints) ? 1.0 | |
1390 : std::pow (10.0, calc_scale_exp (x_max - 1)); | |
1391 | |
1392 set_range_format (x_max, x_min, all_ints, fw); | |
1393 } | |
1394 | |
1395 static inline void | |
1396 set_format (const Range& r) | |
1397 { | |
1398 int fw; | |
1399 double scale; | |
1400 set_format (r, fw, scale); | |
1401 } | |
1402 | |
1403 union equiv | |
1404 { | |
1405 double d; | |
1406 unsigned char i[sizeof (double)]; | |
1407 }; | |
1408 | |
1409 #define PRINT_CHAR_BITS(os, c) \ | |
1410 do \ | |
1411 { \ | |
1412 unsigned char ctmp = c; \ | |
1413 char stmp[9]; \ | |
1414 stmp[0] = (ctmp & 0x80) ? '1' : '0'; \ | |
1415 stmp[1] = (ctmp & 0x40) ? '1' : '0'; \ | |
1416 stmp[2] = (ctmp & 0x20) ? '1' : '0'; \ | |
1417 stmp[3] = (ctmp & 0x10) ? '1' : '0'; \ | |
1418 stmp[4] = (ctmp & 0x08) ? '1' : '0'; \ | |
1419 stmp[5] = (ctmp & 0x04) ? '1' : '0'; \ | |
1420 stmp[6] = (ctmp & 0x02) ? '1' : '0'; \ | |
1421 stmp[7] = (ctmp & 0x01) ? '1' : '0'; \ | |
1422 stmp[8] = '\0'; \ | |
1423 os << stmp; \ | |
1424 } \ | |
1425 while (0) | |
1426 | |
1427 #define PRINT_CHAR_BITS_SWAPPED(os, c) \ | |
1428 do \ | |
1429 { \ | |
1430 unsigned char ctmp = c; \ | |
1431 char stmp[9]; \ | |
1432 stmp[0] = (ctmp & 0x01) ? '1' : '0'; \ | |
1433 stmp[1] = (ctmp & 0x02) ? '1' : '0'; \ | |
1434 stmp[2] = (ctmp & 0x04) ? '1' : '0'; \ | |
1435 stmp[3] = (ctmp & 0x08) ? '1' : '0'; \ | |
1436 stmp[4] = (ctmp & 0x10) ? '1' : '0'; \ | |
1437 stmp[5] = (ctmp & 0x20) ? '1' : '0'; \ | |
1438 stmp[6] = (ctmp & 0x40) ? '1' : '0'; \ | |
1439 stmp[7] = (ctmp & 0x80) ? '1' : '0'; \ | |
1440 stmp[8] = '\0'; \ | |
1441 os << stmp; \ | |
1442 } \ | |
1443 while (0) | |
1444 | |
1445 static void | |
1446 pr_any_float (const float_format *fmt, std::ostream& os, double d, int fw = 0) | |
1447 { | |
1448 if (fmt) | |
1449 { | |
1450 // Unless explicitly asked for, always print in big-endian | |
1451 // format for hex and bit formats. | |
1452 // | |
1453 // {bit,hex}_format == 1: print big-endian | |
1454 // {bit,hex}_format == 2: print native | |
1455 | |
1456 if (hex_format) | |
1457 { | |
1458 equiv tmp; | |
1459 tmp.d = d; | |
1460 | |
1461 // Unless explicitly asked for, always print in big-endian | |
1462 // format. | |
1463 | |
1464 // FIXME -- is it correct to swap bytes for VAX | |
1465 // formats and not for Cray? | |
1466 | |
1467 // FIXME -- will bad things happen if we are | |
1468 // interrupted before resetting the format flags and fill | |
1469 // character? | |
1470 | |
1471 oct_mach_info::float_format flt_fmt = | |
1472 oct_mach_info::native_float_format (); | |
1473 | |
1474 char ofill = os.fill ('0'); | |
1475 | |
1476 std::ios::fmtflags oflags | |
1477 = os.flags (std::ios::right | std::ios::hex); | |
1478 | |
1479 if (hex_format > 1 | |
1480 || flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian | |
1481 || flt_fmt == oct_mach_info::flt_fmt_cray | |
1482 || flt_fmt == oct_mach_info::flt_fmt_unknown) | |
1483 { | |
1484 for (size_t i = 0; i < sizeof (double); i++) | |
1485 os << std::setw (2) << static_cast<int> (tmp.i[i]); | |
1486 } | |
1487 else | |
1488 { | |
1489 for (int i = sizeof (double) - 1; i >= 0; i--) | |
1490 os << std::setw (2) << static_cast<int> (tmp.i[i]); | |
1491 } | |
1492 | |
1493 os.fill (ofill); | |
1494 os.setf (oflags); | |
1495 } | |
1496 else if (bit_format) | |
1497 { | |
1498 equiv tmp; | |
1499 tmp.d = d; | |
1500 | |
1501 // FIXME -- is it correct to swap bytes for VAX | |
1502 // formats and not for Cray? | |
1503 | |
1504 oct_mach_info::float_format flt_fmt = | |
1505 oct_mach_info::native_float_format (); | |
1506 | |
1507 if (flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian | |
1508 || flt_fmt == oct_mach_info::flt_fmt_cray | |
1509 || flt_fmt == oct_mach_info::flt_fmt_unknown) | |
1510 { | |
1511 for (size_t i = 0; i < sizeof (double); i++) | |
1512 PRINT_CHAR_BITS (os, tmp.i[i]); | |
1513 } | |
1514 else | |
1515 { | |
1516 if (bit_format > 1) | |
1517 { | |
1518 for (size_t i = 0; i < sizeof (double); i++) | |
1519 PRINT_CHAR_BITS_SWAPPED (os, tmp.i[i]); | |
1520 } | |
1521 else | |
1522 { | |
1523 for (int i = sizeof (double) - 1; i >= 0; i--) | |
1524 PRINT_CHAR_BITS (os, tmp.i[i]); | |
1525 } | |
1526 } | |
1527 } | |
1528 else if (octave_is_NA (d)) | |
1529 { | |
1530 if (fw > 0) | |
1531 os << std::setw (fw) << "NA"; | |
1532 else | |
1533 os << "NA"; | |
1534 } | |
1535 else if (rat_format) | |
1536 os << pr_rational_float (*fmt, d); | |
1537 else if (xisinf (d)) | |
1538 { | |
1539 const char *s; | |
1540 if (d < 0.0) | |
1541 s = "-Inf"; | |
1542 else | |
1543 s = "Inf"; | |
1544 | |
1545 if (fw > 0) | |
1546 os << std::setw (fw) << s; | |
1547 else | |
1548 os << s; | |
1549 } | |
1550 else if (xisnan (d)) | |
1551 { | |
1552 if (fw > 0) | |
1553 os << std::setw (fw) << "NaN"; | |
1554 else | |
1555 os << "NaN"; | |
1556 } | |
1557 else if (print_eng) | |
1558 os << pr_engineering_float (*fmt, d); | |
1559 else | |
1560 os << pr_formatted_float (*fmt, d); | |
1561 } | |
1562 else | |
1563 os << d; | |
1564 } | |
1565 | |
1566 static inline void | |
1567 pr_float (std::ostream& os, double d, int fw = 0, double scale = 1.0) | |
1568 { | |
1569 if (Vfixed_point_format && ! print_g && scale != 1.0) | |
1570 d /= scale; | |
1571 | |
1572 pr_any_float (curr_real_fmt, os, d, fw); | |
1573 } | |
1574 | |
1575 static inline void | |
1576 pr_imag_float (std::ostream& os, double d, int fw = 0) | |
1577 { | |
1578 pr_any_float (curr_imag_fmt, os, d, fw); | |
1579 } | |
1580 | |
1581 static void | |
1582 pr_complex (std::ostream& os, const Complex& c, int r_fw = 0, | |
1583 int i_fw = 0, double scale = 1.0) | |
1584 { | |
1585 Complex tmp | |
1586 = (Vfixed_point_format && ! print_g && scale != 1.0) ? c / scale : c; | |
1587 | |
1588 double r = tmp.real (); | |
1589 | |
1590 pr_float (os, r, r_fw); | |
1591 | |
1592 if (! bank_format) | |
1593 { | |
1594 double i = tmp.imag (); | |
1595 if (! (hex_format || bit_format) && lo_ieee_signbit (i)) | |
1596 { | |
1597 os << " - "; | |
1598 i = -i; | |
1599 pr_imag_float (os, i, i_fw); | |
1600 } | |
1601 else | |
1602 { | |
1603 if (hex_format || bit_format) | |
1604 os << " "; | |
1605 else | |
1606 os << " + "; | |
1607 | |
1608 pr_imag_float (os, i, i_fw); | |
1609 } | |
1610 os << "i"; | |
1611 } | |
1612 } | |
1613 | |
1614 static void | |
1615 print_empty_matrix (std::ostream& os, octave_idx_type nr, octave_idx_type nc, bool pr_as_read_syntax) | |
1616 { | |
1617 assert (nr == 0 || nc == 0); | |
1618 | |
1619 if (pr_as_read_syntax) | |
1620 { | |
1621 if (nr == 0 && nc == 0) | |
1622 os << "[]"; | |
1623 else | |
1624 os << "zeros (" << nr << ", " << nc << ")"; | |
1625 } | |
1626 else | |
1627 { | |
1628 os << "[]"; | |
1629 | |
1630 if (Vprint_empty_dimensions) | |
1631 os << "(" << nr << "x" << nc << ")"; | |
1632 } | |
1633 } | |
1634 | |
1635 static void | |
1636 print_empty_nd_array (std::ostream& os, const dim_vector& dims, | |
1637 bool pr_as_read_syntax) | |
1638 { | |
1639 assert (dims.any_zero ()); | |
1640 | |
1641 if (pr_as_read_syntax) | |
1642 os << "zeros (" << dims.str (',') << ")"; | |
1643 else | |
1644 { | |
1645 os << "[]"; | |
1646 | |
1647 if (Vprint_empty_dimensions) | |
1648 os << "(" << dims.str () << ")"; | |
1649 } | |
1650 } | |
1651 | |
1652 static void | |
1653 pr_scale_header (std::ostream& os, double scale) | |
1654 { | |
1655 if (Vfixed_point_format && ! print_g && scale != 1.0) | |
1656 { | |
1657 os << " " | |
1658 << std::setw (8) << std::setprecision (1) | |
1659 << std::setiosflags (std::ios::scientific|std::ios::left) | |
1660 << scale | |
1661 << std::resetiosflags (std::ios::scientific|std::ios::left) | |
1662 << " *\n"; | |
1663 | |
1664 if (! Vcompact_format) | |
1665 os << "\n"; | |
1666 } | |
1667 } | |
1668 | |
1669 static void | |
1670 pr_col_num_header (std::ostream& os, octave_idx_type total_width, int max_width, | |
1671 octave_idx_type lim, octave_idx_type col, int extra_indent) | |
1672 { | |
1673 if (total_width > max_width && Vsplit_long_rows) | |
1674 { | |
1675 if (col != 0) | |
1676 { | |
1677 if (Vcompact_format) | |
1678 os << "\n"; | |
1679 else | |
1680 os << "\n\n"; | |
1681 } | |
1682 | |
1683 octave_idx_type num_cols = lim - col; | |
1684 | |
1685 os << std::setw (extra_indent) << ""; | |
1686 | |
1687 if (num_cols == 1) | |
1688 os << " Column " << col + 1 << ":\n"; | |
1689 else if (num_cols == 2) | |
1690 os << " Columns " << col + 1 << " and " << lim << ":\n"; | |
1691 else | |
1692 os << " Columns " << col + 1 << " through " << lim << ":\n"; | |
1693 | |
1694 if (! Vcompact_format) | |
1695 os << "\n"; | |
1696 } | |
1697 } | |
1698 | |
1699 template <class T> | |
1700 /* static */ inline void | |
1701 pr_plus_format (std::ostream& os, const T& val) | |
1702 { | |
1703 if (val > T (0)) | |
1704 os << plus_format_chars[0]; | |
1705 else if (val < T (0)) | |
1706 os << plus_format_chars[1]; | |
1707 else | |
1708 os << plus_format_chars[2]; | |
1709 } | |
1710 | |
1711 void | |
1712 octave_print_internal (std::ostream& os, double d, | |
1713 bool /* pr_as_read_syntax */) | |
1714 { | |
1715 if (plus_format) | |
1716 { | |
1717 pr_plus_format (os, d); | |
1718 } | |
1719 else | |
1720 { | |
1721 set_format (d); | |
1722 if (free_format) | |
1723 os << d; | |
1724 else | |
1725 pr_float (os, d); | |
1726 } | |
1727 } | |
1728 | |
1729 void | |
1730 octave_print_internal (std::ostream& os, const Matrix& m, | |
1731 bool pr_as_read_syntax, int extra_indent) | |
1732 { | |
1733 octave_idx_type nr = m.rows (); | |
1734 octave_idx_type nc = m.columns (); | |
1735 | |
1736 if (nr == 0 || nc == 0) | |
1737 print_empty_matrix (os, nr, nc, pr_as_read_syntax); | |
1738 else if (plus_format && ! pr_as_read_syntax) | |
1739 { | |
1740 for (octave_idx_type i = 0; i < nr; i++) | |
1741 { | |
1742 for (octave_idx_type j = 0; j < nc; j++) | |
1743 { | |
1744 octave_quit (); | |
1745 | |
1746 pr_plus_format (os, m(i,j)); | |
1747 } | |
1748 | |
1749 if (i < nr - 1) | |
1750 os << "\n"; | |
1751 } | |
1752 } | |
1753 else | |
1754 { | |
1755 int fw; | |
1756 double scale = 1.0; | |
1757 set_format (m, fw, scale); | |
1758 int column_width = fw + 2; | |
1759 octave_idx_type total_width = nc * column_width; | |
1760 octave_idx_type max_width = command_editor::terminal_cols (); | |
1761 | |
1762 if (pr_as_read_syntax) | |
1763 max_width -= 4; | |
1764 else | |
1765 max_width -= extra_indent; | |
1766 | |
1767 if (max_width < 0) | |
1768 max_width = 0; | |
1769 | |
1770 if (free_format) | |
1771 { | |
1772 if (pr_as_read_syntax) | |
1773 os << "[\n"; | |
1774 | |
1775 os << m; | |
1776 | |
1777 if (pr_as_read_syntax) | |
1778 os << "]"; | |
1779 | |
1780 return; | |
1781 } | |
1782 | |
1783 octave_idx_type inc = nc; | |
1784 if (total_width > max_width && Vsplit_long_rows) | |
1785 { | |
1786 inc = max_width / column_width; | |
1787 if (inc == 0) | |
1788 inc++; | |
1789 } | |
1790 | |
1791 if (pr_as_read_syntax) | |
1792 { | |
1793 for (octave_idx_type i = 0; i < nr; i++) | |
1794 { | |
1795 octave_idx_type col = 0; | |
1796 while (col < nc) | |
1797 { | |
1798 octave_idx_type lim = col + inc < nc ? col + inc : nc; | |
1799 | |
1800 for (octave_idx_type j = col; j < lim; j++) | |
1801 { | |
1802 octave_quit (); | |
1803 | |
1804 if (i == 0 && j == 0) | |
1805 os << "[ "; | |
1806 else | |
1807 { | |
1808 if (j > col && j < lim) | |
1809 os << ", "; | |
1810 else | |
1811 os << " "; | |
1812 } | |
1813 | |
1814 pr_float (os, m(i,j)); | |
1815 } | |
1816 | |
1817 col += inc; | |
1818 | |
1819 if (col >= nc) | |
1820 { | |
1821 if (i == nr - 1) | |
1822 os << " ]"; | |
1823 else | |
1824 os << ";\n"; | |
1825 } | |
1826 else | |
1827 os << " ...\n"; | |
1828 } | |
1829 } | |
1830 } | |
1831 else | |
1832 { | |
1833 pr_scale_header (os, scale); | |
1834 | |
1835 for (octave_idx_type col = 0; col < nc; col += inc) | |
1836 { | |
1837 octave_idx_type lim = col + inc < nc ? col + inc : nc; | |
1838 | |
1839 pr_col_num_header (os, total_width, max_width, lim, col, | |
1840 extra_indent); | |
1841 | |
1842 for (octave_idx_type i = 0; i < nr; i++) | |
1843 { | |
1844 os << std::setw (extra_indent) << ""; | |
1845 | |
1846 for (octave_idx_type j = col; j < lim; j++) | |
1847 { | |
1848 octave_quit (); | |
1849 | |
1850 os << " "; | |
1851 | |
1852 pr_float (os, m(i,j), fw, scale); | |
1853 } | |
1854 | |
1855 if (i < nr - 1) | |
1856 os << "\n"; | |
1857 } | |
1858 } | |
1859 } | |
1860 } | |
1861 } | |
1862 | |
1863 void | |
1864 octave_print_internal (std::ostream& os, const DiagMatrix& m, | |
1865 bool pr_as_read_syntax, int extra_indent) | |
1866 { | |
1867 octave_idx_type nr = m.rows (); | |
1868 octave_idx_type nc = m.columns (); | |
1869 | |
1870 if (nr == 0 || nc == 0) | |
1871 print_empty_matrix (os, nr, nc, pr_as_read_syntax); | |
1872 else if (plus_format && ! pr_as_read_syntax) | |
1873 { | |
1874 for (octave_idx_type i = 0; i < nr; i++) | |
1875 { | |
1876 for (octave_idx_type j = 0; j < nc; j++) | |
1877 { | |
1878 octave_quit (); | |
1879 | |
1880 pr_plus_format (os, m(i,j)); | |
1881 } | |
1882 | |
1883 if (i < nr - 1) | |
1884 os << "\n"; | |
1885 } | |
1886 } | |
1887 else | |
1888 { | |
1889 int fw; | |
1890 double scale = 1.0; | |
1891 set_format (Matrix (m.diag ()), fw, scale); | |
1892 int column_width = fw + 2; | |
1893 octave_idx_type total_width = nc * column_width; | |
1894 octave_idx_type max_width = command_editor::terminal_cols (); | |
1895 | |
1896 if (pr_as_read_syntax) | |
1897 max_width -= 4; | |
1898 else | |
1899 max_width -= extra_indent; | |
1900 | |
1901 if (max_width < 0) | |
1902 max_width = 0; | |
1903 | |
1904 if (free_format) | |
1905 { | |
1906 if (pr_as_read_syntax) | |
1907 os << "[\n"; | |
1908 | |
1909 os << Matrix (m); | |
1910 | |
1911 if (pr_as_read_syntax) | |
1912 os << "]"; | |
1913 | |
1914 return; | |
1915 } | |
1916 | |
1917 octave_idx_type inc = nc; | |
1918 if (total_width > max_width && Vsplit_long_rows) | |
1919 { | |
1920 inc = max_width / column_width; | |
1921 if (inc == 0) | |
1922 inc++; | |
1923 } | |
1924 | |
1925 if (pr_as_read_syntax) | |
1926 { | |
1927 os << "diag ("; | |
1928 | |
1929 octave_idx_type col = 0; | |
1930 while (col < nc) | |
1931 { | |
1932 octave_idx_type lim = col + inc < nc ? col + inc : nc; | |
1933 | |
1934 for (octave_idx_type j = col; j < lim; j++) | |
1935 { | |
1936 octave_quit (); | |
1937 | |
1938 if (j == 0) | |
1939 os << "[ "; | |
1940 else | |
1941 { | |
1942 if (j > col && j < lim) | |
1943 os << ", "; | |
1944 else | |
1945 os << " "; | |
1946 } | |
1947 | |
1948 pr_float (os, m(j,j)); | |
1949 } | |
1950 | |
1951 col += inc; | |
1952 | |
1953 if (col >= nc) | |
1954 os << " ]"; | |
1955 else | |
1956 os << " ...\n"; | |
1957 } | |
1958 os << ")"; | |
1959 } | |
1960 else | |
1961 { | |
1962 os << "Diagonal Matrix\n"; | |
1963 if (! Vcompact_format) | |
1964 os << "\n"; | |
1965 | |
1966 pr_scale_header (os, scale); | |
1967 | |
1968 // kluge. Get the true width of a number. | |
1969 int zero_fw; | |
1970 | |
1971 { | |
1972 std::ostringstream tmp_oss; | |
1973 pr_float (tmp_oss, 0.0, fw, scale); | |
1974 zero_fw = tmp_oss.str ().length (); | |
1975 } | |
1976 | |
1977 for (octave_idx_type col = 0; col < nc; col += inc) | |
1978 { | |
1979 octave_idx_type lim = col + inc < nc ? col + inc : nc; | |
1980 | |
1981 pr_col_num_header (os, total_width, max_width, lim, col, | |
1982 extra_indent); | |
1983 | |
1984 for (octave_idx_type i = 0; i < nr; i++) | |
1985 { | |
1986 os << std::setw (extra_indent) << ""; | |
1987 | |
1988 for (octave_idx_type j = col; j < lim; j++) | |
1989 { | |
1990 octave_quit (); | |
1991 | |
1992 os << " "; | |
1993 | |
1994 if (i == j) | |
1995 pr_float (os, m(i,j), fw, scale); | |
1996 else | |
1997 os << std::setw (zero_fw) << '0'; | |
1998 | |
1999 } | |
2000 | |
2001 if (i < nr - 1) | |
2002 os << "\n"; | |
2003 } | |
2004 } | |
2005 } | |
2006 } | |
2007 } | |
2008 | |
2009 template <typename NDA_T, typename ELT_T, typename MAT_T> | |
2010 void print_nd_array (std::ostream& os, const NDA_T& nda, | |
2011 bool pr_as_read_syntax) | |
2012 { | |
2013 | |
2014 if (nda.is_empty ()) | |
2015 print_empty_nd_array (os, nda.dims (), pr_as_read_syntax); | |
2016 else | |
2017 { | |
2018 | |
2019 int ndims = nda.ndims (); | |
2020 | |
2021 dim_vector dims = nda.dims (); | |
2022 | |
2023 Array<octave_idx_type> ra_idx (dim_vector (ndims, 1), 0); | |
2024 | |
2025 octave_idx_type m = 1; | |
2026 | |
2027 for (int i = 2; i < ndims; i++) | |
2028 m *= dims(i); | |
2029 | |
2030 octave_idx_type nr = dims(0); | |
2031 octave_idx_type nc = dims(1); | |
2032 | |
2033 for (octave_idx_type i = 0; i < m; i++) | |
2034 { | |
2035 octave_quit (); | |
2036 | |
2037 std::string nm = "ans"; | |
2038 | |
2039 if (m > 1) | |
2040 { | |
2041 nm += "(:,:,"; | |
2042 | |
2043 std::ostringstream buf; | |
2044 | |
2045 for (int k = 2; k < ndims; k++) | |
2046 { | |
2047 buf << ra_idx(k) + 1; | |
2048 | |
2049 if (k < ndims - 1) | |
2050 buf << ","; | |
2051 else | |
2052 buf << ")"; | |
2053 } | |
2054 | |
2055 nm += buf.str (); | |
2056 } | |
2057 | |
2058 Array<idx_vector> idx (dim_vector (ndims, 1)); | |
2059 | |
2060 idx(0) = idx_vector (':'); | |
2061 idx(1) = idx_vector (':'); | |
2062 | |
2063 for (int k = 2; k < ndims; k++) | |
2064 idx(k) = idx_vector (ra_idx(k)); | |
2065 | |
2066 octave_value page | |
2067 = MAT_T (Array<ELT_T> (nda.index (idx), dim_vector (nr, nc))); | |
2068 | |
2069 if (i != m - 1) | |
2070 { | |
2071 page.print_with_name (os, nm); | |
2072 } | |
2073 else | |
2074 { | |
2075 page.print_name_tag (os, nm); | |
2076 page.print_raw (os); | |
2077 } | |
2078 | |
2079 if (i < m) | |
2080 NDA_T::increment_index (ra_idx, dims, 2); | |
2081 } | |
2082 } | |
2083 } | |
2084 | |
2085 void | |
2086 octave_print_internal (std::ostream& os, const NDArray& nda, | |
2087 bool pr_as_read_syntax, int extra_indent) | |
2088 { | |
2089 switch (nda.ndims ()) | |
2090 { | |
2091 case 1: | |
2092 case 2: | |
2093 octave_print_internal (os, nda.matrix_value (), | |
2094 pr_as_read_syntax, extra_indent); | |
2095 break; | |
2096 | |
2097 default: | |
2098 print_nd_array <NDArray, double, Matrix> (os, nda, pr_as_read_syntax); | |
2099 break; | |
2100 } | |
2101 } | |
2102 | |
2103 template <> | |
2104 /* static */ inline void | |
2105 pr_plus_format<> (std::ostream& os, const Complex& c) | |
2106 { | |
2107 double rp = c.real (); | |
2108 double ip = c.imag (); | |
2109 | |
2110 if (rp == 0.0) | |
2111 { | |
2112 if (ip == 0.0) | |
2113 os << " "; | |
2114 else | |
2115 os << "i"; | |
2116 } | |
2117 else if (ip == 0.0) | |
2118 pr_plus_format (os, rp); | |
2119 else | |
2120 os << "c"; | |
2121 } | |
2122 | |
2123 void | |
2124 octave_print_internal (std::ostream& os, const Complex& c, | |
2125 bool /* pr_as_read_syntax */) | |
2126 { | |
2127 if (plus_format) | |
2128 { | |
2129 pr_plus_format (os, c); | |
2130 } | |
2131 else | |
2132 { | |
2133 set_format (c); | |
2134 if (free_format) | |
2135 os << c; | |
2136 else | |
2137 pr_complex (os, c); | |
2138 } | |
2139 } | |
2140 | |
2141 void | |
2142 octave_print_internal (std::ostream& os, const ComplexMatrix& cm, | |
2143 bool pr_as_read_syntax, int extra_indent) | |
2144 { | |
2145 octave_idx_type nr = cm.rows (); | |
2146 octave_idx_type nc = cm.columns (); | |
2147 | |
2148 if (nr == 0 || nc == 0) | |
2149 print_empty_matrix (os, nr, nc, pr_as_read_syntax); | |
2150 else if (plus_format && ! pr_as_read_syntax) | |
2151 { | |
2152 for (octave_idx_type i = 0; i < nr; i++) | |
2153 { | |
2154 for (octave_idx_type j = 0; j < nc; j++) | |
2155 { | |
2156 octave_quit (); | |
2157 | |
2158 pr_plus_format (os, cm(i,j)); | |
2159 } | |
2160 | |
2161 if (i < nr - 1) | |
2162 os << "\n"; | |
2163 } | |
2164 } | |
2165 else | |
2166 { | |
2167 int r_fw, i_fw; | |
2168 double scale = 1.0; | |
2169 set_format (cm, r_fw, i_fw, scale); | |
2170 int column_width = i_fw + r_fw; | |
2171 column_width += (rat_format || bank_format || hex_format | |
2172 || bit_format) ? 2 : 7; | |
2173 octave_idx_type total_width = nc * column_width; | |
2174 octave_idx_type max_width = command_editor::terminal_cols (); | |
2175 | |
2176 if (pr_as_read_syntax) | |
2177 max_width -= 4; | |
2178 else | |
2179 max_width -= extra_indent; | |
2180 | |
2181 if (max_width < 0) | |
2182 max_width = 0; | |
2183 | |
2184 if (free_format) | |
2185 { | |
2186 if (pr_as_read_syntax) | |
2187 os << "[\n"; | |
2188 | |
2189 os << cm; | |
2190 | |
2191 if (pr_as_read_syntax) | |
2192 os << "]"; | |
2193 | |
2194 return; | |
2195 } | |
2196 | |
2197 octave_idx_type inc = nc; | |
2198 if (total_width > max_width && Vsplit_long_rows) | |
2199 { | |
2200 inc = max_width / column_width; | |
2201 if (inc == 0) | |
2202 inc++; | |
2203 } | |
2204 | |
2205 if (pr_as_read_syntax) | |
2206 { | |
2207 for (octave_idx_type i = 0; i < nr; i++) | |
2208 { | |
2209 octave_idx_type col = 0; | |
2210 while (col < nc) | |
2211 { | |
2212 octave_idx_type lim = col + inc < nc ? col + inc : nc; | |
2213 | |
2214 for (octave_idx_type j = col; j < lim; j++) | |
2215 { | |
2216 octave_quit (); | |
2217 | |
2218 if (i == 0 && j == 0) | |
2219 os << "[ "; | |
2220 else | |
2221 { | |
2222 if (j > col && j < lim) | |
2223 os << ", "; | |
2224 else | |
2225 os << " "; | |
2226 } | |
2227 | |
2228 pr_complex (os, cm(i,j)); | |
2229 } | |
2230 | |
2231 col += inc; | |
2232 | |
2233 if (col >= nc) | |
2234 { | |
2235 if (i == nr - 1) | |
2236 os << " ]"; | |
2237 else | |
2238 os << ";\n"; | |
2239 } | |
2240 else | |
2241 os << " ...\n"; | |
2242 } | |
2243 } | |
2244 } | |
2245 else | |
2246 { | |
2247 pr_scale_header (os, scale); | |
2248 | |
2249 for (octave_idx_type col = 0; col < nc; col += inc) | |
2250 { | |
2251 octave_idx_type lim = col + inc < nc ? col + inc : nc; | |
2252 | |
2253 pr_col_num_header (os, total_width, max_width, lim, col, | |
2254 extra_indent); | |
2255 | |
2256 for (octave_idx_type i = 0; i < nr; i++) | |
2257 { | |
2258 os << std::setw (extra_indent) << ""; | |
2259 | |
2260 for (octave_idx_type j = col; j < lim; j++) | |
2261 { | |
2262 octave_quit (); | |
2263 | |
2264 os << " "; | |
2265 | |
2266 pr_complex (os, cm(i,j), r_fw, i_fw, scale); | |
2267 } | |
2268 | |
2269 if (i < nr - 1) | |
2270 os << "\n"; | |
2271 } | |
2272 } | |
2273 } | |
2274 } | |
2275 } | |
2276 | |
2277 void | |
2278 octave_print_internal (std::ostream& os, const ComplexDiagMatrix& cm, | |
2279 bool pr_as_read_syntax, int extra_indent) | |
2280 { | |
2281 octave_idx_type nr = cm.rows (); | |
2282 octave_idx_type nc = cm.columns (); | |
2283 | |
2284 if (nr == 0 || nc == 0) | |
2285 print_empty_matrix (os, nr, nc, pr_as_read_syntax); | |
2286 else if (plus_format && ! pr_as_read_syntax) | |
2287 { | |
2288 for (octave_idx_type i = 0; i < nr; i++) | |
2289 { | |
2290 for (octave_idx_type j = 0; j < nc; j++) | |
2291 { | |
2292 octave_quit (); | |
2293 | |
2294 pr_plus_format (os, cm(i,j)); | |
2295 } | |
2296 | |
2297 if (i < nr - 1) | |
2298 os << "\n"; | |
2299 } | |
2300 } | |
2301 else | |
2302 { | |
2303 int r_fw, i_fw; | |
2304 double scale = 1.0; | |
2305 set_format (ComplexMatrix (cm.diag ()), r_fw, i_fw, scale); | |
2306 int column_width = i_fw + r_fw; | |
2307 column_width += (rat_format || bank_format || hex_format | |
2308 || bit_format) ? 2 : 7; | |
2309 octave_idx_type total_width = nc * column_width; | |
2310 octave_idx_type max_width = command_editor::terminal_cols (); | |
2311 | |
2312 if (pr_as_read_syntax) | |
2313 max_width -= 4; | |
2314 else | |
2315 max_width -= extra_indent; | |
2316 | |
2317 if (max_width < 0) | |
2318 max_width = 0; | |
2319 | |
2320 if (free_format) | |
2321 { | |
2322 if (pr_as_read_syntax) | |
2323 os << "[\n"; | |
2324 | |
2325 os << ComplexMatrix (cm); | |
2326 | |
2327 if (pr_as_read_syntax) | |
2328 os << "]"; | |
2329 | |
2330 return; | |
2331 } | |
2332 | |
2333 octave_idx_type inc = nc; | |
2334 if (total_width > max_width && Vsplit_long_rows) | |
2335 { | |
2336 inc = max_width / column_width; | |
2337 if (inc == 0) | |
2338 inc++; | |
2339 } | |
2340 | |
2341 if (pr_as_read_syntax) | |
2342 { | |
2343 os << "diag ("; | |
2344 | |
2345 octave_idx_type col = 0; | |
2346 while (col < nc) | |
2347 { | |
2348 octave_idx_type lim = col + inc < nc ? col + inc : nc; | |
2349 | |
2350 for (octave_idx_type j = col; j < lim; j++) | |
2351 { | |
2352 octave_quit (); | |
2353 | |
2354 if (j == 0) | |
2355 os << "[ "; | |
2356 else | |
2357 { | |
2358 if (j > col && j < lim) | |
2359 os << ", "; | |
2360 else | |
2361 os << " "; | |
2362 } | |
2363 | |
2364 pr_complex (os, cm(j,j)); | |
2365 } | |
2366 | |
2367 col += inc; | |
2368 | |
2369 if (col >= nc) | |
2370 os << " ]"; | |
2371 else | |
2372 os << " ...\n"; | |
2373 } | |
2374 os << ")"; | |
2375 } | |
2376 else | |
2377 { | |
2378 os << "Diagonal Matrix\n"; | |
2379 if (! Vcompact_format) | |
2380 os << "\n"; | |
2381 | |
2382 pr_scale_header (os, scale); | |
2383 | |
2384 // kluge. Get the true width of a number. | |
2385 int zero_fw; | |
2386 | |
2387 { | |
2388 std::ostringstream tmp_oss; | |
2389 pr_complex (tmp_oss, Complex (0.0), r_fw, i_fw, scale); | |
2390 zero_fw = tmp_oss.str ().length (); | |
2391 } | |
2392 | |
2393 for (octave_idx_type col = 0; col < nc; col += inc) | |
2394 { | |
2395 octave_idx_type lim = col + inc < nc ? col + inc : nc; | |
2396 | |
2397 pr_col_num_header (os, total_width, max_width, lim, col, | |
2398 extra_indent); | |
2399 | |
2400 for (octave_idx_type i = 0; i < nr; i++) | |
2401 { | |
2402 os << std::setw (extra_indent) << ""; | |
2403 | |
2404 for (octave_idx_type j = col; j < lim; j++) | |
2405 { | |
2406 octave_quit (); | |
2407 | |
2408 os << " "; | |
2409 | |
2410 if (i == j) | |
2411 pr_complex (os, cm(i,j), r_fw, i_fw, scale); | |
2412 else | |
2413 os << std::setw (zero_fw) << '0'; | |
2414 } | |
2415 | |
2416 if (i < nr - 1) | |
2417 os << "\n"; | |
2418 } | |
2419 } | |
2420 } | |
2421 } | |
2422 } | |
2423 | |
2424 void | |
2425 octave_print_internal (std::ostream& os, const PermMatrix& m, | |
2426 bool pr_as_read_syntax, int extra_indent) | |
2427 { | |
2428 octave_idx_type nr = m.rows (); | |
2429 octave_idx_type nc = m.columns (); | |
2430 | |
2431 if (nr == 0 || nc == 0) | |
2432 print_empty_matrix (os, nr, nc, pr_as_read_syntax); | |
2433 else if (plus_format && ! pr_as_read_syntax) | |
2434 { | |
2435 for (octave_idx_type i = 0; i < nr; i++) | |
2436 { | |
2437 for (octave_idx_type j = 0; j < nc; j++) | |
2438 { | |
2439 octave_quit (); | |
2440 | |
2441 pr_plus_format (os, m(i,j)); | |
2442 } | |
2443 | |
2444 if (i < nr - 1) | |
2445 os << "\n"; | |
2446 } | |
2447 } | |
2448 else | |
2449 { | |
2450 int fw = 2; | |
2451 int column_width = fw + 2; | |
2452 octave_idx_type total_width = nc * column_width; | |
2453 octave_idx_type max_width = command_editor::terminal_cols (); | |
2454 | |
2455 if (pr_as_read_syntax) | |
2456 max_width -= 4; | |
2457 else | |
2458 max_width -= extra_indent; | |
2459 | |
2460 if (max_width < 0) | |
2461 max_width = 0; | |
2462 | |
2463 if (free_format) | |
2464 { | |
2465 if (pr_as_read_syntax) | |
2466 os << "[\n"; | |
2467 | |
2468 os << Matrix (m); | |
2469 | |
2470 if (pr_as_read_syntax) | |
2471 os << "]"; | |
2472 | |
2473 return; | |
2474 } | |
2475 | |
2476 octave_idx_type inc = nc; | |
2477 if (total_width > max_width && Vsplit_long_rows) | |
2478 { | |
2479 inc = max_width / column_width; | |
2480 if (inc == 0) | |
2481 inc++; | |
2482 } | |
2483 | |
2484 if (pr_as_read_syntax) | |
2485 { | |
2486 Array<octave_idx_type> pvec = m.pvec (); | |
2487 bool colp = m.is_col_perm (); | |
2488 | |
2489 os << "eye ("; | |
2490 if (colp) os << ":, "; | |
2491 | |
2492 octave_idx_type col = 0; | |
2493 while (col < nc) | |
2494 { | |
2495 octave_idx_type lim = col + inc < nc ? col + inc : nc; | |
2496 | |
2497 for (octave_idx_type j = col; j < lim; j++) | |
2498 { | |
2499 octave_quit (); | |
2500 | |
2501 if (j == 0) | |
2502 os << "[ "; | |
2503 else | |
2504 { | |
2505 if (j > col && j < lim) | |
2506 os << ", "; | |
2507 else | |
2508 os << " "; | |
2509 } | |
2510 | |
2511 os << pvec (j); | |
2512 } | |
2513 | |
2514 col += inc; | |
2515 | |
2516 if (col >= nc) | |
2517 os << " ]"; | |
2518 else | |
2519 os << " ...\n"; | |
2520 } | |
2521 if (! colp) os << ", :"; | |
2522 os << ")"; | |
2523 } | |
2524 else | |
2525 { | |
2526 os << "Permutation Matrix\n"; | |
2527 if (! Vcompact_format) | |
2528 os << "\n"; | |
2529 | |
2530 for (octave_idx_type col = 0; col < nc; col += inc) | |
2531 { | |
2532 octave_idx_type lim = col + inc < nc ? col + inc : nc; | |
2533 | |
2534 pr_col_num_header (os, total_width, max_width, lim, col, | |
2535 extra_indent); | |
2536 | |
2537 for (octave_idx_type i = 0; i < nr; i++) | |
2538 { | |
2539 os << std::setw (extra_indent) << ""; | |
2540 | |
2541 for (octave_idx_type j = col; j < lim; j++) | |
2542 { | |
2543 octave_quit (); | |
2544 | |
2545 os << " "; | |
2546 | |
2547 os << std::setw (fw) << m(i,j); | |
2548 } | |
2549 | |
2550 if (i < nr - 1) | |
2551 os << "\n"; | |
2552 } | |
2553 } | |
2554 } | |
2555 } | |
2556 } | |
2557 | |
2558 void | |
2559 octave_print_internal (std::ostream& os, const ComplexNDArray& nda, | |
2560 bool pr_as_read_syntax, int extra_indent) | |
2561 { | |
2562 switch (nda.ndims ()) | |
2563 { | |
2564 case 1: | |
2565 case 2: | |
2566 octave_print_internal (os, nda.matrix_value (), | |
2567 pr_as_read_syntax, extra_indent); | |
2568 break; | |
2569 | |
2570 default: | |
2571 print_nd_array <ComplexNDArray, Complex, | |
2572 ComplexMatrix> (os, nda, pr_as_read_syntax); | |
2573 break; | |
2574 } | |
2575 } | |
2576 | |
2577 void | |
2578 octave_print_internal (std::ostream& os, bool d, bool pr_as_read_syntax) | |
2579 { | |
2580 octave_print_internal (os, double (d), pr_as_read_syntax); | |
2581 } | |
2582 | |
2583 // FIXME -- write single precision versions of the printing functions. | |
2584 | |
2585 void | |
2586 octave_print_internal (std::ostream& os, float d, bool pr_as_read_syntax) | |
2587 { | |
2588 octave_print_internal (os, double (d), pr_as_read_syntax); | |
2589 } | |
2590 | |
2591 void | |
2592 octave_print_internal (std::ostream& os, const FloatMatrix& m, | |
2593 bool pr_as_read_syntax, int extra_indent) | |
2594 { | |
2595 octave_print_internal (os, Matrix (m), pr_as_read_syntax, extra_indent); | |
2596 } | |
2597 | |
2598 void | |
2599 octave_print_internal (std::ostream& os, const FloatDiagMatrix& m, | |
2600 bool pr_as_read_syntax, int extra_indent) | |
2601 { | |
2602 octave_print_internal (os, DiagMatrix (m), pr_as_read_syntax, extra_indent); | |
2603 } | |
2604 | |
2605 void | |
2606 octave_print_internal (std::ostream& os, const FloatNDArray& nda, | |
2607 bool pr_as_read_syntax, int extra_indent) | |
2608 { | |
2609 octave_print_internal (os, NDArray (nda), pr_as_read_syntax, extra_indent); | |
2610 } | |
2611 | |
2612 void | |
2613 octave_print_internal (std::ostream& os, const FloatComplex& c, | |
2614 bool pr_as_read_syntax) | |
2615 { | |
2616 octave_print_internal (os, Complex (c), pr_as_read_syntax); | |
2617 } | |
2618 | |
2619 void | |
2620 octave_print_internal (std::ostream& os, const FloatComplexMatrix& cm, | |
2621 bool pr_as_read_syntax, int extra_indent) | |
2622 { | |
2623 octave_print_internal (os, ComplexMatrix (cm), pr_as_read_syntax, extra_indent); | |
2624 } | |
2625 | |
2626 void | |
2627 octave_print_internal (std::ostream& os, const FloatComplexDiagMatrix& cm, | |
2628 bool pr_as_read_syntax, int extra_indent) | |
2629 { | |
2630 octave_print_internal (os, ComplexDiagMatrix (cm), pr_as_read_syntax, extra_indent); | |
2631 } | |
2632 | |
2633 void | |
2634 octave_print_internal (std::ostream& os, const FloatComplexNDArray& nda, | |
2635 bool pr_as_read_syntax, int extra_indent) | |
2636 { | |
2637 octave_print_internal (os, ComplexNDArray (nda), pr_as_read_syntax, extra_indent); | |
2638 } | |
2639 | |
2640 void | |
2641 octave_print_internal (std::ostream& os, const Range& r, | |
2642 bool pr_as_read_syntax, int extra_indent) | |
2643 { | |
2644 double base = r.base (); | |
2645 double increment = r.inc (); | |
2646 double limit = r.limit (); | |
2647 octave_idx_type num_elem = r.nelem (); | |
2648 | |
2649 if (plus_format && ! pr_as_read_syntax) | |
2650 { | |
2651 for (octave_idx_type i = 0; i < num_elem; i++) | |
2652 { | |
2653 octave_quit (); | |
2654 | |
2655 double val = base + i * increment; | |
2656 | |
2657 pr_plus_format (os, val); | |
2658 } | |
2659 } | |
2660 else | |
2661 { | |
2662 int fw = 0; | |
2663 double scale = 1.0; | |
2664 set_format (r, fw, scale); | |
2665 | |
2666 if (pr_as_read_syntax) | |
2667 { | |
2668 if (free_format) | |
2669 { | |
2670 os << base << " : "; | |
2671 if (increment != 1.0) | |
2672 os << increment << " : "; | |
2673 os << limit; | |
2674 } | |
2675 else | |
2676 { | |
2677 pr_float (os, base, fw); | |
2678 os << " : "; | |
2679 if (increment != 1.0) | |
2680 { | |
2681 pr_float (os, increment, fw); | |
2682 os << " : "; | |
2683 } | |
2684 pr_float (os, limit, fw); | |
2685 } | |
2686 } | |
2687 else | |
2688 { | |
2689 int column_width = fw + 2; | |
2690 octave_idx_type total_width = num_elem * column_width; | |
2691 octave_idx_type max_width = command_editor::terminal_cols (); | |
2692 | |
2693 if (free_format) | |
2694 { | |
2695 os << r; | |
2696 return; | |
2697 } | |
2698 | |
2699 octave_idx_type inc = num_elem; | |
2700 if (total_width > max_width && Vsplit_long_rows) | |
2701 { | |
2702 inc = max_width / column_width; | |
2703 if (inc == 0) | |
2704 inc++; | |
2705 } | |
2706 | |
2707 max_width -= extra_indent; | |
2708 | |
2709 if (max_width < 0) | |
2710 max_width = 0; | |
2711 | |
2712 pr_scale_header (os, scale); | |
2713 | |
2714 octave_idx_type col = 0; | |
2715 while (col < num_elem) | |
2716 { | |
2717 octave_idx_type lim = col + inc < num_elem ? col + inc : num_elem; | |
2718 | |
2719 pr_col_num_header (os, total_width, max_width, lim, col, | |
2720 extra_indent); | |
2721 | |
2722 os << std::setw (extra_indent) << ""; | |
2723 | |
2724 for (octave_idx_type i = col; i < lim; i++) | |
2725 { | |
2726 octave_quit (); | |
2727 | |
2728 double val; | |
2729 if (i == 0) | |
2730 val = base; | |
2731 else | |
2732 val = base + i * increment; | |
2733 | |
2734 if (i == num_elem - 1) | |
2735 { | |
2736 // See the comments in Range::matrix_value. | |
2737 if ((increment > 0 && val >= limit) | |
2738 || (increment < 0 && val <= limit)) | |
2739 val = limit; | |
2740 } | |
2741 | |
2742 os << " "; | |
2743 | |
2744 pr_float (os, val, fw, scale); | |
2745 } | |
2746 | |
2747 col += inc; | |
2748 } | |
2749 } | |
2750 } | |
2751 } | |
2752 | |
2753 void | |
2754 octave_print_internal (std::ostream& os, const boolMatrix& bm, | |
2755 bool pr_as_read_syntax, | |
2756 int extra_indent) | |
2757 { | |
2758 Matrix tmp (bm); | |
2759 octave_print_internal (os, tmp, pr_as_read_syntax, extra_indent); | |
2760 } | |
2761 | |
2762 void | |
2763 octave_print_internal (std::ostream& os, const boolNDArray& nda, | |
2764 bool pr_as_read_syntax, | |
2765 int extra_indent) | |
2766 { | |
2767 switch (nda.ndims ()) | |
2768 { | |
2769 case 1: | |
2770 case 2: | |
2771 octave_print_internal (os, nda.matrix_value (), | |
2772 pr_as_read_syntax, extra_indent); | |
2773 break; | |
2774 | |
2775 default: | |
2776 print_nd_array<boolNDArray, bool, | |
2777 boolMatrix> (os, nda, pr_as_read_syntax); | |
2778 break; | |
2779 } | |
2780 } | |
2781 | |
2782 void | |
2783 octave_print_internal (std::ostream& os, const charMatrix& chm, | |
2784 bool pr_as_read_syntax, | |
2785 int /* extra_indent FIXME */, | |
2786 bool pr_as_string) | |
2787 { | |
2788 if (pr_as_string) | |
2789 { | |
2790 octave_idx_type nstr = chm.rows (); | |
2791 | |
2792 if (pr_as_read_syntax && nstr > 1) | |
2793 os << "[ "; | |
2794 | |
2795 if (nstr != 0) | |
2796 { | |
2797 for (octave_idx_type i = 0; i < nstr; i++) | |
2798 { | |
2799 octave_quit (); | |
2800 | |
2801 std::string row = chm.row_as_string (i); | |
2802 | |
2803 if (pr_as_read_syntax) | |
2804 { | |
2805 os << "\"" << undo_string_escapes (row) << "\""; | |
2806 | |
2807 if (i < nstr - 1) | |
2808 os << "; "; | |
2809 } | |
2810 else | |
2811 { | |
2812 os << row; | |
2813 | |
2814 if (i < nstr - 1) | |
2815 os << "\n"; | |
2816 } | |
2817 } | |
2818 } | |
2819 | |
2820 if (pr_as_read_syntax && nstr > 1) | |
2821 os << " ]"; | |
2822 } | |
2823 else | |
2824 { | |
2825 os << "sorry, printing char matrices not implemented yet\n"; | |
2826 } | |
2827 } | |
2828 | |
2829 void | |
2830 octave_print_internal (std::ostream& os, const charNDArray& nda, | |
2831 bool pr_as_read_syntax, int extra_indent, | |
2832 bool pr_as_string) | |
2833 { | |
2834 switch (nda.ndims ()) | |
2835 { | |
2836 case 1: | |
2837 case 2: | |
2838 octave_print_internal (os, nda.matrix_value (), | |
2839 pr_as_read_syntax, extra_indent, pr_as_string); | |
2840 break; | |
2841 | |
2842 default: | |
2843 print_nd_array <charNDArray, char, | |
2844 charMatrix> (os, nda, pr_as_read_syntax); | |
2845 break; | |
2846 } | |
2847 } | |
2848 | |
2849 void | |
2850 octave_print_internal (std::ostream& os, const std::string& s, | |
2851 bool pr_as_read_syntax, int extra_indent) | |
2852 { | |
2853 Array<std::string> nda (dim_vector (1, 1), s); | |
2854 | |
2855 octave_print_internal (os, nda, pr_as_read_syntax, extra_indent); | |
2856 } | |
2857 | |
2858 void | |
2859 octave_print_internal (std::ostream& os, const Array<std::string>& nda, | |
2860 bool pr_as_read_syntax, int /* extra_indent */) | |
2861 { | |
2862 // FIXME -- this mostly duplicates the code in the print_nd_array<> | |
2863 // function. Can fix this with std::is_same from C++11. | |
2864 | |
2865 if (nda.is_empty ()) | |
2866 print_empty_nd_array (os, nda.dims (), pr_as_read_syntax); | |
2867 else if (nda.length () == 1) | |
2868 { | |
2869 os << nda(0); | |
2870 } | |
2871 else | |
2872 { | |
2873 int ndims = nda.ndims (); | |
2874 | |
2875 dim_vector dims = nda.dims (); | |
2876 | |
2877 Array<octave_idx_type> ra_idx (dim_vector (ndims, 1), 0); | |
2878 | |
2879 octave_idx_type m = 1; | |
2880 | |
2881 for (int i = 2; i < ndims; i++) | |
2882 m *= dims(i); | |
2883 | |
2884 octave_idx_type nr = dims(0); | |
2885 octave_idx_type nc = dims(1); | |
2886 | |
2887 for (octave_idx_type i = 0; i < m; i++) | |
2888 { | |
2889 std::string nm = "ans"; | |
2890 | |
2891 if (m > 1) | |
2892 { | |
2893 nm += "(:,:,"; | |
2894 | |
2895 std::ostringstream buf; | |
2896 | |
2897 for (int k = 2; k < ndims; k++) | |
2898 { | |
2899 buf << ra_idx(k) + 1; | |
2900 | |
2901 if (k < ndims - 1) | |
2902 buf << ","; | |
2903 else | |
2904 buf << ")"; | |
2905 } | |
2906 | |
2907 nm += buf.str (); | |
2908 } | |
2909 | |
2910 Array<idx_vector> idx (dim_vector (ndims, 1)); | |
2911 | |
2912 idx(0) = idx_vector (':'); | |
2913 idx(1) = idx_vector (':'); | |
2914 | |
2915 for (int k = 2; k < ndims; k++) | |
2916 idx(k) = idx_vector (ra_idx(k)); | |
2917 | |
2918 Array<std::string> page (nda.index (idx), dim_vector (nr, nc)); | |
2919 | |
2920 // FIXME -- need to do some more work to put these | |
2921 // in neatly aligned columns... | |
2922 | |
2923 octave_idx_type n_rows = page.rows (); | |
2924 octave_idx_type n_cols = page.cols (); | |
2925 | |
2926 os << nm << " =\n"; | |
2927 if (! Vcompact_format) | |
2928 os << "\n"; | |
2929 | |
2930 for (octave_idx_type ii = 0; ii < n_rows; ii++) | |
2931 { | |
2932 for (octave_idx_type jj = 0; jj < n_cols; jj++) | |
2933 os << " " << page(ii,jj); | |
2934 | |
2935 os << "\n"; | |
2936 } | |
2937 | |
2938 if (i < m - 1) | |
2939 os << "\n"; | |
2940 | |
2941 if (i < m) | |
2942 increment_index (ra_idx, dims, 2); | |
2943 } | |
2944 } | |
2945 } | |
2946 | |
2947 template <class T> | |
2948 class | |
2949 octave_print_conv | |
2950 { | |
2951 public: | |
2952 typedef T print_conv_type; | |
2953 }; | |
2954 | |
2955 #define PRINT_CONV(T1, T2) \ | |
2956 template <> \ | |
2957 class \ | |
2958 octave_print_conv<T1> \ | |
2959 { \ | |
2960 public: \ | |
2961 typedef T2 print_conv_type; \ | |
2962 } | |
2963 | |
2964 PRINT_CONV (octave_int8, octave_int16); | |
2965 PRINT_CONV (octave_uint8, octave_uint16); | |
2966 | |
2967 #undef PRINT_CONV | |
2968 | |
2969 template <class T> | |
2970 /* static */ inline void | |
2971 pr_int (std::ostream& os, const T& d, int fw = 0) | |
2972 { | |
2973 size_t sz = d.byte_size (); | |
2974 const unsigned char * tmpi = d.iptr (); | |
2975 | |
2976 // Unless explicitly asked for, always print in big-endian | |
2977 // format for hex and bit formats. | |
2978 // | |
2979 // {bit,hex}_format == 1: print big-endian | |
2980 // {bit,hex}_format == 2: print native | |
2981 | |
2982 if (hex_format) | |
2983 { | |
2984 char ofill = os.fill ('0'); | |
2985 | |
2986 std::ios::fmtflags oflags | |
2987 = os.flags (std::ios::right | std::ios::hex); | |
2988 | |
2989 if (hex_format > 1 || oct_mach_info::words_big_endian ()) | |
2990 { | |
2991 for (size_t i = 0; i < sz; i++) | |
2992 os << std::setw (2) << static_cast<int> (tmpi[i]); | |
2993 } | |
2994 else | |
2995 { | |
2996 for (int i = sz - 1; i >= 0; i--) | |
2997 os << std::setw (2) << static_cast<int> (tmpi[i]); | |
2998 } | |
2999 | |
3000 os.fill (ofill); | |
3001 os.setf (oflags); | |
3002 } | |
3003 else if (bit_format) | |
3004 { | |
3005 if (oct_mach_info::words_big_endian ()) | |
3006 { | |
3007 for (size_t i = 0; i < sz; i++) | |
3008 PRINT_CHAR_BITS (os, tmpi[i]); | |
3009 } | |
3010 else | |
3011 { | |
3012 if (bit_format > 1) | |
3013 { | |
3014 for (size_t i = 0; i < sz; i++) | |
3015 PRINT_CHAR_BITS_SWAPPED (os, tmpi[i]); | |
3016 } | |
3017 else | |
3018 { | |
3019 for (int i = sz - 1; i >= 0; i--) | |
3020 PRINT_CHAR_BITS (os, tmpi[i]); | |
3021 } | |
3022 } | |
3023 } | |
3024 else | |
3025 { | |
3026 os << std::setw (fw) | |
3027 << typename octave_print_conv<T>::print_conv_type (d); | |
3028 | |
3029 if (bank_format) | |
3030 os << ".00"; | |
3031 } | |
3032 } | |
3033 | |
3034 // FIXME -- all this mess with abs is an attempt to avoid seeing | |
3035 // | |
3036 // warning: comparison of unsigned expression < 0 is always false | |
3037 // | |
3038 // from GCC. Isn't there a better way | |
3039 | |
3040 template <class T> | |
3041 /* static */ inline T | |
3042 abs (T x) | |
3043 { | |
3044 return x < 0 ? -x : x; | |
3045 } | |
3046 | |
3047 #define INSTANTIATE_ABS(T) \ | |
3048 template /* static */ T abs (T) | |
3049 | |
3050 INSTANTIATE_ABS(signed char); | |
3051 INSTANTIATE_ABS(short); | |
3052 INSTANTIATE_ABS(int); | |
3053 INSTANTIATE_ABS(long); | |
3054 INSTANTIATE_ABS(long long); | |
3055 | |
3056 #define SPECIALIZE_UABS(T) \ | |
3057 template <> \ | |
3058 /* static */ inline unsigned T \ | |
3059 abs (unsigned T x) \ | |
3060 { \ | |
3061 return x; \ | |
3062 } | |
3063 | |
3064 SPECIALIZE_UABS(char) | |
3065 SPECIALIZE_UABS(short) | |
3066 SPECIALIZE_UABS(int) | |
3067 SPECIALIZE_UABS(long) | |
3068 SPECIALIZE_UABS(long long) | |
3069 | |
3070 template void | |
3071 pr_int (std::ostream&, const octave_int8&, int); | |
3072 | |
3073 template void | |
3074 pr_int (std::ostream&, const octave_int16&, int); | |
3075 | |
3076 template void | |
3077 pr_int (std::ostream&, const octave_int32&, int); | |
3078 | |
3079 template void | |
3080 pr_int (std::ostream&, const octave_int64&, int); | |
3081 | |
3082 template void | |
3083 pr_int (std::ostream&, const octave_uint8&, int); | |
3084 | |
3085 template void | |
3086 pr_int (std::ostream&, const octave_uint16&, int); | |
3087 | |
3088 template void | |
3089 pr_int (std::ostream&, const octave_uint32&, int); | |
3090 | |
3091 template void | |
3092 pr_int (std::ostream&, const octave_uint64&, int); | |
3093 | |
3094 template <class T> | |
3095 void | |
3096 octave_print_internal_template (std::ostream& os, const octave_int<T>& val, | |
3097 bool) | |
3098 { | |
3099 if (plus_format) | |
3100 { | |
3101 pr_plus_format (os, val); | |
3102 } | |
3103 else | |
3104 { | |
3105 if (free_format) | |
3106 os << typename octave_print_conv<octave_int<T> >::print_conv_type (val); | |
3107 else | |
3108 pr_int (os, val); | |
3109 } | |
3110 } | |
3111 | |
3112 #define PRINT_INT_SCALAR_INTERNAL(TYPE) \ | |
3113 OCTINTERP_API void \ | |
3114 octave_print_internal (std::ostream& os, const octave_int<TYPE>& val, bool dummy) \ | |
3115 { \ | |
3116 octave_print_internal_template (os, val, dummy); \ | |
3117 } | |
3118 | |
3119 PRINT_INT_SCALAR_INTERNAL (int8_t) | |
3120 PRINT_INT_SCALAR_INTERNAL (uint8_t) | |
3121 PRINT_INT_SCALAR_INTERNAL (int16_t) | |
3122 PRINT_INT_SCALAR_INTERNAL (uint16_t) | |
3123 PRINT_INT_SCALAR_INTERNAL (int32_t) | |
3124 PRINT_INT_SCALAR_INTERNAL (uint32_t) | |
3125 PRINT_INT_SCALAR_INTERNAL (int64_t) | |
3126 PRINT_INT_SCALAR_INTERNAL (uint64_t) | |
3127 | |
3128 template <class T> | |
3129 /* static */ inline void | |
3130 octave_print_internal_template (std::ostream& os, const intNDArray<T>& nda, | |
3131 bool pr_as_read_syntax, int extra_indent) | |
3132 { | |
3133 // FIXME -- this mostly duplicates the code in the print_nd_array<> | |
3134 // function. Can fix this with std::is_same from C++11. | |
3135 | |
3136 if (nda.is_empty ()) | |
3137 print_empty_nd_array (os, nda.dims (), pr_as_read_syntax); | |
3138 else if (nda.length () == 1) | |
3139 octave_print_internal_template (os, nda(0), pr_as_read_syntax); | |
3140 else if (plus_format && ! pr_as_read_syntax) | |
3141 { | |
3142 int ndims = nda.ndims (); | |
3143 | |
3144 Array<octave_idx_type> ra_idx (dim_vector (ndims, 1), 0); | |
3145 | |
3146 dim_vector dims = nda.dims (); | |
3147 | |
3148 octave_idx_type m = 1; | |
3149 | |
3150 for (int i = 2; i < ndims; i++) | |
3151 m *= dims(i); | |
3152 | |
3153 octave_idx_type nr = dims(0); | |
3154 octave_idx_type nc = dims(1); | |
3155 | |
3156 for (octave_idx_type i = 0; i < m; i++) | |
3157 { | |
3158 if (m > 1) | |
3159 { | |
3160 std::string nm = "ans(:,:,"; | |
3161 | |
3162 std::ostringstream buf; | |
3163 | |
3164 for (int k = 2; k < ndims; k++) | |
3165 { | |
3166 buf << ra_idx(k) + 1; | |
3167 | |
3168 if (k < ndims - 1) | |
3169 buf << ","; | |
3170 else | |
3171 buf << ")"; | |
3172 } | |
3173 | |
3174 nm += buf.str (); | |
3175 | |
3176 os << nm << " =\n"; | |
3177 if (! Vcompact_format) | |
3178 os << "\n"; | |
3179 } | |
3180 | |
3181 Array<idx_vector> idx (dim_vector (ndims, 1)); | |
3182 | |
3183 idx(0) = idx_vector (':'); | |
3184 idx(1) = idx_vector (':'); | |
3185 | |
3186 for (int k = 2; k < ndims; k++) | |
3187 idx(k) = idx_vector (ra_idx(k)); | |
3188 | |
3189 Array<T> page (nda.index (idx), dim_vector (nr, nc)); | |
3190 | |
3191 for (octave_idx_type ii = 0; ii < nr; ii++) | |
3192 { | |
3193 for (octave_idx_type jj = 0; jj < nc; jj++) | |
3194 { | |
3195 octave_quit (); | |
3196 | |
3197 pr_plus_format (os, page(ii,jj)); | |
3198 } | |
3199 | |
3200 if ((ii < nr - 1) || (i < m -1)) | |
3201 os << "\n"; | |
3202 } | |
3203 | |
3204 if (i < m - 1) | |
3205 { | |
3206 os << "\n"; | |
3207 increment_index (ra_idx, dims, 2); | |
3208 } | |
3209 } | |
3210 } | |
3211 else | |
3212 { | |
3213 int ndims = nda.ndims (); | |
3214 | |
3215 dim_vector dims = nda.dims (); | |
3216 | |
3217 Array<octave_idx_type> ra_idx (dim_vector (ndims, 1), 0); | |
3218 | |
3219 octave_idx_type m = 1; | |
3220 | |
3221 for (int i = 2; i < ndims; i++) | |
3222 m *= dims(i); | |
3223 | |
3224 octave_idx_type nr = dims(0); | |
3225 octave_idx_type nc = dims(1); | |
3226 | |
3227 int fw = 0; | |
3228 if (hex_format) | |
3229 fw = 2 * nda(0).byte_size (); | |
3230 else if (bit_format) | |
3231 fw = nda(0).nbits (); | |
3232 else | |
3233 { | |
3234 bool isneg = false; | |
3235 int digits = 0; | |
3236 | |
3237 for (octave_idx_type i = 0; i < dims.numel (); i++) | |
3238 { | |
3239 int new_digits = static_cast<int> | |
3240 (gnulib::floor (log10 (double (abs (nda(i).value ()))) + 1.0)); | |
3241 | |
3242 if (new_digits > digits) | |
3243 digits = new_digits; | |
3244 | |
3245 if (! isneg) | |
3246 isneg = (abs (nda(i).value ()) != nda(i).value ()); | |
3247 } | |
3248 | |
3249 fw = digits + isneg; | |
3250 } | |
3251 | |
3252 int column_width = fw + (rat_format ? 0 : (bank_format ? 5 : 2)); | |
3253 octave_idx_type total_width = nc * column_width; | |
3254 int max_width = command_editor::terminal_cols () - extra_indent; | |
3255 octave_idx_type inc = nc; | |
3256 if (total_width > max_width && Vsplit_long_rows) | |
3257 { | |
3258 inc = max_width / column_width; | |
3259 if (inc == 0) | |
3260 inc++; | |
3261 } | |
3262 | |
3263 for (octave_idx_type i = 0; i < m; i++) | |
3264 { | |
3265 if (m > 1) | |
3266 { | |
3267 std::string nm = "ans(:,:,"; | |
3268 | |
3269 std::ostringstream buf; | |
3270 | |
3271 for (int k = 2; k < ndims; k++) | |
3272 { | |
3273 buf << ra_idx(k) + 1; | |
3274 | |
3275 if (k < ndims - 1) | |
3276 buf << ","; | |
3277 else | |
3278 buf << ")"; | |
3279 } | |
3280 | |
3281 nm += buf.str (); | |
3282 | |
3283 os << nm << " =\n"; | |
3284 if (! Vcompact_format) | |
3285 os << "\n"; | |
3286 } | |
3287 | |
3288 Array<idx_vector> idx (dim_vector (ndims, 1)); | |
3289 | |
3290 idx(0) = idx_vector (':'); | |
3291 idx(1) = idx_vector (':'); | |
3292 | |
3293 for (int k = 2; k < ndims; k++) | |
3294 idx(k) = idx_vector (ra_idx(k)); | |
3295 | |
3296 Array<T> page (nda.index (idx), dim_vector (nr, nc)); | |
3297 | |
3298 if (free_format) | |
3299 { | |
3300 if (pr_as_read_syntax) | |
3301 os << "[\n"; | |
3302 | |
3303 for (octave_idx_type ii = 0; ii < nr; ii++) | |
3304 { | |
3305 for (octave_idx_type jj = 0; jj < nc; jj++) | |
3306 { | |
3307 octave_quit (); | |
3308 os << " "; | |
3309 os << typename octave_print_conv<T>::print_conv_type (page(ii,jj)); | |
3310 } | |
3311 os << "\n"; | |
3312 } | |
3313 | |
3314 if (pr_as_read_syntax) | |
3315 os << "]"; | |
3316 } | |
3317 else | |
3318 { | |
3319 octave_idx_type n_rows = page.rows (); | |
3320 octave_idx_type n_cols = page.cols (); | |
3321 | |
3322 for (octave_idx_type col = 0; col < n_cols; col += inc) | |
3323 { | |
3324 octave_idx_type lim = col + inc < n_cols ? col + inc : n_cols; | |
3325 | |
3326 pr_col_num_header (os, total_width, max_width, lim, col, | |
3327 extra_indent); | |
3328 | |
3329 for (octave_idx_type ii = 0; ii < n_rows; ii++) | |
3330 { | |
3331 os << std::setw (extra_indent) << ""; | |
3332 | |
3333 for (octave_idx_type jj = col; jj < lim; jj++) | |
3334 { | |
3335 octave_quit (); | |
3336 os << " "; | |
3337 pr_int (os, page(ii,jj), fw); | |
3338 } | |
3339 if ((ii < n_rows - 1) || (i < m -1)) | |
3340 os << "\n"; | |
3341 } | |
3342 } | |
3343 } | |
3344 | |
3345 if (i < m - 1) | |
3346 { | |
3347 os << "\n"; | |
3348 increment_index (ra_idx, dims, 2); | |
3349 } | |
3350 } | |
3351 } | |
3352 } | |
3353 | |
3354 #define PRINT_INT_ARRAY_INTERNAL(TYPE) \ | |
3355 OCTINTERP_API void \ | |
3356 octave_print_internal (std::ostream& os, const intNDArray<TYPE>& nda, \ | |
3357 bool pr_as_read_syntax, int extra_indent) \ | |
3358 { \ | |
3359 octave_print_internal_template (os, nda, pr_as_read_syntax, extra_indent); \ | |
3360 } | |
3361 | |
3362 PRINT_INT_ARRAY_INTERNAL (octave_int8) | |
3363 PRINT_INT_ARRAY_INTERNAL (octave_uint8) | |
3364 PRINT_INT_ARRAY_INTERNAL (octave_int16) | |
3365 PRINT_INT_ARRAY_INTERNAL (octave_uint16) | |
3366 PRINT_INT_ARRAY_INTERNAL (octave_int32) | |
3367 PRINT_INT_ARRAY_INTERNAL (octave_uint32) | |
3368 PRINT_INT_ARRAY_INTERNAL (octave_int64) | |
3369 PRINT_INT_ARRAY_INTERNAL (octave_uint64) | |
3370 | |
3371 void | |
3372 octave_print_internal (std::ostream&, const Cell&, bool, int, bool) | |
3373 { | |
3374 panic_impossible (); | |
3375 } | |
3376 | |
3377 DEFUN (rats, args, nargout, | |
3378 "-*- texinfo -*-\n\ | |
3379 @deftypefn {Built-in Function} {} rats (@var{x}, @var{len})\n\ | |
3380 Convert @var{x} into a rational approximation represented as a string.\n\ | |
3381 You can convert the string back into a matrix as follows:\n\ | |
3382 \n\ | |
3383 @example\n\ | |
3384 @group\n\ | |
3385 r = rats (hilb (4));\n\ | |
3386 x = str2num (r)\n\ | |
3387 @end group\n\ | |
3388 @end example\n\ | |
3389 \n\ | |
3390 The optional second argument defines the maximum length of the string\n\ | |
3391 representing the elements of @var{x}. By default @var{len} is 9.\n\ | |
3392 @seealso{format, rat}\n\ | |
3393 @end deftypefn") | |
3394 { | |
3395 octave_value retval; | |
3396 | |
3397 int nargin = args.length (); | |
3398 | |
3399 if (nargin < 1 || nargin > 2 || nargout > 1) | |
3400 print_usage (); | |
3401 else | |
3402 { | |
3403 unwind_protect frame; | |
3404 | |
3405 frame.protect_var (rat_string_len); | |
3406 | |
3407 rat_string_len = 9; | |
3408 | |
3409 if (nargin == 2) | |
3410 rat_string_len = args(1).nint_value (); | |
3411 | |
3412 if (! error_state) | |
3413 { | |
3414 octave_value arg = args(0); | |
3415 | |
3416 if (arg.is_numeric_type ()) | |
3417 { | |
3418 frame.protect_var (rat_format); | |
3419 | |
3420 rat_format = true; | |
3421 | |
3422 std::ostringstream buf; | |
3423 args(0).print (buf); | |
3424 std::string s = buf.str (); | |
3425 | |
3426 std::list<std::string> lst; | |
3427 | |
3428 size_t n = 0; | |
3429 size_t s_len = s.length (); | |
3430 | |
3431 while (n < s_len) | |
3432 { | |
3433 size_t m = s.find ('\n', n); | |
3434 | |
3435 if (m == std::string::npos) | |
3436 { | |
3437 lst.push_back (s.substr (n)); | |
3438 break; | |
3439 } | |
3440 else | |
3441 { | |
3442 lst.push_back (s.substr (n, m - n)); | |
3443 n = m + 1; | |
3444 } | |
3445 } | |
3446 | |
3447 retval = string_vector (lst); | |
3448 } | |
3449 else | |
3450 error ("rats: X must be numeric"); | |
3451 } | |
3452 } | |
3453 | |
3454 return retval; | |
3455 } | |
3456 | |
3457 DEFUN (disp, args, nargout, | |
3458 "-*- texinfo -*-\n\ | |
3459 @deftypefn {Built-in Function} {} disp (@var{x})\n\ | |
3460 Display the value of @var{x}. For example:\n\ | |
3461 \n\ | |
3462 @example\n\ | |
3463 @group\n\ | |
3464 disp (\"The value of pi is:\"), disp (pi)\n\ | |
3465 \n\ | |
3466 @print{} the value of pi is:\n\ | |
3467 @print{} 3.1416\n\ | |
3468 @end group\n\ | |
3469 @end example\n\ | |
3470 \n\ | |
3471 @noindent\n\ | |
3472 Note that the output from @code{disp} always ends with a newline.\n\ | |
3473 \n\ | |
3474 If an output value is requested, @code{disp} prints nothing and\n\ | |
3475 returns the formatted output in a string.\n\ | |
3476 @seealso{fdisp}\n\ | |
3477 @end deftypefn") | |
3478 { | |
3479 octave_value_list retval; | |
3480 | |
3481 int nargin = args.length (); | |
3482 | |
3483 if (nargin == 1 && nargout < 2) | |
3484 { | |
3485 if (nargout == 0) | |
3486 args(0).print (octave_stdout); | |
3487 else | |
3488 { | |
3489 octave_value arg = args(0); | |
3490 std::ostringstream buf; | |
3491 arg.print (buf); | |
3492 retval = octave_value (buf.str (), arg.is_dq_string () ? '"' : '\''); | |
3493 } | |
3494 } | |
3495 else | |
3496 print_usage (); | |
3497 | |
3498 return retval; | |
3499 } | |
3500 | |
3501 DEFUN (fdisp, args, , | |
3502 "-*- texinfo -*-\n\ | |
3503 @deftypefn {Built-in Function} {} fdisp (@var{fid}, @var{x})\n\ | |
3504 Display the value of @var{x} on the stream @var{fid}. For example:\n\ | |
3505 \n\ | |
3506 @example\n\ | |
3507 @group\n\ | |
3508 fdisp (stdout, \"The value of pi is:\"), fdisp (stdout, pi)\n\ | |
3509 \n\ | |
3510 @print{} the value of pi is:\n\ | |
3511 @print{} 3.1416\n\ | |
3512 @end group\n\ | |
3513 @end example\n\ | |
3514 \n\ | |
3515 @noindent\n\ | |
3516 Note that the output from @code{fdisp} always ends with a newline.\n\ | |
3517 @seealso{disp}\n\ | |
3518 @end deftypefn") | |
3519 { | |
3520 octave_value_list retval; | |
3521 | |
3522 int nargin = args.length (); | |
3523 | |
3524 if (nargin == 2) | |
3525 { | |
3526 int fid = octave_stream_list::get_file_number (args (0)); | |
3527 | |
3528 octave_stream os = octave_stream_list::lookup (fid, "fdisp"); | |
3529 | |
3530 if (! error_state) | |
3531 { | |
3532 std::ostream *osp = os.output_stream (); | |
3533 | |
3534 if (osp) | |
3535 args(1).print (*osp); | |
3536 else | |
3537 error ("fdisp: stream FID not open for writing"); | |
3538 } | |
3539 } | |
3540 else | |
3541 print_usage (); | |
3542 | |
3543 return retval; | |
3544 } | |
3545 | |
3546 /* | |
3547 %!test | |
3548 %! format short | |
3549 %! fd = tmpfile (); | |
3550 %! for r = [0, Inf -Inf, NaN] | |
3551 %! for i = [0, Inf -Inf, NaN] | |
3552 %! fdisp (fd, complex (r, i)); | |
3553 %! endfor | |
3554 %! endfor | |
3555 %! fclose (fd); | |
3556 | |
3557 %!test | |
3558 %! foo.real = pi * ones (3,20,3); | |
3559 %! foo.complex = pi * ones (3,20,3) + 1i; | |
3560 %! foo.char = repmat ("- Hello World -", [3, 20]); | |
3561 %! foo.cell = {foo.real, foo.complex, foo.char}; | |
3562 %! fields = fieldnames (foo); | |
3563 %! for f = 1:numel (fields) | |
3564 %! format loose; | |
3565 %! loose = disp (foo.(fields{f})); | |
3566 %! format compact; | |
3567 %! compact = disp (foo.(fields{f})); | |
3568 %! expected = strrep (loose, "\n\n", "\n"); | |
3569 %! assert (expected, compact); | |
3570 %! endfor | |
3571 */ | |
3572 | |
3573 static void | |
3574 init_format_state (void) | |
3575 { | |
3576 free_format = false; | |
3577 plus_format = false; | |
3578 rat_format = false; | |
3579 bank_format = false; | |
3580 hex_format = 0; | |
3581 bit_format = 0; | |
3582 Vcompact_format = false; | |
3583 print_e = false; | |
3584 print_big_e = false; | |
3585 print_g = false; | |
3586 print_eng = false; | |
3587 } | |
3588 | |
3589 static void | |
3590 set_output_prec_and_fw (int prec, int fw) | |
3591 { | |
3592 Voutput_precision = prec; | |
3593 Voutput_max_field_width = fw; | |
3594 } | |
3595 | |
3596 static void | |
3597 set_format_style (int argc, const string_vector& argv) | |
3598 { | |
3599 int idx = 1; | |
3600 | |
3601 if (--argc > 0) | |
3602 { | |
3603 std::string arg = argv[idx++]; | |
3604 | |
3605 if (arg == "short") | |
3606 { | |
3607 if (--argc > 0) | |
3608 { | |
3609 arg = argv[idx++]; | |
3610 | |
3611 if (arg == "e") | |
3612 { | |
3613 init_format_state (); | |
3614 print_e = true; | |
3615 } | |
3616 else if (arg == "E") | |
3617 { | |
3618 init_format_state (); | |
3619 print_e = true; | |
3620 print_big_e = true; | |
3621 } | |
3622 else if (arg == "g") | |
3623 { | |
3624 init_format_state (); | |
3625 print_g = true; | |
3626 } | |
3627 else if (arg == "G") | |
3628 { | |
3629 init_format_state (); | |
3630 print_g = true; | |
3631 print_big_e = true; | |
3632 } | |
3633 else if (arg == "eng") | |
3634 { | |
3635 init_format_state (); | |
3636 print_eng = true; | |
3637 } | |
3638 else | |
3639 { | |
3640 error ("format: unrecognized option 'short %s'", | |
3641 arg.c_str ()); | |
3642 return; | |
3643 } | |
3644 } | |
3645 else | |
3646 init_format_state (); | |
3647 | |
3648 set_output_prec_and_fw (5, 10); | |
3649 } | |
3650 else if (arg == "long") | |
3651 { | |
3652 if (--argc > 0) | |
3653 { | |
3654 arg = argv[idx++]; | |
3655 | |
3656 if (arg == "e") | |
3657 { | |
3658 init_format_state (); | |
3659 print_e = true; | |
3660 } | |
3661 else if (arg == "E") | |
3662 { | |
3663 init_format_state (); | |
3664 print_e = true; | |
3665 print_big_e = true; | |
3666 } | |
3667 else if (arg == "g") | |
3668 { | |
3669 init_format_state (); | |
3670 print_g = true; | |
3671 } | |
3672 else if (arg == "G") | |
3673 { | |
3674 init_format_state (); | |
3675 print_g = true; | |
3676 print_big_e = true; | |
3677 } | |
3678 else if (arg == "eng") | |
3679 { | |
3680 init_format_state (); | |
3681 print_eng = true; | |
3682 } | |
3683 else | |
3684 { | |
3685 error ("format: unrecognized option 'long %s'", | |
3686 arg.c_str ()); | |
3687 return; | |
3688 } | |
3689 } | |
3690 else | |
3691 init_format_state (); | |
3692 | |
3693 set_output_prec_and_fw (15, 20); | |
3694 } | |
3695 else if (arg == "hex") | |
3696 { | |
3697 init_format_state (); | |
3698 hex_format = 1; | |
3699 } | |
3700 else if (arg == "native-hex") | |
3701 { | |
3702 init_format_state (); | |
3703 hex_format = 2; | |
3704 } | |
3705 else if (arg == "bit") | |
3706 { | |
3707 init_format_state (); | |
3708 bit_format = 1; | |
3709 } | |
3710 else if (arg == "native-bit") | |
3711 { | |
3712 init_format_state (); | |
3713 bit_format = 2; | |
3714 } | |
3715 else if (arg == "+" || arg == "plus") | |
3716 { | |
3717 if (--argc > 0) | |
3718 { | |
3719 arg = argv[idx++]; | |
3720 | |
3721 if (arg.length () == 3) | |
3722 plus_format_chars = arg; | |
3723 else | |
3724 { | |
3725 error ("format: invalid option for plus format"); | |
3726 return; | |
3727 } | |
3728 } | |
3729 else | |
3730 plus_format_chars = "+ "; | |
3731 | |
3732 init_format_state (); | |
3733 plus_format = true; | |
3734 } | |
3735 else if (arg == "rat") | |
3736 { | |
3737 init_format_state (); | |
3738 rat_format = true; | |
3739 } | |
3740 else if (arg == "bank") | |
3741 { | |
3742 init_format_state (); | |
3743 bank_format = true; | |
3744 } | |
3745 else if (arg == "free") | |
3746 { | |
3747 init_format_state (); | |
3748 free_format = true; | |
3749 } | |
3750 else if (arg == "none") | |
3751 { | |
3752 init_format_state (); | |
3753 free_format = true; | |
3754 } | |
3755 else if (arg == "compact") | |
3756 { | |
3757 Vcompact_format = true; | |
3758 } | |
3759 else if (arg == "loose") | |
3760 { | |
3761 Vcompact_format = false; | |
3762 } | |
3763 else | |
3764 error ("format: unrecognized format state '%s'", arg.c_str ()); | |
3765 } | |
3766 else | |
3767 { | |
3768 init_format_state (); | |
3769 set_output_prec_and_fw (5, 10); | |
3770 } | |
3771 } | |
3772 | |
3773 DEFUN (format, args, , | |
3774 "-*- texinfo -*-\n\ | |
3775 @deftypefn {Command} {} format\n\ | |
3776 @deftypefnx {Command} {} format options\n\ | |
3777 Reset or specify the format of the output produced by @code{disp} and\n\ | |
3778 Octave's normal echoing mechanism. This command only affects the display\n\ | |
3779 of numbers but not how they are stored or computed. To change the internal\n\ | |
3780 representation from the default double use one of the conversion functions\n\ | |
3781 such as @code{single}, @code{uint8}, @code{int64}, etc.\n\ | |
3782 \n\ | |
3783 By default, Octave displays 5 significant digits in a human readable form\n\ | |
3784 (option @samp{short} paired with @samp{loose} format for matrices).\n\ | |
3785 If @code{format} is invoked without any options, this default format\n\ | |
3786 is restored.\n\ | |
3787 \n\ | |
3788 Valid formats for floating point numbers are listed in the following\n\ | |
3789 table.\n\ | |
3790 \n\ | |
3791 @table @code\n\ | |
3792 @item short\n\ | |
3793 Fixed point format with 5 significant figures in a field that is a maximum\n\ | |
3794 of 10 characters wide. (default).\n\ | |
3795 \n\ | |
3796 If Octave is unable to format a matrix so that columns line up on the\n\ | |
3797 decimal point and all numbers fit within the maximum field width then\n\ | |
3798 it switches to an exponential @samp{e} format.\n\ | |
3799 \n\ | |
3800 @item long\n\ | |
3801 Fixed point format with 15 significant figures in a field that is a maximum\n\ | |
3802 of 20 characters wide.\n\ | |
3803 \n\ | |
3804 As with the @samp{short} format, Octave will switch to an exponential\n\ | |
3805 @samp{e} format if it is unable to format a matrix properly using the\n\ | |
3806 current format.\n\ | |
3807 \n\ | |
3808 @item short e\n\ | |
3809 @itemx long e\n\ | |
3810 Exponential format. The number to be represented is split between a mantissa\n\ | |
3811 and an exponent (power of 10). The mantissa has 5 significant digits in the\n\ | |
3812 short format and 15 digits in the long format.\n\ | |
3813 For example, with the @samp{short e} format, @code{pi} is displayed as\n\ | |
3814 @code{3.1416e+00}.\n\ | |
3815 \n\ | |
3816 @item short E\n\ | |
3817 @itemx long E\n\ | |
3818 Identical to @samp{short e} or @samp{long e} but displays an uppercase\n\ | |
3819 @samp{E} to indicate the exponent.\n\ | |
3820 For example, with the @samp{long E} format, @code{pi} is displayed as\n\ | |
3821 @code{3.14159265358979E+00}.\n\ | |
3822 \n\ | |
3823 @item short g\n\ | |
3824 @itemx long g\n\ | |
3825 Optimally choose between fixed point and exponential format based on\n\ | |
3826 the magnitude of the number.\n\ | |
3827 For example, with the @samp{short g} format,\n\ | |
3828 @code{pi .^ [2; 4; 8; 16; 32]} is displayed as\n\ | |
3829 \n\ | |
3830 @example\n\ | |
3831 @group\n\ | |
3832 ans =\n\ | |
3833 \n\ | |
3834 9.8696\n\ | |
3835 97.409\n\ | |
3836 9488.5\n\ | |
3837 9.0032e+07\n\ | |
3838 8.1058e+15\n\ | |
3839 @end group\n\ | |
3840 @end example\n\ | |
3841 \n\ | |
3842 @item short eng\n\ | |
3843 @itemx long eng\n\ | |
3844 Identical to @samp{short e} or @samp{long e} but displays the value\n\ | |
3845 using an engineering format, where the exponent is divisible by 3. For\n\ | |
3846 example, with the @samp{short eng} format, @code{10 * pi} is displayed as\n\ | |
3847 @code{31.4159e+00}.\n\ | |
3848 \n\ | |
3849 @item long G\n\ | |
3850 @itemx short G\n\ | |
3851 Identical to @samp{short g} or @samp{long g} but displays an uppercase\n\ | |
3852 @samp{E} to indicate the exponent.\n\ | |
3853 \n\ | |
3854 @item free\n\ | |
3855 @itemx none\n\ | |
3856 Print output in free format, without trying to line up columns of\n\ | |
3857 matrices on the decimal point. This also causes complex numbers to be\n\ | |
3858 formatted as numeric pairs like this @samp{(0.60419, 0.60709)} instead\n\ | |
3859 of like this @samp{0.60419 + 0.60709i}.\n\ | |
3860 @end table\n\ | |
3861 \n\ | |
3862 The following formats affect all numeric output (floating point and\n\ | |
3863 integer types).\n\ | |
3864 \n\ | |
3865 @table @code\n\ | |
3866 @item +\n\ | |
3867 @itemx + @var{chars}\n\ | |
3868 @itemx plus\n\ | |
3869 @itemx plus @var{chars}\n\ | |
3870 Print a @samp{+} symbol for nonzero matrix elements and a space for zero\n\ | |
3871 matrix elements. This format can be very useful for examining the\n\ | |
3872 structure of a large sparse matrix.\n\ | |
3873 \n\ | |
3874 The optional argument @var{chars} specifies a list of 3 characters to use\n\ | |
3875 for printing values greater than zero, less than zero and equal to zero.\n\ | |
3876 For example, with the @samp{+ \"+-.\"} format, @code{[1, 0, -1; -1, 0, 1]}\n\ | |
3877 is displayed as\n\ | |
3878 \n\ | |
3879 @example\n\ | |
3880 @group\n\ | |
3881 ans =\n\ | |
3882 \n\ | |
3883 +.-\n\ | |
3884 -.+\n\ | |
3885 @end group\n\ | |
3886 @end example\n\ | |
3887 \n\ | |
3888 @item bank\n\ | |
3889 Print in a fixed format with two digits to the right of the decimal\n\ | |
3890 point.\n\ | |
3891 \n\ | |
3892 @item native-hex\n\ | |
3893 Print the hexadecimal representation of numbers as they are stored in\n\ | |
3894 memory. For example, on a workstation which stores 8 byte real values\n\ | |
3895 in IEEE format with the least significant byte first, the value of\n\ | |
3896 @code{pi} when printed in @code{native-hex} format is\n\ | |
3897 @code{400921fb54442d18}.\n\ | |
3898 \n\ | |
3899 @item hex\n\ | |
3900 The same as @code{native-hex}, but always print the most significant\n\ | |
3901 byte first.\n\ | |
3902 \n\ | |
3903 @item native-bit\n\ | |
3904 Print the bit representation of numbers as stored in memory.\n\ | |
3905 For example, the value of @code{pi} is\n\ | |
3906 \n\ | |
3907 @example\n\ | |
3908 @group\n\ | |
3909 01000000000010010010000111111011\n\ | |
3910 01010100010001000010110100011000\n\ | |
3911 @end group\n\ | |
3912 @end example\n\ | |
3913 \n\ | |
3914 (shown here in two 32 bit sections for typesetting purposes) when\n\ | |
3915 printed in native-bit format on a workstation which stores 8 byte real values\n\ | |
3916 in IEEE format with the least significant byte first.\n\ | |
3917 \n\ | |
3918 @item bit\n\ | |
3919 The same as @code{native-bit}, but always print the most significant\n\ | |
3920 bits first.\n\ | |
3921 \n\ | |
3922 @item rat\n\ | |
3923 Print a rational approximation, i.e., values are approximated\n\ | |
3924 as the ratio of small integers.\n\ | |
3925 For example, with the @samp{rat} format,\n\ | |
3926 @code{pi} is displayed as @code{355/113}.\n\ | |
3927 @end table\n\ | |
3928 \n\ | |
3929 The following two options affect the display of all matrices.\n\ | |
3930 \n\ | |
3931 @table @code\n\ | |
3932 @item compact\n\ | |
3933 Remove blank lines around column number labels and between\n\ | |
3934 matrices producing more compact output with more data per page.\n\ | |
3935 \n\ | |
3936 @item loose\n\ | |
3937 Insert blank lines above and below column number labels and between matrices\n\ | |
3938 to produce a more readable output with less data per page. (default).\n\ | |
3939 @end table\n\ | |
3940 @seealso{fixed_point_format, output_max_field_width, output_precision, split_long_rows, rats}\n\ | |
3941 @end deftypefn") | |
3942 { | |
3943 octave_value_list retval; | |
3944 | |
3945 int argc = args.length () + 1; | |
3946 | |
3947 string_vector argv = args.make_argv ("format"); | |
3948 | |
3949 if (error_state) | |
3950 return retval; | |
3951 | |
3952 set_format_style (argc, argv); | |
3953 | |
3954 return retval; | |
3955 } | |
3956 | |
3957 DEFUN (fixed_point_format, args, nargout, | |
3958 "-*- texinfo -*-\n\ | |
3959 @deftypefn {Built-in Function} {@var{val} =} fixed_point_format ()\n\ | |
3960 @deftypefnx {Built-in Function} {@var{old_val} =} fixed_point_format (@var{new_val})\n\ | |
3961 @deftypefnx {Built-in Function} {} fixed_point_format (@var{new_val}, \"local\")\n\ | |
3962 Query or set the internal variable that controls whether Octave will\n\ | |
3963 use a scaled format to print matrix values such that the largest\n\ | |
3964 element may be written with a single leading digit with the scaling\n\ | |
3965 factor is printed on the first line of output. For example:\n\ | |
3966 \n\ | |
3967 @example\n\ | |
3968 @group\n\ | |
3969 octave:1> logspace (1, 7, 5)'\n\ | |
3970 ans =\n\ | |
3971 \n\ | |
3972 1.0e+07 *\n\ | |
3973 \n\ | |
3974 0.00000\n\ | |
3975 0.00003\n\ | |
3976 0.00100\n\ | |
3977 0.03162\n\ | |
3978 1.00000\n\ | |
3979 @end group\n\ | |
3980 @end example\n\ | |
3981 \n\ | |
3982 @noindent\n\ | |
3983 Notice that first value appears to be zero when it is actually 1. For\n\ | |
3984 this reason, you should be careful when setting\n\ | |
3985 @code{fixed_point_format} to a nonzero value.\n\ | |
3986 \n\ | |
3987 When called from inside a function with the \"local\" option, the variable is\n\ | |
3988 changed locally for the function and any subroutines it calls. The original\n\ | |
3989 variable value is restored when exiting the function.\n\ | |
3990 @seealso{format, output_max_field_width, output_precision}\n\ | |
3991 @end deftypefn") | |
3992 { | |
3993 return SET_INTERNAL_VARIABLE (fixed_point_format); | |
3994 } | |
3995 | |
3996 DEFUN (print_empty_dimensions, args, nargout, | |
3997 "-*- texinfo -*-\n\ | |
3998 @deftypefn {Built-in Function} {@var{val} =} print_empty_dimensions ()\n\ | |
3999 @deftypefnx {Built-in Function} {@var{old_val} =} print_empty_dimensions (@var{new_val})\n\ | |
4000 @deftypefnx {Built-in Function} {} print_empty_dimensions (@var{new_val}, \"local\")\n\ | |
4001 Query or set the internal variable that controls whether the\n\ | |
4002 dimensions of empty matrices are printed along with the empty matrix\n\ | |
4003 symbol, @samp{[]}. For example, the expression\n\ | |
4004 \n\ | |
4005 @example\n\ | |
4006 zeros (3, 0)\n\ | |
4007 @end example\n\ | |
4008 \n\ | |
4009 @noindent\n\ | |
4010 will print\n\ | |
4011 \n\ | |
4012 @example\n\ | |
4013 ans = [](3x0)\n\ | |
4014 @end example\n\ | |
4015 \n\ | |
4016 When called from inside a function with the \"local\" option, the variable is\n\ | |
4017 changed locally for the function and any subroutines it calls. The original\n\ | |
4018 variable value is restored when exiting the function.\n\ | |
4019 @seealso{format}\n\ | |
4020 @end deftypefn") | |
4021 { | |
4022 return SET_INTERNAL_VARIABLE (print_empty_dimensions); | |
4023 } | |
4024 | |
4025 DEFUN (split_long_rows, args, nargout, | |
4026 "-*- texinfo -*-\n\ | |
4027 @deftypefn {Built-in Function} {@var{val} =} split_long_rows ()\n\ | |
4028 @deftypefnx {Built-in Function} {@var{old_val} =} split_long_rows (@var{new_val})\n\ | |
4029 @deftypefnx {Built-in Function} {} split_long_rows (@var{new_val}, \"local\")\n\ | |
4030 Query or set the internal variable that controls whether rows of a matrix\n\ | |
4031 may be split when displayed to a terminal window. If the rows are split,\n\ | |
4032 Octave will display the matrix in a series of smaller pieces, each of\n\ | |
4033 which can fit within the limits of your terminal width and each set of\n\ | |
4034 rows is labeled so that you can easily see which columns are currently\n\ | |
4035 being displayed. For example:\n\ | |
4036 \n\ | |
4037 @example\n\ | |
4038 @group\n\ | |
4039 octave:13> rand (2,10)\n\ | |
4040 ans =\n\ | |
4041 \n\ | |
4042 Columns 1 through 6:\n\ | |
4043 \n\ | |
4044 0.75883 0.93290 0.40064 0.43818 0.94958 0.16467\n\ | |
4045 0.75697 0.51942 0.40031 0.61784 0.92309 0.40201\n\ | |
4046 \n\ | |
4047 Columns 7 through 10:\n\ | |
4048 \n\ | |
4049 0.90174 0.11854 0.72313 0.73326\n\ | |
4050 0.44672 0.94303 0.56564 0.82150\n\ | |
4051 @end group\n\ | |
4052 @end example\n\ | |
4053 \n\ | |
4054 When called from inside a function with the \"local\" option, the variable is\n\ | |
4055 changed locally for the function and any subroutines it calls. The original\n\ | |
4056 variable value is restored when exiting the function.\n\ | |
4057 @seealso{format}\n\ | |
4058 @end deftypefn") | |
4059 { | |
4060 return SET_INTERNAL_VARIABLE (split_long_rows); | |
4061 } | |
4062 | |
4063 DEFUN (output_max_field_width, args, nargout, | |
4064 "-*- texinfo -*-\n\ | |
4065 @deftypefn {Built-in Function} {@var{val} =} output_max_field_width ()\n\ | |
4066 @deftypefnx {Built-in Function} {@var{old_val} =} output_max_field_width (@var{new_val})\n\ | |
4067 @deftypefnx {Built-in Function} {} output_max_field_width (@var{new_val}, \"local\")\n\ | |
4068 Query or set the internal variable that specifies the maximum width\n\ | |
4069 of a numeric output field.\n\ | |
4070 \n\ | |
4071 When called from inside a function with the \"local\" option, the variable is\n\ | |
4072 changed locally for the function and any subroutines it calls. The original\n\ | |
4073 variable value is restored when exiting the function.\n\ | |
4074 @seealso{format, fixed_point_format, output_precision}\n\ | |
4075 @end deftypefn") | |
4076 { | |
4077 return SET_INTERNAL_VARIABLE_WITH_LIMITS (output_max_field_width, 0, | |
4078 std::numeric_limits<int>::max ()); | |
4079 } | |
4080 | |
4081 DEFUN (output_precision, args, nargout, | |
4082 "-*- texinfo -*-\n\ | |
4083 @deftypefn {Built-in Function} {@var{val} =} output_precision ()\n\ | |
4084 @deftypefnx {Built-in Function} {@var{old_val} =} output_precision (@var{new_val})\n\ | |
4085 @deftypefnx {Built-in Function} {} output_precision (@var{new_val}, \"local\")\n\ | |
4086 Query or set the internal variable that specifies the minimum number of\n\ | |
4087 significant figures to display for numeric output.\n\ | |
4088 \n\ | |
4089 When called from inside a function with the \"local\" option, the variable is\n\ | |
4090 changed locally for the function and any subroutines it calls. The original\n\ | |
4091 variable value is restored when exiting the function.\n\ | |
4092 @seealso{format, fixed_point_format, output_max_field_width}\n\ | |
4093 @end deftypefn") | |
4094 { | |
4095 return SET_INTERNAL_VARIABLE_WITH_LIMITS (output_precision, -1, | |
4096 std::numeric_limits<int>::max ()); | |
4097 } |