comparison src/pt-mat.cc @ 10764:e141bcb1befd

implement map concat optimizations for [] operator
author Jaroslav Hajek <highegg@gmail.com>
date Fri, 02 Jul 2010 10:10:51 +0200
parents f3892d8eea9f
children 83896a06adaf
comparison
equal deleted inserted replaced
10763:b397b8edd8c5 10764:e141bcb1befd
68 tm_row_const_rep (void) 68 tm_row_const_rep (void)
69 : count (1), dv (0, 0), all_str (false), 69 : count (1), dv (0, 0), all_str (false),
70 all_sq_str (false), all_dq_str (false), 70 all_sq_str (false), all_dq_str (false),
71 some_str (false), all_real (false), all_cmplx (false), 71 some_str (false), all_real (false), all_cmplx (false),
72 all_mt (true), any_sparse (false), any_class (false), 72 all_mt (true), any_sparse (false), any_class (false),
73 class_nm (), ok (false) 73 all_1x1 (false), class_nm (), ok (false)
74 { } 74 { }
75 75
76 tm_row_const_rep (const tree_argument_list& row) 76 tm_row_const_rep (const tree_argument_list& row)
77 : count (1), dv (0, 0), all_str (false), all_sq_str (false), 77 : count (1), dv (0, 0), all_str (false), all_sq_str (false),
78 some_str (false), all_real (false), all_cmplx (false), 78 some_str (false), all_real (false), all_cmplx (false),
79 all_mt (true), any_sparse (false), any_class (false), 79 all_mt (true), any_sparse (false), any_class (false),
80 class_nm (), ok (false) 80 all_1x1 (! row.empty ()), class_nm (), ok (false)
81 { init (row); } 81 { init (row); }
82 82
83 ~tm_row_const_rep (void) { } 83 ~tm_row_const_rep (void) { }
84 84
85 int count; 85 int count;
93 bool all_real; 93 bool all_real;
94 bool all_cmplx; 94 bool all_cmplx;
95 bool all_mt; 95 bool all_mt;
96 bool any_sparse; 96 bool any_sparse;
97 bool any_class; 97 bool any_class;
98 bool all_1x1;
98 99
99 std::string class_nm; 100 std::string class_nm;
100 101
101 bool ok; 102 bool ok;
102 103
169 bool all_real_p (void) const { return rep->all_real; } 170 bool all_real_p (void) const { return rep->all_real; }
170 bool all_complex_p (void) const { return rep->all_cmplx; } 171 bool all_complex_p (void) const { return rep->all_cmplx; }
171 bool all_empty_p (void) const { return rep->all_mt; } 172 bool all_empty_p (void) const { return rep->all_mt; }
172 bool any_sparse_p (void) const { return rep->any_sparse; } 173 bool any_sparse_p (void) const { return rep->any_sparse; }
173 bool any_class_p (void) const { return rep->any_class; } 174 bool any_class_p (void) const { return rep->any_class; }
175 bool all_1x1_p (void) const { return rep->all_1x1; }
174 176
175 std::string class_name (void) const { return rep->class_nm; } 177 std::string class_name (void) const { return rep->class_nm; }
176 178
177 operator bool () const { return (rep && rep->ok); } 179 operator bool () const { return (rep && rep->ok); }
178 180
324 any_sparse = true; 326 any_sparse = true;
325 327
326 if (!any_class && val.is_object ()) 328 if (!any_class && val.is_object ())
327 any_class = true; 329 any_class = true;
328 330
331 all_1x1 = all_1x1 && val.numel () == 1;
332
329 return true; 333 return true;
330 } 334 }
331 335
332 void 336 void
333 tm_row_const::tm_row_const_rep::init (const tree_argument_list& row) 337 tm_row_const::tm_row_const_rep::init (const tree_argument_list& row)
418 bool all_real_p (void) const { return all_real; } 422 bool all_real_p (void) const { return all_real; }
419 bool all_complex_p (void) const { return all_cmplx; } 423 bool all_complex_p (void) const { return all_cmplx; }
420 bool all_empty_p (void) const { return all_mt; } 424 bool all_empty_p (void) const { return all_mt; }
421 bool any_sparse_p (void) const { return any_sparse; } 425 bool any_sparse_p (void) const { return any_sparse; }
422 bool any_class_p (void) const { return any_class; } 426 bool any_class_p (void) const { return any_class; }
427 bool all_1x1_p (void) const { return all_1x1; }
423 428
424 std::string class_name (void) const { return class_nm; } 429 std::string class_name (void) const { return class_nm; }
425 430
426 operator bool () const { return ok; } 431 operator bool () const { return ok; }
427 432
436 bool all_real; 441 bool all_real;
437 bool all_cmplx; 442 bool all_cmplx;
438 bool all_mt; 443 bool all_mt;
439 bool any_sparse; 444 bool any_sparse;
440 bool any_class; 445 bool any_class;
446 bool all_1x1;
441 447
442 std::string class_nm; 448 std::string class_nm;
443 449
444 bool ok; 450 bool ok;
445 451
460 all_dq_str = true; 466 all_dq_str = true;
461 all_real = true; 467 all_real = true;
462 all_cmplx = true; 468 all_cmplx = true;
463 any_sparse = false; 469 any_sparse = false;
464 any_class = false; 470 any_class = false;
471 all_1x1 = ! empty ();
465 472
466 bool first_elem = true; 473 bool first_elem = true;
467 474
468 // Just eval and figure out if what we have is complex or all 475 // Just eval and figure out if what we have is complex or all
469 // strings. We can't check columns until we know that this is a 476 // strings. We can't check columns until we know that this is a
504 if (!any_sparse && tmp.any_sparse_p ()) 511 if (!any_sparse && tmp.any_sparse_p ())
505 any_sparse = true; 512 any_sparse = true;
506 513
507 if (!any_class && tmp.any_class_p ()) 514 if (!any_class && tmp.any_class_p ())
508 any_class = true; 515 any_class = true;
516
517 all_1x1 = all_1x1 && tmp.all_1x1_p ();
509 518
510 append (tmp); 519 append (tmp);
511 } 520 }
512 else 521 else
513 break; 522 break;
679 688
680 if (tmp.length () == 1) 689 if (tmp.length () == 1)
681 { 690 {
682 // If possible, forward the operation to liboctave. 691 // If possible, forward the operation to liboctave.
683 // Single row. 692 // Single row.
693 // FIXME: optimize all scalars case.
684 tm_row_const& row = tmp.front (); 694 tm_row_const& row = tmp.front ();
685 octave_idx_type ncols = row.length (), i = 0; 695 octave_idx_type ncols = row.length (), i = 0;
686 OCTAVE_LOCAL_BUFFER (Array<T>, array_list, ncols); 696 OCTAVE_LOCAL_BUFFER (Array<T>, array_list, ncols);
687 697
688 for (tm_row_const::iterator q = row.begin (); 698 for (tm_row_const::iterator q = row.begin ();
750 } 760 }
751 761
752 result = Sparse<T>::cat (0, nrows, sparse_row_list); 762 result = Sparse<T>::cat (0, nrows, sparse_row_list);
753 } 763 }
754 764
765 template<class MAP>
766 static void
767 single_type_concat (octave_map& result,
768 const dim_vector& dv,
769 tm_const& tmp)
770 {
771 if (dv.any_zero ())
772 {
773 result = octave_map (dv);
774 return;
775 }
776
777 octave_idx_type nrows = tmp.length (), j = 0;
778 OCTAVE_LOCAL_BUFFER (octave_map, map_row_list, nrows);
779 for (tm_const::iterator p = tmp.begin (); p != tmp.end (); p++)
780 {
781 tm_row_const row = *p;
782 octave_idx_type ncols = row.length (), i = 0;
783 OCTAVE_LOCAL_BUFFER (MAP, map_list, ncols);
784
785 for (tm_row_const::iterator q = row.begin ();
786 q != row.end () && ! error_state;
787 q++)
788 {
789 octave_quit ();
790
791 // Use 0x0 in place of all empty arrays to allow looser rules.
792 // If MAP is octave_scalar_map, the condition is vacuously true.
793 if (! q->is_empty ())
794 map_list[i] = octave_value_extract<MAP> (*q);
795 i++;
796 }
797
798 octave_map mtmp = octave_map::cat (1, ncols, map_list);
799 // Use 0x0 in place of all empty arrays to allow looser rules.
800 if (! mtmp.is_empty ())
801 map_row_list[j] = mtmp;
802 j++;
803 }
804
805 result = octave_map::cat (0, nrows, map_row_list);
806 }
807
755 template<class TYPE> 808 template<class TYPE>
756 static octave_value 809 static octave_value
757 do_single_type_concat (const dim_vector& dv, 810 do_single_type_concat (const dim_vector& dv,
758 tm_const& tmp) 811 tm_const& tmp)
759 { 812 {
760 TYPE result; 813 TYPE result;
761 814
762 single_type_concat<TYPE> (result, dv, tmp); 815 single_type_concat<TYPE> (result, dv, tmp);
816
817 return result;
818 }
819
820 template<>
821 octave_value
822 do_single_type_concat<octave_map> (const dim_vector& dv,
823 tm_const& tmp)
824 {
825 octave_map result;
826
827 if (tmp.all_1x1_p ())
828 single_type_concat<octave_scalar_map> (result, dv, tmp);
829 else
830 single_type_concat<octave_map> (result, dv, tmp);
763 831
764 return result; 832 return result;
765 } 833 }
766 834
767 template<class TYPE, class OV_TYPE> 835 template<class TYPE, class OV_TYPE>
931 retval = do_single_type_concat<uint16NDArray> (dv, tmp); 999 retval = do_single_type_concat<uint16NDArray> (dv, tmp);
932 else if (result_type == "uint32") 1000 else if (result_type == "uint32")
933 retval = do_single_type_concat<uint32NDArray> (dv, tmp); 1001 retval = do_single_type_concat<uint32NDArray> (dv, tmp);
934 else if (result_type == "uint64") 1002 else if (result_type == "uint64")
935 retval = do_single_type_concat<uint64NDArray> (dv, tmp); 1003 retval = do_single_type_concat<uint64NDArray> (dv, tmp);
1004 else if (result_type == "cell")
1005 retval = do_single_type_concat<Cell> (dv, tmp);
1006 else if (result_type == "struct")
1007 retval = do_single_type_concat<octave_map> (dv, tmp);
936 else 1008 else
937 { 1009 {
938 // The line below might seem crazy, since we take a copy of 1010 // The line below might seem crazy, since we take a copy of
939 // the first argument, resize it to be empty and then resize 1011 // the first argument, resize it to be empty and then resize
940 // it to be full. This is done since it means that there is 1012 // it to be full. This is done since it means that there is