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