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