Array-d.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1994-2012 John W. Eaton
00004 Copyright (C) 2009 VZLU Prague
00005 
00006 This file is part of Octave.
00007 
00008 Octave is free software; you can redistribute it and/or modify it
00009 under the terms of the GNU General Public License as published by the
00010 Free Software Foundation; either version 3 of the License, or (at your
00011 option) any later version.
00012 
00013 Octave is distributed in the hope that it will be useful, but WITHOUT
00014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00015 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00016 for more details.
00017 
00018 You should have received a copy of the GNU General Public License
00019 along with Octave; see the file COPYING.  If not, see
00020 <http://www.gnu.org/licenses/>.
00021 
00022 */
00023 
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027 
00028 // Instantiate Arrays of double values.
00029 
00030 #include "lo-mappers.h"
00031 #include "Array.h"
00032 #include "Array.cc"
00033 #include "oct-locbuf.h"
00034 
00035 #define INLINE_ASCENDING_SORT
00036 #define INLINE_DESCENDING_SORT
00037 #include "oct-sort.cc"
00038 
00039 template <>
00040 inline bool
00041 sort_isnan<double> (double x)
00042 {
00043   return xisnan (x);
00044 }
00045 
00046 static bool
00047 nan_ascending_compare (double x, double y)
00048 {
00049   return xisnan (y) ? ! xisnan (x) : x < y;
00050 }
00051 
00052 static bool
00053 nan_descending_compare (double x, double y)
00054 {
00055   return xisnan (x) ? ! xisnan (y) : x > y;
00056 }
00057 
00058 Array<double>::compare_fcn_type
00059 safe_comparator (sortmode mode, const Array<double>& a , bool allow_chk)
00060 {
00061   Array<double>::compare_fcn_type result = 0;
00062 
00063   if (allow_chk)
00064     {
00065       octave_idx_type k = 0;
00066       for (; k < a.numel () && ! xisnan (a(k)); k++) ;
00067       if (k == a.numel ())
00068         {
00069           if (mode == ASCENDING)
00070             result = octave_sort<double>::ascending_compare;
00071           else if (mode == DESCENDING)
00072             result = octave_sort<double>::descending_compare;
00073         }
00074     }
00075 
00076   if (! result)
00077     {
00078       if (mode == ASCENDING)
00079         result = nan_ascending_compare;
00080       else if (mode == DESCENDING)
00081         result = nan_descending_compare;
00082     }
00083 
00084   return result;
00085 }
00086 
00087 // The default solution using NaN-safe comparator is OK, but almost twice as
00088 // slow than this code.
00089 template <>
00090 OCTAVE_API
00091 sortmode
00092 Array<double>::is_sorted (sortmode mode) const
00093 {
00094   octave_idx_type n = numel ();
00095 
00096   const double *el = data ();
00097 
00098   if (n <= 1)
00099     return mode ? mode : ASCENDING;
00100 
00101   if (! mode)
00102     {
00103       // Auto-detect mode.
00104       if (el[n-1] < el[0] || xisnan (el[0]))
00105         mode = DESCENDING;
00106       else
00107         mode = ASCENDING;
00108     }
00109 
00110   if (mode == DESCENDING)
00111     {
00112       octave_idx_type j = 0;
00113       double r;
00114       // Sort out NaNs.
00115       do
00116         r = el[j++];
00117       while (xisnan (r) && j < n);
00118 
00119       // Orient the test so that NaN will not pass through.
00120       for (; j < n; j++)
00121         {
00122           if (r >= el[j])
00123             r = el[j];
00124           else
00125             {
00126               mode = UNSORTED;
00127               break;
00128             }
00129         }
00130 
00131     }
00132   else if (mode == ASCENDING)
00133     {
00134       // Sort out NaNs.
00135       while (n > 0 && xisnan (el[n-1]))
00136         n--;
00137 
00138       if (n > 0)
00139         {
00140           // Orient the test so that NaN will not pass through.
00141           double r = el[0];
00142           for (octave_idx_type j = 1; j < n; j++)
00143             {
00144               if (r <= el[j])
00145                 r = el[j];
00146               else
00147                 {
00148                   mode = UNSORTED;
00149                   break;
00150                 }
00151             }
00152         }
00153     }
00154 
00155   return mode;
00156 }
00157 
00158 INSTANTIATE_ARRAY_SORT (double);
00159 
00160 INSTANTIATE_ARRAY (double, OCTAVE_API);
00161 
00162 template OCTAVE_API std::ostream& operator << (std::ostream&, const Array<double>&);
00163 
00164 #include "DiagArray2.h"
00165 #include "DiagArray2.cc"
00166 
00167 template class OCTAVE_API DiagArray2<double>;
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines