00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026
00027 #include <cfloat>
00028 #include <cstdio>
00029 #include <cstring>
00030
00031 #include <iomanip>
00032 #include <iostream>
00033 #include <sstream>
00034 #include <string>
00035
00036 #include "Array-util.h"
00037 #include "CMatrix.h"
00038 #include "Range.h"
00039 #include "cmd-edit.h"
00040 #include "dMatrix.h"
00041 #include "lo-mappers.h"
00042 #include "lo-math.h"
00043 #include "mach-info.h"
00044 #include "oct-cmplx.h"
00045 #include "quit.h"
00046 #include "str-vec.h"
00047
00048 #include "Cell.h"
00049 #include "defun.h"
00050 #include "error.h"
00051 #include "gripes.h"
00052 #include "oct-obj.h"
00053 #include "oct-stream.h"
00054 #include "pager.h"
00055 #include "pr-output.h"
00056 #include "sysdep.h"
00057 #include "unwind-prot.h"
00058 #include "utils.h"
00059 #include "variables.h"
00060
00061
00062
00063 static bool Vfixed_point_format = false;
00064
00065
00066
00067 static int Voutput_max_field_width = 10;
00068
00069
00070
00071 static int Voutput_precision = 5;
00072
00073
00074
00075 bool Vprint_empty_dimensions = true;
00076
00077
00078
00079 static bool Vsplit_long_rows = true;
00080
00081
00082 static bool free_format = false;
00083
00084
00085 static bool plus_format = false;
00086
00087
00088 static std::string plus_format_chars = "+ ";
00089
00090
00091 static bool rat_format = false;
00092
00093
00094 static int rat_string_len = -1;
00095
00096
00097 static bool bank_format = false;
00098
00099
00100 static int hex_format = 0;
00101
00102
00103 static int bit_format = 0;
00104
00105
00106 bool Vcompact_format = false;
00107
00108
00109 static bool print_e = false;
00110
00111
00112 static bool print_g = false;
00113
00114
00115 static bool print_big_e = false;
00116
00117
00118 static bool print_eng = false;
00119
00120 class pr_engineering_float;
00121 class pr_formatted_float;
00122 class pr_rational_float;
00123
00124 static int
00125 current_output_max_field_width (void)
00126 {
00127 return Voutput_max_field_width;
00128 }
00129
00130 static int
00131 current_output_precision (void)
00132 {
00133 return Voutput_precision;
00134 }
00135
00136 class
00137 float_format
00138 {
00139 public:
00140
00141 float_format (int w = current_output_max_field_width (),
00142 int p = current_output_precision (), int f = 0)
00143 : fw (w), ex (0), prec (p), fmt (f), up (0), sp (0) { }
00144
00145 float_format (int w, int e, int p, int f)
00146 : fw (w), ex (e), prec (p), fmt (f), up (0), sp (0) { }
00147
00148 float_format (const float_format& ff)
00149 : fw (ff.fw), ex (ff.ex), prec (ff.prec), fmt (ff.fmt), up (ff.up), sp (ff.sp) { }
00150
00151 float_format& operator = (const float_format& ff)
00152 {
00153 if (&ff != this)
00154 {
00155 fw = ff.fw;
00156 ex = ff.ex;
00157 prec = ff.prec;
00158 fmt = ff.fmt;
00159 up = ff.up;
00160 sp = ff.sp;
00161 }
00162
00163 return *this;
00164 }
00165
00166 ~float_format (void) { }
00167
00168 float_format& scientific (void) { fmt = std::ios::scientific; return *this; }
00169 float_format& fixed (void) { fmt = std::ios::fixed; return *this; }
00170 float_format& general (void) { fmt = 0; return *this; }
00171
00172 float_format& uppercase (void) { up = std::ios::uppercase; return *this; }
00173 float_format& lowercase (void) { up = 0; return *this; }
00174
00175 float_format& precision (int p) { prec = p; return *this; }
00176
00177 float_format& width (int w) { fw = w; return *this; }
00178
00179 float_format& trailing_zeros (bool tz = true)
00180 { sp = tz ? std::ios::showpoint : 0; return *this; }
00181
00182 friend std::ostream& operator << (std::ostream& os,
00183 const pr_engineering_float& pef);
00184
00185 friend std::ostream& operator << (std::ostream& os,
00186 const pr_formatted_float& pff);
00187
00188 friend std::ostream& operator << (std::ostream& os,
00189 const pr_rational_float& prf);
00190
00191 private:
00192
00193
00194 int fw;
00195
00196
00197 int ex;
00198
00199
00200 int prec;
00201
00202
00203 int fmt;
00204
00205
00206 int up;
00207
00208
00209 int sp;
00210 };
00211
00212 static int
00213 calc_scale_exp (const int& x)
00214 {
00215 if (! print_eng)
00216 return x;
00217 else
00218 return x - 3*static_cast<int> (x/3);
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 }
00232
00233 static int
00234 engineering_exponent (const double& x)
00235 {
00236 int ex = 0;
00237 if (x != 0)
00238 {
00239 double absval = (x < 0.0 ? -x : x);
00240 int logabsval = static_cast<int> (gnulib::floor (log10 (absval)));
00241
00242
00243 if (logabsval < 0.0)
00244 ex = logabsval - 2 + ((-logabsval + 2) % 3);
00245 else
00246 ex = logabsval - (logabsval % 3);
00247 }
00248 return ex;
00249 }
00250
00251 static int
00252 num_digits (const double& x)
00253 {
00254 return 1 + (print_eng
00255 ? engineering_exponent (x)
00256 : static_cast<int> (gnulib::floor (log10 (x))));
00257 }
00258
00259 class
00260 pr_engineering_float
00261 {
00262 public:
00263
00264 const float_format& f;
00265
00266 double val;
00267
00268 int exponent (void) const
00269 {
00270 return engineering_exponent (val);
00271 }
00272
00273 double mantissa (void) const
00274 {
00275 return val / std::pow (10.0, exponent ());
00276 }
00277
00278 pr_engineering_float (const float_format& f_arg, double val_arg)
00279 : f (f_arg), val (val_arg) { }
00280 };
00281
00282 std::ostream&
00283 operator << (std::ostream& os, const pr_engineering_float& pef)
00284 {
00285 if (pef.f.fw >= 0)
00286 os << std::setw (pef.f.fw - pef.f.ex);
00287
00288 if (pef.f.prec >= 0)
00289 os << std::setprecision (pef.f.prec);
00290
00291 std::ios::fmtflags oflags =
00292 os.flags (static_cast<std::ios::fmtflags>
00293 (pef.f.fmt | pef.f.up | pef.f.sp));
00294
00295 os << pef.mantissa ();
00296
00297 int ex = pef.exponent ();
00298 if (ex < 0)
00299 {
00300 os << std::setw (0) << "e-";
00301 ex = -ex;
00302 }
00303 else
00304 os << std::setw (0) << "e+";
00305
00306 os << std::setw (pef.f.ex - 2) << std::setfill('0') << ex
00307 << std::setfill(' ');
00308
00309 os.flags (oflags);
00310
00311 return os;
00312 }
00313
00314 class
00315 pr_formatted_float
00316 {
00317 public:
00318
00319 const float_format& f;
00320
00321 double val;
00322
00323 pr_formatted_float (const float_format& f_arg, double val_arg)
00324 : f (f_arg), val (val_arg) { }
00325 };
00326
00327 std::ostream&
00328 operator << (std::ostream& os, const pr_formatted_float& pff)
00329 {
00330 if (pff.f.fw >= 0)
00331 os << std::setw (pff.f.fw);
00332
00333 if (pff.f.prec >= 0)
00334 os << std::setprecision (pff.f.prec);
00335
00336 std::ios::fmtflags oflags =
00337 os.flags (static_cast<std::ios::fmtflags>
00338 (pff.f.fmt | pff.f.up | pff.f.sp));
00339
00340 os << pff.val;
00341
00342 os.flags (oflags);
00343
00344 return os;
00345 }
00346
00347 static inline std::string
00348 rational_approx (double val, int len)
00349 {
00350 std::string s;
00351
00352 if (len <= 0)
00353 len = 10;
00354
00355 if (xisinf (val))
00356 s = "1/0";
00357 else if (xisnan (val))
00358 s = "0/0";
00359 else if (val < INT_MIN || val > INT_MAX || D_NINT (val) == val)
00360 {
00361 std::ostringstream buf;
00362 buf.flags (std::ios::fixed);
00363 buf << std::setprecision (0) << xround(val);
00364 s = buf.str ();
00365 }
00366 else
00367 {
00368 double lastn = 1.;
00369 double lastd = 0.;
00370 double n = xround (val);
00371 double d = 1.;
00372 double frac = val - n;
00373 int m = 0;
00374
00375 std::ostringstream buf2;
00376 buf2.flags (std::ios::fixed);
00377 buf2 << std::setprecision (0) << static_cast<int>(n);
00378 s = buf2.str();
00379
00380 while (1)
00381 {
00382 double flip = 1. / frac;
00383 double step = xround (flip);
00384 double nextn = n;
00385 double nextd = d;
00386
00387
00388 if (m > 100 || fabs (frac) < 1 / static_cast<double>(INT_MAX))
00389 {
00390 lastn = n;
00391 lastd = d;
00392 break;
00393 }
00394
00395 frac = flip - step;
00396 n = n * step + lastn;
00397 d = d * step + lastd;
00398 lastn = nextn;
00399 lastd = nextd;
00400
00401 std::ostringstream buf;
00402 buf.flags (std::ios::fixed);
00403 buf << std::setprecision (0) << static_cast<int>(n)
00404 << "/" << static_cast<int>(d);
00405 m++;
00406
00407 if (n < 0 && d < 0)
00408 {
00409
00410 if (buf.str().length() > static_cast<unsigned int>(len + 2) &&
00411 m > 1)
00412 break;
00413 }
00414 else if (buf.str().length() > static_cast<unsigned int>(len) &&
00415 m > 1)
00416 break;
00417
00418 s = buf.str();
00419 }
00420
00421 if (lastd < 0.)
00422 {
00423
00424 lastd = - lastd;
00425 lastn = - lastn;
00426 std::ostringstream buf;
00427 buf.flags (std::ios::fixed);
00428 buf << std::setprecision (0) << static_cast<int>(lastn)
00429 << "/" << static_cast<int>(lastd);
00430 s = buf.str();
00431 }
00432 }
00433
00434 return s;
00435 }
00436
00437 class
00438 pr_rational_float
00439 {
00440 public:
00441
00442 const float_format& f;
00443
00444 double val;
00445
00446 pr_rational_float (const float_format& f_arg, double val_arg)
00447 : f (f_arg), val (val_arg) { }
00448 };
00449
00450 std::ostream&
00451 operator << (std::ostream& os, const pr_rational_float& prf)
00452 {
00453 int fw = (rat_string_len > 0 ? rat_string_len : prf.f.fw);
00454 std::string s = rational_approx (prf.val, fw);
00455
00456 if (fw >= 0)
00457 os << std::setw (fw);
00458
00459 std::ios::fmtflags oflags =
00460 os.flags (static_cast<std::ios::fmtflags>
00461 (prf.f.fmt | prf.f.up | prf.f.sp));
00462
00463 if (fw > 0 && s.length() > static_cast<unsigned int>(fw))
00464 os << "*";
00465 else
00466 os << s;
00467
00468 os.flags (oflags);
00469
00470 return os;
00471 }
00472
00473
00474
00475 static float_format *curr_real_fmt = 0;
00476
00477
00478 static float_format *curr_imag_fmt = 0;
00479
00480 static double
00481 pr_max_internal (const Matrix& m)
00482 {
00483 octave_idx_type nr = m.rows ();
00484 octave_idx_type nc = m.columns ();
00485
00486 double result = -DBL_MAX;
00487
00488 bool all_inf_or_nan = true;
00489
00490 for (octave_idx_type j = 0; j < nc; j++)
00491 for (octave_idx_type i = 0; i < nr; i++)
00492 {
00493 double val = m(i,j);
00494 if (xisinf (val) || xisnan (val))
00495 continue;
00496
00497 all_inf_or_nan = false;
00498
00499 if (val > result)
00500 result = val;
00501 }
00502
00503 if (all_inf_or_nan)
00504 result = 0.0;
00505
00506 return result;
00507 }
00508
00509 static double
00510 pr_min_internal (const Matrix& m)
00511 {
00512 octave_idx_type nr = m.rows ();
00513 octave_idx_type nc = m.columns ();
00514
00515 double result = DBL_MAX;
00516
00517 bool all_inf_or_nan = true;
00518
00519 for (octave_idx_type j = 0; j < nc; j++)
00520 for (octave_idx_type i = 0; i < nr; i++)
00521 {
00522 double val = m(i,j);
00523 if (xisinf (val) || xisnan (val))
00524 continue;
00525
00526 all_inf_or_nan = false;
00527
00528 if (val < result)
00529 result = val;
00530 }
00531
00532 if (all_inf_or_nan)
00533 result = 0.0;
00534
00535 return result;
00536 }
00537
00538
00539
00540
00541 static void
00542 set_real_format (int digits, bool inf_or_nan, bool int_only, int &fw)
00543 {
00544 static float_format fmt;
00545
00546 int prec = Voutput_precision;
00547
00548 int ld, rd;
00549
00550 if (rat_format)
00551 {
00552 fw = 0;
00553 rd = 0;
00554 }
00555 else if (bank_format)
00556 {
00557 fw = digits < 0 ? 4 : digits + 3;
00558 if (inf_or_nan && fw < 4)
00559 fw = 4;
00560 rd = 2;
00561 }
00562 else if (hex_format)
00563 {
00564 fw = 2 * sizeof (double);
00565 rd = 0;
00566 }
00567 else if (bit_format)
00568 {
00569 fw = 8 * sizeof (double);
00570 rd = 0;
00571 }
00572 else if (inf_or_nan || int_only)
00573 {
00574 fw = 1 + digits;
00575 if (inf_or_nan && fw < 4)
00576 fw = 4;
00577 rd = fw;
00578 }
00579 else
00580 {
00581 if (digits > 0)
00582 {
00583 ld = digits;
00584 rd = prec > digits ? prec - digits : prec;
00585 digits++;
00586 }
00587 else
00588 {
00589 ld = 1;
00590 rd = prec > digits ? prec - digits : prec;
00591 digits = -digits + 1;
00592 }
00593
00594 fw = 1 + ld + 1 + rd;
00595 if (inf_or_nan && fw < 4)
00596 fw = 4;
00597 }
00598
00599 if (! (rat_format || bank_format || hex_format || bit_format)
00600 && (fw > Voutput_max_field_width || print_e || print_g || print_eng))
00601 {
00602 if (print_g)
00603 fmt = float_format ();
00604 else
00605 {
00606 int ex = 4;
00607 if (digits > 100)
00608 ex++;
00609
00610 if (print_eng)
00611 {
00612 fw = 4 + prec + ex;
00613 if (inf_or_nan && fw < 6)
00614 fw = 6;
00615 fmt = float_format (fw, ex, prec - 1, std::ios::fixed);
00616 }
00617 else
00618 {
00619 fw = 2 + prec + ex;
00620 if (inf_or_nan && fw < 4)
00621 fw = 4;
00622 fmt = float_format (fw, prec - 1, std::ios::scientific);
00623 }
00624 }
00625
00626 if (print_big_e)
00627 fmt.uppercase ();
00628 }
00629 else if (! bank_format && (inf_or_nan || int_only))
00630 fmt = float_format (fw, rd);
00631 else
00632 fmt = float_format (fw, rd, std::ios::fixed);
00633
00634 curr_real_fmt = &fmt;
00635 }
00636
00637 static void
00638 set_format (double d, int& fw)
00639 {
00640 curr_real_fmt = 0;
00641 curr_imag_fmt = 0;
00642
00643 if (free_format)
00644 return;
00645
00646 bool inf_or_nan = (xisinf (d) || xisnan (d));
00647
00648 bool int_only = (! inf_or_nan && D_NINT (d) == d);
00649
00650 double d_abs = d < 0.0 ? -d : d;
00651
00652 int digits = (inf_or_nan || d_abs == 0.0)
00653 ? 0 : num_digits (d_abs);
00654
00655 set_real_format (digits, inf_or_nan, int_only, fw);
00656 }
00657
00658 static inline void
00659 set_format (double d)
00660 {
00661 int fw;
00662 set_format (d, fw);
00663 }
00664
00665 static void
00666 set_real_matrix_format (int x_max, int x_min, bool inf_or_nan,
00667 int int_or_inf_or_nan, int& fw)
00668 {
00669 static float_format fmt;
00670
00671 int prec = Voutput_precision;
00672
00673 int ld, rd;
00674
00675 if (rat_format)
00676 {
00677 fw = 9;
00678 rd = 0;
00679 }
00680 else if (bank_format)
00681 {
00682 int digits = x_max > x_min ? x_max : x_min;
00683 fw = digits <= 0 ? 4 : digits + 3;
00684 if (inf_or_nan && fw < 4)
00685 fw = 4;
00686 rd = 2;
00687 }
00688 else if (hex_format)
00689 {
00690 fw = 2 * sizeof (double);
00691 rd = 0;
00692 }
00693 else if (bit_format)
00694 {
00695 fw = 8 * sizeof (double);
00696 rd = 0;
00697 }
00698 else if (Vfixed_point_format && ! print_g)
00699 {
00700 rd = prec;
00701 fw = rd + 2;
00702 if (inf_or_nan && fw < 4)
00703 fw = 4;
00704 }
00705 else if (int_or_inf_or_nan)
00706 {
00707 int digits = x_max > x_min ? x_max : x_min;
00708 fw = digits <= 0 ? 2 : digits + 1;
00709 if (inf_or_nan && fw < 4)
00710 fw = 4;
00711 rd = fw;
00712 }
00713 else
00714 {
00715 int ld_max, rd_max;
00716 if (x_max > 0)
00717 {
00718 ld_max = x_max;
00719 rd_max = prec > x_max ? prec - x_max : prec;
00720 x_max++;
00721 }
00722 else
00723 {
00724 ld_max = 1;
00725 rd_max = prec > x_max ? prec - x_max : prec;
00726 x_max = -x_max + 1;
00727 }
00728
00729 int ld_min, rd_min;
00730 if (x_min > 0)
00731 {
00732 ld_min = x_min;
00733 rd_min = prec > x_min ? prec - x_min : prec;
00734 x_min++;
00735 }
00736 else
00737 {
00738 ld_min = 1;
00739 rd_min = prec > x_min ? prec - x_min : prec;
00740 x_min = -x_min + 1;
00741 }
00742
00743 ld = ld_max > ld_min ? ld_max : ld_min;
00744 rd = rd_max > rd_min ? rd_max : rd_min;
00745
00746 fw = 1 + ld + 1 + rd;
00747 if (inf_or_nan && fw < 4)
00748 fw = 4;
00749 }
00750
00751 if (! (rat_format || bank_format || hex_format || bit_format)
00752 && (print_e
00753 || print_eng || print_g
00754 || (! Vfixed_point_format && fw > Voutput_max_field_width)))
00755 {
00756 if (print_g)
00757 fmt = float_format ();
00758 else
00759 {
00760 int ex = 4;
00761 if (x_max > 100 || x_min > 100)
00762 ex++;
00763
00764 if (print_eng)
00765 {
00766 fw = 4 + prec + ex;
00767 if (inf_or_nan && fw < 6)
00768 fw = 6;
00769 fmt = float_format (fw, ex, prec - 1, std::ios::fixed);
00770 }
00771 else
00772 {
00773 fw = 2 + prec + ex;
00774 if (inf_or_nan && fw < 4)
00775 fw = 4;
00776 fmt = float_format (fw, prec - 1, std::ios::scientific);
00777 }
00778 }
00779
00780 if (print_big_e)
00781 fmt.uppercase ();
00782 }
00783 else if (! bank_format && int_or_inf_or_nan)
00784 fmt = float_format (fw, rd);
00785 else
00786 fmt = float_format (fw, rd, std::ios::fixed);
00787
00788 curr_real_fmt = &fmt;
00789 }
00790
00791 static void
00792 set_format (const Matrix& m, int& fw, double& scale)
00793 {
00794 curr_real_fmt = 0;
00795 curr_imag_fmt = 0;
00796
00797 if (free_format)
00798 return;
00799
00800 bool inf_or_nan = m.any_element_is_inf_or_nan ();
00801
00802 bool int_or_inf_or_nan = m.all_elements_are_int_or_inf_or_nan ();
00803
00804 Matrix m_abs = m.abs ();
00805 double max_abs = pr_max_internal (m_abs);
00806 double min_abs = pr_min_internal (m_abs);
00807
00808 int x_max = max_abs == 0.0 ? 0 : num_digits (max_abs);
00809
00810 int x_min = min_abs == 0.0 ? 0 : num_digits (min_abs);
00811
00812 scale = (x_max == 0 || int_or_inf_or_nan) ? 1.0
00813 : std::pow (10.0, calc_scale_exp (x_max - 1));
00814
00815 set_real_matrix_format (x_max, x_min, inf_or_nan, int_or_inf_or_nan, fw);
00816 }
00817
00818 static inline void
00819 set_format (const Matrix& m)
00820 {
00821 int fw;
00822 double scale;
00823 set_format (m, fw, scale);
00824 }
00825
00826 static void
00827 set_complex_format (int x_max, int x_min, int r_x, bool inf_or_nan,
00828 int int_only, int& r_fw, int& i_fw)
00829 {
00830 static float_format r_fmt;
00831 static float_format i_fmt;
00832
00833 int prec = Voutput_precision;
00834
00835 int ld, rd;
00836
00837 if (rat_format)
00838 {
00839 i_fw = 0;
00840 r_fw = 0;
00841 rd = 0;
00842 }
00843 else if (bank_format)
00844 {
00845 int digits = r_x;
00846 i_fw = 0;
00847 r_fw = digits <= 0 ? 4 : digits + 3;
00848 if (inf_or_nan && r_fw < 4)
00849 r_fw = 4;
00850 rd = 2;
00851 }
00852 else if (hex_format)
00853 {
00854 r_fw = 2 * sizeof (double);
00855 i_fw = 2 * sizeof (double);
00856 rd = 0;
00857 }
00858 else if (bit_format)
00859 {
00860 r_fw = 8 * sizeof (double);
00861 i_fw = 8 * sizeof (double);
00862 rd = 0;
00863 }
00864 else if (inf_or_nan || int_only)
00865 {
00866 int digits = x_max > x_min ? x_max : x_min;
00867 i_fw = digits <= 0 ? 1 : digits;
00868 r_fw = i_fw + 1;
00869 if (inf_or_nan && i_fw < 3)
00870 {
00871 i_fw = 3;
00872 r_fw = 4;
00873 }
00874 rd = r_fw;
00875 }
00876 else
00877 {
00878 int ld_max, rd_max;
00879 if (x_max > 0)
00880 {
00881 ld_max = x_max;
00882 rd_max = prec > x_max ? prec - x_max : prec;
00883 x_max++;
00884 }
00885 else
00886 {
00887 ld_max = 1;
00888 rd_max = prec > x_max ? prec - x_max : prec;
00889 x_max = -x_max + 1;
00890 }
00891
00892 int ld_min, rd_min;
00893 if (x_min > 0)
00894 {
00895 ld_min = x_min;
00896 rd_min = prec > x_min ? prec - x_min : prec;
00897 x_min++;
00898 }
00899 else
00900 {
00901 ld_min = 1;
00902 rd_min = prec > x_min ? prec - x_min : prec;
00903 x_min = -x_min + 1;
00904 }
00905
00906 ld = ld_max > ld_min ? ld_max : ld_min;
00907 rd = rd_max > rd_min ? rd_max : rd_min;
00908
00909 i_fw = ld + 1 + rd;
00910 r_fw = i_fw + 1;
00911 if (inf_or_nan && i_fw < 3)
00912 {
00913 i_fw = 3;
00914 r_fw = 4;
00915 }
00916 }
00917
00918 if (! (rat_format || bank_format || hex_format || bit_format)
00919 && (r_fw > Voutput_max_field_width || print_e || print_eng || print_g))
00920 {
00921 if (print_g)
00922 {
00923 r_fmt = float_format ();
00924 i_fmt = float_format ();
00925 }
00926 else
00927 {
00928 int ex = 4;
00929 if (x_max > 100 || x_min > 100)
00930 ex++;
00931
00932 if (print_eng)
00933 {
00934 i_fw = 3 + prec + ex;
00935 r_fw = i_fw + 1;
00936 if (inf_or_nan && i_fw < 5)
00937 {
00938 i_fw = 5;
00939 r_fw = 6;
00940 }
00941 r_fmt = float_format (r_fw, ex, prec - 1, std::ios::fixed);
00942 i_fmt = float_format (i_fw, ex, prec - 1, std::ios::fixed);
00943 }
00944 else
00945 {
00946 i_fw = 1 + prec + ex;
00947 r_fw = i_fw + 1;
00948 if (inf_or_nan && i_fw < 3)
00949 {
00950 i_fw = 3;
00951 r_fw = 4;
00952 }
00953 r_fmt = float_format (r_fw, prec - 1, std::ios::scientific);
00954 i_fmt = float_format (i_fw, prec - 1, std::ios::scientific);
00955 }
00956 }
00957
00958 if (print_big_e)
00959 {
00960 r_fmt.uppercase ();
00961 i_fmt.uppercase ();
00962 }
00963 }
00964 else if (! bank_format && (inf_or_nan || int_only))
00965 {
00966 r_fmt = float_format (r_fw, rd);
00967 i_fmt = float_format (i_fw, rd);
00968 }
00969 else
00970 {
00971 r_fmt = float_format (r_fw, rd, std::ios::fixed);
00972 i_fmt = float_format (i_fw, rd, std::ios::fixed);
00973 }
00974
00975 curr_real_fmt = &r_fmt;
00976 curr_imag_fmt = &i_fmt;
00977 }
00978
00979 static void
00980 set_format (const Complex& c, int& r_fw, int& i_fw)
00981 {
00982 curr_real_fmt = 0;
00983 curr_imag_fmt = 0;
00984
00985 if (free_format)
00986 return;
00987
00988 double rp = c.real ();
00989 double ip = c.imag ();
00990
00991 bool inf_or_nan = (xisinf (c) || xisnan (c));
00992
00993 bool int_only = (D_NINT (rp) == rp && D_NINT (ip) == ip);
00994
00995 double r_abs = rp < 0.0 ? -rp : rp;
00996 double i_abs = ip < 0.0 ? -ip : ip;
00997
00998 int r_x = (xisinf (rp) || xisnan (rp) || r_abs == 0.0)
00999 ? 0 : num_digits (r_abs);
01000
01001 int i_x = (xisinf (ip) || xisnan (ip) || i_abs == 0.0)
01002 ? 0 : num_digits (i_abs);
01003
01004 int x_max, x_min;
01005
01006 if (r_x > i_x)
01007 {
01008 x_max = r_x;
01009 x_min = i_x;
01010 }
01011 else
01012 {
01013 x_max = i_x;
01014 x_min = r_x;
01015 }
01016
01017 set_complex_format (x_max, x_min, r_x, inf_or_nan, int_only, r_fw, i_fw);
01018 }
01019
01020 static inline void
01021 set_format (const Complex& c)
01022 {
01023 int r_fw, i_fw;
01024 set_format (c, r_fw, i_fw);
01025 }
01026
01027 static void
01028 set_complex_matrix_format (int x_max, int x_min, int r_x_max,
01029 int r_x_min, bool inf_or_nan,
01030 int int_or_inf_or_nan, int& r_fw, int& i_fw)
01031 {
01032 static float_format r_fmt;
01033 static float_format i_fmt;
01034
01035 int prec = Voutput_precision;
01036
01037 int ld, rd;
01038
01039 if (rat_format)
01040 {
01041 i_fw = 9;
01042 r_fw = 9;
01043 rd = 0;
01044 }
01045 else if (bank_format)
01046 {
01047 int digits = r_x_max > r_x_min ? r_x_max : r_x_min;
01048 i_fw = 0;
01049 r_fw = digits <= 0 ? 4 : digits + 3;
01050 if (inf_or_nan && r_fw < 4)
01051 r_fw = 4;
01052 rd = 2;
01053 }
01054 else if (hex_format)
01055 {
01056 r_fw = 2 * sizeof (double);
01057 i_fw = 2 * sizeof (double);
01058 rd = 0;
01059 }
01060 else if (bit_format)
01061 {
01062 r_fw = 8 * sizeof (double);
01063 i_fw = 8 * sizeof (double);
01064 rd = 0;
01065 }
01066 else if (Vfixed_point_format && ! print_g)
01067 {
01068 rd = prec;
01069 i_fw = rd + 1;
01070 r_fw = i_fw + 1;
01071 if (inf_or_nan && i_fw < 3)
01072 {
01073 i_fw = 3;
01074 r_fw = 4;
01075 }
01076 }
01077 else if (int_or_inf_or_nan)
01078 {
01079 int digits = x_max > x_min ? x_max : x_min;
01080 i_fw = digits <= 0 ? 1 : digits;
01081 r_fw = i_fw + 1;
01082 if (inf_or_nan && i_fw < 3)
01083 {
01084 i_fw = 3;
01085 r_fw = 4;
01086 }
01087 rd = r_fw;
01088 }
01089 else
01090 {
01091 int ld_max, rd_max;
01092 if (x_max > 0)
01093 {
01094 ld_max = x_max;
01095 rd_max = prec > x_max ? prec - x_max : prec;
01096 x_max++;
01097 }
01098 else
01099 {
01100 ld_max = 1;
01101 rd_max = prec > x_max ? prec - x_max : prec;
01102 x_max = -x_max + 1;
01103 }
01104
01105 int ld_min, rd_min;
01106 if (x_min > 0)
01107 {
01108 ld_min = x_min;
01109 rd_min = prec > x_min ? prec - x_min : prec;
01110 x_min++;
01111 }
01112 else
01113 {
01114 ld_min = 1;
01115 rd_min = prec > x_min ? prec - x_min : prec;
01116 x_min = -x_min + 1;
01117 }
01118
01119 ld = ld_max > ld_min ? ld_max : ld_min;
01120 rd = rd_max > rd_min ? rd_max : rd_min;
01121
01122 i_fw = ld + 1 + rd;
01123 r_fw = i_fw + 1;
01124 if (inf_or_nan && i_fw < 3)
01125 {
01126 i_fw = 3;
01127 r_fw = 4;
01128 }
01129 }
01130
01131 if (! (rat_format || bank_format || hex_format || bit_format)
01132 && (print_e
01133 || print_eng || print_g
01134 || (! Vfixed_point_format && r_fw > Voutput_max_field_width)))
01135 {
01136 if (print_g)
01137 {
01138 r_fmt = float_format ();
01139 i_fmt = float_format ();
01140 }
01141 else
01142 {
01143 int ex = 4;
01144 if (x_max > 100 || x_min > 100)
01145 ex++;
01146
01147 if (print_eng)
01148 {
01149 i_fw = 3 + prec + ex;
01150 r_fw = i_fw + 1;
01151 if (inf_or_nan && i_fw < 5)
01152 {
01153 i_fw = 5;
01154 r_fw = 6;
01155 }
01156 r_fmt = float_format (r_fw, ex, prec - 1, std::ios::fixed);
01157 i_fmt = float_format (i_fw, ex, prec - 1, std::ios::fixed);
01158 }
01159 else
01160 {
01161 i_fw = 1 + prec + ex;
01162 r_fw = i_fw + 1;
01163 if (inf_or_nan && i_fw < 3)
01164 {
01165 i_fw = 3;
01166 r_fw = 4;
01167 }
01168 r_fmt = float_format (r_fw, prec - 1, std::ios::scientific);
01169 i_fmt = float_format (i_fw, prec - 1, std::ios::scientific);
01170 }
01171 }
01172
01173 if (print_big_e)
01174 {
01175 r_fmt.uppercase ();
01176 i_fmt.uppercase ();
01177 }
01178 }
01179 else if (! bank_format && int_or_inf_or_nan)
01180 {
01181 r_fmt = float_format (r_fw, rd);
01182 i_fmt = float_format (i_fw, rd);
01183 }
01184 else
01185 {
01186 r_fmt = float_format (r_fw, rd, std::ios::fixed);
01187 i_fmt = float_format (i_fw, rd, std::ios::fixed);
01188 }
01189
01190 curr_real_fmt = &r_fmt;
01191 curr_imag_fmt = &i_fmt;
01192 }
01193
01194 static void
01195 set_format (const ComplexMatrix& cm, int& r_fw, int& i_fw, double& scale)
01196 {
01197 curr_real_fmt = 0;
01198 curr_imag_fmt = 0;
01199
01200 if (free_format)
01201 return;
01202
01203 Matrix rp = real (cm);
01204 Matrix ip = imag (cm);
01205
01206 bool inf_or_nan = cm.any_element_is_inf_or_nan ();
01207
01208 bool int_or_inf_or_nan = (rp.all_elements_are_int_or_inf_or_nan ()
01209 && ip.all_elements_are_int_or_inf_or_nan ());
01210
01211 Matrix r_m_abs = rp.abs ();
01212 double r_max_abs = pr_max_internal (r_m_abs);
01213 double r_min_abs = pr_min_internal (r_m_abs);
01214
01215 Matrix i_m_abs = ip.abs ();
01216 double i_max_abs = pr_max_internal (i_m_abs);
01217 double i_min_abs = pr_min_internal (i_m_abs);
01218
01219 int r_x_max = r_max_abs == 0.0 ? 0 : num_digits (r_max_abs);
01220
01221 int r_x_min = r_min_abs == 0.0 ? 0 : num_digits (r_min_abs);
01222
01223 int i_x_max = i_max_abs == 0.0 ? 0 : num_digits (i_max_abs);
01224
01225 int i_x_min = i_min_abs == 0.0 ? 0 : num_digits (i_min_abs);
01226
01227 int x_max = r_x_max > i_x_max ? r_x_max : i_x_max;
01228 int x_min = r_x_min > i_x_min ? r_x_min : i_x_min;
01229
01230 scale = (x_max == 0 || int_or_inf_or_nan) ? 1.0
01231 : std::pow (10.0, calc_scale_exp (x_max - 1));
01232
01233 set_complex_matrix_format (x_max, x_min, r_x_max, r_x_min, inf_or_nan,
01234 int_or_inf_or_nan, r_fw, i_fw);
01235 }
01236
01237 static inline void
01238 set_format (const ComplexMatrix& cm)
01239 {
01240 int r_fw, i_fw;
01241 double scale;
01242 set_format (cm, r_fw, i_fw, scale);
01243 }
01244
01245 static void
01246 set_range_format (int x_max, int x_min, int all_ints, int& fw)
01247 {
01248 static float_format fmt;
01249
01250 int prec = Voutput_precision;
01251
01252 int ld, rd;
01253
01254 if (rat_format)
01255 {
01256 fw = 9;
01257 rd = 0;
01258 }
01259 else if (bank_format)
01260 {
01261 int digits = x_max > x_min ? x_max : x_min;
01262 fw = digits < 0 ? 5 : digits + 4;
01263 rd = 2;
01264 }
01265 else if (hex_format)
01266 {
01267 fw = 2 * sizeof (double);
01268 rd = 0;
01269 }
01270 else if (bit_format)
01271 {
01272 fw = 8 * sizeof (double);
01273 rd = 0;
01274 }
01275 else if (all_ints)
01276 {
01277 int digits = x_max > x_min ? x_max : x_min;
01278 fw = digits + 1;
01279 rd = fw;
01280 }
01281 else if (Vfixed_point_format && ! print_g)
01282 {
01283 rd = prec;
01284 fw = rd + 3;
01285 }
01286 else
01287 {
01288 int ld_max, rd_max;
01289 if (x_max > 0)
01290 {
01291 ld_max = x_max;
01292 rd_max = prec > x_max ? prec - x_max : prec;
01293 x_max++;
01294 }
01295 else
01296 {
01297 ld_max = 1;
01298 rd_max = prec > x_max ? prec - x_max : prec;
01299 x_max = -x_max + 1;
01300 }
01301
01302 int ld_min, rd_min;
01303 if (x_min > 0)
01304 {
01305 ld_min = x_min;
01306 rd_min = prec > x_min ? prec - x_min : prec;
01307 x_min++;
01308 }
01309 else
01310 {
01311 ld_min = 1;
01312 rd_min = prec > x_min ? prec - x_min : prec;
01313 x_min = -x_min + 1;
01314 }
01315
01316 ld = ld_max > ld_min ? ld_max : ld_min;
01317 rd = rd_max > rd_min ? rd_max : rd_min;
01318
01319 fw = ld + rd + 3;
01320 }
01321
01322 if (! (rat_format || bank_format || hex_format || bit_format)
01323 && (print_e
01324 || print_eng || print_g
01325 || (! Vfixed_point_format && fw > Voutput_max_field_width)))
01326 {
01327 if (print_g)
01328 fmt = float_format ();
01329 else
01330 {
01331 int ex = 4;
01332 if (x_max > 100 || x_min > 100)
01333 ex++;
01334
01335 if (print_eng)
01336 {
01337 fw = 5 + prec + ex;
01338 fmt = float_format (fw, ex, prec - 1, std::ios::fixed);
01339 }
01340 else
01341 {
01342 fw = 3 + prec + ex;
01343 fmt = float_format (fw, prec - 1, std::ios::scientific);
01344 }
01345 }
01346
01347 if (print_big_e)
01348 fmt.uppercase ();
01349 }
01350 else if (! bank_format && all_ints)
01351 fmt = float_format (fw, rd);
01352 else
01353 fmt = float_format (fw, rd, std::ios::fixed);
01354
01355 curr_real_fmt = &fmt;
01356 }
01357
01358 static void
01359 set_format (const Range& r, int& fw, double& scale)
01360 {
01361 curr_real_fmt = 0;
01362 curr_imag_fmt = 0;
01363
01364 if (free_format)
01365 return;
01366
01367 double r_min = r.base ();
01368 double r_max = r.limit ();
01369
01370 if (r_max < r_min)
01371 {
01372 double tmp = r_max;
01373 r_max = r_min;
01374 r_min = tmp;
01375 }
01376
01377 bool all_ints = r.all_elements_are_ints ();
01378
01379 double max_abs = r_max < 0.0 ? -r_max : r_max;
01380 double min_abs = r_min < 0.0 ? -r_min : r_min;
01381
01382 int x_max = max_abs == 0.0 ? 0 : num_digits (max_abs);
01383
01384 int x_min = min_abs == 0.0 ? 0 : num_digits (min_abs);
01385
01386 scale = (x_max == 0 || all_ints) ? 1.0
01387 : std::pow (10.0, calc_scale_exp (x_max - 1));
01388
01389 set_range_format (x_max, x_min, all_ints, fw);
01390 }
01391
01392 static inline void
01393 set_format (const Range& r)
01394 {
01395 int fw;
01396 double scale;
01397 set_format (r, fw, scale);
01398 }
01399
01400 union equiv
01401 {
01402 double d;
01403 unsigned char i[sizeof (double)];
01404 };
01405
01406 #define PRINT_CHAR_BITS(os, c) \
01407 do \
01408 { \
01409 unsigned char ctmp = c; \
01410 char stmp[9]; \
01411 stmp[0] = (ctmp & 0x80) ? '1' : '0'; \
01412 stmp[1] = (ctmp & 0x40) ? '1' : '0'; \
01413 stmp[2] = (ctmp & 0x20) ? '1' : '0'; \
01414 stmp[3] = (ctmp & 0x10) ? '1' : '0'; \
01415 stmp[4] = (ctmp & 0x08) ? '1' : '0'; \
01416 stmp[5] = (ctmp & 0x04) ? '1' : '0'; \
01417 stmp[6] = (ctmp & 0x02) ? '1' : '0'; \
01418 stmp[7] = (ctmp & 0x01) ? '1' : '0'; \
01419 stmp[8] = '\0'; \
01420 os << stmp; \
01421 } \
01422 while (0)
01423
01424 #define PRINT_CHAR_BITS_SWAPPED(os, c) \
01425 do \
01426 { \
01427 unsigned char ctmp = c; \
01428 char stmp[9]; \
01429 stmp[0] = (ctmp & 0x01) ? '1' : '0'; \
01430 stmp[1] = (ctmp & 0x02) ? '1' : '0'; \
01431 stmp[2] = (ctmp & 0x04) ? '1' : '0'; \
01432 stmp[3] = (ctmp & 0x08) ? '1' : '0'; \
01433 stmp[4] = (ctmp & 0x10) ? '1' : '0'; \
01434 stmp[5] = (ctmp & 0x20) ? '1' : '0'; \
01435 stmp[6] = (ctmp & 0x40) ? '1' : '0'; \
01436 stmp[7] = (ctmp & 0x80) ? '1' : '0'; \
01437 stmp[8] = '\0'; \
01438 os << stmp; \
01439 } \
01440 while (0)
01441
01442 static void
01443 pr_any_float (const float_format *fmt, std::ostream& os, double d, int fw = 0)
01444 {
01445 if (fmt)
01446 {
01447
01448
01449
01450
01451
01452
01453 if (hex_format)
01454 {
01455 equiv tmp;
01456 tmp.d = d;
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468 oct_mach_info::float_format flt_fmt =
01469 oct_mach_info::native_float_format ();
01470
01471 char ofill = os.fill ('0');
01472
01473 std::ios::fmtflags oflags
01474 = os.flags (std::ios::right | std::ios::hex);
01475
01476 if (hex_format > 1
01477 || flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian
01478 || flt_fmt == oct_mach_info::flt_fmt_cray
01479 || flt_fmt == oct_mach_info::flt_fmt_unknown)
01480 {
01481 for (size_t i = 0; i < sizeof (double); i++)
01482 os << std::setw (2) << static_cast<int> (tmp.i[i]);
01483 }
01484 else
01485 {
01486 for (int i = sizeof (double) - 1; i >= 0; i--)
01487 os << std::setw (2) << static_cast<int> (tmp.i[i]);
01488 }
01489
01490 os.fill (ofill);
01491 os.setf (oflags);
01492 }
01493 else if (bit_format)
01494 {
01495 equiv tmp;
01496 tmp.d = d;
01497
01498
01499
01500
01501 oct_mach_info::float_format flt_fmt =
01502 oct_mach_info::native_float_format ();
01503
01504 if (flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian
01505 || flt_fmt == oct_mach_info::flt_fmt_cray
01506 || flt_fmt == oct_mach_info::flt_fmt_unknown)
01507 {
01508 for (size_t i = 0; i < sizeof (double); i++)
01509 PRINT_CHAR_BITS (os, tmp.i[i]);
01510 }
01511 else
01512 {
01513 if (bit_format > 1)
01514 {
01515 for (size_t i = 0; i < sizeof (double); i++)
01516 PRINT_CHAR_BITS_SWAPPED (os, tmp.i[i]);
01517 }
01518 else
01519 {
01520 for (int i = sizeof (double) - 1; i >= 0; i--)
01521 PRINT_CHAR_BITS (os, tmp.i[i]);
01522 }
01523 }
01524 }
01525 else if (octave_is_NA (d))
01526 {
01527 if (fw > 0)
01528 os << std::setw (fw) << "NA";
01529 else
01530 os << "NA";
01531 }
01532 else if (rat_format)
01533 os << pr_rational_float (*fmt, d);
01534 else if (xisinf (d))
01535 {
01536 const char *s;
01537 if (d < 0.0)
01538 s = "-Inf";
01539 else
01540 s = "Inf";
01541
01542 if (fw > 0)
01543 os << std::setw (fw) << s;
01544 else
01545 os << s;
01546 }
01547 else if (xisnan (d))
01548 {
01549 if (fw > 0)
01550 os << std::setw (fw) << "NaN";
01551 else
01552 os << "NaN";
01553 }
01554 else if (print_eng)
01555 os << pr_engineering_float (*fmt, d);
01556 else
01557 os << pr_formatted_float (*fmt, d);
01558 }
01559 else
01560 os << d;
01561 }
01562
01563 static inline void
01564 pr_float (std::ostream& os, double d, int fw = 0, double scale = 1.0)
01565 {
01566 if (Vfixed_point_format && ! print_g && scale != 1.0)
01567 d /= scale;
01568
01569 pr_any_float (curr_real_fmt, os, d, fw);
01570 }
01571
01572 static inline void
01573 pr_imag_float (std::ostream& os, double d, int fw = 0)
01574 {
01575 pr_any_float (curr_imag_fmt, os, d, fw);
01576 }
01577
01578 static void
01579 pr_complex (std::ostream& os, const Complex& c, int r_fw = 0,
01580 int i_fw = 0, double scale = 1.0)
01581 {
01582 Complex tmp
01583 = (Vfixed_point_format && ! print_g && scale != 1.0) ? c / scale : c;
01584
01585 double r = tmp.real ();
01586
01587 pr_float (os, r, r_fw);
01588
01589 if (! bank_format)
01590 {
01591 double i = tmp.imag ();
01592 if (! (hex_format || bit_format) && lo_ieee_signbit (i))
01593 {
01594 os << " - ";
01595 i = -i;
01596 pr_imag_float (os, i, i_fw);
01597 }
01598 else
01599 {
01600 if (hex_format || bit_format)
01601 os << " ";
01602 else
01603 os << " + ";
01604
01605 pr_imag_float (os, i, i_fw);
01606 }
01607 os << "i";
01608 }
01609 }
01610
01611 static void
01612 print_empty_matrix (std::ostream& os, octave_idx_type nr, octave_idx_type nc, bool pr_as_read_syntax)
01613 {
01614 assert (nr == 0 || nc == 0);
01615
01616 if (pr_as_read_syntax)
01617 {
01618 if (nr == 0 && nc == 0)
01619 os << "[]";
01620 else
01621 os << "zeros (" << nr << ", " << nc << ")";
01622 }
01623 else
01624 {
01625 os << "[]";
01626
01627 if (Vprint_empty_dimensions)
01628 os << "(" << nr << "x" << nc << ")";
01629 }
01630 }
01631
01632 static void
01633 print_empty_nd_array (std::ostream& os, const dim_vector& dims,
01634 bool pr_as_read_syntax)
01635 {
01636 assert (dims.any_zero ());
01637
01638 if (pr_as_read_syntax)
01639 os << "zeros (" << dims.str (',') << ")";
01640 else
01641 {
01642 os << "[]";
01643
01644 if (Vprint_empty_dimensions)
01645 os << "(" << dims.str () << ")";
01646 }
01647 }
01648
01649 static void
01650 pr_scale_header (std::ostream& os, double scale)
01651 {
01652 if (Vfixed_point_format && ! print_g && scale != 1.0)
01653 {
01654 os << " "
01655 << std::setw (8) << std::setprecision (1)
01656 << std::setiosflags (std::ios::scientific|std::ios::left)
01657 << scale
01658 << std::resetiosflags (std::ios::scientific|std::ios::left)
01659 << " *\n";
01660
01661 if (! Vcompact_format)
01662 os << "\n";
01663 }
01664 }
01665
01666 static void
01667 pr_col_num_header (std::ostream& os, octave_idx_type total_width, int max_width,
01668 octave_idx_type lim, octave_idx_type col, int extra_indent)
01669 {
01670 if (total_width > max_width && Vsplit_long_rows)
01671 {
01672 if (col != 0)
01673 {
01674 if (Vcompact_format)
01675 os << "\n";
01676 else
01677 os << "\n\n";
01678 }
01679
01680 octave_idx_type num_cols = lim - col;
01681
01682 os << std::setw (extra_indent) << "";
01683
01684 if (num_cols == 1)
01685 os << " Column " << col + 1 << ":\n";
01686 else if (num_cols == 2)
01687 os << " Columns " << col + 1 << " and " << lim << ":\n";
01688 else
01689 os << " Columns " << col + 1 << " through " << lim << ":\n";
01690
01691 if (! Vcompact_format)
01692 os << "\n";
01693 }
01694 }
01695
01696 template <class T>
01697 inline void
01698 pr_plus_format (std::ostream& os, const T& val)
01699 {
01700 if (val > T (0))
01701 os << plus_format_chars[0];
01702 else if (val < T (0))
01703 os << plus_format_chars[1];
01704 else
01705 os << plus_format_chars[2];
01706 }
01707
01708 void
01709 octave_print_internal (std::ostream& os, double d,
01710 bool )
01711 {
01712 if (plus_format)
01713 {
01714 pr_plus_format (os, d);
01715 }
01716 else
01717 {
01718 set_format (d);
01719 if (free_format)
01720 os << d;
01721 else
01722 pr_float (os, d);
01723 }
01724 }
01725
01726 void
01727 octave_print_internal (std::ostream& os, const Matrix& m,
01728 bool pr_as_read_syntax, int extra_indent)
01729 {
01730 octave_idx_type nr = m.rows ();
01731 octave_idx_type nc = m.columns ();
01732
01733 if (nr == 0 || nc == 0)
01734 print_empty_matrix (os, nr, nc, pr_as_read_syntax);
01735 else if (plus_format && ! pr_as_read_syntax)
01736 {
01737 for (octave_idx_type i = 0; i < nr; i++)
01738 {
01739 for (octave_idx_type j = 0; j < nc; j++)
01740 {
01741 octave_quit ();
01742
01743 pr_plus_format (os, m(i,j));
01744 }
01745
01746 if (i < nr - 1)
01747 os << "\n";
01748 }
01749 }
01750 else
01751 {
01752 int fw;
01753 double scale = 1.0;
01754 set_format (m, fw, scale);
01755 int column_width = fw + 2;
01756 octave_idx_type total_width = nc * column_width;
01757 octave_idx_type max_width = command_editor::terminal_cols ();
01758
01759 if (pr_as_read_syntax)
01760 max_width -= 4;
01761 else
01762 max_width -= extra_indent;
01763
01764 if (max_width < 0)
01765 max_width = 0;
01766
01767 if (free_format)
01768 {
01769 if (pr_as_read_syntax)
01770 os << "[\n";
01771
01772 os << m;
01773
01774 if (pr_as_read_syntax)
01775 os << "]";
01776
01777 return;
01778 }
01779
01780 octave_idx_type inc = nc;
01781 if (total_width > max_width && Vsplit_long_rows)
01782 {
01783 inc = max_width / column_width;
01784 if (inc == 0)
01785 inc++;
01786 }
01787
01788 if (pr_as_read_syntax)
01789 {
01790 for (octave_idx_type i = 0; i < nr; i++)
01791 {
01792 octave_idx_type col = 0;
01793 while (col < nc)
01794 {
01795 octave_idx_type lim = col + inc < nc ? col + inc : nc;
01796
01797 for (octave_idx_type j = col; j < lim; j++)
01798 {
01799 octave_quit ();
01800
01801 if (i == 0 && j == 0)
01802 os << "[ ";
01803 else
01804 {
01805 if (j > col && j < lim)
01806 os << ", ";
01807 else
01808 os << " ";
01809 }
01810
01811 pr_float (os, m(i,j));
01812 }
01813
01814 col += inc;
01815
01816 if (col >= nc)
01817 {
01818 if (i == nr - 1)
01819 os << " ]";
01820 else
01821 os << ";\n";
01822 }
01823 else
01824 os << " ...\n";
01825 }
01826 }
01827 }
01828 else
01829 {
01830 pr_scale_header (os, scale);
01831
01832 for (octave_idx_type col = 0; col < nc; col += inc)
01833 {
01834 octave_idx_type lim = col + inc < nc ? col + inc : nc;
01835
01836 pr_col_num_header (os, total_width, max_width, lim, col,
01837 extra_indent);
01838
01839 for (octave_idx_type i = 0; i < nr; i++)
01840 {
01841 os << std::setw (extra_indent) << "";
01842
01843 for (octave_idx_type j = col; j < lim; j++)
01844 {
01845 octave_quit ();
01846
01847 os << " ";
01848
01849 pr_float (os, m(i,j), fw, scale);
01850 }
01851
01852 if (i < nr - 1)
01853 os << "\n";
01854 }
01855 }
01856 }
01857 }
01858 }
01859
01860 void
01861 octave_print_internal (std::ostream& os, const DiagMatrix& m,
01862 bool pr_as_read_syntax, int extra_indent)
01863 {
01864 octave_idx_type nr = m.rows ();
01865 octave_idx_type nc = m.columns ();
01866
01867 if (nr == 0 || nc == 0)
01868 print_empty_matrix (os, nr, nc, pr_as_read_syntax);
01869 else if (plus_format && ! pr_as_read_syntax)
01870 {
01871 for (octave_idx_type i = 0; i < nr; i++)
01872 {
01873 for (octave_idx_type j = 0; j < nc; j++)
01874 {
01875 octave_quit ();
01876
01877 pr_plus_format (os, m(i,j));
01878 }
01879
01880 if (i < nr - 1)
01881 os << "\n";
01882 }
01883 }
01884 else
01885 {
01886 int fw;
01887 double scale = 1.0;
01888 set_format (Matrix (m.diag ()), fw, scale);
01889 int column_width = fw + 2;
01890 octave_idx_type total_width = nc * column_width;
01891 octave_idx_type max_width = command_editor::terminal_cols ();
01892
01893 if (pr_as_read_syntax)
01894 max_width -= 4;
01895 else
01896 max_width -= extra_indent;
01897
01898 if (max_width < 0)
01899 max_width = 0;
01900
01901 if (free_format)
01902 {
01903 if (pr_as_read_syntax)
01904 os << "[\n";
01905
01906 os << Matrix (m);
01907
01908 if (pr_as_read_syntax)
01909 os << "]";
01910
01911 return;
01912 }
01913
01914 octave_idx_type inc = nc;
01915 if (total_width > max_width && Vsplit_long_rows)
01916 {
01917 inc = max_width / column_width;
01918 if (inc == 0)
01919 inc++;
01920 }
01921
01922 if (pr_as_read_syntax)
01923 {
01924 os << "diag (";
01925
01926 octave_idx_type col = 0;
01927 while (col < nc)
01928 {
01929 octave_idx_type lim = col + inc < nc ? col + inc : nc;
01930
01931 for (octave_idx_type j = col; j < lim; j++)
01932 {
01933 octave_quit ();
01934
01935 if (j == 0)
01936 os << "[ ";
01937 else
01938 {
01939 if (j > col && j < lim)
01940 os << ", ";
01941 else
01942 os << " ";
01943 }
01944
01945 pr_float (os, m(j,j));
01946 }
01947
01948 col += inc;
01949
01950 if (col >= nc)
01951 os << " ]";
01952 else
01953 os << " ...\n";
01954 }
01955 os << ")";
01956 }
01957 else
01958 {
01959 os << "Diagonal Matrix\n";
01960 if (! Vcompact_format)
01961 os << "\n";
01962
01963 pr_scale_header (os, scale);
01964
01965
01966 int zero_fw;
01967
01968 {
01969 std::ostringstream tmp_oss;
01970 pr_float (tmp_oss, 0.0, fw, scale);
01971 zero_fw = tmp_oss.str ().length ();
01972 }
01973
01974 for (octave_idx_type col = 0; col < nc; col += inc)
01975 {
01976 octave_idx_type lim = col + inc < nc ? col + inc : nc;
01977
01978 pr_col_num_header (os, total_width, max_width, lim, col,
01979 extra_indent);
01980
01981 for (octave_idx_type i = 0; i < nr; i++)
01982 {
01983 os << std::setw (extra_indent) << "";
01984
01985 for (octave_idx_type j = col; j < lim; j++)
01986 {
01987 octave_quit ();
01988
01989 os << " ";
01990
01991 if (i == j)
01992 pr_float (os, m(i,j), fw, scale);
01993 else
01994 os << std::setw (zero_fw) << '0';
01995
01996 }
01997
01998 if (i < nr - 1)
01999 os << "\n";
02000 }
02001 }
02002 }
02003 }
02004 }
02005
02006 template <typename NDA_T, typename ELT_T, typename MAT_T>
02007 void print_nd_array(std::ostream& os, const NDA_T& nda,
02008 bool pr_as_read_syntax)
02009 {
02010
02011 if (nda.is_empty ())
02012 print_empty_nd_array (os, nda.dims (), pr_as_read_syntax);
02013 else
02014 {
02015
02016 int ndims = nda.ndims ();
02017
02018 dim_vector dims = nda.dims ();
02019
02020 Array<octave_idx_type> ra_idx (dim_vector (ndims, 1), 0);
02021
02022 octave_idx_type m = 1;
02023
02024 for (int i = 2; i < ndims; i++)
02025 m *= dims(i);
02026
02027 octave_idx_type nr = dims(0);
02028 octave_idx_type nc = dims(1);
02029
02030 for (octave_idx_type i = 0; i < m; i++)
02031 {
02032 octave_quit ();
02033
02034 std::string nm = "ans";
02035
02036 if (m > 1)
02037 {
02038 nm += "(:,:,";
02039
02040 std::ostringstream buf;
02041
02042 for (int k = 2; k < ndims; k++)
02043 {
02044 buf << ra_idx(k) + 1;
02045
02046 if (k < ndims - 1)
02047 buf << ",";
02048 else
02049 buf << ")";
02050 }
02051
02052 nm += buf.str ();
02053 }
02054
02055 Array<idx_vector> idx (dim_vector (ndims, 1));
02056
02057 idx(0) = idx_vector (':');
02058 idx(1) = idx_vector (':');
02059
02060 for (int k = 2; k < ndims; k++)
02061 idx(k) = idx_vector (ra_idx(k));
02062
02063 octave_value page
02064 = MAT_T (Array<ELT_T> (nda.index (idx), dim_vector (nr, nc)));
02065
02066 if (i != m - 1)
02067 {
02068 page.print_with_name (os, nm);
02069 }
02070 else
02071 {
02072 page.print_name_tag (os, nm);
02073 page.print_raw (os);
02074 }
02075
02076 if (i < m)
02077 NDA_T::increment_index (ra_idx, dims, 2);
02078 }
02079 }
02080 }
02081
02082 void
02083 octave_print_internal (std::ostream& os, const NDArray& nda,
02084 bool pr_as_read_syntax, int extra_indent)
02085 {
02086 switch (nda.ndims ())
02087 {
02088 case 1:
02089 case 2:
02090 octave_print_internal (os, nda.matrix_value (),
02091 pr_as_read_syntax, extra_indent);
02092 break;
02093
02094 default:
02095 print_nd_array <NDArray, double, Matrix> (os, nda, pr_as_read_syntax);
02096 break;
02097 }
02098 }
02099
02100 template <>
02101 inline void
02102 pr_plus_format<> (std::ostream& os, const Complex& c)
02103 {
02104 double rp = c.real ();
02105 double ip = c.imag ();
02106
02107 if (rp == 0.0)
02108 {
02109 if (ip == 0.0)
02110 os << " ";
02111 else
02112 os << "i";
02113 }
02114 else if (ip == 0.0)
02115 pr_plus_format (os, rp);
02116 else
02117 os << "c";
02118 }
02119
02120 void
02121 octave_print_internal (std::ostream& os, const Complex& c,
02122 bool )
02123 {
02124 if (plus_format)
02125 {
02126 pr_plus_format (os, c);
02127 }
02128 else
02129 {
02130 set_format (c);
02131 if (free_format)
02132 os << c;
02133 else
02134 pr_complex (os, c);
02135 }
02136 }
02137
02138 void
02139 octave_print_internal (std::ostream& os, const ComplexMatrix& cm,
02140 bool pr_as_read_syntax, int extra_indent)
02141 {
02142 octave_idx_type nr = cm.rows ();
02143 octave_idx_type nc = cm.columns ();
02144
02145 if (nr == 0 || nc == 0)
02146 print_empty_matrix (os, nr, nc, pr_as_read_syntax);
02147 else if (plus_format && ! pr_as_read_syntax)
02148 {
02149 for (octave_idx_type i = 0; i < nr; i++)
02150 {
02151 for (octave_idx_type j = 0; j < nc; j++)
02152 {
02153 octave_quit ();
02154
02155 pr_plus_format (os, cm(i,j));
02156 }
02157
02158 if (i < nr - 1)
02159 os << "\n";
02160 }
02161 }
02162 else
02163 {
02164 int r_fw, i_fw;
02165 double scale = 1.0;
02166 set_format (cm, r_fw, i_fw, scale);
02167 int column_width = i_fw + r_fw;
02168 column_width += (rat_format || bank_format || hex_format
02169 || bit_format) ? 2 : 7;
02170 octave_idx_type total_width = nc * column_width;
02171 octave_idx_type max_width = command_editor::terminal_cols ();
02172
02173 if (pr_as_read_syntax)
02174 max_width -= 4;
02175 else
02176 max_width -= extra_indent;
02177
02178 if (max_width < 0)
02179 max_width = 0;
02180
02181 if (free_format)
02182 {
02183 if (pr_as_read_syntax)
02184 os << "[\n";
02185
02186 os << cm;
02187
02188 if (pr_as_read_syntax)
02189 os << "]";
02190
02191 return;
02192 }
02193
02194 octave_idx_type inc = nc;
02195 if (total_width > max_width && Vsplit_long_rows)
02196 {
02197 inc = max_width / column_width;
02198 if (inc == 0)
02199 inc++;
02200 }
02201
02202 if (pr_as_read_syntax)
02203 {
02204 for (octave_idx_type i = 0; i < nr; i++)
02205 {
02206 octave_idx_type col = 0;
02207 while (col < nc)
02208 {
02209 octave_idx_type lim = col + inc < nc ? col + inc : nc;
02210
02211 for (octave_idx_type j = col; j < lim; j++)
02212 {
02213 octave_quit ();
02214
02215 if (i == 0 && j == 0)
02216 os << "[ ";
02217 else
02218 {
02219 if (j > col && j < lim)
02220 os << ", ";
02221 else
02222 os << " ";
02223 }
02224
02225 pr_complex (os, cm(i,j));
02226 }
02227
02228 col += inc;
02229
02230 if (col >= nc)
02231 {
02232 if (i == nr - 1)
02233 os << " ]";
02234 else
02235 os << ";\n";
02236 }
02237 else
02238 os << " ...\n";
02239 }
02240 }
02241 }
02242 else
02243 {
02244 pr_scale_header (os, scale);
02245
02246 for (octave_idx_type col = 0; col < nc; col += inc)
02247 {
02248 octave_idx_type lim = col + inc < nc ? col + inc : nc;
02249
02250 pr_col_num_header (os, total_width, max_width, lim, col,
02251 extra_indent);
02252
02253 for (octave_idx_type i = 0; i < nr; i++)
02254 {
02255 os << std::setw (extra_indent) << "";
02256
02257 for (octave_idx_type j = col; j < lim; j++)
02258 {
02259 octave_quit ();
02260
02261 os << " ";
02262
02263 pr_complex (os, cm(i,j), r_fw, i_fw, scale);
02264 }
02265
02266 if (i < nr - 1)
02267 os << "\n";
02268 }
02269 }
02270 }
02271 }
02272 }
02273
02274 void
02275 octave_print_internal (std::ostream& os, const ComplexDiagMatrix& cm,
02276 bool pr_as_read_syntax, int extra_indent)
02277 {
02278 octave_idx_type nr = cm.rows ();
02279 octave_idx_type nc = cm.columns ();
02280
02281 if (nr == 0 || nc == 0)
02282 print_empty_matrix (os, nr, nc, pr_as_read_syntax);
02283 else if (plus_format && ! pr_as_read_syntax)
02284 {
02285 for (octave_idx_type i = 0; i < nr; i++)
02286 {
02287 for (octave_idx_type j = 0; j < nc; j++)
02288 {
02289 octave_quit ();
02290
02291 pr_plus_format (os, cm(i,j));
02292 }
02293
02294 if (i < nr - 1)
02295 os << "\n";
02296 }
02297 }
02298 else
02299 {
02300 int r_fw, i_fw;
02301 double scale = 1.0;
02302 set_format (ComplexMatrix (cm.diag ()), r_fw, i_fw, scale);
02303 int column_width = i_fw + r_fw;
02304 column_width += (rat_format || bank_format || hex_format
02305 || bit_format) ? 2 : 7;
02306 octave_idx_type total_width = nc * column_width;
02307 octave_idx_type max_width = command_editor::terminal_cols ();
02308
02309 if (pr_as_read_syntax)
02310 max_width -= 4;
02311 else
02312 max_width -= extra_indent;
02313
02314 if (max_width < 0)
02315 max_width = 0;
02316
02317 if (free_format)
02318 {
02319 if (pr_as_read_syntax)
02320 os << "[\n";
02321
02322 os << ComplexMatrix (cm);
02323
02324 if (pr_as_read_syntax)
02325 os << "]";
02326
02327 return;
02328 }
02329
02330 octave_idx_type inc = nc;
02331 if (total_width > max_width && Vsplit_long_rows)
02332 {
02333 inc = max_width / column_width;
02334 if (inc == 0)
02335 inc++;
02336 }
02337
02338 if (pr_as_read_syntax)
02339 {
02340 os << "diag (";
02341
02342 octave_idx_type col = 0;
02343 while (col < nc)
02344 {
02345 octave_idx_type lim = col + inc < nc ? col + inc : nc;
02346
02347 for (octave_idx_type j = col; j < lim; j++)
02348 {
02349 octave_quit ();
02350
02351 if (j == 0)
02352 os << "[ ";
02353 else
02354 {
02355 if (j > col && j < lim)
02356 os << ", ";
02357 else
02358 os << " ";
02359 }
02360
02361 pr_complex (os, cm(j,j));
02362 }
02363
02364 col += inc;
02365
02366 if (col >= nc)
02367 os << " ]";
02368 else
02369 os << " ...\n";
02370 }
02371 os << ")";
02372 }
02373 else
02374 {
02375 os << "Diagonal Matrix\n";
02376 if (! Vcompact_format)
02377 os << "\n";
02378
02379 pr_scale_header (os, scale);
02380
02381
02382 int zero_fw;
02383
02384 {
02385 std::ostringstream tmp_oss;
02386 pr_complex (tmp_oss, Complex (0.0), r_fw, i_fw, scale);
02387 zero_fw = tmp_oss.str ().length ();
02388 }
02389
02390 for (octave_idx_type col = 0; col < nc; col += inc)
02391 {
02392 octave_idx_type lim = col + inc < nc ? col + inc : nc;
02393
02394 pr_col_num_header (os, total_width, max_width, lim, col,
02395 extra_indent);
02396
02397 for (octave_idx_type i = 0; i < nr; i++)
02398 {
02399 os << std::setw (extra_indent) << "";
02400
02401 for (octave_idx_type j = col; j < lim; j++)
02402 {
02403 octave_quit ();
02404
02405 os << " ";
02406
02407 if (i == j)
02408 pr_complex (os, cm(i,j), r_fw, i_fw, scale);
02409 else
02410 os << std::setw (zero_fw) << '0';
02411 }
02412
02413 if (i < nr - 1)
02414 os << "\n";
02415 }
02416 }
02417 }
02418 }
02419 }
02420
02421 void
02422 octave_print_internal (std::ostream& os, const PermMatrix& m,
02423 bool pr_as_read_syntax, int extra_indent)
02424 {
02425 octave_idx_type nr = m.rows ();
02426 octave_idx_type nc = m.columns ();
02427
02428 if (nr == 0 || nc == 0)
02429 print_empty_matrix (os, nr, nc, pr_as_read_syntax);
02430 else if (plus_format && ! pr_as_read_syntax)
02431 {
02432 for (octave_idx_type i = 0; i < nr; i++)
02433 {
02434 for (octave_idx_type j = 0; j < nc; j++)
02435 {
02436 octave_quit ();
02437
02438 pr_plus_format (os, m(i,j));
02439 }
02440
02441 if (i < nr - 1)
02442 os << "\n";
02443 }
02444 }
02445 else
02446 {
02447 int fw = 2;
02448 int column_width = fw + 2;
02449 octave_idx_type total_width = nc * column_width;
02450 octave_idx_type max_width = command_editor::terminal_cols ();
02451
02452 if (pr_as_read_syntax)
02453 max_width -= 4;
02454 else
02455 max_width -= extra_indent;
02456
02457 if (max_width < 0)
02458 max_width = 0;
02459
02460 if (free_format)
02461 {
02462 if (pr_as_read_syntax)
02463 os << "[\n";
02464
02465 os << Matrix (m);
02466
02467 if (pr_as_read_syntax)
02468 os << "]";
02469
02470 return;
02471 }
02472
02473 octave_idx_type inc = nc;
02474 if (total_width > max_width && Vsplit_long_rows)
02475 {
02476 inc = max_width / column_width;
02477 if (inc == 0)
02478 inc++;
02479 }
02480
02481 if (pr_as_read_syntax)
02482 {
02483 Array<octave_idx_type> pvec = m.pvec ();
02484 bool colp = m.is_col_perm ();
02485
02486 os << "eye (";
02487 if (colp) os << ":, ";
02488
02489 octave_idx_type col = 0;
02490 while (col < nc)
02491 {
02492 octave_idx_type lim = col + inc < nc ? col + inc : nc;
02493
02494 for (octave_idx_type j = col; j < lim; j++)
02495 {
02496 octave_quit ();
02497
02498 if (j == 0)
02499 os << "[ ";
02500 else
02501 {
02502 if (j > col && j < lim)
02503 os << ", ";
02504 else
02505 os << " ";
02506 }
02507
02508 os << pvec (j);
02509 }
02510
02511 col += inc;
02512
02513 if (col >= nc)
02514 os << " ]";
02515 else
02516 os << " ...\n";
02517 }
02518 if (! colp) os << ", :";
02519 os << ")";
02520 }
02521 else
02522 {
02523 os << "Permutation Matrix\n";
02524 if (! Vcompact_format)
02525 os << "\n";
02526
02527 for (octave_idx_type col = 0; col < nc; col += inc)
02528 {
02529 octave_idx_type lim = col + inc < nc ? col + inc : nc;
02530
02531 pr_col_num_header (os, total_width, max_width, lim, col,
02532 extra_indent);
02533
02534 for (octave_idx_type i = 0; i < nr; i++)
02535 {
02536 os << std::setw (extra_indent) << "";
02537
02538 for (octave_idx_type j = col; j < lim; j++)
02539 {
02540 octave_quit ();
02541
02542 os << " ";
02543
02544 os << std::setw (fw) << m(i,j);
02545 }
02546
02547 if (i < nr - 1)
02548 os << "\n";
02549 }
02550 }
02551 }
02552 }
02553 }
02554
02555 void
02556 octave_print_internal (std::ostream& os, const ComplexNDArray& nda,
02557 bool pr_as_read_syntax, int extra_indent)
02558 {
02559 switch (nda.ndims ())
02560 {
02561 case 1:
02562 case 2:
02563 octave_print_internal (os, nda.matrix_value (),
02564 pr_as_read_syntax, extra_indent);
02565 break;
02566
02567 default:
02568 print_nd_array <ComplexNDArray, Complex,
02569 ComplexMatrix> (os, nda, pr_as_read_syntax);
02570 break;
02571 }
02572 }
02573
02574 void
02575 octave_print_internal (std::ostream& os, bool d, bool pr_as_read_syntax)
02576 {
02577 octave_print_internal (os, double (d), pr_as_read_syntax);
02578 }
02579
02580
02581
02582 void
02583 octave_print_internal (std::ostream& os, float d, bool pr_as_read_syntax)
02584 {
02585 octave_print_internal (os, double (d), pr_as_read_syntax);
02586 }
02587
02588 void
02589 octave_print_internal (std::ostream& os, const FloatMatrix& m,
02590 bool pr_as_read_syntax, int extra_indent)
02591 {
02592 octave_print_internal (os, Matrix (m), pr_as_read_syntax, extra_indent);
02593 }
02594
02595 void
02596 octave_print_internal (std::ostream& os, const FloatDiagMatrix& m,
02597 bool pr_as_read_syntax, int extra_indent)
02598 {
02599 octave_print_internal (os, DiagMatrix (m), pr_as_read_syntax, extra_indent);
02600 }
02601
02602 void
02603 octave_print_internal (std::ostream& os, const FloatNDArray& nda,
02604 bool pr_as_read_syntax, int extra_indent)
02605 {
02606 octave_print_internal (os, NDArray (nda), pr_as_read_syntax, extra_indent);
02607 }
02608
02609 void
02610 octave_print_internal (std::ostream& os, const FloatComplex& c,
02611 bool pr_as_read_syntax)
02612 {
02613 octave_print_internal (os, Complex (c), pr_as_read_syntax);
02614 }
02615
02616 void
02617 octave_print_internal (std::ostream& os, const FloatComplexMatrix& cm,
02618 bool pr_as_read_syntax, int extra_indent)
02619 {
02620 octave_print_internal (os, ComplexMatrix (cm), pr_as_read_syntax, extra_indent);
02621 }
02622
02623 void
02624 octave_print_internal (std::ostream& os, const FloatComplexDiagMatrix& cm,
02625 bool pr_as_read_syntax, int extra_indent)
02626 {
02627 octave_print_internal (os, ComplexDiagMatrix (cm), pr_as_read_syntax, extra_indent);
02628 }
02629
02630 void
02631 octave_print_internal (std::ostream& os, const FloatComplexNDArray& nda,
02632 bool pr_as_read_syntax, int extra_indent)
02633 {
02634 octave_print_internal (os, ComplexNDArray (nda), pr_as_read_syntax, extra_indent);
02635 }
02636
02637 void
02638 octave_print_internal (std::ostream& os, const Range& r,
02639 bool pr_as_read_syntax, int extra_indent)
02640 {
02641 double base = r.base ();
02642 double increment = r.inc ();
02643 double limit = r.limit ();
02644 octave_idx_type num_elem = r.nelem ();
02645
02646 if (plus_format && ! pr_as_read_syntax)
02647 {
02648 for (octave_idx_type i = 0; i < num_elem; i++)
02649 {
02650 octave_quit ();
02651
02652 double val = base + i * increment;
02653
02654 pr_plus_format (os, val);
02655 }
02656 }
02657 else
02658 {
02659 int fw = 0;
02660 double scale = 1.0;
02661 set_format (r, fw, scale);
02662
02663 if (pr_as_read_syntax)
02664 {
02665 if (free_format)
02666 {
02667 os << base << " : ";
02668 if (increment != 1.0)
02669 os << increment << " : ";
02670 os << limit;
02671 }
02672 else
02673 {
02674 pr_float (os, base, fw);
02675 os << " : ";
02676 if (increment != 1.0)
02677 {
02678 pr_float (os, increment, fw);
02679 os << " : ";
02680 }
02681 pr_float (os, limit, fw);
02682 }
02683 }
02684 else
02685 {
02686 int column_width = fw + 2;
02687 octave_idx_type total_width = num_elem * column_width;
02688 octave_idx_type max_width = command_editor::terminal_cols ();
02689
02690 if (free_format)
02691 {
02692 os << r;
02693 return;
02694 }
02695
02696 octave_idx_type inc = num_elem;
02697 if (total_width > max_width && Vsplit_long_rows)
02698 {
02699 inc = max_width / column_width;
02700 if (inc == 0)
02701 inc++;
02702 }
02703
02704 max_width -= extra_indent;
02705
02706 if (max_width < 0)
02707 max_width = 0;
02708
02709 pr_scale_header (os, scale);
02710
02711 octave_idx_type col = 0;
02712 while (col < num_elem)
02713 {
02714 octave_idx_type lim = col + inc < num_elem ? col + inc : num_elem;
02715
02716 pr_col_num_header (os, total_width, max_width, lim, col,
02717 extra_indent);
02718
02719 os << std::setw (extra_indent) << "";
02720
02721 for (octave_idx_type i = col; i < lim; i++)
02722 {
02723 octave_quit ();
02724
02725 double val = base + i * increment;
02726
02727 if (i == num_elem - 1)
02728 {
02729
02730
02731 if ((increment > 0 && val > limit)
02732 || (increment < 0 && val < limit))
02733 val = limit;
02734 }
02735
02736 os << " ";
02737
02738 pr_float (os, val, fw, scale);
02739 }
02740
02741 col += inc;
02742 }
02743 }
02744 }
02745 }
02746
02747 void
02748 octave_print_internal (std::ostream& os, const boolMatrix& bm,
02749 bool pr_as_read_syntax,
02750 int extra_indent)
02751 {
02752 Matrix tmp (bm);
02753 octave_print_internal (os, tmp, pr_as_read_syntax, extra_indent);
02754 }
02755
02756 void
02757 octave_print_internal (std::ostream& os, const boolNDArray& nda,
02758 bool pr_as_read_syntax,
02759 int extra_indent)
02760 {
02761 switch (nda.ndims ())
02762 {
02763 case 1:
02764 case 2:
02765 octave_print_internal (os, nda.matrix_value (),
02766 pr_as_read_syntax, extra_indent);
02767 break;
02768
02769 default:
02770 print_nd_array<boolNDArray, bool,
02771 boolMatrix> (os, nda, pr_as_read_syntax);
02772 break;
02773 }
02774 }
02775
02776 void
02777 octave_print_internal (std::ostream& os, const charMatrix& chm,
02778 bool pr_as_read_syntax,
02779 int ,
02780 bool pr_as_string)
02781 {
02782 if (pr_as_string)
02783 {
02784 octave_idx_type nstr = chm.rows ();
02785
02786 if (pr_as_read_syntax && nstr > 1)
02787 os << "[ ";
02788
02789 if (nstr != 0)
02790 {
02791 for (octave_idx_type i = 0; i < nstr; i++)
02792 {
02793 octave_quit ();
02794
02795 std::string row = chm.row_as_string (i);
02796
02797 if (pr_as_read_syntax)
02798 {
02799 os << "\"" << undo_string_escapes (row) << "\"";
02800
02801 if (i < nstr - 1)
02802 os << "; ";
02803 }
02804 else
02805 {
02806 os << row;
02807
02808 if (i < nstr - 1)
02809 os << "\n";
02810 }
02811 }
02812 }
02813
02814 if (pr_as_read_syntax && nstr > 1)
02815 os << " ]";
02816 }
02817 else
02818 {
02819 os << "sorry, printing char matrices not implemented yet\n";
02820 }
02821 }
02822
02823 void
02824 octave_print_internal (std::ostream& os, const charNDArray& nda,
02825 bool pr_as_read_syntax, int extra_indent,
02826 bool pr_as_string)
02827 {
02828 switch (nda.ndims ())
02829 {
02830 case 1:
02831 case 2:
02832 octave_print_internal (os, nda.matrix_value (),
02833 pr_as_read_syntax, extra_indent, pr_as_string);
02834 break;
02835
02836 default:
02837 print_nd_array <charNDArray, char,
02838 charMatrix> (os, nda, pr_as_read_syntax);
02839 break;
02840 }
02841 }
02842
02843 void
02844 octave_print_internal (std::ostream& os, const std::string& s,
02845 bool pr_as_read_syntax, int extra_indent)
02846 {
02847 Array<std::string> nda (dim_vector (1, 1), s);
02848
02849 octave_print_internal (os, nda, pr_as_read_syntax, extra_indent);
02850 }
02851
02852 void
02853 octave_print_internal (std::ostream& os, const Array<std::string>& nda,
02854 bool pr_as_read_syntax, int )
02855 {
02856
02857
02858
02859 if (nda.is_empty ())
02860 print_empty_nd_array (os, nda.dims (), pr_as_read_syntax);
02861 else if (nda.length () == 1)
02862 {
02863 os << nda(0);
02864 }
02865 else
02866 {
02867 int ndims = nda.ndims ();
02868
02869 dim_vector dims = nda.dims ();
02870
02871 Array<octave_idx_type> ra_idx (dim_vector (ndims, 1), 0);
02872
02873 octave_idx_type m = 1;
02874
02875 for (int i = 2; i < ndims; i++)
02876 m *= dims(i);
02877
02878 octave_idx_type nr = dims(0);
02879 octave_idx_type nc = dims(1);
02880
02881 for (octave_idx_type i = 0; i < m; i++)
02882 {
02883 std::string nm = "ans";
02884
02885 if (m > 1)
02886 {
02887 nm += "(:,:,";
02888
02889 std::ostringstream buf;
02890
02891 for (int k = 2; k < ndims; k++)
02892 {
02893 buf << ra_idx(k) + 1;
02894
02895 if (k < ndims - 1)
02896 buf << ",";
02897 else
02898 buf << ")";
02899 }
02900
02901 nm += buf.str ();
02902 }
02903
02904 Array<idx_vector> idx (dim_vector (ndims, 1));
02905
02906 idx(0) = idx_vector (':');
02907 idx(1) = idx_vector (':');
02908
02909 for (int k = 2; k < ndims; k++)
02910 idx(k) = idx_vector (ra_idx(k));
02911
02912 Array<std::string> page (nda.index (idx), dim_vector (nr, nc));
02913
02914
02915
02916
02917 octave_idx_type n_rows = page.rows ();
02918 octave_idx_type n_cols = page.cols ();
02919
02920 os << nm << " =\n";
02921 if (! Vcompact_format)
02922 os << "\n";
02923
02924 for (octave_idx_type ii = 0; ii < n_rows; ii++)
02925 {
02926 for (octave_idx_type jj = 0; jj < n_cols; jj++)
02927 os << " " << page(ii,jj);
02928
02929 os << "\n";
02930 }
02931
02932 if (i < m - 1)
02933 os << "\n";
02934
02935 if (i < m)
02936 increment_index (ra_idx, dims, 2);
02937 }
02938 }
02939 }
02940
02941 template <class T>
02942 class
02943 octave_print_conv
02944 {
02945 public:
02946 typedef T print_conv_type;
02947 };
02948
02949 #define PRINT_CONV(T1, T2) \
02950 template <> \
02951 class \
02952 octave_print_conv<T1> \
02953 { \
02954 public: \
02955 typedef T2 print_conv_type; \
02956 }
02957
02958 PRINT_CONV (octave_int8, octave_int16);
02959 PRINT_CONV (octave_uint8, octave_uint16);
02960
02961 #undef PRINT_CONV
02962
02963 template <class T>
02964 inline void
02965 pr_int (std::ostream& os, const T& d, int fw = 0)
02966 {
02967 size_t sz = d.byte_size();
02968 const unsigned char * tmpi = d.iptr();
02969
02970
02971
02972
02973
02974
02975
02976 if (hex_format)
02977 {
02978 char ofill = os.fill ('0');
02979
02980 std::ios::fmtflags oflags
02981 = os.flags (std::ios::right | std::ios::hex);
02982
02983 if (hex_format > 1 || oct_mach_info::words_big_endian ())
02984 {
02985 for (size_t i = 0; i < sz; i++)
02986 os << std::setw (2) << static_cast<int> (tmpi[i]);
02987 }
02988 else
02989 {
02990 for (int i = sz - 1; i >= 0; i--)
02991 os << std::setw (2) << static_cast<int> (tmpi[i]);
02992 }
02993
02994 os.fill (ofill);
02995 os.setf (oflags);
02996 }
02997 else if (bit_format)
02998 {
02999 if (oct_mach_info::words_big_endian ())
03000 {
03001 for (size_t i = 0; i < sz; i++)
03002 PRINT_CHAR_BITS (os, tmpi[i]);
03003 }
03004 else
03005 {
03006 if (bit_format > 1)
03007 {
03008 for (size_t i = 0; i < sz; i++)
03009 PRINT_CHAR_BITS_SWAPPED (os, tmpi[i]);
03010 }
03011 else
03012 {
03013 for (int i = sz - 1; i >= 0; i--)
03014 PRINT_CHAR_BITS (os, tmpi[i]);
03015 }
03016 }
03017 }
03018 else
03019 {
03020 os << std::setw (fw)
03021 << typename octave_print_conv<T>::print_conv_type (d);
03022
03023 if (bank_format)
03024 os << ".00";
03025 }
03026 }
03027
03028
03029
03030
03031
03032
03033
03034 template <class T>
03035 inline T
03036 abs (T x)
03037 {
03038 return x < 0 ? -x : x;
03039 }
03040
03041 #define INSTANTIATE_ABS(T) \
03042 template T abs (T)
03043
03044 INSTANTIATE_ABS(signed char);
03045 INSTANTIATE_ABS(short);
03046 INSTANTIATE_ABS(int);
03047 INSTANTIATE_ABS(long);
03048 INSTANTIATE_ABS(long long);
03049
03050 #define SPECIALIZE_UABS(T) \
03051 template <> \
03052 inline unsigned T \
03053 abs (unsigned T x) \
03054 { \
03055 return x; \
03056 }
03057
03058 SPECIALIZE_UABS(char)
03059 SPECIALIZE_UABS(short)
03060 SPECIALIZE_UABS(int)
03061 SPECIALIZE_UABS(long)
03062 SPECIALIZE_UABS(long long)
03063
03064 template void
03065 pr_int (std::ostream&, const octave_int8&, int);
03066
03067 template void
03068 pr_int (std::ostream&, const octave_int16&, int);
03069
03070 template void
03071 pr_int (std::ostream&, const octave_int32&, int);
03072
03073 template void
03074 pr_int (std::ostream&, const octave_int64&, int);
03075
03076 template void
03077 pr_int (std::ostream&, const octave_uint8&, int);
03078
03079 template void
03080 pr_int (std::ostream&, const octave_uint16&, int);
03081
03082 template void
03083 pr_int (std::ostream&, const octave_uint32&, int);
03084
03085 template void
03086 pr_int (std::ostream&, const octave_uint64&, int);
03087
03088 template <class T>
03089 void
03090 octave_print_internal_template (std::ostream& os, const octave_int<T>& val,
03091 bool)
03092 {
03093 if (plus_format)
03094 {
03095 pr_plus_format (os, val);
03096 }
03097 else
03098 {
03099 if (free_format)
03100 os << typename octave_print_conv<octave_int<T> >::print_conv_type (val);
03101 else
03102 pr_int (os, val);
03103 }
03104 }
03105
03106 #define PRINT_INT_SCALAR_INTERNAL(TYPE) \
03107 OCTINTERP_API void \
03108 octave_print_internal (std::ostream& os, const octave_int<TYPE>& val, bool dummy) \
03109 { \
03110 octave_print_internal_template (os, val, dummy); \
03111 }
03112
03113 PRINT_INT_SCALAR_INTERNAL (int8_t)
03114 PRINT_INT_SCALAR_INTERNAL (uint8_t)
03115 PRINT_INT_SCALAR_INTERNAL (int16_t)
03116 PRINT_INT_SCALAR_INTERNAL (uint16_t)
03117 PRINT_INT_SCALAR_INTERNAL (int32_t)
03118 PRINT_INT_SCALAR_INTERNAL (uint32_t)
03119 PRINT_INT_SCALAR_INTERNAL (int64_t)
03120 PRINT_INT_SCALAR_INTERNAL (uint64_t)
03121
03122 template <class T>
03123 inline void
03124 octave_print_internal_template (std::ostream& os, const intNDArray<T>& nda,
03125 bool pr_as_read_syntax, int extra_indent)
03126 {
03127
03128
03129
03130 if (nda.is_empty ())
03131 print_empty_nd_array (os, nda.dims (), pr_as_read_syntax);
03132 else if (nda.length () == 1)
03133 octave_print_internal_template (os, nda(0), pr_as_read_syntax);
03134 else if (plus_format && ! pr_as_read_syntax)
03135 {
03136 int ndims = nda.ndims ();
03137
03138 Array<octave_idx_type> ra_idx (dim_vector (ndims, 1), 0);
03139
03140 dim_vector dims = nda.dims ();
03141
03142 octave_idx_type m = 1;
03143
03144 for (int i = 2; i < ndims; i++)
03145 m *= dims(i);
03146
03147 octave_idx_type nr = dims(0);
03148 octave_idx_type nc = dims(1);
03149
03150 for (octave_idx_type i = 0; i < m; i++)
03151 {
03152 if (m > 1)
03153 {
03154 std::string nm = "ans(:,:,";
03155
03156 std::ostringstream buf;
03157
03158 for (int k = 2; k < ndims; k++)
03159 {
03160 buf << ra_idx(k) + 1;
03161
03162 if (k < ndims - 1)
03163 buf << ",";
03164 else
03165 buf << ")";
03166 }
03167
03168 nm += buf.str ();
03169
03170 os << nm << " =\n";
03171 if (! Vcompact_format)
03172 os << "\n";
03173 }
03174
03175 Array<idx_vector> idx (dim_vector (ndims, 1));
03176
03177 idx(0) = idx_vector (':');
03178 idx(1) = idx_vector (':');
03179
03180 for (int k = 2; k < ndims; k++)
03181 idx(k) = idx_vector (ra_idx(k));
03182
03183 Array<T> page (nda.index (idx), dim_vector (nr, nc));
03184
03185 for (octave_idx_type ii = 0; ii < nr; ii++)
03186 {
03187 for (octave_idx_type jj = 0; jj < nc; jj++)
03188 {
03189 octave_quit ();
03190
03191 pr_plus_format (os, page(ii,jj));
03192 }
03193
03194 if ((ii < nr - 1) || (i < m -1))
03195 os << "\n";
03196 }
03197
03198 if (i < m - 1)
03199 {
03200 os << "\n";
03201 increment_index (ra_idx, dims, 2);
03202 }
03203 }
03204 }
03205 else
03206 {
03207 int ndims = nda.ndims ();
03208
03209 dim_vector dims = nda.dims ();
03210
03211 Array<octave_idx_type> ra_idx (dim_vector (ndims, 1), 0);
03212
03213 octave_idx_type m = 1;
03214
03215 for (int i = 2; i < ndims; i++)
03216 m *= dims(i);
03217
03218 octave_idx_type nr = dims(0);
03219 octave_idx_type nc = dims(1);
03220
03221 int fw = 0;
03222 if (hex_format)
03223 fw = 2 * nda(0).byte_size ();
03224 else if (bit_format)
03225 fw = nda(0).nbits ();
03226 else
03227 {
03228 bool isneg = false;
03229 int digits = 0;
03230
03231 for (octave_idx_type i = 0; i < dims.numel (); i++)
03232 {
03233 int new_digits = static_cast<int>
03234 (gnulib::floor (log10 (double (abs (nda(i).value ()))) + 1.0));
03235
03236 if (new_digits > digits)
03237 digits = new_digits;
03238
03239 if (! isneg)
03240 isneg = (abs (nda(i).value ()) != nda(i).value ());
03241 }
03242
03243 fw = digits + isneg;
03244 }
03245
03246 int column_width = fw + (rat_format ? 0 : (bank_format ? 5 : 2));
03247 octave_idx_type total_width = nc * column_width;
03248 int max_width = command_editor::terminal_cols () - extra_indent;
03249 octave_idx_type inc = nc;
03250 if (total_width > max_width && Vsplit_long_rows)
03251 {
03252 inc = max_width / column_width;
03253 if (inc == 0)
03254 inc++;
03255 }
03256
03257 for (octave_idx_type i = 0; i < m; i++)
03258 {
03259 if (m > 1)
03260 {
03261 std::string nm = "ans(:,:,";
03262
03263 std::ostringstream buf;
03264
03265 for (int k = 2; k < ndims; k++)
03266 {
03267 buf << ra_idx(k) + 1;
03268
03269 if (k < ndims - 1)
03270 buf << ",";
03271 else
03272 buf << ")";
03273 }
03274
03275 nm += buf.str ();
03276
03277 os << nm << " =\n";
03278 if (! Vcompact_format)
03279 os << "\n";
03280 }
03281
03282 Array<idx_vector> idx (dim_vector (ndims, 1));
03283
03284 idx(0) = idx_vector (':');
03285 idx(1) = idx_vector (':');
03286
03287 for (int k = 2; k < ndims; k++)
03288 idx(k) = idx_vector (ra_idx(k));
03289
03290 Array<T> page (nda.index (idx), dim_vector (nr, nc));
03291
03292 if (free_format)
03293 {
03294 if (pr_as_read_syntax)
03295 os << "[\n";
03296
03297 for (octave_idx_type ii = 0; ii < nr; ii++)
03298 {
03299 for (octave_idx_type jj = 0; jj < nc; jj++)
03300 {
03301 octave_quit ();
03302 os << " ";
03303 os << typename octave_print_conv<T>::print_conv_type (page(ii,jj));
03304 }
03305 os << "\n";
03306 }
03307
03308 if (pr_as_read_syntax)
03309 os << "]";
03310 }
03311 else
03312 {
03313 octave_idx_type n_rows = page.rows ();
03314 octave_idx_type n_cols = page.cols ();
03315
03316 for (octave_idx_type col = 0; col < n_cols; col += inc)
03317 {
03318 octave_idx_type lim = col + inc < n_cols ? col + inc : n_cols;
03319
03320 pr_col_num_header (os, total_width, max_width, lim, col,
03321 extra_indent);
03322
03323 for (octave_idx_type ii = 0; ii < n_rows; ii++)
03324 {
03325 os << std::setw (extra_indent) << "";
03326
03327 for (octave_idx_type jj = col; jj < lim; jj++)
03328 {
03329 octave_quit ();
03330 os << " ";
03331 pr_int (os, page(ii,jj), fw);
03332 }
03333 if ((ii < n_rows - 1) || (i < m -1))
03334 os << "\n";
03335 }
03336 }
03337 }
03338
03339 if (i < m - 1)
03340 {
03341 os << "\n";
03342 increment_index (ra_idx, dims, 2);
03343 }
03344 }
03345 }
03346 }
03347
03348 #define PRINT_INT_ARRAY_INTERNAL(TYPE) \
03349 OCTINTERP_API void \
03350 octave_print_internal (std::ostream& os, const intNDArray<TYPE>& nda, \
03351 bool pr_as_read_syntax, int extra_indent) \
03352 { \
03353 octave_print_internal_template (os, nda, pr_as_read_syntax, extra_indent); \
03354 }
03355
03356 PRINT_INT_ARRAY_INTERNAL (octave_int8)
03357 PRINT_INT_ARRAY_INTERNAL (octave_uint8)
03358 PRINT_INT_ARRAY_INTERNAL (octave_int16)
03359 PRINT_INT_ARRAY_INTERNAL (octave_uint16)
03360 PRINT_INT_ARRAY_INTERNAL (octave_int32)
03361 PRINT_INT_ARRAY_INTERNAL (octave_uint32)
03362 PRINT_INT_ARRAY_INTERNAL (octave_int64)
03363 PRINT_INT_ARRAY_INTERNAL (octave_uint64)
03364
03365 void
03366 octave_print_internal (std::ostream&, const Cell&, bool, int, bool)
03367 {
03368 panic_impossible ();
03369 }
03370
03371 DEFUN (rats, args, nargout,
03372 "-*- texinfo -*-\n\
03373 @deftypefn {Built-in Function} {} rats (@var{x}, @var{len})\n\
03374 Convert @var{x} into a rational approximation represented as a string.\n\
03375 You can convert the string back into a matrix as follows:\n\
03376 \n\
03377 @example\n\
03378 @group\n\
03379 r = rats(hilb(4));\n\
03380 x = str2num(r)\n\
03381 @end group\n\
03382 @end example\n\
03383 \n\
03384 The optional second argument defines the maximum length of the string\n\
03385 representing the elements of @var{x}. By default @var{len} is 9.\n\
03386 @seealso{format, rat}\n\
03387 @end deftypefn")
03388 {
03389 octave_value retval;
03390
03391 int nargin = args.length ();
03392
03393 if (nargin < 1 || nargin > 2 || nargout > 1)
03394 print_usage ();
03395 else
03396 {
03397 unwind_protect frame;
03398
03399 frame.protect_var (rat_string_len);
03400
03401 rat_string_len = 9;
03402
03403 if (nargin == 2)
03404 rat_string_len = args(1).nint_value ();
03405
03406 if (! error_state)
03407 {
03408 octave_value arg = args(0);
03409
03410 if (arg.is_numeric_type ())
03411 {
03412 frame.protect_var (rat_format);
03413
03414 rat_format = true;
03415
03416 std::ostringstream buf;
03417 args(0).print (buf);
03418 std::string s = buf.str ();
03419
03420 std::list<std::string> lst;
03421
03422 size_t n = 0;
03423 size_t s_len = s.length ();
03424
03425 while (n < s_len)
03426 {
03427 size_t m = s.find ('\n', n);
03428
03429 if (m == std::string::npos)
03430 {
03431 lst.push_back (s.substr (n));
03432 break;
03433 }
03434 else
03435 {
03436 lst.push_back (s.substr (n, m - n));
03437 n = m + 1;
03438 }
03439 }
03440
03441 retval = string_vector (lst);
03442 }
03443 else
03444 error ("rats: X must be numeric");
03445 }
03446 }
03447
03448 return retval;
03449 }
03450
03451 DEFUN (disp, args, nargout,
03452 "-*- texinfo -*-\n\
03453 @deftypefn {Built-in Function} {} disp (@var{x})\n\
03454 Display the value of @var{x}. For example:\n\
03455 \n\
03456 @example\n\
03457 @group\n\
03458 disp (\"The value of pi is:\"), disp (pi)\n\
03459 \n\
03460 @print{} the value of pi is:\n\
03461 @print{} 3.1416\n\
03462 @end group\n\
03463 @end example\n\
03464 \n\
03465 @noindent\n\
03466 Note that the output from @code{disp} always ends with a newline.\n\
03467 \n\
03468 If an output value is requested, @code{disp} prints nothing and\n\
03469 returns the formatted output in a string.\n\
03470 @seealso{fdisp}\n\
03471 @end deftypefn")
03472 {
03473 octave_value_list retval;
03474
03475 int nargin = args.length ();
03476
03477 if (nargin == 1 && nargout < 2)
03478 {
03479 if (nargout == 0)
03480 args(0).print (octave_stdout);
03481 else
03482 {
03483 octave_value arg = args(0);
03484 std::ostringstream buf;
03485 arg.print (buf);
03486 retval = octave_value (buf.str (), arg.is_dq_string () ? '"' : '\'');
03487 }
03488 }
03489 else
03490 print_usage ();
03491
03492 return retval;
03493 }
03494
03495 DEFUN (fdisp, args, ,
03496 "-*- texinfo -*-\n\
03497 @deftypefn {Built-in Function} {} fdisp (@var{fid}, @var{x})\n\
03498 Display the value of @var{x} on the stream @var{fid}. For example:\n\
03499 \n\
03500 @example\n\
03501 @group\n\
03502 fdisp (stdout, \"The value of pi is:\"), fdisp (stdout, pi)\n\
03503 \n\
03504 @print{} the value of pi is:\n\
03505 @print{} 3.1416\n\
03506 @end group\n\
03507 @end example\n\
03508 \n\
03509 @noindent\n\
03510 Note that the output from @code{fdisp} always ends with a newline.\n\
03511 @seealso{disp}\n\
03512 @end deftypefn")
03513 {
03514 octave_value_list retval;
03515
03516 int nargin = args.length ();
03517
03518 if (nargin == 2)
03519 {
03520 int fid = octave_stream_list::get_file_number (args (0));
03521
03522 octave_stream os = octave_stream_list::lookup (fid, "fdisp");
03523
03524 if (! error_state)
03525 {
03526 std::ostream *osp = os.output_stream ();
03527
03528 if (osp)
03529 args(1).print (*osp);
03530 else
03531 error ("fdisp: stream FID not open for writing");
03532 }
03533 }
03534 else
03535 print_usage ();
03536
03537 return retval;
03538 }
03539
03540
03541
03542
03543
03544
03545
03546
03547
03548
03549
03550
03551
03552
03553
03554
03555
03556
03557
03558
03559
03560
03561
03562
03563
03564
03565
03566
03567 static void
03568 init_format_state (void)
03569 {
03570 free_format = false;
03571 plus_format = false;
03572 rat_format = false;
03573 bank_format = false;
03574 hex_format = 0;
03575 bit_format = 0;
03576 Vcompact_format = false;
03577 print_e = false;
03578 print_big_e = false;
03579 print_g = false;
03580 print_eng = false;
03581 }
03582
03583 static void
03584 set_output_prec_and_fw (int prec, int fw)
03585 {
03586 Voutput_precision = prec;
03587 Voutput_max_field_width = fw;
03588 }
03589
03590 static void
03591 set_format_style (int argc, const string_vector& argv)
03592 {
03593 int idx = 1;
03594
03595 if (--argc > 0)
03596 {
03597 std::string arg = argv[idx++];
03598
03599 if (arg == "short")
03600 {
03601 if (--argc > 0)
03602 {
03603 arg = argv[idx++];
03604
03605 if (arg == "e")
03606 {
03607 init_format_state ();
03608 print_e = true;
03609 }
03610 else if (arg == "E")
03611 {
03612 init_format_state ();
03613 print_e = true;
03614 print_big_e = true;
03615 }
03616 else if (arg == "g")
03617 {
03618 init_format_state ();
03619 print_g = true;
03620 }
03621 else if (arg == "G")
03622 {
03623 init_format_state ();
03624 print_g = true;
03625 print_big_e = true;
03626 }
03627 else if (arg == "eng")
03628 {
03629 init_format_state ();
03630 print_eng = true;
03631 }
03632 else
03633 {
03634 error ("format: unrecognized option 'short %s'",
03635 arg.c_str ());
03636 return;
03637 }
03638 }
03639 else
03640 init_format_state ();
03641
03642 set_output_prec_and_fw (5, 10);
03643 }
03644 else if (arg == "long")
03645 {
03646 if (--argc > 0)
03647 {
03648 arg = argv[idx++];
03649
03650 if (arg == "e")
03651 {
03652 init_format_state ();
03653 print_e = true;
03654 }
03655 else if (arg == "E")
03656 {
03657 init_format_state ();
03658 print_e = true;
03659 print_big_e = true;
03660 }
03661 else if (arg == "g")
03662 {
03663 init_format_state ();
03664 print_g = true;
03665 }
03666 else if (arg == "G")
03667 {
03668 init_format_state ();
03669 print_g = true;
03670 print_big_e = true;
03671 }
03672 else if (arg == "eng")
03673 {
03674 init_format_state ();
03675 print_eng = true;
03676 }
03677 else
03678 {
03679 error ("format: unrecognized option 'long %s'",
03680 arg.c_str ());
03681 return;
03682 }
03683 }
03684 else
03685 init_format_state ();
03686
03687 set_output_prec_and_fw (15, 20);
03688 }
03689 else if (arg == "hex")
03690 {
03691 init_format_state ();
03692 hex_format = 1;
03693 }
03694 else if (arg == "native-hex")
03695 {
03696 init_format_state ();
03697 hex_format = 2;
03698 }
03699 else if (arg == "bit")
03700 {
03701 init_format_state ();
03702 bit_format = 1;
03703 }
03704 else if (arg == "native-bit")
03705 {
03706 init_format_state ();
03707 bit_format = 2;
03708 }
03709 else if (arg == "+" || arg == "plus")
03710 {
03711 if (--argc > 0)
03712 {
03713 arg = argv[idx++];
03714
03715 if (arg.length () == 3)
03716 plus_format_chars = arg;
03717 else
03718 {
03719 error ("format: invalid option for plus format");
03720 return;
03721 }
03722 }
03723 else
03724 plus_format_chars = "+ ";
03725
03726 init_format_state ();
03727 plus_format = true;
03728 }
03729 else if (arg == "rat")
03730 {
03731 init_format_state ();
03732 rat_format = true;
03733 }
03734 else if (arg == "bank")
03735 {
03736 init_format_state ();
03737 bank_format = true;
03738 }
03739 else if (arg == "free")
03740 {
03741 init_format_state ();
03742 free_format = true;
03743 }
03744 else if (arg == "none")
03745 {
03746 init_format_state ();
03747 free_format = true;
03748 }
03749 else if (arg == "compact")
03750 {
03751 Vcompact_format = true;
03752 }
03753 else if (arg == "loose")
03754 {
03755 Vcompact_format = false;
03756 }
03757 else
03758 error ("format: unrecognized format state '%s'", arg.c_str ());
03759 }
03760 else
03761 {
03762 init_format_state ();
03763 set_output_prec_and_fw (5, 10);
03764 }
03765 }
03766
03767 DEFUN (format, args, ,
03768 "-*- texinfo -*-\n\
03769 @deftypefn {Command} {} format\n\
03770 @deftypefnx {Command} {} format options\n\
03771 Reset or specify the format of the output produced by @code{disp} and\n\
03772 Octave's normal echoing mechanism. This command only affects the display\n\
03773 of numbers but not how they are stored or computed. To change the internal\n\
03774 representation from the default double use one of the conversion functions\n\
03775 such as @code{single}, @code{uint8}, @code{int64}, etc.\n\
03776 \n\
03777 By default, Octave displays 5 significant digits in a human readable form\n\
03778 (option @samp{short} paired with @samp{loose} format for matrices).\n\
03779 If @code{format} is invoked without any options, this default format\n\
03780 is restored.\n\
03781 \n\
03782 Valid formats for floating point numbers are listed in the following\n\
03783 table.\n\
03784 \n\
03785 @table @code\n\
03786 @item short\n\
03787 Fixed point format with 5 significant figures in a field that is a maximum\n\
03788 of 10 characters wide. (default).\n\
03789 \n\
03790 If Octave is unable to format a matrix so that columns line up on the\n\
03791 decimal point and all numbers fit within the maximum field width then\n\
03792 it switches to an exponential @samp{e} format.\n\
03793 \n\
03794 @item long\n\
03795 Fixed point format with 15 significant figures in a field that is a maximum\n\
03796 of 20 characters wide.\n\
03797 \n\
03798 As with the @samp{short} format, Octave will switch to an exponential\n\
03799 @samp{e} format if it is unable to format a matrix properly using the\n\
03800 current format.\n\
03801 \n\
03802 @item short e\n\
03803 @itemx long e\n\
03804 Exponential format. The number to be represented is split between a mantissa\n\
03805 and an exponent (power of 10). The mantissa has 5 significant digits in the\n\
03806 short format and 15 digits in the long format.\n\
03807 For example, with the @samp{short e} format, @code{pi} is displayed as\n\
03808 @code{3.1416e+00}.\n\
03809 \n\
03810 @item short E\n\
03811 @itemx long E\n\
03812 Identical to @samp{short e} or @samp{long e} but displays an uppercase\n\
03813 @samp{E} to indicate the exponent.\n\
03814 For example, with the @samp{long E} format, @code{pi} is displayed as\n\
03815 @code{3.14159265358979E+00}.\n\
03816 \n\
03817 @item short g\n\
03818 @itemx long g\n\
03819 Optimally choose between fixed point and exponential format based on\n\
03820 the magnitude of the number.\n\
03821 For example, with the @samp{short g} format,\n\
03822 @code{pi .^ [2; 4; 8; 16; 32]} is displayed as\n\
03823 \n\
03824 @example\n\
03825 @group\n\
03826 ans =\n\
03827 \n\
03828 9.8696\n\
03829 97.409\n\
03830 9488.5\n\
03831 9.0032e+07\n\
03832 8.1058e+15\n\
03833 @end group\n\
03834 @end example\n\
03835 \n\
03836 @item short eng\n\
03837 @itemx long eng\n\
03838 Identical to @samp{short e} or @samp{long e} but displays the value\n\
03839 using an engineering format, where the exponent is divisible by 3. For\n\
03840 example, with the @samp{short eng} format, @code{10 * pi} is displayed as\n\
03841 @code{31.4159e+00}.\n\
03842 \n\
03843 @item long G\n\
03844 @itemx short G\n\
03845 Identical to @samp{short g} or @samp{long g} but displays an uppercase\n\
03846 @samp{E} to indicate the exponent.\n\
03847 \n\
03848 @item free\n\
03849 @itemx none\n\
03850 Print output in free format, without trying to line up columns of\n\
03851 matrices on the decimal point. This also causes complex numbers to be\n\
03852 formatted as numeric pairs like this @samp{(0.60419, 0.60709)} instead\n\
03853 of like this @samp{0.60419 + 0.60709i}.\n\
03854 @end table\n\
03855 \n\
03856 The following formats affect all numeric output (floating point and\n\
03857 integer types).\n\
03858 \n\
03859 @table @code\n\
03860 @item +\n\
03861 @itemx + @var{chars}\n\
03862 @itemx plus\n\
03863 @itemx plus @var{chars}\n\
03864 Print a @samp{+} symbol for nonzero matrix elements and a space for zero\n\
03865 matrix elements. This format can be very useful for examining the\n\
03866 structure of a large sparse matrix.\n\
03867 \n\
03868 The optional argument @var{chars} specifies a list of 3 characters to use\n\
03869 for printing values greater than zero, less than zero and equal to zero.\n\
03870 For example, with the @samp{+ \"+-.\"} format, @code{[1, 0, -1; -1, 0, 1]}\n\
03871 is displayed as\n\
03872 \n\
03873 @example\n\
03874 @group\n\
03875 ans =\n\
03876 \n\
03877 +.-\n\
03878 -.+\n\
03879 @end group\n\
03880 @end example\n\
03881 \n\
03882 @item bank\n\
03883 Print in a fixed format with two digits to the right of the decimal\n\
03884 point.\n\
03885 \n\
03886 @item native-hex\n\
03887 Print the hexadecimal representation of numbers as they are stored in\n\
03888 memory. For example, on a workstation which stores 8 byte real values\n\
03889 in IEEE format with the least significant byte first, the value of\n\
03890 @code{pi} when printed in @code{native-hex} format is\n\
03891 @code{400921fb54442d18}.\n\
03892 \n\
03893 @item hex\n\
03894 The same as @code{native-hex}, but always print the most significant\n\
03895 byte first.\n\
03896 \n\
03897 @item native-bit\n\
03898 Print the bit representation of numbers as stored in memory.\n\
03899 For example, the value of @code{pi} is\n\
03900 \n\
03901 @example\n\
03902 @group\n\
03903 01000000000010010010000111111011\n\
03904 01010100010001000010110100011000\n\
03905 @end group\n\
03906 @end example\n\
03907 \n\
03908 (shown here in two 32 bit sections for typesetting purposes) when\n\
03909 printed in native-bit format on a workstation which stores 8 byte real values\n\
03910 in IEEE format with the least significant byte first.\n\
03911 \n\
03912 @item bit\n\
03913 The same as @code{native-bit}, but always print the most significant\n\
03914 bits first.\n\
03915 \n\
03916 @item rat\n\
03917 Print a rational approximation, i.e., values are approximated\n\
03918 as the ratio of small integers.\n\
03919 For example, with the @samp{rat} format,\n\
03920 @code{pi} is displayed as @code{355/113}.\n\
03921 @end table\n\
03922 \n\
03923 The following two options affect the display of all matrices.\n\
03924 \n\
03925 @table @code\n\
03926 @item compact\n\
03927 Remove blank lines around column number labels and between\n\
03928 matrices producing more compact output with more data per page.\n\
03929 \n\
03930 @item loose\n\
03931 Insert blank lines above and below column number labels and between matrices\n\
03932 to produce a more readable output with less data per page. (default).\n\
03933 @end table\n\
03934 @seealso{fixed_point_format, output_max_field_width, output_precision, split_long_rows, rats}\n\
03935 @end deftypefn")
03936 {
03937 octave_value_list retval;
03938
03939 int argc = args.length () + 1;
03940
03941 string_vector argv = args.make_argv ("format");
03942
03943 if (error_state)
03944 return retval;
03945
03946 set_format_style (argc, argv);
03947
03948 return retval;
03949 }
03950
03951 DEFUN (fixed_point_format, args, nargout,
03952 "-*- texinfo -*-\n\
03953 @deftypefn {Built-in Function} {@var{val} =} fixed_point_format ()\n\
03954 @deftypefnx {Built-in Function} {@var{old_val} =} fixed_point_format (@var{new_val})\n\
03955 @deftypefnx {Built-in Function} {} fixed_point_format (@var{new_val}, \"local\")\n\
03956 Query or set the internal variable that controls whether Octave will\n\
03957 use a scaled format to print matrix values such that the largest\n\
03958 element may be written with a single leading digit with the scaling\n\
03959 factor is printed on the first line of output. For example:\n\
03960 \n\
03961 @example\n\
03962 @group\n\
03963 octave:1> logspace (1, 7, 5)'\n\
03964 ans =\n\
03965 \n\
03966 1.0e+07 *\n\
03967 \n\
03968 0.00000\n\
03969 0.00003\n\
03970 0.00100\n\
03971 0.03162\n\
03972 1.00000\n\
03973 @end group\n\
03974 @end example\n\
03975 \n\
03976 @noindent\n\
03977 Notice that first value appears to be zero when it is actually 1. For\n\
03978 this reason, you should be careful when setting\n\
03979 @code{fixed_point_format} to a nonzero value.\n\
03980 \n\
03981 When called from inside a function with the \"local\" option, the variable is\n\
03982 changed locally for the function and any subroutines it calls. The original\n\
03983 variable value is restored when exiting the function.\n\
03984 @seealso{format, output_max_field_width, output_precision}\n\
03985 @end deftypefn")
03986 {
03987 return SET_INTERNAL_VARIABLE (fixed_point_format);
03988 }
03989
03990 DEFUN (print_empty_dimensions, args, nargout,
03991 "-*- texinfo -*-\n\
03992 @deftypefn {Built-in Function} {@var{val} =} print_empty_dimensions ()\n\
03993 @deftypefnx {Built-in Function} {@var{old_val} =} print_empty_dimensions (@var{new_val})\n\
03994 @deftypefnx {Built-in Function} {} print_empty_dimensions (@var{new_val}, \"local\")\n\
03995 Query or set the internal variable that controls whether the\n\
03996 dimensions of empty matrices are printed along with the empty matrix\n\
03997 symbol, @samp{[]}. For example, the expression\n\
03998 \n\
03999 @example\n\
04000 zeros (3, 0)\n\
04001 @end example\n\
04002 \n\
04003 @noindent\n\
04004 will print\n\
04005 \n\
04006 @example\n\
04007 ans = [](3x0)\n\
04008 @end example\n\
04009 \n\
04010 When called from inside a function with the \"local\" option, the variable is\n\
04011 changed locally for the function and any subroutines it calls. The original\n\
04012 variable value is restored when exiting the function.\n\
04013 @seealso{format}\n\
04014 @end deftypefn")
04015 {
04016 return SET_INTERNAL_VARIABLE (print_empty_dimensions);
04017 }
04018
04019 DEFUN (split_long_rows, args, nargout,
04020 "-*- texinfo -*-\n\
04021 @deftypefn {Built-in Function} {@var{val} =} split_long_rows ()\n\
04022 @deftypefnx {Built-in Function} {@var{old_val} =} split_long_rows (@var{new_val})\n\
04023 @deftypefnx {Built-in Function} {} split_long_rows (@var{new_val}, \"local\")\n\
04024 Query or set the internal variable that controls whether rows of a matrix\n\
04025 may be split when displayed to a terminal window. If the rows are split,\n\
04026 Octave will display the matrix in a series of smaller pieces, each of\n\
04027 which can fit within the limits of your terminal width and each set of\n\
04028 rows is labeled so that you can easily see which columns are currently\n\
04029 being displayed. For example:\n\
04030 \n\
04031 @example\n\
04032 @group\n\
04033 octave:13> rand (2,10)\n\
04034 ans =\n\
04035 \n\
04036 Columns 1 through 6:\n\
04037 \n\
04038 0.75883 0.93290 0.40064 0.43818 0.94958 0.16467\n\
04039 0.75697 0.51942 0.40031 0.61784 0.92309 0.40201\n\
04040 \n\
04041 Columns 7 through 10:\n\
04042 \n\
04043 0.90174 0.11854 0.72313 0.73326\n\
04044 0.44672 0.94303 0.56564 0.82150\n\
04045 @end group\n\
04046 @end example\n\
04047 \n\
04048 When called from inside a function with the \"local\" option, the variable is\n\
04049 changed locally for the function and any subroutines it calls. The original\n\
04050 variable value is restored when exiting the function.\n\
04051 @seealso{format}\n\
04052 @end deftypefn")
04053 {
04054 return SET_INTERNAL_VARIABLE (split_long_rows);
04055 }
04056
04057 DEFUN (output_max_field_width, args, nargout,
04058 "-*- texinfo -*-\n\
04059 @deftypefn {Built-in Function} {@var{val} =} output_max_field_width ()\n\
04060 @deftypefnx {Built-in Function} {@var{old_val} =} output_max_field_width (@var{new_val})\n\
04061 @deftypefnx {Built-in Function} {} output_max_field_width (@var{new_val}, \"local\")\n\
04062 Query or set the internal variable that specifies the maximum width\n\
04063 of a numeric output field.\n\
04064 \n\
04065 When called from inside a function with the \"local\" option, the variable is\n\
04066 changed locally for the function and any subroutines it calls. The original\n\
04067 variable value is restored when exiting the function.\n\
04068 @seealso{format, fixed_point_format, output_precision}\n\
04069 @end deftypefn")
04070 {
04071 return SET_INTERNAL_VARIABLE_WITH_LIMITS (output_max_field_width, 0, INT_MAX);
04072 }
04073
04074 DEFUN (output_precision, args, nargout,
04075 "-*- texinfo -*-\n\
04076 @deftypefn {Built-in Function} {@var{val} =} output_precision ()\n\
04077 @deftypefnx {Built-in Function} {@var{old_val} =} output_precision (@var{new_val})\n\
04078 @deftypefnx {Built-in Function} {} output_precision (@var{new_val}, \"local\")\n\
04079 Query or set the internal variable that specifies the minimum number of\n\
04080 significant figures to display for numeric output.\n\
04081 \n\
04082 When called from inside a function with the \"local\" option, the variable is\n\
04083 changed locally for the function and any subroutines it calls. The original\n\
04084 variable value is restored when exiting the function.\n\
04085 @seealso{format, fixed_point_format, output_max_field_width}\n\
04086 @end deftypefn")
04087 {
04088 return SET_INTERNAL_VARIABLE_WITH_LIMITS (output_precision, -1, INT_MAX);
04089 }