GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Array-f.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1994-2013 John W. Eaton
4 Copyright (C) 2009 VZLU Prague
5 
6 This file is part of Octave.
7 
8 Octave is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, see
20 <http://www.gnu.org/licenses/>.
21 
22 */
23 
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27 
28 // Instantiate Arrays of float values.
29 
30 #include "lo-mappers.h"
31 #include "Array.h"
32 #include "Array.cc"
33 #include "oct-locbuf.h"
34 
35 #define INLINE_ASCENDING_SORT
36 #define INLINE_DESCENDING_SORT
37 #include "oct-sort.cc"
38 
39 template <>
40 inline bool
42 {
43  return xisnan (x);
44 }
45 
46 static bool
47 nan_ascending_compare (float x, float y)
48 {
49  return xisnan (y) ? ! xisnan (x) : x < y;
50 }
51 
52 static bool
53 nan_descending_compare (float x, float y)
54 {
55  return xisnan (x) ? ! xisnan (y) : x > y;
56 }
57 
59 safe_comparator (sortmode mode, const Array<float>& a , bool allow_chk)
60 {
62 
63  if (allow_chk)
64  {
65  octave_idx_type k = 0;
66  for (; k < a.numel () && ! xisnan (a(k)); k++) ;
67  if (k == a.numel ())
68  {
69  if (mode == ASCENDING)
71  else if (mode == DESCENDING)
73  }
74  }
75 
76  if (! result)
77  {
78  if (mode == ASCENDING)
79  result = nan_ascending_compare;
80  else if (mode == DESCENDING)
81  result = nan_descending_compare;
82  }
83 
84  return result;
85 }
86 
87 // The default solution using NaN-safe comparator is OK, but almost twice as
88 // slow than this code.
89 template <>
90 OCTAVE_API
93 {
94  octave_idx_type n = numel ();
95 
96  const float *el = data ();
97 
98  if (n <= 1)
99  return mode ? mode : ASCENDING;
100 
101  if (! mode)
102  {
103  // Auto-detect mode.
104  if (el[n-1] < el[0] || xisnan (el[0]))
105  mode = DESCENDING;
106  else
107  mode = ASCENDING;
108  }
109 
110  if (mode == DESCENDING)
111  {
112  octave_idx_type j = 0;
113  float r;
114  // Sort out NaNs.
115  do
116  r = el[j++];
117  while (xisnan (r) && j < n);
118 
119  // Orient the test so that NaN will not pass through.
120  for (; j < n; j++)
121  {
122  if (r >= el[j])
123  r = el[j];
124  else
125  {
126  mode = UNSORTED;
127  break;
128  }
129  }
130 
131  }
132  else if (mode == ASCENDING)
133  {
134  // Sort out NaNs.
135  while (n > 0 && xisnan (el[n-1]))
136  n--;
137 
138  if (n > 0)
139  {
140  // Orient the test so that NaN will not pass through.
141  float r = el[0];
142  for (octave_idx_type j = 1; j < n; j++)
143  {
144  if (r <= el[j])
145  r = el[j];
146  else
147  {
148  mode = UNSORTED;
149  break;
150  }
151  }
152  }
153  }
154 
155  return mode;
156 }
157 
159 
160 INSTANTIATE_ARRAY (float, OCTAVE_API);
161 
162 template OCTAVE_API std::ostream& operator << (std::ostream&,
163  const Array<float>&);
164 
165 #include "DiagArray2.h"
166 #include "DiagArray2.cc"
167 
168 template class OCTAVE_API DiagArray2<float>;