comparison src/pt-mat.cc @ 13144:c99f24c10ca3

fix vertical concatenation involving cell arrays * pt-mat.cc (tm_row_const::tm_row_const_rep::cellify): New function. (tm_row_const::tm_row_const_rep::init): Use it. Call octave_quit in all loops. (tm_row_const::cellify): New function. (tm_row_const::first_elem_struct_p): New function. (tm_const::any_cell): New data member. Adjust constructor initialization lists. (tm_const::any_cell_p): New function. (tm_const::init): Handle concatenation of cells. * pt-mat.cc: Additional test for concatentation with cell arrays.
author John W. Eaton <jwe@octave.org>
date Thu, 15 Sep 2011 22:03:58 -0400
parents d803d2702a39
children cf5ebc0e47e4
comparison
equal deleted inserted replaced
13143:bda7b080f205 13144:c99f24c10ca3
106 106
107 void do_init_element (const octave_value&, bool&); 107 void do_init_element (const octave_value&, bool&);
108 108
109 void init (const tree_argument_list&); 109 void init (const tree_argument_list&);
110 110
111 void cellify (void);
112
111 private: 113 private:
112 114
113 tm_row_const_rep (const tm_row_const_rep&); 115 tm_row_const_rep (const tm_row_const_rep&);
114 116
115 tm_row_const_rep& operator = (const tm_row_const_rep&); 117 tm_row_const_rep& operator = (const tm_row_const_rep&);
175 bool all_empty_p (void) const { return rep->all_mt; } 177 bool all_empty_p (void) const { return rep->all_mt; }
176 bool any_cell_p (void) const { return rep->any_cell; } 178 bool any_cell_p (void) const { return rep->any_cell; }
177 bool any_sparse_p (void) const { return rep->any_sparse; } 179 bool any_sparse_p (void) const { return rep->any_sparse; }
178 bool any_class_p (void) const { return rep->any_class; } 180 bool any_class_p (void) const { return rep->any_class; }
179 bool all_1x1_p (void) const { return rep->all_1x1; } 181 bool all_1x1_p (void) const { return rep->all_1x1; }
182 bool first_elem_struct_p (void) const { return rep->first_elem_is_struct; }
180 183
181 std::string class_name (void) const { return rep->class_nm; } 184 std::string class_name (void) const { return rep->class_nm; }
185
186 void cellify (void) { rep->cellify (); }
182 187
183 operator bool () const { return (rep && rep->ok); } 188 operator bool () const { return (rep && rep->ok); }
184 189
185 iterator begin (void) { return rep->begin (); } 190 iterator begin (void) { return rep->begin (); }
186 const_iterator begin (void) const { return rep->begin (); } 191 const_iterator begin (void) const { return rep->begin (); }
374 do_init_element (tmp, first_elem); 379 do_init_element (tmp, first_elem);
375 } 380 }
376 } 381 }
377 382
378 if (any_cell && ! any_class && ! first_elem_is_struct) 383 if (any_cell && ! any_class && ! first_elem_is_struct)
379 { 384 cellify ();
380 for (iterator p = begin (); p != end (); p++)
381 {
382 if (! p->is_cell ())
383 *p = Cell (*p);
384 }
385 }
386 385
387 first_elem = true; 386 first_elem = true;
388 387
389 for (iterator p = begin (); p != end (); p++) 388 for (iterator p = begin (); p != end (); p++)
390 { 389 {
390 octave_quit ();
391
391 octave_value val = *p; 392 octave_value val = *p;
392 393
393 dim_vector this_elt_dv = val.dims (); 394 dim_vector this_elt_dv = val.dims ();
394 395
395 if (! this_elt_dv.zero_by_zero ()) 396 if (! this_elt_dv.zero_by_zero ())
408 } 409 }
409 } 410 }
410 } 411 }
411 412
412 ok = ! error_state; 413 ok = ! error_state;
414 }
415
416 void
417 tm_row_const::tm_row_const_rep::cellify (void)
418 {
419 bool elt_changed = false;
420
421 for (iterator p = begin (); p != end (); p++)
422 {
423 octave_quit ();
424
425 if (! p->is_cell ())
426 {
427 elt_changed = true;
428
429 *p = Cell (*p);
430 }
431 }
432
433 if (elt_changed)
434 {
435 bool first_elem = true;
436
437 for (iterator p = begin (); p != end (); p++)
438 {
439 octave_quit ();
440
441 octave_value val = *p;
442
443 dim_vector this_elt_dv = val.dims ();
444
445 if (! this_elt_dv.zero_by_zero ())
446 {
447 if (first_elem)
448 {
449 first_elem = false;
450 dv = this_elt_dv;
451 }
452 else if (! dv.hvcat (this_elt_dv, 1))
453 {
454 eval_error ("horizontal dimensions mismatch", dv, this_elt_dv);
455 break;
456 }
457 }
458 }
459 }
413 } 460 }
414 461
415 void 462 void
416 tm_row_const::tm_row_const_rep::eval_warning (const char *msg, int l, 463 tm_row_const::tm_row_const_rep::eval_warning (const char *msg, int l,
417 int c) const 464 int c) const
429 public: 476 public:
430 477
431 tm_const (const tree_matrix& tm) 478 tm_const (const tree_matrix& tm)
432 : dv (0, 0), all_str (false), all_sq_str (false), all_dq_str (false), 479 : dv (0, 0), all_str (false), all_sq_str (false), all_dq_str (false),
433 some_str (false), all_real (false), all_cmplx (false), 480 some_str (false), all_real (false), all_cmplx (false),
434 all_mt (true), any_sparse (false), any_class (false), 481 all_mt (true), any_cell (false), any_sparse (false),
435 class_nm (), ok (false) 482 any_class (false), class_nm (), ok (false)
436 { init (tm); } 483 { init (tm); }
437 484
438 ~tm_const (void) { } 485 ~tm_const (void) { }
439 486
440 octave_idx_type rows (void) const { return dv.elem (0); } 487 octave_idx_type rows (void) const { return dv.elem (0); }
447 bool all_dq_strings_p (void) const { return all_dq_str; } 494 bool all_dq_strings_p (void) const { return all_dq_str; }
448 bool some_strings_p (void) const { return some_str; } 495 bool some_strings_p (void) const { return some_str; }
449 bool all_real_p (void) const { return all_real; } 496 bool all_real_p (void) const { return all_real; }
450 bool all_complex_p (void) const { return all_cmplx; } 497 bool all_complex_p (void) const { return all_cmplx; }
451 bool all_empty_p (void) const { return all_mt; } 498 bool all_empty_p (void) const { return all_mt; }
499 bool any_cell_p (void) const { return any_cell; }
452 bool any_sparse_p (void) const { return any_sparse; } 500 bool any_sparse_p (void) const { return any_sparse; }
453 bool any_class_p (void) const { return any_class; } 501 bool any_class_p (void) const { return any_class; }
454 bool all_1x1_p (void) const { return all_1x1; } 502 bool all_1x1_p (void) const { return all_1x1; }
455 503
456 std::string class_name (void) const { return class_nm; } 504 std::string class_name (void) const { return class_nm; }
466 bool all_dq_str; 514 bool all_dq_str;
467 bool some_str; 515 bool some_str;
468 bool all_real; 516 bool all_real;
469 bool all_cmplx; 517 bool all_cmplx;
470 bool all_mt; 518 bool all_mt;
519 bool any_cell;
471 bool any_sparse; 520 bool any_sparse;
472 bool any_class; 521 bool any_class;
473 bool all_1x1; 522 bool all_1x1;
474 523
475 std::string class_nm; 524 std::string class_nm;
491 all_str = true; 540 all_str = true;
492 all_sq_str = true; 541 all_sq_str = true;
493 all_dq_str = true; 542 all_dq_str = true;
494 all_real = true; 543 all_real = true;
495 all_cmplx = true; 544 all_cmplx = true;
545 any_cell = false;
496 any_sparse = false; 546 any_sparse = false;
497 any_class = false; 547 any_class = false;
498 all_1x1 = ! empty (); 548 all_1x1 = ! empty ();
499 549
500 bool first_elem = true; 550 bool first_elem = true;
551 bool first_elem_is_struct = false;
501 552
502 // Just eval and figure out if what we have is complex or all 553 // Just eval and figure out if what we have is complex or all
503 // strings. We can't check columns until we know that this is a 554 // strings. We can't check columns until we know that this is a
504 // numeric matrix -- collections of strings can have elements of 555 // numeric matrix -- collections of strings can have elements of
505 // different lengths. 556 // different lengths.
510 561
511 tree_argument_list *elt = *p; 562 tree_argument_list *elt = *p;
512 563
513 tm_row_const tmp (*elt); 564 tm_row_const tmp (*elt);
514 565
566 if (first_elem)
567 {
568 first_elem_is_struct = tmp.first_elem_struct_p ();
569
570 first_elem = false;
571 }
572
515 if (tmp && ! tmp.empty ()) 573 if (tmp && ! tmp.empty ())
516 { 574 {
517 if (all_str && ! tmp.all_strings_p ()) 575 if (all_str && ! tmp.all_strings_p ())
518 all_str = false; 576 all_str = false;
519 577
533 all_cmplx = false; 591 all_cmplx = false;
534 592
535 if (all_mt && ! tmp.all_empty_p ()) 593 if (all_mt && ! tmp.all_empty_p ())
536 all_mt = false; 594 all_mt = false;
537 595
596 if (!any_cell && tmp.any_cell_p ())
597 any_cell = true;
598
538 if (!any_sparse && tmp.any_sparse_p ()) 599 if (!any_sparse && tmp.any_sparse_p ())
539 any_sparse = true; 600 any_sparse = true;
540 601
541 if (!any_class && tmp.any_class_p ()) 602 if (!any_class && tmp.any_class_p ())
542 any_class = true; 603 any_class = true;
549 break; 610 break;
550 } 611 }
551 612
552 if (! error_state) 613 if (! error_state)
553 { 614 {
615 iterator p = begin ();
616
617 if (any_cell && ! any_class && ! first_elem_is_struct)
618 {
619 for (iterator p = begin (); p != end (); p++)
620 {
621 octave_quit ();
622
623 p->cellify ();
624 }
625 }
626
627 first_elem = true;
628
554 for (iterator p = begin (); p != end (); p++) 629 for (iterator p = begin (); p != end (); p++)
555 { 630 {
556 octave_quit (); 631 octave_quit ();
557 632
558 tm_row_const elt = *p; 633 tm_row_const elt = *p;
1159 /* 1234 /*
1160 %% test concatenation with all zero matrices 1235 %% test concatenation with all zero matrices
1161 %!assert([ '' 65*ones(1,10) ], 'AAAAAAAAAA'); 1236 %!assert([ '' 65*ones(1,10) ], 'AAAAAAAAAA');
1162 %!assert([ 65*ones(1,10) '' ], 'AAAAAAAAAA'); 1237 %!assert([ 65*ones(1,10) '' ], 'AAAAAAAAAA');
1163 1238
1239 %!test
1240 %! c = {'foo'; 'bar'; 'bazoloa'};
1241 %! assert ([c; 'a'; 'bc'; 'def'], {'foo'; 'bar'; 'bazoloa'; 'a'; 'bc'; 'def'});
1242
1164 %!assert (class ([int64(1), int64(1)]), 'int64') 1243 %!assert (class ([int64(1), int64(1)]), 'int64')
1165 %!assert (class ([int64(1), int32(1)]), 'int64') 1244 %!assert (class ([int64(1), int32(1)]), 'int64')
1166 %!assert (class ([int64(1), int16(1)]), 'int64') 1245 %!assert (class ([int64(1), int16(1)]), 'int64')
1167 %!assert (class ([int64(1), int8(1)]), 'int64') 1246 %!assert (class ([int64(1), int8(1)]), 'int64')
1168 %!assert (class ([int64(1), uint64(1)]), 'int64') 1247 %!assert (class ([int64(1), uint64(1)]), 'int64')