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