GNU Octave  4.0.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
pt-mat.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1996-2015 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include <iostream>
28 
29 #include "oct-locbuf.h"
30 #include "quit.h"
31 
32 #include "data.h"
33 #include "defun.h"
34 #include "error.h"
35 #include "gripes.h"
36 #include "oct-obj.h"
37 #include "pt-arg-list.h"
38 #include "pt-bp.h"
39 #include "pt-exp.h"
40 #include "pt-mat.h"
41 #include "pt-walk.h"
42 #include "utils.h"
43 #include "ov.h"
44 #include "variables.h"
45 
46 #include "ov-cx-mat.h"
47 #include "ov-flt-cx-mat.h"
48 #include "ov-re-sparse.h"
49 #include "ov-cx-sparse.h"
50 
51 // The character to fill with when creating string arrays.
52 char Vstring_fill_char = ' ';
53 
54 // General matrices. This list type is much more work to handle than
55 // constant matrices, but it allows us to construct matrices from
56 // other matrices, variables, and functions.
57 
58 // But first, some internal classes that make our job much easier.
59 
60 class
62 {
63 private:
64 
65  class
67  {
68  public:
69 
71  : count (1), dv (0, 0), all_str (false),
72  all_sq_str (false), all_dq_str (false),
73  some_str (false), all_real (false), all_cmplx (false),
74  all_mt (true), any_cell (false), any_sparse (false),
75  any_class (false), all_1x1 (false),
76  first_elem_is_struct (false), class_nm (), ok (false)
77  { }
78 
80  : count (1), dv (0, 0), all_str (false), all_sq_str (false),
81  some_str (false), all_real (false), all_cmplx (false),
82  all_mt (true), any_cell (false), any_sparse (false),
83  any_class (false), all_1x1 (! row.empty ()),
84  first_elem_is_struct (false), class_nm (), ok (false)
85  { init (row); }
86 
87  ~tm_row_const_rep (void) { }
88 
90 
92 
93  bool all_str;
94  bool all_sq_str;
95  bool all_dq_str;
96  bool some_str;
97  bool all_real;
98  bool all_cmplx;
99  bool all_mt;
100  bool any_cell;
102  bool any_class;
103  bool all_1x1;
105 
106  std::string class_nm;
107 
108  bool ok;
109 
110  void do_init_element (const octave_value&, bool&);
111 
112  void init (const tree_argument_list&);
113 
114  void cellify (void);
115 
116  private:
117 
119 
120  tm_row_const_rep& operator = (const tm_row_const_rep&);
121 
122  };
123 
124 public:
125 
128 
130  : rep (0) { }
131 
133  : rep (new tm_row_const_rep (row)) { }
134 
136  : rep (x.rep)
137  {
138  if (rep)
139  rep->count++;
140  }
141 
142  tm_row_const& operator = (const tm_row_const& x)
143  {
144  if (this != &x && rep != x.rep)
145  {
146  if (rep && --rep->count == 0)
147  delete rep;
148 
149  rep = x.rep;
150 
151  if (rep)
152  rep->count++;
153  }
154 
155  return *this;
156  }
157 
159  {
160  if (rep && --rep->count == 0)
161  delete rep;
162  }
163 
164  octave_idx_type rows (void) { return rep->dv(0); }
165  octave_idx_type cols (void) { return rep->dv(1); }
166 
167  bool empty (void) const { return rep->empty (); }
168 
169  size_t length (void) const { return rep->length (); }
170 
171  dim_vector dims (void) { return rep->dv; }
172 
173  bool all_strings_p (void) const { return rep->all_str; }
174  bool all_sq_strings_p (void) const { return rep->all_sq_str; }
175  bool all_dq_strings_p (void) const { return rep->all_dq_str; }
176  bool some_strings_p (void) const { return rep->some_str; }
177  bool all_real_p (void) const { return rep->all_real; }
178  bool all_complex_p (void) const { return rep->all_cmplx; }
179  bool all_empty_p (void) const { return rep->all_mt; }
180  bool any_cell_p (void) const { return rep->any_cell; }
181  bool any_sparse_p (void) const { return rep->any_sparse; }
182  bool any_class_p (void) const { return rep->any_class; }
183  bool all_1x1_p (void) const { return rep->all_1x1; }
184  bool first_elem_struct_p (void) const { return rep->first_elem_is_struct; }
185 
186  std::string class_name (void) const { return rep->class_nm; }
187 
188  void cellify (void) { rep->cellify (); }
189 
190  operator bool () const { return (rep && rep->ok); }
191 
192  iterator begin (void) { return rep->begin (); }
193  const_iterator begin (void) const { return rep->begin (); }
194 
195  iterator end (void) { return rep->end (); }
196  const_iterator end (void) const { return rep->end (); }
197 
198 private:
199 
201 };
202 
203 std::string
204 get_concat_class (const std::string& c1, const std::string& c2)
205 {
206  std::string retval = octave_base_value::static_class_name ();
207 
208  if (c1 == c2)
209  retval = c1;
210  else if (c1.empty ())
211  retval = c2;
212  else if (c2.empty ())
213  retval = c1;
214  else if (c1 == "class" || c2 == "class")
215  retval = "class";
216  else
217  {
218  bool c1_is_int = (c1 == "int8" || c1 == "uint8"
219  || c1 == "int16" || c1 == "uint16"
220  || c1 == "int32" || c1 == "uint32"
221  || c1 == "int64" || c1 == "uint64");
222  bool c2_is_int = (c2 == "int8" || c2 == "uint8"
223  || c2 == "int16" || c2 == "uint16"
224  || c2 == "int32" || c2 == "uint32"
225  || c2 == "int64" || c2 == "uint64");
226 
227  bool c1_is_char = (c1 == "char");
228  bool c2_is_char = (c2 == "char");
229 
230  bool c1_is_double = (c1 == "double");
231  bool c2_is_double = (c2 == "double");
232 
233  bool c1_is_single = (c1 == "single");
234  bool c2_is_single = (c2 == "single");
235 
236  bool c1_is_logical = (c1 == "logical");
237  bool c2_is_logical = (c2 == "logical");
238 
239  bool c1_is_built_in_type
240  = (c1_is_int || c1_is_char || c1_is_double || c1_is_single
241  || c1_is_logical);
242 
243  bool c2_is_built_in_type
244  = (c2_is_int || c2_is_char || c2_is_double || c2_is_single
245  || c2_is_logical);
246 
247  // Order is important here...
248 
249  if (c1 == "struct" && c2 == c1)
250  retval = c1;
251  else if (c1 == "cell" || c2 == "cell")
252  retval = "cell";
253  else if (c1_is_char && c2_is_built_in_type)
254  retval = c1;
255  else if (c2_is_char && c1_is_built_in_type)
256  retval = c2;
257  else if (c1_is_int && c2_is_built_in_type)
258  retval = c1;
259  else if (c2_is_int && c1_is_built_in_type)
260  retval = c2;
261  else if (c1_is_single && c2_is_built_in_type)
262  retval = c1;
263  else if (c2_is_single && c1_is_built_in_type)
264  retval = c2;
265  else if (c1_is_double && c2_is_built_in_type)
266  retval = c1;
267  else if (c2_is_double && c1_is_built_in_type)
268  retval = c2;
269  else if (c1_is_logical && c2_is_logical)
270  retval = c1;
271  }
272 
273  return retval;
274 }
275 
276 static void
277 eval_error (const char *msg, const dim_vector& x, const dim_vector& y)
278 {
279  ::error ("%s (%s vs %s)", msg, x.str ().c_str (), y.str ().c_str ());
280 }
281 
282 void
284  bool& first_elem)
285 {
286  std::string this_elt_class_nm
287  = val.is_object () ? std::string ("class") : val.class_name ();
288 
289  class_nm = get_concat_class (class_nm, this_elt_class_nm);
290 
291  dim_vector this_elt_dv = val.dims ();
292 
293  if (! this_elt_dv.zero_by_zero ())
294  {
295  all_mt = false;
296 
297  if (first_elem)
298  {
299  if (val.is_map ())
300  first_elem_is_struct = true;
301 
302  first_elem = false;
303  }
304  }
305 
306  append (val);
307 
308  if (all_str && ! val.is_string ())
309  all_str = false;
310 
311  if (all_sq_str && ! val.is_sq_string ())
312  all_sq_str = false;
313 
314  if (all_dq_str && ! val.is_dq_string ())
315  all_dq_str = false;
316 
317  if (! some_str && val.is_string ())
318  some_str = true;
319 
320  if (all_real && ! val.is_real_type ())
321  all_real = false;
322 
323  if (all_cmplx && ! (val.is_complex_type () || val.is_real_type ()))
324  all_cmplx = false;
325 
326  if (!any_cell && val.is_cell ())
327  any_cell = true;
328 
329  if (!any_sparse && val.is_sparse_type ())
330  any_sparse = true;
331 
332  if (!any_class && val.is_object ())
333  any_class = true;
334 
335  // Special treatment of sparse matrices to avoid out-of-memory error
336  all_1x1 = all_1x1 && ! val.is_sparse_type () && val.numel () == 1;
337 }
338 
339 void
341 {
342  all_str = true;
343  all_sq_str = true;
344  all_dq_str = true;
345  all_real = true;
346  all_cmplx = true;
347  any_cell = false;
348  any_sparse = false;
349  any_class = false;
350 
351  bool first_elem = true;
352 
354  p != row.end ();
355  p++)
356  {
357  octave_quit ();
358 
359  tree_expression *elt = *p;
360 
361  octave_value tmp = elt->rvalue1 ();
362 
363  if (error_state || tmp.is_undefined ())
364  {
365  ok = ! error_state;
366  return;
367  }
368  else
369  {
370  if (tmp.is_cs_list ())
371  {
372  octave_value_list tlst = tmp.list_value ();
373 
374  for (octave_idx_type i = 0; i < tlst.length (); i++)
375  {
376  octave_quit ();
377 
378  do_init_element (tlst(i), first_elem);
379  }
380  }
381  else
382  do_init_element (tmp, first_elem);
383  }
384  }
385 
386  if (any_cell && ! any_class && ! first_elem_is_struct)
387  cellify ();
388 
389  first_elem = true;
390 
391  if (! error_state)
392  {
393  for (iterator p = begin (); p != end (); p++)
394  {
395  octave_quit ();
396 
397  octave_value val = *p;
398 
399  dim_vector this_elt_dv = val.dims ();
400 
401  if (! this_elt_dv.zero_by_zero ())
402  {
403  all_mt = false;
404 
405  if (first_elem)
406  {
407  first_elem = false;
408  dv = this_elt_dv;
409  }
410  else if ((! any_class) && (! dv.hvcat (this_elt_dv, 1)))
411  {
412  eval_error ("horizontal dimensions mismatch", dv, this_elt_dv);
413  break;
414  }
415  }
416  }
417  }
418 
419  ok = ! error_state;
420 }
421 
422 void
424 {
425  bool elt_changed = false;
426 
427  for (iterator p = begin (); p != end (); p++)
428  {
429  octave_quit ();
430 
431  if (! p->is_cell ())
432  {
433  elt_changed = true;
434 
435  *p = Cell (*p);
436  }
437  }
438 
439  if (elt_changed)
440  {
441  bool first_elem = true;
442 
443  for (iterator p = begin (); p != end (); p++)
444  {
445  octave_quit ();
446 
447  octave_value val = *p;
448 
449  dim_vector this_elt_dv = val.dims ();
450 
451  if (! this_elt_dv.zero_by_zero ())
452  {
453  if (first_elem)
454  {
455  first_elem = false;
456  dv = this_elt_dv;
457  }
458  else if (! dv.hvcat (this_elt_dv, 1))
459  {
460  eval_error ("horizontal dimensions mismatch",
461  dv, this_elt_dv);
462  break;
463  }
464  }
465  }
466  }
467 }
468 
469 class
471 {
472 public:
473 
474  tm_const (const tree_matrix& tm)
475  : dv (0, 0), all_str (false), all_sq_str (false), all_dq_str (false),
476  some_str (false), all_real (false), all_cmplx (false),
477  all_mt (true), any_cell (false), any_sparse (false),
478  any_class (false), class_nm (), ok (false)
479  { init (tm); }
480 
481  ~tm_const (void) { }
482 
483  octave_idx_type rows (void) const { return dv.elem (0); }
484  octave_idx_type cols (void) const { return dv.elem (1); }
485 
486  dim_vector dims (void) const { return dv; }
487 
488  bool all_strings_p (void) const { return all_str; }
489  bool all_sq_strings_p (void) const { return all_sq_str; }
490  bool all_dq_strings_p (void) const { return all_dq_str; }
491  bool some_strings_p (void) const { return some_str; }
492  bool all_real_p (void) const { return all_real; }
493  bool all_complex_p (void) const { return all_cmplx; }
494  bool all_empty_p (void) const { return all_mt; }
495  bool any_cell_p (void) const { return any_cell; }
496  bool any_sparse_p (void) const { return any_sparse; }
497  bool any_class_p (void) const { return any_class; }
498  bool all_1x1_p (void) const { return all_1x1; }
499 
500  std::string class_name (void) const { return class_nm; }
501 
502  operator bool () const { return ok; }
503 
504 private:
505 
507 
508  bool all_str;
511  bool some_str;
512  bool all_real;
513  bool all_cmplx;
514  bool all_mt;
515  bool any_cell;
517  bool any_class;
518  bool all_1x1;
519 
520  std::string class_nm;
521 
522  bool ok;
523 
524  tm_const (void);
525 
526  tm_const (const tm_const&);
527 
528  tm_const& operator = (const tm_const&);
529 
530  void init (const tree_matrix& tm);
531 };
532 
533 void
535 {
536  all_str = true;
537  all_sq_str = true;
538  all_dq_str = true;
539  all_real = true;
540  all_cmplx = true;
541  any_cell = false;
542  any_sparse = false;
543  any_class = false;
544  all_1x1 = ! tm.empty ();
545 
546  bool first_elem = true;
547  bool first_elem_is_struct = false;
548 
549  // Just eval and figure out if what we have is complex or all
550  // strings. We can't check columns until we know that this is a
551  // numeric matrix -- collections of strings can have elements of
552  // different lengths.
553 
554  for (tree_matrix::const_iterator p = tm.begin (); p != tm.end (); p++)
555  {
556  octave_quit ();
557 
558  tree_argument_list *elt = *p;
559 
560  tm_row_const tmp (*elt);
561 
562  if (first_elem)
563  {
564  first_elem_is_struct = tmp.first_elem_struct_p ();
565 
566  first_elem = false;
567  }
568 
569  if (tmp && ! tmp.empty ())
570  {
571  if (all_str && ! tmp.all_strings_p ())
572  all_str = false;
573 
574  if (all_sq_str && ! tmp.all_sq_strings_p ())
575  all_sq_str = false;
576 
577  if (all_dq_str && ! tmp.all_dq_strings_p ())
578  all_dq_str = false;
579 
580  if (! some_str && tmp.some_strings_p ())
581  some_str = true;
582 
583  if (all_real && ! tmp.all_real_p ())
584  all_real = false;
585 
586  if (all_cmplx && ! tmp.all_complex_p ())
587  all_cmplx = false;
588 
589  if (all_mt && ! tmp.all_empty_p ())
590  all_mt = false;
591 
592  if (!any_cell && tmp.any_cell_p ())
593  any_cell = true;
594 
595  if (!any_sparse && tmp.any_sparse_p ())
596  any_sparse = true;
597 
598  if (!any_class && tmp.any_class_p ())
599  any_class = true;
600 
601  all_1x1 = all_1x1 && tmp.all_1x1_p ();
602 
603  append (tmp);
604  }
605  else
606  break;
607  }
608 
609  if (! error_state)
610  {
611  if (any_cell && ! any_class && ! first_elem_is_struct)
612  {
613  for (iterator q = begin (); q != end (); q++)
614  {
615  octave_quit ();
616 
617  q->cellify ();
618  }
619  }
620 
621  first_elem = true;
622 
623  for (iterator q = begin (); q != end (); q++)
624  {
625  octave_quit ();
626 
627  tm_row_const elt = *q;
628 
629  octave_idx_type this_elt_nr = elt.rows ();
630  octave_idx_type this_elt_nc = elt.cols ();
631 
632  std::string this_elt_class_nm = elt.class_name ();
633  class_nm = get_concat_class (class_nm, this_elt_class_nm);
634 
635  dim_vector this_elt_dv = elt.dims ();
636 
637  all_mt = false;
638 
639  if (first_elem)
640  {
641  first_elem = false;
642 
643  dv = this_elt_dv;
644  }
645  else if (all_str && dv.length () == 2
646  && this_elt_dv.length () == 2)
647  {
648  // FIXME: this is Octave's specialty. Character matrices allow
649  // rows of unequal length.
650  if (this_elt_nc > cols ())
651  dv(1) = this_elt_nc;
652  dv(0) += this_elt_nr;
653  }
654  else if ((!any_class) && (!dv.hvcat (this_elt_dv, 0)))
655  {
656  eval_error ("vertical dimensions mismatch", dv, this_elt_dv);
657  return;
658  }
659  }
660  }
661 
662  ok = ! error_state;
663 }
664 
666 tree_matrix::rvalue (int nargout)
667 {
668  octave_value_list retval;
669 
670  if (nargout > 1)
671  error ("invalid number of output arguments for matrix list");
672  else
673  retval = rvalue1 (nargout);
674 
675  return retval;
676 }
677 
678 void
680 {
681  if (! (all_dq_strings_p || all_sq_strings_p))
682  warning_with_id ("Octave:mixed-string-concat",
683  "concatenation of different character string types may have unintended consequences");
684 }
685 
686 template<class TYPE, class T>
687 static void
689  tm_const& tmp)
690 {
691  octave_idx_type r = 0;
692  octave_idx_type c = 0;
693 
694  for (tm_const::iterator p = tmp.begin (); p != tmp.end (); p++)
695  {
696  tm_row_const row = *p;
697  // Skip empty arrays to allow looser rules.
698  if (row.dims ().any_zero ())
699  continue;
700 
701  for (tm_row_const::iterator q = row.begin ();
702  q != row.end ();
703  q++)
704  {
705  octave_quit ();
706 
707  TYPE ra = octave_value_extract<TYPE> (*q);
708 
709  // Skip empty arrays to allow looser rules.
710  if (! error_state)
711  {
712  if (! ra.is_empty ())
713  {
714  result.insert (ra, r, c);
715 
716  if (! error_state)
717  c += ra.columns ();
718  else
719  return;
720  }
721  }
722  else
723  return;
724  }
725 
726  r += row.rows ();
727  c = 0;
728  }
729 }
730 
731 template<class TYPE, class T>
732 static void
734  const dim_vector& dv,
735  tm_const& tmp)
736 {
737  if (dv.any_zero ())
738  {
739  result = Array<T> (dv);
740  return;
741  }
742 
743  if (tmp.length () == 1)
744  {
745  // If possible, forward the operation to liboctave.
746  // Single row.
747  tm_row_const& row = tmp.front ();
749  && row.all_1x1_p ())
750  {
751  // Optimize all scalars case.
752  result.clear (dv);
753  assert (static_cast<size_t> (result.numel ()) == row.length ());
754  octave_idx_type i = 0;
755  for (tm_row_const::iterator q = row.begin ();
756  q != row.end () && ! error_state; q++)
757  result(i++) = octave_value_extract<T> (*q);
758 
759  return;
760  }
761 
762  octave_idx_type ncols = row.length ();
763  octave_idx_type i = 0;
764  OCTAVE_LOCAL_BUFFER (Array<T>, array_list, ncols);
765 
766  for (tm_row_const::iterator q = row.begin ();
767  q != row.end () && ! error_state;
768  q++)
769  {
770  octave_quit ();
771 
772  array_list[i] = octave_value_extract<TYPE> (*q);
773  i++;
774  }
775 
776  if (! error_state)
777  result = Array<T>::cat (-2, ncols, array_list);
778  }
779  else
780  {
781  result = Array<T> (dv);
782  single_type_concat<TYPE> (result, tmp);
783  }
784 }
785 
786 template<class TYPE, class T>
787 static void
789  const dim_vector& dv,
790  tm_const& tmp)
791 {
792  if (dv.any_zero ())
793  {
794  result = Sparse<T> (dv);
795  return;
796  }
797 
798  // Sparse matrices require preallocation for efficient indexing; besides,
799  // only horizontal concatenation can be efficiently handled by indexing.
800  // So we just cat all rows through liboctave, then cat the final column.
801  octave_idx_type nrows = tmp.length ();
802  octave_idx_type j = 0;
803  OCTAVE_LOCAL_BUFFER (Sparse<T>, sparse_row_list, nrows);
804  for (tm_const::iterator p = tmp.begin (); p != tmp.end (); p++)
805  {
806  tm_row_const row = *p;
807  octave_idx_type ncols = row.length ();
808  octave_idx_type i = 0;
809  OCTAVE_LOCAL_BUFFER (Sparse<T>, sparse_list, ncols);
810 
811  for (tm_row_const::iterator q = row.begin ();
812  q != row.end () && ! error_state;
813  q++)
814  {
815  octave_quit ();
816 
817  sparse_list[i] = octave_value_extract<TYPE> (*q);
818  i++;
819  }
820 
821  Sparse<T> stmp = Sparse<T>::cat (-2, ncols, sparse_list);
822  sparse_row_list[j] = stmp;
823  j++;
824  }
825 
826  result = Sparse<T>::cat (-1, nrows, sparse_row_list);
827 }
828 
829 template<class MAP>
830 static void
832  const dim_vector& dv,
833  tm_const& tmp)
834 {
835  if (dv.any_zero ())
836  {
837  result = octave_map (dv);
838  return;
839  }
840 
841  octave_idx_type nrows = tmp.length ();
842  octave_idx_type j = 0;
843  OCTAVE_LOCAL_BUFFER (octave_map, map_row_list, nrows);
844  for (tm_const::iterator p = tmp.begin (); p != tmp.end (); p++)
845  {
846  tm_row_const row = *p;
847  octave_idx_type ncols = row.length ();
848  octave_idx_type i = 0;
849  OCTAVE_LOCAL_BUFFER (MAP, map_list, ncols);
850 
851  for (tm_row_const::iterator q = row.begin ();
852  q != row.end () && ! error_state;
853  q++)
854  {
855  octave_quit ();
856 
857  map_list[i] = octave_value_extract<MAP> (*q);
858  i++;
859  }
860 
861  octave_map mtmp = octave_map::cat (-2, ncols, map_list);
862  map_row_list[j] = mtmp;
863  j++;
864  }
865 
866  result = octave_map::cat (-1, nrows, map_row_list);
867 }
868 
869 template<class TYPE>
870 static octave_value
872  tm_const& tmp)
873 {
874  TYPE result;
875 
876  single_type_concat<TYPE> (result, dv, tmp);
877 
878  return result;
879 }
880 
881 template<>
884  tm_const& tmp)
885 {
886  octave_map result;
887 
888  if (tmp.all_1x1_p ())
889  single_type_concat<octave_scalar_map> (result, dv, tmp);
890  else
891  single_type_concat<octave_map> (result, dv, tmp);
892 
893  return result;
894 }
895 
896 static octave_value
898 {
899  octave_value retval;
900 
902 
903  octave_idx_type j = 0;
904  for (tm_const::iterator p = tmc.begin (); p != tmc.end (); p++)
905  {
906  octave_quit ();
907 
908  tm_row_const tmrc = *p;
909 
910  if (tmrc.length () == 1)
911  rows(j++) = *(tmrc.begin ());
912  else
913  {
914  octave_value_list row (tmrc.length (), octave_value ());
915 
916  octave_idx_type i = 0;
917  for (tm_row_const::iterator q = tmrc.begin (); q != tmrc.end (); q++)
918  row(i++) = *q;
919 
920  rows(j++) = do_class_concat (row, "horzcat", 1);
921  }
922  }
923 
924  if (! error_state)
925  {
926  if (rows.length () == 1)
927  retval = rows(0);
928  else
929  retval = do_class_concat (rows, "vertcat", 0);
930  }
931 
932  return retval;
933 }
934 
937 {
938  octave_value retval = Matrix ();
939 
940  bool all_strings_p = false;
941  bool all_sq_strings_p = false;
942  bool all_dq_strings_p = false;
943  bool all_empty_p = false;
944  bool all_real_p = false;
945  bool any_sparse_p = false;
946  bool any_class_p = false;
947  bool frc_str_conv = false;
948 
949  tm_const tmp (*this);
950 
951  if (tmp && ! tmp.empty ())
952  {
953  dim_vector dv = tmp.dims ();
954  all_strings_p = tmp.all_strings_p ();
955  all_sq_strings_p = tmp.all_sq_strings_p ();
956  all_dq_strings_p = tmp.all_dq_strings_p ();
957  all_empty_p = tmp.all_empty_p ();
958  all_real_p = tmp.all_real_p ();
959  any_sparse_p = tmp.any_sparse_p ();
960  any_class_p = tmp.any_class_p ();
961  frc_str_conv = tmp.some_strings_p ();
962 
963  // Try to speed up the common cases.
964 
965  std::string result_type = tmp.class_name ();
966 
967  if (any_class_p)
968  {
969  retval = do_class_concat (tmp);
970  }
971  else if (result_type == "double")
972  {
973  if (any_sparse_p)
974  {
975  if (all_real_p)
976  retval = do_single_type_concat<SparseMatrix> (dv, tmp);
977  else
978  retval = do_single_type_concat<SparseComplexMatrix> (dv, tmp);
979  }
980  else
981  {
982  if (all_real_p)
983  retval = do_single_type_concat<NDArray> (dv, tmp);
984  else
985  retval = do_single_type_concat<ComplexNDArray> (dv, tmp);
986  }
987  }
988  else if (result_type == "single")
989  {
990  if (all_real_p)
991  retval = do_single_type_concat<FloatNDArray> (dv, tmp);
992  else
993  retval = do_single_type_concat<FloatComplexNDArray> (dv, tmp);
994  }
995  else if (result_type == "char")
996  {
997  char type = all_dq_strings_p ? '"' : '\'';
998 
999  if (! all_strings_p)
1000  gripe_implicit_conversion ("Octave:num-to-str",
1001  "numeric", result_type);
1002  else
1003  maybe_warn_string_concat (all_dq_strings_p, all_sq_strings_p);
1004 
1005  charNDArray result (dv, Vstring_fill_char);
1006 
1007  single_type_concat<charNDArray> (result, tmp);
1008 
1009  retval = octave_value (result, type);
1010  }
1011  else if (result_type == "logical")
1012  {
1013  if (any_sparse_p)
1014  retval = do_single_type_concat<SparseBoolMatrix> (dv, tmp);
1015  else
1016  retval = do_single_type_concat<boolNDArray> (dv, tmp);
1017  }
1018  else if (result_type == "int8")
1019  retval = do_single_type_concat<int8NDArray> (dv, tmp);
1020  else if (result_type == "int16")
1021  retval = do_single_type_concat<int16NDArray> (dv, tmp);
1022  else if (result_type == "int32")
1023  retval = do_single_type_concat<int32NDArray> (dv, tmp);
1024  else if (result_type == "int64")
1025  retval = do_single_type_concat<int64NDArray> (dv, tmp);
1026  else if (result_type == "uint8")
1027  retval = do_single_type_concat<uint8NDArray> (dv, tmp);
1028  else if (result_type == "uint16")
1029  retval = do_single_type_concat<uint16NDArray> (dv, tmp);
1030  else if (result_type == "uint32")
1031  retval = do_single_type_concat<uint32NDArray> (dv, tmp);
1032  else if (result_type == "uint64")
1033  retval = do_single_type_concat<uint64NDArray> (dv, tmp);
1034  else if (result_type == "cell")
1035  retval = do_single_type_concat<Cell> (dv, tmp);
1036  else if (result_type == "struct")
1037  retval = do_single_type_concat<octave_map> (dv, tmp);
1038  else
1039  {
1040  // The line below might seem crazy, since we take a copy of
1041  // the first argument, resize it to be empty and then resize
1042  // it to be full. This is done since it means that there is
1043  // no recopying of data, as would happen if we used a single
1044  // resize. It should be noted that resize operation is also
1045  // significantly slower than the do_cat_op function, so it
1046  // makes sense to have an empty matrix and copy all data.
1047  //
1048  // We might also start with a empty octave_value using
1049  //
1050  // ctmp = octave_value_typeinfo::lookup_type
1051  // (tmp.begin() -> begin() -> type_name());
1052  //
1053  // and then directly resize. However, for some types there
1054  // might be some additional setup needed, and so this should
1055  // be avoided.
1056 
1057  octave_value ctmp;
1058 
1059  // Find the first non-empty object
1060 
1061  if (any_sparse_p)
1062  {
1063  // Start with sparse matrix to avoid issues memory issues
1064  // with things like [ones(1,4),sprandn(1e8,4,1e-4)]
1065  if (all_real_p)
1066  ctmp = octave_sparse_matrix ().resize (dv);
1067  else
1068  ctmp = octave_sparse_complex_matrix ().resize (dv);
1069  }
1070  else
1071  {
1072  for (tm_const::iterator p = tmp.begin (); p != tmp.end (); p++)
1073  {
1074  octave_quit ();
1075 
1076  tm_row_const row = *p;
1077 
1078  for (tm_row_const::iterator q = row.begin ();
1079  q != row.end (); q++)
1080  {
1081  octave_quit ();
1082 
1083  ctmp = *q;
1084 
1085  if (! ctmp.all_zero_dims ())
1086  goto found_non_empty;
1087  }
1088  }
1089 
1090  ctmp = (*(tmp.begin () -> begin ()));
1091 
1092  found_non_empty:
1093 
1094  if (! all_empty_p)
1095  ctmp = ctmp.resize (dim_vector (0,0)).resize (dv);
1096  }
1097 
1098  if (! error_state)
1099  {
1100  // Now, extract the values from the individual elements and
1101  // insert them in the result matrix.
1102 
1103  int dv_len = dv.length ();
1104  octave_idx_type ntmp = dv_len > 1 ? dv_len : 2;
1105  Array<octave_idx_type> ra_idx (dim_vector (ntmp, 1), 0);
1106 
1107  for (tm_const::iterator p = tmp.begin (); p != tmp.end (); p++)
1108  {
1109  octave_quit ();
1110 
1111  tm_row_const row = *p;
1112 
1113  for (tm_row_const::iterator q = row.begin ();
1114  q != row.end ();
1115  q++)
1116  {
1117  octave_quit ();
1118 
1119  octave_value elt = *q;
1120 
1121  if (elt.is_empty ())
1122  continue;
1123 
1124  ctmp = do_cat_op (ctmp, elt, ra_idx);
1125 
1126  if (error_state)
1127  goto done;
1128 
1129  ra_idx (1) += elt.columns ();
1130  }
1131 
1132  ra_idx (0) += row.rows ();
1133  ra_idx (1) = 0;
1134  }
1135 
1136  retval = ctmp;
1137 
1138  if (frc_str_conv && ! retval.is_string ())
1139  retval = retval.convert_to_str ();
1140  }
1141  }
1142  }
1143 
1144 done:
1145  return retval;
1146 }
1147 
1151 {
1152  tree_matrix *new_matrix = new tree_matrix (0, line (), column ());
1153 
1154  new_matrix->copy_base (*this, scope, context);
1155 
1156  return new_matrix;
1157 }
1158 
1159 void
1161 {
1162  tw.visit_matrix (*this);
1163 }
1164 
1165 /*
1166 ## test concatenation with all zero matrices
1167 %!assert ([ "" 65*ones(1,10) ], "AAAAAAAAAA");
1168 %!assert ([ 65*ones(1,10) "" ], "AAAAAAAAAA");
1169 
1170 %!test
1171 %! c = {"foo"; "bar"; "bazoloa"};
1172 %! assert ([c; "a"; "bc"; "def"], {"foo"; "bar"; "bazoloa"; "a"; "bc"; "def"});
1173 
1174 %!assert (class ([int64(1), int64(1)]), "int64")
1175 %!assert (class ([int64(1), int32(1)]), "int64")
1176 %!assert (class ([int64(1), int16(1)]), "int64")
1177 %!assert (class ([int64(1), int8(1)]), "int64")
1178 %!assert (class ([int64(1), uint64(1)]), "int64")
1179 %!assert (class ([int64(1), uint32(1)]), "int64")
1180 %!assert (class ([int64(1), uint16(1)]), "int64")
1181 %!assert (class ([int64(1), uint8(1)]), "int64")
1182 %!assert (class ([int64(1), single(1)]), "int64")
1183 %!assert (class ([int64(1), double(1)]), "int64")
1184 %!assert (class ([int64(1), cell(1)]), "cell")
1185 %!assert (class ([int64(1), true]), "int64")
1186 %!assert (class ([int64(1), "a"]), "char")
1187 
1188 %!assert (class ([int32(1), int64(1)]), "int32")
1189 %!assert (class ([int32(1), int32(1)]), "int32")
1190 %!assert (class ([int32(1), int16(1)]), "int32")
1191 %!assert (class ([int32(1), int8(1)]), "int32")
1192 %!assert (class ([int32(1), uint64(1)]), "int32")
1193 %!assert (class ([int32(1), uint32(1)]), "int32")
1194 %!assert (class ([int32(1), uint16(1)]), "int32")
1195 %!assert (class ([int32(1), uint8(1)]), "int32")
1196 %!assert (class ([int32(1), single(1)]), "int32")
1197 %!assert (class ([int32(1), double(1)]), "int32")
1198 %!assert (class ([int32(1), cell(1)]), "cell")
1199 %!assert (class ([int32(1), true]), "int32")
1200 %!assert (class ([int32(1), "a"]), "char")
1201 
1202 %!assert (class ([int16(1), int64(1)]), "int16")
1203 %!assert (class ([int16(1), int32(1)]), "int16")
1204 %!assert (class ([int16(1), int16(1)]), "int16")
1205 %!assert (class ([int16(1), int8(1)]), "int16")
1206 %!assert (class ([int16(1), uint64(1)]), "int16")
1207 %!assert (class ([int16(1), uint32(1)]), "int16")
1208 %!assert (class ([int16(1), uint16(1)]), "int16")
1209 %!assert (class ([int16(1), uint8(1)]), "int16")
1210 %!assert (class ([int16(1), single(1)]), "int16")
1211 %!assert (class ([int16(1), double(1)]), "int16")
1212 %!assert (class ([int16(1), cell(1)]), "cell")
1213 %!assert (class ([int16(1), true]), "int16")
1214 %!assert (class ([int16(1), "a"]), "char")
1215 
1216 %!assert (class ([int8(1), int64(1)]), "int8")
1217 %!assert (class ([int8(1), int32(1)]), "int8")
1218 %!assert (class ([int8(1), int16(1)]), "int8")
1219 %!assert (class ([int8(1), int8(1)]), "int8")
1220 %!assert (class ([int8(1), uint64(1)]), "int8")
1221 %!assert (class ([int8(1), uint32(1)]), "int8")
1222 %!assert (class ([int8(1), uint16(1)]), "int8")
1223 %!assert (class ([int8(1), uint8(1)]), "int8")
1224 %!assert (class ([int8(1), single(1)]), "int8")
1225 %!assert (class ([int8(1), double(1)]), "int8")
1226 %!assert (class ([int8(1), cell(1)]), "cell")
1227 %!assert (class ([int8(1), true]), "int8")
1228 %!assert (class ([int8(1), "a"]), "char")
1229 
1230 %!assert (class ([uint64(1), int64(1)]), "uint64")
1231 %!assert (class ([uint64(1), int32(1)]), "uint64")
1232 %!assert (class ([uint64(1), int16(1)]), "uint64")
1233 %!assert (class ([uint64(1), int8(1)]), "uint64")
1234 %!assert (class ([uint64(1), uint64(1)]), "uint64")
1235 %!assert (class ([uint64(1), uint32(1)]), "uint64")
1236 %!assert (class ([uint64(1), uint16(1)]), "uint64")
1237 %!assert (class ([uint64(1), uint8(1)]), "uint64")
1238 %!assert (class ([uint64(1), single(1)]), "uint64")
1239 %!assert (class ([uint64(1), double(1)]), "uint64")
1240 %!assert (class ([uint64(1), cell(1)]), "cell")
1241 %!assert (class ([uint64(1), true]), "uint64")
1242 %!assert (class ([uint64(1), "a"]), "char")
1243 
1244 %!assert (class ([uint32(1), int64(1)]), "uint32")
1245 %!assert (class ([uint32(1), int32(1)]), "uint32")
1246 %!assert (class ([uint32(1), int16(1)]), "uint32")
1247 %!assert (class ([uint32(1), int8(1)]), "uint32")
1248 %!assert (class ([uint32(1), uint64(1)]), "uint32")
1249 %!assert (class ([uint32(1), uint32(1)]), "uint32")
1250 %!assert (class ([uint32(1), uint16(1)]), "uint32")
1251 %!assert (class ([uint32(1), uint8(1)]), "uint32")
1252 %!assert (class ([uint32(1), single(1)]), "uint32")
1253 %!assert (class ([uint32(1), double(1)]), "uint32")
1254 %!assert (class ([uint32(1), cell(1)]), "cell")
1255 %!assert (class ([uint32(1), true]), "uint32")
1256 %!assert (class ([uint32(1), "a"]), "char")
1257 
1258 %!assert (class ([uint16(1), int64(1)]), "uint16")
1259 %!assert (class ([uint16(1), int32(1)]), "uint16")
1260 %!assert (class ([uint16(1), int16(1)]), "uint16")
1261 %!assert (class ([uint16(1), int8(1)]), "uint16")
1262 %!assert (class ([uint16(1), uint64(1)]), "uint16")
1263 %!assert (class ([uint16(1), uint32(1)]), "uint16")
1264 %!assert (class ([uint16(1), uint16(1)]), "uint16")
1265 %!assert (class ([uint16(1), uint8(1)]), "uint16")
1266 %!assert (class ([uint16(1), single(1)]), "uint16")
1267 %!assert (class ([uint16(1), double(1)]), "uint16")
1268 %!assert (class ([uint16(1), cell(1)]), "cell")
1269 %!assert (class ([uint16(1), true]), "uint16")
1270 %!assert (class ([uint16(1), "a"]), "char")
1271 
1272 %!assert (class ([uint8(1), int64(1)]), "uint8")
1273 %!assert (class ([uint8(1), int32(1)]), "uint8")
1274 %!assert (class ([uint8(1), int16(1)]), "uint8")
1275 %!assert (class ([uint8(1), int8(1)]), "uint8")
1276 %!assert (class ([uint8(1), uint64(1)]), "uint8")
1277 %!assert (class ([uint8(1), uint32(1)]), "uint8")
1278 %!assert (class ([uint8(1), uint16(1)]), "uint8")
1279 %!assert (class ([uint8(1), uint8(1)]), "uint8")
1280 %!assert (class ([uint8(1), single(1)]), "uint8")
1281 %!assert (class ([uint8(1), double(1)]), "uint8")
1282 %!assert (class ([uint8(1), cell(1)]), "cell")
1283 %!assert (class ([uint8(1), true]), "uint8")
1284 %!assert (class ([uint8(1), "a"]), "char")
1285 
1286 %!assert (class ([single(1), int64(1)]), "int64")
1287 %!assert (class ([single(1), int32(1)]), "int32")
1288 %!assert (class ([single(1), int16(1)]), "int16")
1289 %!assert (class ([single(1), int8(1)]), "int8")
1290 %!assert (class ([single(1), uint64(1)]), "uint64")
1291 %!assert (class ([single(1), uint32(1)]), "uint32")
1292 %!assert (class ([single(1), uint16(1)]), "uint16")
1293 %!assert (class ([single(1), uint8(1)]), "uint8")
1294 %!assert (class ([single(1), single(1)]), "single")
1295 %!assert (class ([single(1), double(1)]), "single")
1296 %!assert (class ([single(1), cell(1)]), "cell")
1297 %!assert (class ([single(1), true]), "single")
1298 %!assert (class ([single(1), "a"]), "char")
1299 
1300 %!assert (class ([double(1), int64(1)]), "int64")
1301 %!assert (class ([double(1), int32(1)]), "int32")
1302 %!assert (class ([double(1), int16(1)]), "int16")
1303 %!assert (class ([double(1), int8(1)]), "int8")
1304 %!assert (class ([double(1), uint64(1)]), "uint64")
1305 %!assert (class ([double(1), uint32(1)]), "uint32")
1306 %!assert (class ([double(1), uint16(1)]), "uint16")
1307 %!assert (class ([double(1), uint8(1)]), "uint8")
1308 %!assert (class ([double(1), single(1)]), "single")
1309 %!assert (class ([double(1), double(1)]), "double")
1310 %!assert (class ([double(1), cell(1)]), "cell")
1311 %!assert (class ([double(1), true]), "double")
1312 %!assert (class ([double(1), "a"]), "char")
1313 
1314 %!assert (class ([cell(1), int64(1)]), "cell")
1315 %!assert (class ([cell(1), int32(1)]), "cell")
1316 %!assert (class ([cell(1), int16(1)]), "cell")
1317 %!assert (class ([cell(1), int8(1)]), "cell")
1318 %!assert (class ([cell(1), uint64(1)]), "cell")
1319 %!assert (class ([cell(1), uint32(1)]), "cell")
1320 %!assert (class ([cell(1), uint16(1)]), "cell")
1321 %!assert (class ([cell(1), uint8(1)]), "cell")
1322 %!assert (class ([cell(1), single(1)]), "cell")
1323 %!assert (class ([cell(1), double(1)]), "cell")
1324 %!assert (class ([cell(1), cell(1)]), "cell")
1325 %!assert (class ([cell(1), true]), "cell")
1326 %!assert (class ([cell(1), "a"]), "cell")
1327 
1328 %!assert (class ([true, int64(1)]), "int64")
1329 %!assert (class ([true, int32(1)]), "int32")
1330 %!assert (class ([true, int16(1)]), "int16")
1331 %!assert (class ([true, int8(1)]), "int8")
1332 %!assert (class ([true, uint64(1)]), "uint64")
1333 %!assert (class ([true, uint32(1)]), "uint32")
1334 %!assert (class ([true, uint16(1)]), "uint16")
1335 %!assert (class ([true, uint8(1)]), "uint8")
1336 %!assert (class ([true, single(1)]), "single")
1337 %!assert (class ([true, double(1)]), "double")
1338 %!assert (class ([true, cell(1)]), "cell")
1339 %!assert (class ([true, true]), "logical")
1340 %!assert (class ([true, "a"]), "char")
1341 
1342 %!assert (class (["a", int64(1)]), "char")
1343 %!assert (class (["a", int32(1)]), "char")
1344 %!assert (class (["a", int16(1)]), "char")
1345 %!assert (class (["a", int8(1)]), "char")
1346 %!assert (class (["a", int64(1)]), "char")
1347 %!assert (class (["a", int32(1)]), "char")
1348 %!assert (class (["a", int16(1)]), "char")
1349 %!assert (class (["a", int8(1)]), "char")
1350 %!assert (class (["a", single(1)]), "char")
1351 %!assert (class (["a", double(1)]), "char")
1352 %!assert (class (["a", cell(1)]), "cell")
1353 %!assert (class (["a", true]), "char")
1354 %!assert (class (["a", "a"]), "char")
1355 
1356 %!assert (class ([cell(1), struct("foo", "bar")]), "cell")
1357 %!error [struct("foo", "bar"), cell(1)]
1358 
1359 %!assert ([,1], 1)
1360 %!assert ([1,], 1)
1361 %!assert ([,1,], 1)
1362 %!assert ([,1,;;], 1)
1363 %!assert ([,1,;,;], 1)
1364 
1365 %!assert ([1,1], ones (1, 2))
1366 %!assert ([,1,1], ones (1, 2))
1367 %!assert ([1,1,], ones (1, 2))
1368 %!assert ([,1,1,], ones (1, 2))
1369 %!assert ([,1,1,;;], ones (1, 2))
1370 %!assert ([,1,1,;,;], ones (1, 2))
1371 %!assert ([,;,1,1], ones (1, 2))
1372 
1373 %!assert ([1;1], ones (2, 1))
1374 %!assert ([1,;1], ones (2, 1))
1375 %!assert ([1,;,;1], ones (2, 1))
1376 
1377 %!error eval ("[,,]")
1378 %!error eval ("[,,;,]")
1379 %!error eval ("[,;,,;,]")
1380 
1381 %!assert (isnull ([,]))
1382 %!assert (isnull ([;]))
1383 %!assert (isnull ([;;]))
1384 %!assert (isnull ([;,;]))
1385 %!assert (isnull ([,;,;,]))
1386 */
1387 
1388 DEFUN (string_fill_char, args, nargout,
1389  "-*- texinfo -*-\n\
1390 @deftypefn {Built-in Function} {@var{val} =} string_fill_char ()\n\
1391 @deftypefnx {Built-in Function} {@var{old_val} =} string_fill_char (@var{new_val})\n\
1392 @deftypefnx {Built-in Function} {} string_fill_char (@var{new_val}, \"local\")\n\
1393 Query or set the internal variable used to pad all rows of a character\n\
1394 matrix to the same length.\n\
1395 \n\
1396 The value must be a single character and the default is @qcode{\" \"} (a\n\
1397 single space). For example:\n\
1398 \n\
1399 @example\n\
1400 @group\n\
1401 string_fill_char (\"X\");\n\
1402 [ \"these\"; \"are\"; \"strings\" ]\n\
1403  @result{} \"theseXX\"\n\
1404  \"areXXXX\"\n\
1405  \"strings\"\n\
1406 @end group\n\
1407 @end example\n\
1408 \n\
1409 When called from inside a function with the @qcode{\"local\"} option, the\n\
1410 variable is changed locally for the function and any subroutines it calls.\n\
1411 The original variable value is restored when exiting the function.\n\
1412 @end deftypefn")
1413 {
1414  return SET_INTERNAL_VARIABLE (string_fill_char);
1415 }
1416 
1417 /*
1418 ## string_fill_char() function call must be outside of %!test block
1419 ## due to the way a %!test block is wrapped inside a function
1420 %!shared orig_val, old_val
1421 %! orig_val = string_fill_char ();
1422 %! old_val = string_fill_char ("X");
1423 %!test
1424 %! assert (orig_val, old_val);
1425 %! assert (string_fill_char (), "X");
1426 %! assert (["these"; "are"; "strings"], ["theseXX"; "areXXXX"; "strings"]);
1427 %! string_fill_char (orig_val);
1428 %! assert (string_fill_char (), orig_val);
1429 
1430 %!error (string_fill_char (1, 2))
1431 */
char Vstring_fill_char
Definition: pt-mat.cc:52
tm_row_const & operator=(const tm_row_const &x)
Definition: pt-mat.cc:142
bool any_class_p(void) const
Definition: pt-mat.cc:497
void gripe_implicit_conversion(const char *id, const char *from, const char *to)
Definition: gripes.cc:180
bool some_strings_p(void) const
Definition: pt-mat.cc:176
void warning_with_id(const char *id, const char *fmt,...)
Definition: error.cc:696
int bool
Definition: mex.h:56
bool is_object(void) const
Definition: ov.h:577
size_t length(void) const
Definition: base-list.h:45
Definition: Cell.h:35
static octave_map cat(int dim, octave_idx_type n, const octave_scalar_map *map_list)
Definition: oct-map.cc:662
std::string str(char sep= 'x') const
Definition: dim-vector.cc:63
bool is_real_type(void) const
Definition: ov.h:651
const octave_base_value const Array< octave_idx_type > & ra_idx
octave_value do_cat_op(const octave_value &v1, const octave_value &v2, const Array< octave_idx_type > &ra_idx)
Definition: ov.cc:2304
std::string get_concat_class(const std::string &c1, const std::string &c2)
Definition: pt-mat.cc:204
dim_vector dims(void)
Definition: pt-mat.cc:171
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:275
bool all_real_p(void) const
Definition: pt-mat.cc:492
std::string class_name(void) const
Definition: pt-mat.cc:500
octave_idx_type length(void) const
Definition: oct-obj.h:89
iterator begin(void)
Definition: pt-mat.cc:192
static octave_value do_single_type_concat(const dim_vector &dv, tm_const &tmp)
Definition: pt-mat.cc:871
bool any_class
Definition: pt-mat.cc:517
bool all_dq_strings_p(void) const
Definition: pt-mat.cc:490
bool all_str
Definition: pt-mat.cc:508
bool all_complex_p(void) const
Definition: pt-mat.cc:178
#define DEFUN(name, args_name, nargout_name, doc)
Definition: defun.h:44
~tm_const(void)
Definition: pt-mat.cc:481
bool any_cell_p(void) const
Definition: pt-mat.cc:495
bool all_empty_p(void) const
Definition: pt-mat.cc:494
void error(const char *fmt,...)
Definition: error.cc:476
tree_expression * dup(symbol_table::scope_id scope, symbol_table::context_id context) const
Definition: pt-mat.cc:1149
tm_row_const_rep * rep
Definition: pt-mat.cc:200
#define SET_INTERNAL_VARIABLE(NM)
Definition: variables.h:120
tm_const(const tree_matrix &tm)
Definition: pt-mat.cc:474
bool all_strings_p(void) const
Definition: pt-mat.cc:173
static Sparse< T > cat(int dim, octave_idx_type n, const Sparse< T > *sparse_list)
Definition: Sparse.cc:2584
octave_value resize(const dim_vector &dv, bool fill=false) const
Definition: ov.h:507
bool is_cell(void) const
Definition: ov.h:529
const_iterator end(void) const
Definition: pt-mat.cc:196
octave_base_list< tree_argument_list * >::const_iterator const_iterator
Definition: pt-array-list.h:40
elt_type & front(void)
Definition: base-list.h:92
static std::string static_class_name(void)
Definition: ov-base.h:830
bool any_cell
Definition: pt-mat.cc:515
Array< T > & insert(const Array< T > &a, const Array< octave_idx_type > &idx)
Insert an array into another at a specified position.
Definition: Array.cc:1591
tm_row_const_rep::iterator iterator
Definition: pt-mat.cc:126
bool any_sparse_p(void) const
Definition: pt-mat.cc:181
bool all_mt
Definition: pt-mat.cc:514
std::list< octave_value >::iterator iterator
Definition: base-list.h:36
octave_idx_type columns(void) const
Definition: ov.h:475
iterator end(void)
Definition: base-list.h:81
bool all_dq_str
Definition: pt-mat.cc:510
bool all_1x1
Definition: pt-mat.cc:518
void append(const octave_value &s)
Definition: base-list.h:105
tm_row_const_rep::const_iterator const_iterator
Definition: pt-mat.cc:127
octave_value convert_to_str(bool pad=false, bool force=false, char type= '\'') const
Definition: ov.h:1017
bool is_sparse_type(void) const
Definition: ov.h:666
octave_idx_type numel(const octave_value_list &idx)
Definition: ov.h:395
static llvm::LLVMContext & context
Definition: jit-typeinfo.cc:76
size_t length(void) const
Definition: pt-mat.cc:169
octave_value do_single_type_concat< octave_map >(const dim_vector &dv, tm_const &tmp)
Definition: pt-mat.cc:883
bool empty(void) const
Definition: base-list.h:42
static Array< T > cat(int dim, octave_idx_type n, const Array< T > *array_list)
Concatenation along a specified (0-based) dimension, equivalent to cat().
Definition: Array.cc:2634
bool is_string(void) const
Definition: ov.h:562
bool all_sq_strings_p(void) const
Definition: pt-mat.cc:489
bool all_sq_str
Definition: pt-mat.cc:509
int error_state
Definition: error.cc:101
void accept(tree_walker &tw)
Definition: pt-mat.cc:1160
bool is_complex_type(void) const
Definition: ov.h:654
octave_refcount< int > count
Definition: pt-mat.cc:89
bool all_strings_p(void) const
Definition: pt-mat.cc:488
tm_row_const(void)
Definition: pt-mat.cc:129
bool some_strings_p(void) const
Definition: pt-mat.cc:491
static octave_value do_class_concat(tm_const &tmc)
Definition: pt-mat.cc:897
tm_row_const_rep(const tree_argument_list &row)
Definition: pt-mat.cc:79
bool all_1x1_p(void) const
Definition: pt-mat.cc:183
bool empty(void) const
Definition: pt-mat.cc:167
bool all_dq_strings_p(void) const
Definition: pt-mat.cc:175
std::list< octave_value >::const_iterator const_iterator
Definition: base-list.h:37
bool all_zero_dims(void) const
Definition: ov.h:481
octave_idx_type length(void) const
Definition: ov.cc:1525
bool some_str
Definition: pt-mat.cc:511
Definition: dMatrix.h:35
bool any_sparse
Definition: pt-mat.cc:516
bool any_zero(void) const
Definition: dim-vector.h:331
bool all_real
Definition: pt-mat.cc:512
void copy_base(const tree_array_list &array_list)
std::string class_name(void) const
Definition: pt-mat.cc:186
dim_vector dims(void) const
Definition: ov.h:470
octave_value rvalue1(int nargout=1)
Definition: pt-mat.cc:936
iterator begin(void)
Definition: base-list.h:78
bool all_complex_p(void) const
Definition: pt-mat.cc:493
bool any_class_p(void) const
Definition: pt-mat.cc:182
bool is_map(void) const
Definition: ov.h:574
octave_value resize(const dim_vector &dv, bool=false) const
Handles the reference counting for all the derived classes.
Definition: Array.h:45
virtual octave_value rvalue1(int nargout=1)
Definition: pt-exp.cc:58
octave_idx_type cols(void) const
Definition: pt-mat.cc:484
void clear(void)
Definition: Array.cc:84
bool is_empty(void) const
Definition: ov.h:526
octave_idx_type rows(void)
Definition: pt-mat.cc:164
bool is_sq_string(void) const
Definition: ov.h:565
void init(const tree_argument_list &)
Definition: pt-mat.cc:340
bool all_sq_strings_p(void) const
Definition: pt-mat.cc:174
dim_vector dims(void) const
Definition: pt-mat.cc:486
const_iterator begin(void) const
Definition: pt-mat.cc:193
bool is_dq_string(void) const
Definition: ov.h:568
void do_init_element(const octave_value &, bool &)
Definition: pt-mat.cc:283
bool zero_by_zero(void) const
Definition: dim-vector.h:326
bool is_cs_list(void) const
Definition: ov.h:586
bool any_sparse_p(void) const
Definition: pt-mat.cc:496
tm_row_const(const tree_argument_list &row)
Definition: pt-mat.cc:132
bool all_real_p(void) const
Definition: pt-mat.cc:177
bool any_cell_p(void) const
Definition: pt-mat.cc:180
octave_idx_type rows(void) const
Definition: pt-mat.cc:483
std::string class_name(void) const
Definition: ov.h:1049
octave_idx_type cols(void)
Definition: pt-mat.cc:165
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition: oct-locbuf.h:197
bool all_1x1_p(void) const
Definition: pt-mat.cc:498
bool is_undefined(void) const
Definition: ov.h:523
bool ok
Definition: pt-mat.cc:522
iterator end(void)
Definition: pt-mat.cc:195
tm_row_const(const tm_row_const &x)
Definition: pt-mat.cc:135
octave_value_list list_value(void) const
Definition: ov.cc:1633
void init(const tree_matrix &tm)
Definition: pt-mat.cc:534
bool all_empty_p(void) const
Definition: pt-mat.cc:179
static MArray< double > const octave_idx_type const octave_idx_type octave_idx_type octave_idx_type octave_idx_type c1
bool first_elem_struct_p(void) const
Definition: pt-mat.cc:184
std::string class_nm
Definition: pt-mat.cc:520
octave_value_list rvalue(int nargout)
Definition: pt-mat.cc:666
void cellify(void)
Definition: pt-mat.cc:188
static void single_type_concat(Array< T > &result, tm_const &tmp)
Definition: pt-mat.cc:688
virtual void visit_matrix(tree_matrix &)=0
dim_vector dv
Definition: pt-mat.cc:506
static void eval_error(const char *msg, const dim_vector &x, const dim_vector &y)
Definition: pt-mat.cc:277
int length(void) const
Definition: dim-vector.h:281
~tm_row_const(void)
Definition: pt-mat.cc:158
bool all_cmplx
Definition: pt-mat.cc:513
return octave_value(v1.char_array_value().concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string())? '\'': '"'))
F77_RET_T const double * x
void maybe_warn_string_concat(bool all_dq_strings_p, bool all_sq_strings_p)
Definition: pt-mat.cc:679