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