Mercurial > hg > octave-nkf
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 |