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