comparison liboctave/dNDArray.cc @ 8751:9f7ce4bf7650

optimize min/max functions
author Jaroslav Hajek <highegg@gmail.com>
date Mon, 16 Feb 2009 08:52:00 +0100
parents 1bd918cfb6e2
children b756ce0002db
comparison
equal deleted inserted replaced
8750:8af4ba6b4216 8751:9f7ce4bf7650
729 } 729 }
730 730
731 NDArray 731 NDArray
732 NDArray::max (int dim) const 732 NDArray::max (int dim) const
733 { 733 {
734 ArrayN<octave_idx_type> dummy_idx; 734 return do_mx_minmax_op<NDArray> (*this, dim, mx_inline_max);
735 return max (dummy_idx, dim);
736 } 735 }
737 736
738 NDArray 737 NDArray
739 NDArray::max (ArrayN<octave_idx_type>& idx_arg, int dim) const 738 NDArray::max (ArrayN<octave_idx_type>& idx_arg, int dim) const
740 { 739 {
741 dim_vector dv = dims (); 740 return do_mx_minmax_op<NDArray> (*this, idx_arg, dim, mx_inline_max);
742 dim_vector dr = dims ();
743
744 if (dv.numel () == 0 || dim > dv.length () || dim < 0)
745 return NDArray ();
746
747 dr(dim) = 1;
748
749 NDArray result (dr);
750 idx_arg.resize (dr);
751
752 octave_idx_type x_stride = 1;
753 octave_idx_type x_len = dv(dim);
754 for (int i = 0; i < dim; i++)
755 x_stride *= dv(i);
756
757 for (octave_idx_type i = 0; i < dr.numel (); i++)
758 {
759 octave_idx_type x_offset;
760 if (x_stride == 1)
761 x_offset = i * x_len;
762 else
763 {
764 octave_idx_type x_offset2 = 0;
765 x_offset = i;
766 while (x_offset >= x_stride)
767 {
768 x_offset -= x_stride;
769 x_offset2++;
770 }
771 x_offset += x_offset2 * x_stride * x_len;
772 }
773
774 octave_idx_type idx_j;
775
776 double tmp_max = octave_NaN;
777
778 for (idx_j = 0; idx_j < x_len; idx_j++)
779 {
780 tmp_max = elem (idx_j * x_stride + x_offset);
781
782 if (! xisnan (tmp_max))
783 break;
784 }
785
786 for (octave_idx_type j = idx_j+1; j < x_len; j++)
787 {
788 double tmp = elem (j * x_stride + x_offset);
789
790 if (xisnan (tmp))
791 continue;
792 else if (tmp > tmp_max)
793 {
794 idx_j = j;
795 tmp_max = tmp;
796 }
797 }
798
799 result.elem (i) = tmp_max;
800 idx_arg.elem (i) = xisnan (tmp_max) ? 0 : idx_j;
801 }
802
803 result.chop_trailing_singletons ();
804 idx_arg.chop_trailing_singletons ();
805
806 return result;
807 } 741 }
808 742
809 NDArray 743 NDArray
810 NDArray::min (int dim) const 744 NDArray::min (int dim) const
811 { 745 {
812 ArrayN<octave_idx_type> dummy_idx; 746 return do_mx_minmax_op<NDArray> (*this, dim, mx_inline_min);
813 return min (dummy_idx, dim);
814 } 747 }
815 748
816 NDArray 749 NDArray
817 NDArray::min (ArrayN<octave_idx_type>& idx_arg, int dim) const 750 NDArray::min (ArrayN<octave_idx_type>& idx_arg, int dim) const
818 { 751 {
819 dim_vector dv = dims (); 752 return do_mx_minmax_op<NDArray> (*this, idx_arg, dim, mx_inline_min);
820 dim_vector dr = dims ();
821
822 if (dv.numel () == 0 || dim > dv.length () || dim < 0)
823 return NDArray ();
824
825 dr(dim) = 1;
826
827 NDArray result (dr);
828 idx_arg.resize (dr);
829
830 octave_idx_type x_stride = 1;
831 octave_idx_type x_len = dv(dim);
832 for (int i = 0; i < dim; i++)
833 x_stride *= dv(i);
834
835 for (octave_idx_type i = 0; i < dr.numel (); i++)
836 {
837 octave_idx_type x_offset;
838 if (x_stride == 1)
839 x_offset = i * x_len;
840 else
841 {
842 octave_idx_type x_offset2 = 0;
843 x_offset = i;
844 while (x_offset >= x_stride)
845 {
846 x_offset -= x_stride;
847 x_offset2++;
848 }
849 x_offset += x_offset2 * x_stride * x_len;
850 }
851
852 octave_idx_type idx_j;
853
854 double tmp_min = octave_NaN;
855
856 for (idx_j = 0; idx_j < x_len; idx_j++)
857 {
858 tmp_min = elem (idx_j * x_stride + x_offset);
859
860 if (! xisnan (tmp_min))
861 break;
862 }
863
864 for (octave_idx_type j = idx_j+1; j < x_len; j++)
865 {
866 double tmp = elem (j * x_stride + x_offset);
867
868 if (xisnan (tmp))
869 continue;
870 else if (tmp < tmp_min)
871 {
872 idx_j = j;
873 tmp_min = tmp;
874 }
875 }
876
877 result.elem (i) = tmp_min;
878 idx_arg.elem (i) = xisnan (tmp_min) ? 0 : idx_j;
879 }
880
881 result.chop_trailing_singletons ();
882 idx_arg.chop_trailing_singletons ();
883
884 return result;
885 } 753 }
886 754
887 NDArray 755 NDArray
888 NDArray::concat (const NDArray& rb, const Array<octave_idx_type>& ra_idx) 756 NDArray::concat (const NDArray& rb, const Array<octave_idx_type>& ra_idx)
889 { 757 {