Mercurial > hg > octave-lyh
annotate src/pt-mat.cc @ 8913:35cd375d4bb3
make tree::dup functions const
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 05 Mar 2009 13:50:25 -0500 |
parents | 73c4516fae10 |
children | eb63fbe60fab |
rev | line source |
---|---|
1741 | 1 /* |
2 | |
7017 | 3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, |
4 2005, 2006, 2007 John W. Eaton | |
1741 | 5 |
6 This file is part of Octave. | |
7 | |
8 Octave is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
7016 | 10 Free Software Foundation; either version 3 of the License, or (at your |
11 option) any later version. | |
1741 | 12 |
13 Octave is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
7016 | 19 along with Octave; see the file COPYING. If not, see |
20 <http://www.gnu.org/licenses/>. | |
1741 | 21 |
22 */ | |
23 | |
24 #ifdef HAVE_CONFIG_H | |
25 #include <config.h> | |
26 #endif | |
27 | |
3503 | 28 #include <iostream> |
1741 | 29 |
5502 | 30 #include "quit.h" |
31 | |
2172 | 32 #include "defun.h" |
1741 | 33 #include "error.h" |
34 #include "oct-obj.h" | |
2982 | 35 #include "pt-arg-list.h" |
3770 | 36 #include "pt-bp.h" |
1741 | 37 #include "pt-exp.h" |
38 #include "pt-mat.h" | |
2124 | 39 #include "pt-walk.h" |
2201 | 40 #include "utils.h" |
2371 | 41 #include "ov.h" |
42 #include "variables.h" | |
1741 | 43 |
5630 | 44 #include "ov-re-sparse.h" |
45 #include "ov-cx-sparse.h" | |
46 | |
2254 | 47 // The character to fill with when creating string arrays. |
3836 | 48 char Vstring_fill_char = ' '; |
2254 | 49 |
1741 | 50 // General matrices. This list type is much more work to handle than |
51 // constant matrices, but it allows us to construct matrices from | |
52 // other matrices, variables, and functions. | |
53 | |
1827 | 54 // But first, some internal classes that make our job much easier. |
1741 | 55 |
1827 | 56 class |
57 tm_row_const | |
1741 | 58 { |
1827 | 59 private: |
60 | |
61 class | |
4219 | 62 tm_row_const_rep : public octave_base_list<octave_value> |
1827 | 63 { |
64 public: | |
65 | |
66 tm_row_const_rep (void) | |
5514 | 67 : count (1), dv (0, 0), all_str (false), |
5280 | 68 all_sq_str (false), all_dq_str (false), |
5502 | 69 some_str (false), all_real (false), all_cmplx (false), |
8147
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
70 all_mt (true), any_sparse (false), any_class (false), |
5630 | 71 class_nm (octave_base_value::static_class_name ()), ok (false) |
5533 | 72 { } |
1827 | 73 |
2971 | 74 tm_row_const_rep (const tree_argument_list& row) |
5514 | 75 : count (1), dv (0, 0), all_str (false), all_sq_str (false), |
5502 | 76 some_str (false), all_real (false), all_cmplx (false), |
8147
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
77 all_mt (true), any_sparse (false), any_class (false), |
5630 | 78 class_nm (octave_base_value::static_class_name ()), ok (false) |
3110 | 79 { init (row); } |
1827 | 80 |
81 ~tm_row_const_rep (void) { } | |
82 | |
83 int count; | |
84 | |
4765 | 85 dim_vector dv; |
1741 | 86 |
1827 | 87 bool all_str; |
5280 | 88 bool all_sq_str; |
89 bool all_dq_str; | |
3110 | 90 bool some_str; |
5502 | 91 bool all_real; |
92 bool all_cmplx; | |
2602 | 93 bool all_mt; |
5630 | 94 bool any_sparse; |
8147
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
95 bool any_class; |
1827 | 96 |
5533 | 97 std::string class_nm; |
98 | |
1827 | 99 bool ok; |
100 | |
4501 | 101 bool do_init_element (tree_expression *, const octave_value&, bool&); |
102 | |
2971 | 103 void init (const tree_argument_list&); |
1827 | 104 |
105 private: | |
106 | |
107 tm_row_const_rep (const tm_row_const_rep&); | |
108 | |
2971 | 109 tm_row_const_rep& operator = (const tm_row_const_rep&); |
2419 | 110 |
3661 | 111 void eval_error (const char *msg, int l, int c, |
112 int x = -1, int y = -1) const; | |
2419 | 113 |
114 void eval_warning (const char *msg, int l, int c) const; | |
1827 | 115 }; |
116 | |
117 public: | |
118 | |
4219 | 119 typedef tm_row_const_rep::iterator iterator; |
120 typedef tm_row_const_rep::const_iterator const_iterator; | |
121 | |
2990 | 122 tm_row_const (void) |
123 : rep (0) { } | |
1827 | 124 |
2971 | 125 tm_row_const (const tree_argument_list& row) |
126 : rep (new tm_row_const_rep (row)) { } | |
1827 | 127 |
2990 | 128 tm_row_const (const tm_row_const& x) |
129 : rep (x.rep) | |
130 { | |
131 if (rep) | |
132 rep->count++; | |
133 } | |
1827 | 134 |
135 tm_row_const& operator = (const tm_row_const& x) | |
2990 | 136 { |
137 if (this != &x && rep != x.rep) | |
138 { | |
139 if (rep && --rep->count == 0) | |
140 delete rep; | |
1741 | 141 |
2990 | 142 rep = x.rep; |
1827 | 143 |
2990 | 144 if (rep) |
145 rep->count++; | |
146 } | |
1741 | 147 |
2990 | 148 return *this; |
149 } | |
1827 | 150 |
151 ~tm_row_const (void) | |
2990 | 152 { |
153 if (rep && --rep->count == 0) | |
154 delete rep; | |
155 } | |
1741 | 156 |
5514 | 157 octave_idx_type rows (void) { return rep->dv(0); } |
158 octave_idx_type cols (void) { return rep->dv(1); } | |
4765 | 159 |
6200 | 160 bool empty (void) const { return rep->empty (); } |
161 | |
8147
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
162 size_t length (void) const { return rep->length (); } |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
163 |
4765 | 164 dim_vector dims (void) { return rep->dv; } |
1827 | 165 |
2868 | 166 bool all_strings_p (void) const { return rep->all_str; } |
5280 | 167 bool all_sq_strings_p (void) const { return rep->all_sq_str; } |
168 bool all_dq_strings_p (void) const { return rep->all_dq_str; } | |
3110 | 169 bool some_strings_p (void) const { return rep->some_str; } |
5502 | 170 bool all_real_p (void) const { return rep->all_real; } |
171 bool all_complex_p (void) const { return rep->all_cmplx; } | |
2868 | 172 bool all_empty_p (void) const { return rep->all_mt; } |
5630 | 173 bool any_sparse_p (void) const { return rep->any_sparse; } |
8147
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
174 bool any_class_p (void) const { return rep->any_class; } |
1827 | 175 |
5533 | 176 std::string class_name (void) const { return rep->class_nm; } |
177 | |
4219 | 178 operator bool () const { return (rep && rep->ok); } |
1827 | 179 |
4219 | 180 iterator begin (void) { return rep->begin (); } |
181 const_iterator begin (void) const { return rep->begin (); } | |
182 | |
183 iterator end (void) { return rep->end (); } | |
184 const_iterator end (void) const { return rep->end (); } | |
1827 | 185 |
186 private: | |
187 | |
188 tm_row_const_rep *rep; | |
189 }; | |
190 | |
8107
8655dc0906e6
Special case single type conacation in Fcat. Rework cell2mat to take advantage
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
191 std::string |
5533 | 192 get_concat_class (const std::string& c1, const std::string& c2) |
193 { | |
194 std::string retval = octave_base_value::static_class_name (); | |
195 | |
196 if (c1 == c2) | |
197 retval = c1; | |
198 else | |
199 { | |
200 bool c1_is_int = (c1 == "int8" || c1 == "uint8" | |
201 || c1 == "int16" || c1 == "uint16" | |
202 || c1 == "int32" || c1 == "uint32" | |
203 || c1 == "int64" || c1 == "uint64"); | |
204 bool c2_is_int = (c2 == "int8" || c2 == "uint8" | |
205 || c2 == "int16" || c2 == "uint16" | |
206 || c2 == "int32" || c2 == "uint32" | |
207 || c2 == "int64" || c2 == "uint64"); | |
208 | |
209 bool c1_is_char = (c1 == "char"); | |
210 bool c2_is_char = (c2 == "char"); | |
211 | |
212 bool c1_is_double = (c1 == "double"); | |
213 bool c2_is_double = (c2 == "double"); | |
214 | |
215 bool c1_is_single = (c1 == "single"); | |
216 bool c2_is_single = (c2 == "single"); | |
217 | |
218 bool c1_is_logical = (c1 == "logical"); | |
219 bool c2_is_logical = (c2 == "logical"); | |
220 | |
221 bool c1_is_built_in_type | |
222 = (c1_is_int || c1_is_char || c1_is_double || c1_is_single | |
223 || c1_is_logical); | |
224 | |
225 bool c2_is_built_in_type | |
226 = (c2_is_int || c2_is_char || c2_is_double || c2_is_single | |
227 || c2_is_logical); | |
228 | |
229 // Order is important here... | |
230 | |
231 if (c1_is_char && c2_is_built_in_type) | |
232 retval = c1; | |
233 else if (c2_is_char && c1_is_built_in_type) | |
234 retval = c2; | |
235 else if (c1_is_int && c2_is_built_in_type) | |
236 retval = c1; | |
237 else if (c2_is_int && c1_is_built_in_type) | |
238 retval = c2; | |
239 else if (c1_is_single && c2_is_built_in_type) | |
240 retval = c1; | |
241 else if (c2_is_single && c1_is_built_in_type) | |
242 retval = c2; | |
243 else if (c1_is_double && c2_is_built_in_type) | |
244 retval = c1; | |
245 else if (c2_is_double && c1_is_built_in_type) | |
246 retval = c2; | |
247 else if (c1_is_logical && c2_is_logical) | |
248 retval = c1; | |
249 } | |
250 | |
251 return retval; | |
252 } | |
253 | |
4501 | 254 bool |
255 tm_row_const::tm_row_const_rep::do_init_element (tree_expression *elt, | |
256 const octave_value& val, | |
257 bool& first_elem) | |
258 { | |
5275 | 259 octave_idx_type this_elt_nr = val.rows (); |
260 octave_idx_type this_elt_nc = val.columns (); | |
4501 | 261 |
5533 | 262 std::string this_elt_class_nm = val.class_name (); |
263 | |
4765 | 264 dim_vector this_elt_dv = val.dims (); |
265 | |
5502 | 266 if (! this_elt_dv.all_zero ()) |
4501 | 267 { |
268 all_mt = false; | |
269 | |
270 if (first_elem) | |
271 { | |
272 first_elem = false; | |
273 | |
5533 | 274 class_nm = this_elt_class_nm; |
275 | |
4765 | 276 dv.resize (this_elt_dv.length ()); |
277 for (int i = 2; i < dv.length (); i++) | |
278 dv.elem (i) = this_elt_dv.elem (i); | |
279 | |
280 dv.elem (0) = this_elt_nr; | |
281 | |
282 dv.elem (1) = 0; | |
4501 | 283 } |
4765 | 284 else |
4501 | 285 { |
5533 | 286 class_nm = get_concat_class (class_nm, this_elt_class_nm); |
287 | |
5045 | 288 int len = (this_elt_dv.length () < dv.length () |
289 ? this_elt_dv.length () : dv.length ()); | |
290 | |
4765 | 291 if (this_elt_nr != dv (0)) |
292 { | |
293 eval_error ("number of rows must match", | |
294 elt->line (), elt->column (), this_elt_nr, dv (0)); | |
295 return false; | |
296 } | |
5045 | 297 for (int i = 2; i < len; i++) |
4765 | 298 { |
299 if (this_elt_dv (i) != dv (i)) | |
300 { | |
301 eval_error ("dimensions mismatch", elt->line (), elt->column (), this_elt_dv (i), dv (i)); | |
302 return false; | |
303 } | |
304 } | |
5045 | 305 |
306 if (this_elt_dv.length () > len) | |
307 for (int i = len; i < this_elt_dv.length (); i++) | |
308 if (this_elt_dv (i) != 1) | |
309 { | |
310 eval_error ("dimensions mismatch", elt->line (), elt->column (), this_elt_dv (i), 1); | |
311 return false; | |
312 } | |
313 | |
314 if (dv.length () > len) | |
315 for (int i = len; i < dv.length (); i++) | |
316 if (dv (i) != 1) | |
317 { | |
318 eval_error ("dimensions mismatch", elt->line (), elt->column (), 1, dv (i)); | |
319 return false; | |
320 } | |
4501 | 321 } |
4765 | 322 dv.elem (1) = dv.elem (1) + this_elt_nc; |
4501 | 323 |
324 } | |
5781 | 325 else |
4501 | 326 eval_warning ("empty matrix found in matrix list", |
327 elt->line (), elt->column ()); | |
328 | |
4915 | 329 append (val); |
330 | |
4501 | 331 if (all_str && ! val.is_string ()) |
332 all_str = false; | |
333 | |
5280 | 334 if (all_sq_str && ! val.is_sq_string ()) |
335 all_sq_str = false; | |
336 | |
337 if (all_dq_str && ! val.is_dq_string ()) | |
338 all_dq_str = false; | |
339 | |
4501 | 340 if (! some_str && val.is_string ()) |
341 some_str = true; | |
342 | |
5502 | 343 if (all_real && ! val.is_real_type ()) |
344 all_real = false; | |
345 | |
346 if (all_cmplx && ! (val.is_complex_type () || val.is_real_type ())) | |
347 all_cmplx = false; | |
4501 | 348 |
5631 | 349 if (!any_sparse && val.is_sparse_type ()) |
5630 | 350 any_sparse = true; |
351 | |
8147
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
352 if (!any_class && val.is_object ()) |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
353 any_class = true; |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
354 |
4501 | 355 return true; |
356 } | |
357 | |
1827 | 358 void |
2971 | 359 tm_row_const::tm_row_const_rep::init (const tree_argument_list& row) |
1827 | 360 { |
361 all_str = true; | |
5280 | 362 all_sq_str = true; |
363 all_dq_str = true; | |
5502 | 364 all_real = true; |
365 all_cmplx = true; | |
5630 | 366 any_sparse = false; |
8147
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
367 any_class = false; |
1827 | 368 |
369 bool first_elem = true; | |
370 | |
4219 | 371 for (tree_argument_list::const_iterator p = row.begin (); |
372 p != row.end (); | |
373 p++) | |
1827 | 374 { |
5502 | 375 OCTAVE_QUIT; |
376 | |
4219 | 377 tree_expression *elt = *p; |
1827 | 378 |
8658
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
8147
diff
changeset
|
379 octave_value tmp = elt->rvalue1 (); |
1827 | 380 |
381 if (error_state || tmp.is_undefined ()) | |
382 break; | |
383 else | |
384 { | |
4501 | 385 if (tmp.is_cs_list ()) |
1827 | 386 { |
4587 | 387 octave_value_list tlst = tmp.list_value (); |
2602 | 388 |
5275 | 389 for (octave_idx_type i = 0; i < tlst.length (); i++) |
1827 | 390 { |
5502 | 391 OCTAVE_QUIT; |
392 | |
4587 | 393 if (! do_init_element (elt, tlst(i), first_elem)) |
4501 | 394 goto done; |
1827 | 395 } |
396 } | |
4501 | 397 else |
398 { | |
399 if (! do_init_element (elt, tmp, first_elem)) | |
400 goto done; | |
401 } | |
1827 | 402 } |
403 } | |
404 | |
4501 | 405 done: |
406 | |
1827 | 407 ok = ! error_state; |
1741 | 408 } |
409 | |
2419 | 410 void |
411 tm_row_const::tm_row_const_rep::eval_error (const char *msg, int l, | |
3661 | 412 int c, int x, int y) const |
2419 | 413 { |
414 if (l == -1 && c == -1) | |
3661 | 415 { |
416 if (x == -1 || y == -1) | |
417 ::error ("%s", msg); | |
418 else | |
419 ::error ("%s (%d != %d)", msg, x, y); | |
420 } | |
2419 | 421 else |
3661 | 422 { |
423 if (x == -1 || y == -1) | |
424 ::error ("%s near line %d, column %d", msg, l, c); | |
425 else | |
426 ::error ("%s (%d != %d) near line %d, column %d", msg, x, y, l, c); | |
427 } | |
2419 | 428 } |
429 | |
430 void | |
431 tm_row_const::tm_row_const_rep::eval_warning (const char *msg, int l, | |
432 int c) const | |
433 { | |
434 if (l == -1 && c == -1) | |
5781 | 435 warning_with_id ("Octave:empty-list-elements", "%s", msg); |
2419 | 436 else |
5781 | 437 warning_with_id ("Octave:empty-list-elements", |
438 "%s near line %d, column %d", msg, l, c); | |
2419 | 439 } |
440 | |
1827 | 441 class |
4219 | 442 tm_const : public octave_base_list<tm_row_const> |
1827 | 443 { |
444 public: | |
445 | |
446 tm_const (const tree_matrix& tm) | |
5514 | 447 : dv (0, 0), all_str (false), all_sq_str (false), all_dq_str (false), |
5502 | 448 some_str (false), all_real (false), all_cmplx (false), |
8147
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
449 all_mt (true), any_sparse (false), any_class (false), |
5630 | 450 class_nm (octave_base_value::static_class_name ()), ok (false) |
5533 | 451 { init (tm); } |
1827 | 452 |
453 ~tm_const (void) { } | |
454 | |
5514 | 455 octave_idx_type rows (void) const { return dv.elem (0); } |
456 octave_idx_type cols (void) const { return dv.elem (1); } | |
4765 | 457 |
458 dim_vector dims (void) const { return dv; } | |
1827 | 459 |
2868 | 460 bool all_strings_p (void) const { return all_str; } |
5280 | 461 bool all_sq_strings_p (void) const { return all_sq_str; } |
462 bool all_dq_strings_p (void) const { return all_dq_str; } | |
3110 | 463 bool some_strings_p (void) const { return some_str; } |
5502 | 464 bool all_real_p (void) const { return all_real; } |
465 bool all_complex_p (void) const { return all_cmplx; } | |
2868 | 466 bool all_empty_p (void) const { return all_mt; } |
5630 | 467 bool any_sparse_p (void) const { return any_sparse; } |
8147
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
468 bool any_class_p (void) const { return any_class; } |
1827 | 469 |
5533 | 470 std::string class_name (void) const { return class_nm; } |
471 | |
3145 | 472 operator bool () const { return ok; } |
1827 | 473 |
474 private: | |
475 | |
4765 | 476 dim_vector dv; |
1827 | 477 |
478 bool all_str; | |
5280 | 479 bool all_sq_str; |
480 bool all_dq_str; | |
3110 | 481 bool some_str; |
5502 | 482 bool all_real; |
483 bool all_cmplx; | |
2602 | 484 bool all_mt; |
5630 | 485 bool any_sparse; |
8147
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
486 bool any_class; |
1827 | 487 |
5533 | 488 std::string class_nm; |
489 | |
1827 | 490 bool ok; |
491 | |
492 tm_const (void); | |
493 | |
494 tm_const (const tm_const&); | |
495 | |
496 tm_const& operator = (const tm_const&); | |
497 | |
498 void init (const tree_matrix& tm); | |
499 }; | |
500 | |
501 void | |
502 tm_const::init (const tree_matrix& tm) | |
1741 | 503 { |
1827 | 504 all_str = true; |
5280 | 505 all_sq_str = true; |
506 all_dq_str = true; | |
5502 | 507 all_real = true; |
508 all_cmplx = true; | |
5630 | 509 any_sparse = false; |
8147
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
510 any_class = false; |
1827 | 511 |
512 bool first_elem = true; | |
513 | |
514 // Just eval and figure out if what we have is complex or all | |
515 // strings. We can't check columns until we know that this is a | |
516 // numeric matrix -- collections of strings can have elements of | |
517 // different lengths. | |
518 | |
4219 | 519 for (tree_matrix::const_iterator p = tm.begin (); p != tm.end (); p++) |
1827 | 520 { |
5502 | 521 OCTAVE_QUIT; |
522 | |
4219 | 523 tree_argument_list *elt = *p; |
1827 | 524 |
525 tm_row_const tmp (*elt); | |
526 | |
6200 | 527 if (tmp && ! tmp.empty ()) |
1827 | 528 { |
2868 | 529 if (all_str && ! tmp.all_strings_p ()) |
1827 | 530 all_str = false; |
531 | |
5280 | 532 if (all_sq_str && ! tmp.all_sq_strings_p ()) |
533 all_sq_str = false; | |
534 | |
535 if (all_dq_str && ! tmp.all_dq_strings_p ()) | |
536 all_dq_str = false; | |
537 | |
3110 | 538 if (! some_str && tmp.some_strings_p ()) |
539 some_str = true; | |
540 | |
5502 | 541 if (all_real && ! tmp.all_real_p ()) |
542 all_real = false; | |
543 | |
544 if (all_cmplx && ! tmp.all_complex_p ()) | |
545 all_cmplx = false; | |
1827 | 546 |
2868 | 547 if (all_mt && ! tmp.all_empty_p ()) |
2602 | 548 all_mt = false; |
549 | |
5630 | 550 if (!any_sparse && tmp.any_sparse_p ()) |
551 any_sparse = true; | |
552 | |
8147
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
553 if (!any_class && tmp.any_class_p ()) |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
554 any_class = true; |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
555 |
1827 | 556 append (tmp); |
557 } | |
558 else | |
559 break; | |
560 } | |
561 | |
562 if (! error_state) | |
563 { | |
4219 | 564 for (iterator p = begin (); p != end (); p++) |
1827 | 565 { |
5502 | 566 OCTAVE_QUIT; |
567 | |
4219 | 568 tm_row_const elt = *p; |
1827 | 569 |
5275 | 570 octave_idx_type this_elt_nr = elt.rows (); |
571 octave_idx_type this_elt_nc = elt.cols (); | |
1827 | 572 |
5533 | 573 std::string this_elt_class_nm = elt.class_name (); |
574 | |
4765 | 575 dim_vector this_elt_dv = elt.dims (); |
576 | |
577 if (!this_elt_dv.all_zero ()) | |
1827 | 578 { |
2602 | 579 all_mt = false; |
580 | |
1827 | 581 if (first_elem) |
582 { | |
583 first_elem = false; | |
584 | |
5533 | 585 class_nm = this_elt_class_nm; |
586 | |
4765 | 587 dv.resize (this_elt_dv.length ()); |
588 for (int i = 2; i < dv.length (); i++) | |
589 dv.elem (i) = this_elt_dv.elem (i); | |
590 | |
591 dv.elem (0) = 0; | |
592 | |
593 dv.elem (1) = this_elt_nc; | |
1827 | 594 } |
595 else if (all_str) | |
596 { | |
5533 | 597 class_nm = get_concat_class (class_nm, this_elt_class_nm); |
598 | |
4765 | 599 if (this_elt_nc > cols ()) |
600 dv.elem (1) = this_elt_nc; | |
1827 | 601 } |
4765 | 602 else |
1827 | 603 { |
5533 | 604 class_nm = get_concat_class (class_nm, this_elt_class_nm); |
605 | |
4765 | 606 bool get_out = false; |
5045 | 607 int len = (this_elt_dv.length () < dv.length () |
608 ? this_elt_dv.length () : dv.length ()); | |
4765 | 609 |
5045 | 610 for (int i = 1; i < len; i++) |
4765 | 611 { |
612 if (i == 1 && this_elt_nc != dv (1)) | |
613 { | |
614 ::error ("number of columns must match (%d != %d)", | |
615 this_elt_nc, dv (1)); | |
616 get_out = true; | |
617 break; | |
618 } | |
619 else if (this_elt_dv (i) != dv (i)) | |
620 { | |
621 ::error ("dimensions mismatch (dim = %i, %d != %d)", i+1, this_elt_dv (i), dv (i)); | |
622 get_out = true; | |
623 break; | |
624 } | |
625 } | |
626 | |
5045 | 627 if (this_elt_dv.length () > len) |
628 for (int i = len; i < this_elt_dv.length (); i++) | |
629 if (this_elt_dv (i) != 1) | |
630 { | |
631 ::error ("dimensions mismatch (dim = %i, %d != %d)", i+1, this_elt_dv (i), 1); | |
632 get_out = true; | |
633 break; | |
634 } | |
635 | |
636 if (dv.length () > len) | |
637 for (int i = len; i < dv.length (); i++) | |
638 if (dv (i) != 1) | |
639 { | |
640 ::error ("dimensions mismatch (dim = %i, %d != %d)", i+1, 1, dv(i)); | |
641 get_out = true; | |
642 break; | |
643 } | |
644 | |
4765 | 645 if (get_out) |
646 break; | |
1827 | 647 } |
4765 | 648 dv.elem (0) = dv.elem (0) + this_elt_nr; |
1827 | 649 } |
5781 | 650 else |
651 warning_with_id ("Octave:empty-list-elements", | |
652 "empty matrix found in matrix list"); | |
1827 | 653 } |
654 } | |
655 | |
656 ok = ! error_state; | |
1741 | 657 } |
658 | |
2990 | 659 tree_matrix::~tree_matrix (void) |
660 { | |
4219 | 661 while (! empty ()) |
2990 | 662 { |
4219 | 663 iterator p = begin (); |
664 delete *p; | |
665 erase (p); | |
2990 | 666 } |
667 } | |
668 | |
1827 | 669 bool |
4267 | 670 tree_matrix::has_magic_end (void) const |
671 { | |
672 for (const_iterator p = begin (); p != end (); p++) | |
673 { | |
5502 | 674 OCTAVE_QUIT; |
675 | |
4267 | 676 tree_argument_list *elt = *p; |
677 | |
678 if (elt && elt->has_magic_end ()) | |
679 return true; | |
680 } | |
681 | |
682 return false; | |
683 } | |
684 | |
685 bool | |
2529 | 686 tree_matrix::all_elements_are_constant (void) const |
1827 | 687 { |
4219 | 688 for (const_iterator p = begin (); p != end (); p++) |
1827 | 689 { |
5502 | 690 OCTAVE_QUIT; |
691 | |
4219 | 692 tree_argument_list *elt = *p; |
1827 | 693 |
2529 | 694 if (! elt->all_elements_are_constant ()) |
1827 | 695 return false; |
696 } | |
697 | |
698 return true; | |
699 } | |
700 | |
2971 | 701 octave_value_list |
702 tree_matrix::rvalue (int nargout) | |
703 { | |
704 octave_value_list retval; | |
705 | |
706 if (nargout > 1) | |
707 error ("invalid number of output arguments for matrix list"); | |
708 else | |
8658
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
8147
diff
changeset
|
709 retval = rvalue1 (nargout); |
2971 | 710 |
711 return retval; | |
712 } | |
713 | |
8107
8655dc0906e6
Special case single type conacation in Fcat. Rework cell2mat to take advantage
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
714 void |
5280 | 715 maybe_warn_string_concat (bool all_dq_strings_p, bool all_sq_strings_p) |
716 { | |
5781 | 717 if (! (all_dq_strings_p || all_sq_strings_p)) |
718 warning_with_id ("Octave:string-concat", | |
719 "concatenation of different character string types may have unintended consequences"); | |
5280 | 720 } |
721 | |
5502 | 722 #define SINGLE_TYPE_CONCAT(TYPE, EXTRACTOR) \ |
723 do \ | |
724 { \ | |
725 int dv_len = dv.length (); \ | |
726 Array<octave_idx_type> ra_idx (dv_len > 1 ? dv_len : 2, 0); \ | |
727 \ | |
728 for (tm_const::iterator p = tmp.begin (); p != tmp.end (); p++) \ | |
729 { \ | |
730 OCTAVE_QUIT; \ | |
731 \ | |
732 tm_row_const row = *p; \ | |
733 \ | |
734 for (tm_row_const::iterator q = row.begin (); \ | |
735 q != row.end (); \ | |
736 q++) \ | |
737 { \ | |
738 OCTAVE_QUIT; \ | |
739 \ | |
740 TYPE ra = q->EXTRACTOR (); \ | |
741 \ | |
742 if (! error_state) \ | |
743 { \ | |
744 result.insert (ra, ra_idx); \ | |
745 \ | |
746 if (! error_state) \ | |
747 ra_idx(1) += ra.columns (); \ | |
748 else \ | |
749 goto done; \ | |
750 } \ | |
751 else \ | |
752 goto done; \ | |
753 } \ | |
754 \ | |
755 ra_idx(0) += row.rows (); \ | |
756 ra_idx(1) = 0; \ | |
757 } \ | |
758 } \ | |
759 while (0) | |
760 | |
5533 | 761 #define DO_SINGLE_TYPE_CONCAT(TYPE, EXTRACTOR) \ |
762 do \ | |
763 { \ | |
764 TYPE result (dv); \ | |
765 \ | |
766 SINGLE_TYPE_CONCAT(TYPE, EXTRACTOR); \ | |
767 \ | |
768 retval = result; \ | |
769 } \ | |
770 while (0) | |
771 | |
2086 | 772 octave_value |
8658
73c4516fae10
New evaluator and debugger derived from tree-walker class
John W. Eaton <jwe@octave.org>
parents:
8147
diff
changeset
|
773 tree_matrix::rvalue1 (int) |
1741 | 774 { |
6200 | 775 octave_value retval = Matrix (); |
1741 | 776 |
4915 | 777 bool all_strings_p = false; |
5280 | 778 bool all_sq_strings_p = false; |
779 bool all_dq_strings_p = false; | |
4915 | 780 bool all_empty_p = false; |
5502 | 781 bool all_real_p = false; |
782 bool all_complex_p = false; | |
5630 | 783 bool any_sparse_p = false; |
8147
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
784 bool any_class_p = false; |
4915 | 785 bool frc_str_conv = false; |
1741 | 786 |
4915 | 787 tm_const tmp (*this); |
3110 | 788 |
6200 | 789 if (tmp && ! tmp.empty ()) |
1827 | 790 { |
4765 | 791 dim_vector dv = tmp.dims (); |
4915 | 792 all_strings_p = tmp.all_strings_p (); |
5280 | 793 all_sq_strings_p = tmp.all_sq_strings_p (); |
794 all_dq_strings_p = tmp.all_dq_strings_p (); | |
4915 | 795 all_empty_p = tmp.all_empty_p (); |
5502 | 796 all_real_p = tmp.all_real_p (); |
797 all_complex_p = tmp.all_complex_p (); | |
5630 | 798 any_sparse_p = tmp.any_sparse_p (); |
8147
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
799 any_class_p = tmp.any_class_p (); |
4915 | 800 frc_str_conv = tmp.some_strings_p (); |
1741 | 801 |
5502 | 802 // Try to speed up the common cases. |
4915 | 803 |
5533 | 804 std::string result_type = tmp.class_name (); |
805 | |
8147
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
806 if (any_class_p) |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
807 { |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
808 octave_value_list tmp3 (tmp.length (), octave_value ()); |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
809 |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
810 int j = 0; |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
811 for (tm_const::iterator p = tmp.begin (); p != tmp.end (); p++) |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
812 { |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
813 OCTAVE_QUIT; |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
814 |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
815 tm_row_const row = *p; |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
816 |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
817 if (row.length () == 1) |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
818 tmp3 (j++) = *(row.begin ()); |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
819 else |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
820 { |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
821 octave_value_list tmp1 (row.length (), octave_value ()); |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
822 |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
823 int i = 0; |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
824 for (tm_row_const::iterator q = row.begin (); |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
825 q != row.end (); q++) |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
826 tmp1 (i++) = *q; |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
827 |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
828 octave_value_list tmp2; |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
829 octave_value fcn = |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
830 symbol_table::find_function ("horzcat", tmp1); |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
831 |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
832 if (fcn.is_defined ()) |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
833 { |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
834 tmp2 = fcn.do_multi_index_op (1, tmp1); |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
835 |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
836 if (error_state) |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
837 goto done; |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
838 |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
839 tmp3 (j++) = tmp2 (0); |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
840 } |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
841 else |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
842 { |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
843 ::error ("cat not find overloaded horzcat function"); |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
844 goto done; |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
845 } |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
846 } |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
847 } |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
848 |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
849 if (tmp.length () == 1) |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
850 retval = tmp3 (0); |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
851 else |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
852 { |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
853 octave_value_list tmp2; |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
854 octave_value fcn = symbol_table::find_function ("vertcat", tmp3); |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
855 |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
856 if (fcn.is_defined ()) |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
857 { |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
858 tmp2 = fcn.do_multi_index_op (1, tmp3); |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
859 |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
860 if (! error_state) |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
861 retval = tmp2 (0); |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
862 } |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
863 else |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
864 ::error ("cat not find overloaded vertcat function"); |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
865 } |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
866 } |
9a5ef4f632a3
Add class dispatch for [] operator to vertcat/horzcat methods
David Bateman <dbateman@free.fr>
parents:
8107
diff
changeset
|
867 else if (result_type == "double") |
5533 | 868 { |
6823 | 869 if (any_sparse_p) |
870 { | |
871 if (all_real_p) | |
872 DO_SINGLE_TYPE_CONCAT (SparseMatrix, sparse_matrix_value); | |
873 else | |
874 DO_SINGLE_TYPE_CONCAT (SparseComplexMatrix, sparse_complex_matrix_value); | |
875 } | |
5533 | 876 else |
6823 | 877 { |
878 if (all_real_p) | |
879 DO_SINGLE_TYPE_CONCAT (NDArray, array_value); | |
880 else | |
881 DO_SINGLE_TYPE_CONCAT (ComplexNDArray, complex_array_value); | |
882 } | |
5533 | 883 } |
884 else if (result_type == "single") | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7767
diff
changeset
|
885 { |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7767
diff
changeset
|
886 if (all_real_p) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7767
diff
changeset
|
887 DO_SINGLE_TYPE_CONCAT (FloatNDArray, float_array_value); |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7767
diff
changeset
|
888 else |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7767
diff
changeset
|
889 DO_SINGLE_TYPE_CONCAT (FloatComplexNDArray, |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7767
diff
changeset
|
890 float_complex_array_value); |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7767
diff
changeset
|
891 } |
5533 | 892 else if (result_type == "char") |
5280 | 893 { |
7270 | 894 char type = all_dq_strings_p ? '"' : '\''; |
5280 | 895 |
896 maybe_warn_string_concat (all_dq_strings_p, all_sq_strings_p); | |
897 | |
5502 | 898 charNDArray result (dv, Vstring_fill_char); |
899 | |
900 SINGLE_TYPE_CONCAT (charNDArray, char_array_value); | |
901 | |
902 retval = octave_value (result, true, type); | |
903 } | |
5533 | 904 else if (result_type == "logical") |
6823 | 905 { |
906 if (any_sparse_p) | |
907 DO_SINGLE_TYPE_CONCAT (SparseBoolMatrix, sparse_bool_matrix_value); | |
908 else | |
909 DO_SINGLE_TYPE_CONCAT (boolNDArray, bool_array_value); | |
910 } | |
5533 | 911 else if (result_type == "int8") |
912 DO_SINGLE_TYPE_CONCAT (int8NDArray, int8_array_value); | |
913 else if (result_type == "int16") | |
914 DO_SINGLE_TYPE_CONCAT (int16NDArray, int16_array_value); | |
915 else if (result_type == "int32") | |
916 DO_SINGLE_TYPE_CONCAT (int32NDArray, int32_array_value); | |
917 else if (result_type == "int64") | |
918 DO_SINGLE_TYPE_CONCAT (int64NDArray, int64_array_value); | |
919 else if (result_type == "uint8") | |
920 DO_SINGLE_TYPE_CONCAT (uint8NDArray, uint8_array_value); | |
921 else if (result_type == "uint16") | |
922 DO_SINGLE_TYPE_CONCAT (uint16NDArray, uint16_array_value); | |
923 else if (result_type == "uint32") | |
924 DO_SINGLE_TYPE_CONCAT (uint32NDArray, uint32_array_value); | |
925 else if (result_type == "uint64") | |
926 DO_SINGLE_TYPE_CONCAT (uint64NDArray, uint64_array_value); | |
4915 | 927 else |
928 { | |
5502 | 929 // The line below might seem crazy, since we take a copy of |
930 // the first argument, resize it to be empty and then resize | |
931 // it to be full. This is done since it means that there is | |
932 // no recopying of data, as would happen if we used a single | |
933 // resize. It should be noted that resize operation is also | |
934 // significantly slower than the do_cat_op function, so it | |
935 // makes sense to have an empty matrix and copy all data. | |
936 // | |
937 // We might also start with a empty octave_value using | |
938 // | |
939 // ctmp = octave_value_typeinfo::lookup_type | |
940 // (tmp.begin() -> begin() -> type_name()); | |
941 // | |
942 // and then directly resize. However, for some types there | |
943 // might be some additional setup needed, and so this should | |
944 // be avoided. | |
945 | |
946 octave_value ctmp; | |
947 | |
5164 | 948 // Find the first non-empty object |
5502 | 949 |
5630 | 950 if (any_sparse_p) |
5164 | 951 { |
5630 | 952 // Start with sparse matrix to avoid issues memory issues |
953 // with things like [ones(1,4),sprandn(1e8,4,1e-4)] | |
954 if (all_real_p) | |
955 ctmp = octave_sparse_matrix ().resize (dv); | |
956 else | |
957 ctmp = octave_sparse_complex_matrix ().resize (dv); | |
958 } | |
959 else | |
960 { | |
961 for (tm_const::iterator p = tmp.begin (); p != tmp.end (); p++) | |
5164 | 962 { |
5502 | 963 OCTAVE_QUIT; |
964 | |
5630 | 965 tm_row_const row = *p; |
5502 | 966 |
5630 | 967 for (tm_row_const::iterator q = row.begin (); |
968 q != row.end (); q++) | |
969 { | |
970 OCTAVE_QUIT; | |
971 | |
972 ctmp = *q; | |
5164 | 973 |
5630 | 974 if (! ctmp.all_zero_dims ()) |
975 goto found_non_empty; | |
976 } | |
977 } | |
5164 | 978 |
5630 | 979 ctmp = (*(tmp.begin() -> begin())); |
980 | |
981 found_non_empty: | |
5502 | 982 |
5630 | 983 if (! all_empty_p) |
984 ctmp = ctmp.resize (dim_vector (0,0)).resize (dv); | |
985 } | |
4915 | 986 |
5502 | 987 if (! error_state) |
1827 | 988 { |
5502 | 989 // Now, extract the values from the individual elements and |
990 // insert them in the result matrix. | |
991 | |
992 int dv_len = dv.length (); | |
6867 | 993 Array<octave_idx_type> ra_idx (dv_len > 1 ? dv_len : 2, 0); |
5502 | 994 |
995 for (tm_const::iterator p = tmp.begin (); p != tmp.end (); p++) | |
996 { | |
997 OCTAVE_QUIT; | |
998 | |
999 tm_row_const row = *p; | |
1000 | |
1001 for (tm_row_const::iterator q = row.begin (); | |
1002 q != row.end (); | |
1003 q++) | |
1004 { | |
1005 OCTAVE_QUIT; | |
1741 | 1006 |
5502 | 1007 octave_value elt = *q; |
1008 | |
1009 ctmp = do_cat_op (ctmp, elt, ra_idx); | |
1010 | |
1011 if (error_state) | |
1012 goto done; | |
1013 | |
1014 ra_idx (1) += elt.columns (); | |
1015 } | |
1016 | |
1017 ra_idx (0) += row.rows (); | |
1018 ra_idx (1) = 0; | |
1019 } | |
1020 | |
1021 retval = ctmp; | |
1022 | |
1023 if (frc_str_conv && ! retval.is_string ()) | |
1024 retval = retval.convert_to_str (); | |
1741 | 1025 } |
1026 } | |
1027 } | |
1028 | |
1827 | 1029 done: |
1741 | 1030 return retval; |
1031 } | |
1032 | |
5861 | 1033 tree_expression * |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
1034 tree_matrix::dup (symbol_table::scope_id scope, |
8913
35cd375d4bb3
make tree::dup functions const
John W. Eaton <jwe@octave.org>
parents:
8658
diff
changeset
|
1035 symbol_table::context_id context) const |
5861 | 1036 { |
1037 tree_matrix *new_matrix = new tree_matrix (0, line (), column ()); | |
1038 | |
8913
35cd375d4bb3
make tree::dup functions const
John W. Eaton <jwe@octave.org>
parents:
8658
diff
changeset
|
1039 for (const_iterator p = begin (); p != end (); p++) |
5861 | 1040 { |
8913
35cd375d4bb3
make tree::dup functions const
John W. Eaton <jwe@octave.org>
parents:
8658
diff
changeset
|
1041 const tree_argument_list *elt = *p; |
5861 | 1042 |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
1043 new_matrix->append (elt ? elt->dup (scope, context) : 0); |
5861 | 1044 } |
1045 | |
1046 new_matrix->copy_base (*this); | |
1047 | |
1048 return new_matrix; | |
1049 } | |
1050 | |
1741 | 1051 void |
2124 | 1052 tree_matrix::accept (tree_walker& tw) |
1741 | 1053 { |
2124 | 1054 tw.visit_matrix (*this); |
1741 | 1055 } |
1056 | |
5794 | 1057 DEFUN (string_fill_char, args, nargout, |
1058 "-*- texinfo -*-\n\ | |
1059 @deftypefn {Built-in Function} {@var{val} =} string_fill_char ()\n\ | |
1060 @deftypefnx {Built-in Function} {@var{old_val} =} string_fill_char (@var{new_val})\n\ | |
1061 Query or set the internal variable used to pad all rows of a character\n\ | |
1062 matrix to the same length. It must be a single character. The default\n\ | |
1063 value is @code{\" \"} (a single space). For example,\n\ | |
3361 | 1064 \n\ |
1065 @example\n\ | |
1066 @group\n\ | |
5794 | 1067 string_fill_char (\"X\");\n\ |
3361 | 1068 [ \"these\"; \"are\"; \"strings\" ]\n\ |
1069 @result{} \"theseXX\"\n\ | |
1070 \"areXXXX\"\n\ | |
1071 \"strings\"\n\ | |
1072 @end group\n\ | |
1073 @end example\n\ | |
5794 | 1074 @end deftypefn") |
1075 { | |
1076 return SET_INTERNAL_VARIABLE (string_fill_char); | |
2172 | 1077 } |
1078 | |
1741 | 1079 /* |
1080 ;;; Local Variables: *** | |
1081 ;;; mode: C++ *** | |
1082 ;;; End: *** | |
1083 */ |