Mercurial > hg > octave-lyh
comparison src/pt-mat.cc @ 1827:effa9400766f
[project @ 1996-02-02 14:07:51 by jwe]
author | jwe |
---|---|
date | Fri, 02 Feb 1996 14:10:10 +0000 |
parents | a02f140ed897 |
children | 003570e69c7b |
comparison
equal
deleted
inserted
replaced
1826:b14829582cc4 | 1827:effa9400766f |
---|---|
1 // pt-mat.cc -*- C++ -*- | 1 // pt-mat.cc -*- C++ -*- |
2 /* | 2 /* |
3 | 3 |
4 Copyright (C) 1992, 1993, 1994, 1995 John W. Eaton | 4 Copyright (C) 1996 John W. Eaton |
5 | 5 |
6 This file is part of Octave. | 6 This file is part of Octave. |
7 | 7 |
8 Octave is free software; you can redistribute it and/or modify it | 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 | 9 under the terms of the GNU General Public License as published by the |
44 | 44 |
45 // General matrices. This list type is much more work to handle than | 45 // General matrices. This list type is much more work to handle than |
46 // constant matrices, but it allows us to construct matrices from | 46 // constant matrices, but it allows us to construct matrices from |
47 // other matrices, variables, and functions. | 47 // other matrices, variables, and functions. |
48 | 48 |
49 tree_matrix::~tree_matrix (void) | 49 // But first, some internal classes that make our job much easier. |
50 { | 50 |
51 delete element; | 51 class |
52 delete next; | 52 tm_row_const |
53 } | 53 { |
54 | 54 private: |
55 int | 55 |
56 tree_matrix::is_matrix_constant (void) const | 56 class |
57 { | 57 tm_row_const_rep : public SLList<tree_constant> |
58 const tree_matrix *list = this; | 58 { |
59 | 59 public: |
60 while (list) | 60 |
61 { | 61 tm_row_const_rep (void) |
62 tree_expression *elem = list->element; | 62 : SLList<tree_constant> (), count (1), nr (0), nc (0), |
63 | 63 all_str (false), is_cmplx (false), ok (false) { } |
64 if (! elem->is_constant ()) | 64 |
65 return 0; | 65 tm_row_const_rep (const tree_matrix_row& mr) |
66 | 66 : SLList<tree_constant> (), count (1), nr (0), nc (0), |
67 list = list->next; | 67 all_str (false), is_cmplx (false), ok (false) |
68 } | 68 { init (mr); } |
69 | 69 |
70 return 1; | 70 ~tm_row_const_rep (void) { } |
71 } | 71 |
72 | 72 int count; |
73 tree_matrix * | 73 |
74 tree_matrix::chain (tree_expression *t, tree_matrix::dir d) | 74 int nr; |
75 { | 75 int nc; |
76 tree_matrix *tmp = new tree_matrix (t, d); | 76 |
77 tmp->next = this; | 77 bool all_str; |
78 return tmp; | 78 bool is_cmplx; |
79 } | 79 |
80 | 80 bool ok; |
81 tree_matrix * | 81 |
82 tree_matrix::reverse (void) | 82 void init (const tree_matrix_row&); |
83 { | 83 |
84 tree_matrix *list = this; | 84 private: |
85 tree_matrix *next; | 85 |
86 tree_matrix *prev = 0; | 86 tm_row_const_rep (const tm_row_const_rep&); |
87 | 87 |
88 while (list) | 88 tm_row_const_rep& operator = |
89 { | 89 (const tm_row_const_rep&); |
90 next = list->next; | 90 }; |
91 list->next = prev; | 91 |
92 prev = list; | 92 public: |
93 list = next; | 93 |
94 } | 94 tm_row_const (void) : rep (0) { } |
95 return prev; | 95 |
96 } | 96 tm_row_const (const tree_matrix_row& mr) |
97 | 97 : rep (new tm_row_const_rep (mr)) { } |
98 int | 98 |
99 tree_matrix::length (void) | 99 tm_row_const (const tm_row_const& x) : rep (x.rep) |
100 { | 100 { |
101 tree_matrix *list = this; | 101 if (rep) |
102 int len = 0; | 102 rep->count++; |
103 while (list) | 103 } |
104 { | 104 |
105 len++; | 105 tm_row_const& operator = (const tm_row_const& x) |
106 list = list->next; | 106 { |
107 } | 107 if (this != &x && rep != x.rep) |
108 return len; | 108 { |
109 if (rep && --rep->count == 0) | |
110 delete rep; | |
111 | |
112 rep = x.rep; | |
113 | |
114 if (rep) | |
115 rep->count++; | |
116 } | |
117 | |
118 return *this; | |
119 } | |
120 | |
121 ~tm_row_const (void) | |
122 { | |
123 if (rep && --rep->count == 0) | |
124 delete rep; | |
125 } | |
126 | |
127 int rows (void) { return rep->nr; } | |
128 int cols (void) { return rep->nc; } | |
129 | |
130 bool all_strings (void) const { return rep->all_str; } | |
131 bool is_complex (void) const { return rep->is_cmplx; } | |
132 | |
133 tree_constant& operator () (Pix p) { return rep->operator () (p); } | |
134 | |
135 const tree_constant& operator () (Pix p) const | |
136 { return rep->operator () (p); } | |
137 | |
138 Pix first (void) const { return rep->first (); } | |
139 void next (Pix& p) const { rep->next (p); } | |
140 | |
141 operator void* () const | |
142 { | |
143 return (rep && rep->ok) ? (void *) -1 : (void *) 0; | |
144 } | |
145 | |
146 private: | |
147 | |
148 tm_row_const_rep *rep; | |
149 }; | |
150 | |
151 void | |
152 tm_row_const::tm_row_const_rep::init (const tree_matrix_row& mr) | |
153 { | |
154 all_str = true; | |
155 | |
156 int empties_ok = user_pref.empty_list_elements_ok; | |
157 | |
158 bool first_elem = true; | |
159 | |
160 for (Pix p = mr.first (); p != 0; mr.next (p)) | |
161 { | |
162 tree_expression *elt = mr (p); | |
163 | |
164 tree_constant tmp = elt->eval (false); | |
165 | |
166 if (error_state || tmp.is_undefined ()) | |
167 break; | |
168 else | |
169 { | |
170 int this_elt_nr = tmp.rows (); | |
171 int this_elt_nc = tmp.columns (); | |
172 | |
173 if (this_elt_nr == 0 || this_elt_nc == 0) | |
174 { | |
175 if (empties_ok < 0) | |
176 warning ("empty matrix found in matrix list"); | |
177 else if (empties_ok == 0) | |
178 { | |
179 ::error ("empty matrix found in matrix list"); | |
180 break; | |
181 } | |
182 } | |
183 else | |
184 { | |
185 if (first_elem) | |
186 { | |
187 first_elem = false; | |
188 | |
189 nr = this_elt_nr; | |
190 } | |
191 else if (this_elt_nr != nr) | |
192 { | |
193 ::error ("number of rows must match"); | |
194 break; | |
195 } | |
196 | |
197 nc += this_elt_nc; | |
198 | |
199 append (tmp); | |
200 } | |
201 | |
202 if (all_str && ! tmp.is_string ()) | |
203 all_str = false; | |
204 | |
205 if (! is_cmplx && tmp.is_complex_type ()) | |
206 is_cmplx = true; | |
207 } | |
208 } | |
209 | |
210 ok = ! error_state; | |
211 } | |
212 | |
213 template class SLNode<tm_row_const>; | |
214 template class SLList<tm_row_const>; | |
215 | |
216 class | |
217 tm_const : public SLList<tm_row_const> | |
218 { | |
219 public: | |
220 | |
221 tm_const (const tree_matrix& tm) | |
222 : SLList<tm_row_const> (), nr (0), nc (0), all_str (false), | |
223 is_cmplx (false), ok (false) | |
224 { init (tm); } | |
225 | |
226 ~tm_const (void) { } | |
227 | |
228 int rows (void) const { return nr; } | |
229 int cols (void) const { return nc; } | |
230 | |
231 bool all_strings (void) const { return all_str; } | |
232 bool is_complex (void) const { return is_cmplx; } | |
233 | |
234 operator void* () const { return ok ? (void *) -1 : (void *) 0; } | |
235 | |
236 private: | |
237 | |
238 int nr; | |
239 int nc; | |
240 | |
241 bool all_str; | |
242 bool is_cmplx; | |
243 | |
244 bool ok; | |
245 | |
246 tm_const (void); | |
247 | |
248 tm_const (const tm_const&); | |
249 | |
250 tm_const& operator = (const tm_const&); | |
251 | |
252 void init (const tree_matrix& tm); | |
253 }; | |
254 | |
255 void | |
256 tm_const::init (const tree_matrix& tm) | |
257 { | |
258 all_str = true; | |
259 | |
260 int empties_ok = user_pref.empty_list_elements_ok; | |
261 | |
262 bool first_elem = true; | |
263 | |
264 // Just eval and figure out if what we have is complex or all | |
265 // strings. We can't check columns until we know that this is a | |
266 // numeric matrix -- collections of strings can have elements of | |
267 // different lengths. | |
268 | |
269 for (Pix p = tm.first (); p != 0; tm.next (p)) | |
270 { | |
271 tree_matrix_row *elt = tm (p); | |
272 | |
273 tm_row_const tmp (*elt); | |
274 | |
275 if (tmp) | |
276 { | |
277 if (all_str && ! tmp.all_strings ()) | |
278 all_str = false; | |
279 | |
280 if (! is_cmplx && tmp.is_complex ()) | |
281 is_cmplx = true; | |
282 | |
283 append (tmp); | |
284 } | |
285 else | |
286 break; | |
287 } | |
288 | |
289 if (! error_state) | |
290 { | |
291 for (Pix p = first (); p != 0; next (p)) | |
292 { | |
293 tm_row_const elt = this->operator () (p); | |
294 | |
295 int this_elt_nr = elt.rows (); | |
296 int this_elt_nc = elt.cols (); | |
297 | |
298 if (this_elt_nr == 0 || this_elt_nc == 0) | |
299 { | |
300 if (empties_ok < 0) | |
301 warning ("empty matrix found in matrix list"); | |
302 else if (empties_ok == 0) | |
303 { | |
304 ::error ("empty matrix found in matrix list"); | |
305 break; | |
306 } | |
307 } | |
308 else | |
309 { | |
310 if (first_elem) | |
311 { | |
312 first_elem = false; | |
313 | |
314 nc = this_elt_nc; | |
315 } | |
316 else if (all_str) | |
317 { | |
318 if (this_elt_nc > nc) | |
319 nc = this_elt_nc; | |
320 } | |
321 else if (this_elt_nc != nc) | |
322 { | |
323 ::error ("number of columns must match"); | |
324 break; | |
325 } | |
326 | |
327 nr += this_elt_nr; | |
328 } | |
329 } | |
330 } | |
331 | |
332 ok = ! error_state; | |
333 } | |
334 | |
335 bool | |
336 tree_matrix_row::is_matrix_constant (void) const | |
337 { | |
338 for (Pix p = first (); p != 0; next (p)) | |
339 { | |
340 tree_expression *elt = this->operator () (p); | |
341 | |
342 if (! elt->is_constant ()) | |
343 return false; | |
344 } | |
345 | |
346 return true; | |
109 } | 347 } |
110 | 348 |
111 tree_return_list * | 349 tree_return_list * |
112 tree_matrix::to_return_list (void) | 350 tree_matrix_row::to_return_list (void) |
113 { | 351 { |
114 tree_return_list *retval = 0; | 352 tree_return_list *retval = 0; |
115 | 353 |
116 tree_matrix *list; | 354 bool first_elem = true; |
117 | 355 |
118 for (list = this; list; list = list->next) | 356 for (Pix p = first (); p != 0; next (p)) |
119 { | 357 { |
120 tree_expression *elem = list->element; | 358 tree_expression *elt = this->operator () (p); |
121 | 359 |
122 int is_id = elem->is_identifier (); | 360 bool is_id = elt->is_identifier (); |
123 | 361 |
124 int is_idx_expr = elem->is_index_expression (); | 362 bool is_idx_expr = elt->is_index_expression (); |
125 | 363 |
126 if (is_id || is_idx_expr) | 364 if (is_id || is_idx_expr) |
127 { | 365 { |
128 tree_index_expression *idx_expr; | 366 tree_index_expression *idx_expr; |
367 | |
129 if (is_id) | 368 if (is_id) |
130 { | 369 { |
131 tree_identifier *id = (tree_identifier *) elem; | 370 tree_identifier *id = (tree_identifier *) elt; |
132 idx_expr = new tree_index_expression (id); | 371 idx_expr = new tree_index_expression (id); |
133 } | 372 } |
134 else | 373 else |
135 idx_expr = (tree_index_expression *) elem; | 374 idx_expr = (tree_index_expression *) elt; |
136 | 375 |
137 if (list == this) | 376 if (first_elem) |
138 retval = new tree_return_list (idx_expr); | 377 { |
378 first_elem = false; | |
379 | |
380 retval = new tree_return_list (idx_expr); | |
381 } | |
139 else | 382 else |
140 retval->append (idx_expr); | 383 retval->append (idx_expr); |
141 } | 384 } |
142 else | 385 else |
143 { | 386 { |
148 } | 391 } |
149 | 392 |
150 return retval; | 393 return retval; |
151 } | 394 } |
152 | 395 |
396 void | |
397 tree_matrix_row::print_code (ostream& os) | |
398 { | |
399 Pix p = first (); | |
400 | |
401 while (p) | |
402 { | |
403 tree_expression *elt = this->operator () (p); | |
404 | |
405 next (p); | |
406 | |
407 if (elt) | |
408 { | |
409 elt->print_code (os); | |
410 | |
411 if (p) | |
412 os << ", "; | |
413 } | |
414 } | |
415 } | |
416 | |
417 bool | |
418 tree_matrix::is_matrix_constant (void) const | |
419 { | |
420 for (Pix p = first (); p != 0; next (p)) | |
421 { | |
422 tree_matrix_row *elt = this->operator () (p); | |
423 | |
424 if (! elt->is_matrix_constant ()) | |
425 return false; | |
426 } | |
427 | |
428 return true; | |
429 } | |
430 | |
153 // Just about as ugly as it gets. | 431 // Just about as ugly as it gets. |
154 | |
155 struct const_matrix_list | |
156 { | |
157 tree_matrix::dir direction; | |
158 tree_constant elem; | |
159 int nr; | |
160 int nc; | |
161 }; | |
162 | |
163 // Less ugly than before, anyway. | 432 // Less ugly than before, anyway. |
433 // Looking better all the time. | |
164 | 434 |
165 tree_constant | 435 tree_constant |
166 tree_matrix::eval (int /* print */) | 436 tree_matrix::eval (bool /* print */) |
167 { | 437 { |
168 tree_constant retval; | 438 tree_constant retval; |
169 | 439 |
170 if (error_state) | 440 tm_const tmp (*this); |
171 return retval; | 441 |
172 | 442 if (tmp) |
173 // Just count the elements without looking at them. | 443 { |
174 | |
175 int total_len = length (); | |
176 | |
177 // Easier to deal with this later instead of a tree_matrix | |
178 // structure. | |
179 | |
180 const_matrix_list *list = new const_matrix_list [total_len]; | |
181 | |
182 // Stats we want to keep track of. | |
183 | |
184 int all_strings = 1; | |
185 | |
186 int found_complex = 0; | |
187 | |
188 int row_total = 0; | |
189 int col_total = 0; | |
190 | |
191 int row_height = 0; | |
192 | |
193 int cols_this_row = 0; | |
194 | |
195 int first_row = 1; | |
196 | |
197 int empties_ok = user_pref.empty_list_elements_ok; | |
198 | |
199 tree_matrix *ptr = this; | |
200 | |
201 // Stuff for the result matrix or string. Declared here so that we | |
202 // don't get warnings from gcc about the goto crossing the | |
203 // initialization of these values. | |
204 | |
205 int put_row = 0; | |
206 int put_col = 0; | |
207 | |
208 int prev_nr = 0; | |
209 int prev_nc = 0; | |
210 | |
211 Matrix m; | |
212 ComplexMatrix cm; | |
213 charMatrix chm; | |
214 | |
215 // Eliminate empties and gather stats. | |
216 | |
217 int found_new_row_in_empties = 0; | |
218 | |
219 int len = 0; | |
220 for (int i = 0; i < total_len; i++) | |
221 { | |
222 tree_expression *elem = ptr->element; | |
223 if (! elem) | |
224 { | |
225 retval = tree_constant (Matrix ()); | |
226 goto done; | |
227 } | |
228 | |
229 tree_constant tmp = elem->eval (0); | |
230 if (error_state || tmp.is_undefined ()) | |
231 { | |
232 retval = tree_constant (); | |
233 goto done; | |
234 } | |
235 | |
236 int nr = tmp.rows (); | 444 int nr = tmp.rows (); |
237 int nc = tmp.columns (); | 445 int nc = tmp.cols (); |
238 | 446 |
239 dir direct = ptr->direction; | 447 Matrix m; |
240 | 448 ComplexMatrix cm; |
241 if (nr == 0 || nc == 0) | 449 charMatrix chm; |
242 { | 450 |
243 if (empties_ok < 0) | 451 // Now, extract the values from the individual elements and |
244 warning ("empty matrix found in matrix list"); | 452 // insert them in the result matrix. |
245 else if (empties_ok == 0) | 453 |
246 { | 454 bool all_strings = tmp.all_strings (); |
247 ::error ("empty matrix found in matrix list"); | 455 bool found_complex = tmp.is_complex (); |
248 retval = tree_constant (); | 456 |
249 goto done; | 457 if (all_strings) |
250 } | 458 chm.resize (nr, nc, 0); |
251 | 459 else if (found_complex) |
252 if (direct == md_down) | 460 cm.resize (nr, nc, 0.0); |
253 found_new_row_in_empties = 1; | |
254 | |
255 goto next; | |
256 } | |
257 | |
258 if (found_new_row_in_empties) | |
259 { | |
260 found_new_row_in_empties = 0; | |
261 list[len].direction = md_down; | |
262 } | |
263 else | 461 else |
264 list[len].direction = direct; | 462 m.resize (nr, nc, 0.0); |
265 | 463 |
266 list[len].elem = tmp; | 464 int put_row = 0; |
267 list[len].nr = nr; | 465 |
268 list[len].nc = nc; | 466 for (Pix p = tmp.first (); p != 0; tmp.next (p)) |
269 | 467 { |
270 if (all_strings && ! tmp.is_string ()) | 468 int put_col = 0; |
271 all_strings = 0; | 469 |
272 | 470 tm_row_const row = tmp (p); |
273 if (! found_complex && tmp.is_complex_type ()) | 471 |
274 found_complex = 1; | 472 for (Pix q = row.first (); q != 0; row.next (q)) |
275 | 473 { |
276 len++; | 474 tree_constant elt = row (q); |
277 | 475 |
278 next: | 476 if (found_complex) |
279 | 477 { |
280 ptr = ptr->next; | 478 if (elt.is_real_scalar ()) |
281 } | 479 cm (put_row, put_col) = elt.double_value (); |
282 | 480 else if (elt.is_real_matrix () || elt.is_range ()) |
283 // if (all_strings) | 481 cm.insert (elt.matrix_value (), put_row, put_col); |
284 // cerr << "all strings\n"; | 482 else if (elt.is_complex_scalar ()) |
285 | 483 cm (put_row, put_col) = elt.complex_value (); |
286 // Compute size of result matrix, and check to see that the dimensions | 484 else |
287 // of all the elements will match up properly. | 485 { |
288 | 486 ComplexMatrix cm_elt = elt.complex_matrix_value (); |
289 for (int i = 0; i < len; i++) | 487 |
290 { | 488 if (error_state) |
291 dir direct = list[i].direction; | 489 goto done; |
292 | 490 |
293 int nr = list[i].nr; | 491 cm.insert (cm_elt, put_row, put_col); |
294 int nc = list[i].nc; | 492 } |
295 | 493 } |
296 if (i == 0) | 494 else |
297 { | 495 { |
298 row_total = nr; | 496 if (elt.is_real_scalar ()) |
299 col_total = nc; | 497 m (put_row, put_col) = elt.double_value (); |
300 | 498 else if (elt.is_string () && all_strings) |
301 row_height = nr; | 499 { |
302 cols_this_row = nc; | 500 charMatrix chm_elt = elt.all_strings (); |
303 } | 501 |
304 else | 502 if (error_state) |
305 { | 503 goto done; |
306 switch (direct) | 504 |
307 { | 505 chm.insert (chm_elt, put_row, put_col); |
308 case md_right: | 506 } |
309 { | 507 else |
310 if (nr != row_height) | 508 { |
311 { | 509 Matrix m_elt = elt.matrix_value (); |
312 ::error ("number of rows must match"); | 510 |
313 goto done; | 511 if (error_state) |
314 } | 512 goto done; |
315 else | 513 |
316 { | 514 m.insert (m_elt, put_row, put_col); |
317 cols_this_row += nc; | 515 } |
318 | 516 } |
319 if (first_row) | 517 |
320 col_total = cols_this_row; | 518 if (all_strings && chm.rows () > 0 && chm.cols () > 0) |
321 else if (all_strings && cols_this_row > col_total) | 519 retval = tree_constant (chm, true); |
322 col_total = cols_this_row; | 520 else if (found_complex) |
323 } | 521 retval = cm; |
324 } | 522 else |
325 break; | 523 retval = m; |
326 | 524 |
327 case md_down: | 525 put_col += elt.columns (); |
328 { | 526 } |
329 if (cols_this_row != col_total && ! all_strings) | 527 |
330 { | 528 put_row += row.rows (); |
331 ::error ("number of columns must match"); | 529 } |
332 goto done; | 530 } |
333 } | 531 |
334 first_row = 0; | 532 done: |
335 row_total += nr; | |
336 row_height = nr; | |
337 cols_this_row = nc; | |
338 } | |
339 break; | |
340 | |
341 default: | |
342 panic_impossible (); | |
343 break; | |
344 } | |
345 } | |
346 } | |
347 | |
348 // Don't forget to check to see if the last element will fit. | |
349 | |
350 if (all_strings && cols_this_row > col_total) | |
351 { | |
352 col_total = cols_this_row; | |
353 } | |
354 else if (cols_this_row != col_total) | |
355 { | |
356 ::error ("number of columns must match"); | |
357 goto done; | |
358 } | |
359 | |
360 // Now, extract the values from the individual elements and insert | |
361 // them in the result matrix. | |
362 | |
363 if (all_strings) | |
364 chm.resize (row_total, col_total, 0); | |
365 else if (found_complex) | |
366 cm.resize (row_total, col_total, 0.0); | |
367 else | |
368 m.resize (row_total, col_total, 0.0); | |
369 | |
370 for (int i = 0; i < len; i++) | |
371 { | |
372 tree_constant tmp = list[i].elem; | |
373 | |
374 int nr = list[i].nr; | |
375 int nc = list[i].nc; | |
376 | |
377 if (nr == 0 || nc == 0) | |
378 continue; | |
379 | |
380 if (i == 0) | |
381 { | |
382 put_row = 0; | |
383 put_col = 0; | |
384 } | |
385 else | |
386 { | |
387 switch (list[i].direction) | |
388 { | |
389 case md_right: | |
390 put_col += prev_nc; | |
391 break; | |
392 | |
393 case md_down: | |
394 put_row += prev_nr; | |
395 put_col = 0; | |
396 break; | |
397 | |
398 default: | |
399 panic_impossible (); | |
400 break; | |
401 } | |
402 } | |
403 | |
404 if (found_complex) | |
405 { | |
406 if (tmp.is_real_scalar ()) | |
407 { | |
408 cm (put_row, put_col) = tmp.double_value (); | |
409 } | |
410 else if (tmp.is_real_matrix () || tmp.is_range ()) | |
411 { | |
412 cm.insert (tmp.matrix_value (), put_row, put_col); | |
413 } | |
414 else if (tmp.is_complex_scalar ()) | |
415 { | |
416 cm (put_row, put_col) = tmp.complex_value (); | |
417 } | |
418 else | |
419 { | |
420 ComplexMatrix cm_tmp = tmp.complex_matrix_value (); | |
421 | |
422 if (error_state) | |
423 goto done; | |
424 | |
425 cm.insert (cm_tmp, put_row, put_col); | |
426 } | |
427 } | |
428 else | |
429 { | |
430 if (tmp.is_real_scalar ()) | |
431 { | |
432 m (put_row, put_col) = tmp.double_value (); | |
433 } | |
434 else if (tmp.is_string () && all_strings) | |
435 { | |
436 charMatrix chm_tmp = tmp.all_strings (); | |
437 | |
438 if (error_state) | |
439 goto done; | |
440 | |
441 chm.insert (chm_tmp, put_row, put_col); | |
442 } | |
443 else | |
444 { | |
445 Matrix m_tmp = tmp.matrix_value (); | |
446 | |
447 if (error_state) | |
448 goto done; | |
449 | |
450 m.insert (m_tmp, put_row, put_col); | |
451 } | |
452 } | |
453 | |
454 prev_nr = nr; | |
455 prev_nc = nc; | |
456 } | |
457 | |
458 if (all_strings && chm.rows () > 0 && chm.cols () > 0) | |
459 retval = tree_constant (chm, 1); | |
460 else if (found_complex) | |
461 retval = cm; | |
462 else | |
463 retval = m; | |
464 | |
465 done: | |
466 delete [] list; | |
467 | 533 |
468 return retval; | 534 return retval; |
469 } | 535 } |
470 | 536 |
471 void | 537 void |
476 if (in_parens) | 542 if (in_parens) |
477 os << "("; | 543 os << "("; |
478 | 544 |
479 os << "["; | 545 os << "["; |
480 | 546 |
481 tree_matrix *list = this; | 547 Pix p = first (); |
482 | 548 |
483 while (list) | 549 while (p) |
484 { | 550 { |
485 list->element->print_code (os); | 551 tree_matrix_row *elt = this->operator () (p); |
486 | 552 |
487 list = list->next; | 553 next (p); |
488 | 554 |
489 if (list) | 555 if (elt) |
490 { | 556 { |
491 switch (list->direction) | 557 elt->print_code (os); |
492 { | 558 |
493 case md_right: | 559 if (p) |
494 os << ", "; | 560 os << "; "; |
495 break; | |
496 | |
497 case md_down: | |
498 os << "; "; | |
499 break; | |
500 | |
501 default: | |
502 break; | |
503 } | |
504 } | 561 } |
505 } | 562 } |
506 | 563 |
507 os << "]"; | 564 os << "]"; |
508 | 565 |