comparison src/data.cc @ 8934:c2099a4d12ea

partially optimize accumarray
author Jaroslav Hajek <highegg@gmail.com>
date Mon, 09 Mar 2009 10:59:19 +0100
parents eb63fbe60fab
children 1e4b3149365a
comparison
equal deleted inserted replaced
8933:346fde2030b5 8934:c2099a4d12ea
5722 print_usage (); 5722 print_usage ();
5723 5723
5724 return retval; 5724 return retval;
5725 } 5725 }
5726 5726
5727 template <class NDT>
5728 static NDT
5729 do_accumarray_sum (const idx_vector& idx, const NDT& vals,
5730 octave_idx_type n = -1)
5731 {
5732 typedef typename NDT::element_type T;
5733 if (n < 0)
5734 n = idx.extent (0);
5735 else if (idx.extent (n) > n)
5736 error ("accumarray: index out of range");
5737
5738 // FIXME: the class tree in liboctave is overly complicated, hence the
5739 // following type gymnastics.
5740 MArray<T> array;
5741
5742 if (vals.numel () == 1)
5743 {
5744 array = MArray<T> (n, T ());
5745 array.idx_add (idx, vals (0));
5746 }
5747 else if (vals.length () == idx.length (n))
5748 {
5749 array = MArray<T> (n, T ());
5750 array.idx_add (idx, MArray<T> (vals));
5751 }
5752 else
5753 error ("accumarray: dimensions mismatch");
5754
5755 return NDT (MArrayN<T> (ArrayN<T> (array)));
5756 }
5757
5758 DEFUN (__accumarray_sum__, args, ,
5759 "-*- texinfo -*-\n\
5760 @deftypefn {Built-in Function} {} __accumarray_sum__ (@var{idx}, @var{vals}, @var{n})\n\
5761 Undocumented internal function.\n\
5762 @end deftypefn")
5763 {
5764 octave_value retval;
5765 int nargin = args.length ();
5766 if (nargin >= 2 && nargin <= 3 && args(0).is_numeric_type ())
5767 {
5768 idx_vector idx = args(0).index_vector ();
5769 octave_idx_type n = -1;
5770 if (nargin == 3)
5771 n = args(2).idx_type_value (true);
5772
5773 if (! error_state)
5774 {
5775 octave_value vals = args(1);
5776 if (vals.is_single_type ())
5777 {
5778 if (vals.is_complex_type ())
5779 retval = do_accumarray_sum (idx, vals.float_complex_array_value (), n);
5780 else
5781 retval = do_accumarray_sum (idx, vals.float_array_value (), n);
5782 }
5783 else if (vals.is_numeric_type ())
5784 {
5785 if (vals.is_complex_type ())
5786 retval = do_accumarray_sum (idx, vals.complex_array_value (), n);
5787 else
5788 retval = do_accumarray_sum (idx, vals.array_value (), n);
5789 }
5790 else
5791 gripe_wrong_type_arg ("accumarray", vals);
5792 }
5793 }
5794 else
5795 print_usage ();
5796
5797 return retval;
5798 }
5727 5799
5728 5800
5729 /* 5801 /*
5730 ;;; Local Variables: *** 5802 ;;; Local Variables: ***
5731 ;;; mode: C++ *** 5803 ;;; mode: C++ ***