Mercurial > octave
annotate liboctave/array/Range.cc @ 24780:0d21e2a1cdfc
new element access operators for Range objects
* Range.h, Range.cc (Range::checkelem, Range::elem, Range::operator()):
Allow indexing by row and column.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 21 Feb 2018 09:15:37 -0500 |
parents | 194eb4bd202b |
children | 74a596fd6bab |
rev | line source |
---|---|
3 | 1 /* |
2 | |
23219
3ac9f9ecfae5
maint: Update copyright dates.
John W. Eaton <jwe@octave.org>
parents:
23083
diff
changeset
|
3 Copyright (C) 1993-2017 John W. Eaton |
3 | 4 |
5 This file is part of Octave. | |
6 | |
24534
194eb4bd202b
maint: Update punctuation for GPL v3 license text.
Rik <rik@octave.org>
parents:
23807
diff
changeset
|
7 Octave is free software: you can redistribute it and/or modify it |
22755
3a2b891d0b33
maint: Standardize Copyright formatting.
Rik <rik@octave.org>
parents:
22402
diff
changeset
|
8 under the terms of the GNU General Public License as published by |
24534
194eb4bd202b
maint: Update punctuation for GPL v3 license text.
Rik <rik@octave.org>
parents:
23807
diff
changeset
|
9 the Free Software Foundation, either version 3 of the License, or |
22755
3a2b891d0b33
maint: Standardize Copyright formatting.
Rik <rik@octave.org>
parents:
22402
diff
changeset
|
10 (at your option) any later version. |
3 | 11 |
22755
3a2b891d0b33
maint: Standardize Copyright formatting.
Rik <rik@octave.org>
parents:
22402
diff
changeset
|
12 Octave is distributed in the hope that it will be useful, but |
3a2b891d0b33
maint: Standardize Copyright formatting.
Rik <rik@octave.org>
parents:
22402
diff
changeset
|
13 WITHOUT ANY WARRANTY; without even the implied warranty of |
3a2b891d0b33
maint: Standardize Copyright formatting.
Rik <rik@octave.org>
parents:
22402
diff
changeset
|
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3a2b891d0b33
maint: Standardize Copyright formatting.
Rik <rik@octave.org>
parents:
22402
diff
changeset
|
15 GNU General Public License for more details. |
3 | 16 |
17 You should have received a copy of the GNU General Public License | |
7016 | 18 along with Octave; see the file COPYING. If not, see |
24534
194eb4bd202b
maint: Update punctuation for GPL v3 license text.
Rik <rik@octave.org>
parents:
23807
diff
changeset
|
19 <https://www.gnu.org/licenses/>. |
3 | 20 |
21 */ | |
22 | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21321
diff
changeset
|
23 #if defined (HAVE_CONFIG_H) |
21301
40de9f8f23a6
Use '#include "config.h"' rather than <config.h>.
Rik <rik@octave.org>
parents:
21229
diff
changeset
|
24 # include "config.h" |
3 | 25 #endif |
26 | |
23443
3f1bf237908b
maint: Eliminate <cfloat.h> header from liboctave files.
Rik <rik@octave.org>
parents:
23398
diff
changeset
|
27 #include <cmath> |
1367 | 28 |
3503 | 29 #include <iostream> |
6490 | 30 #include <limits> |
3 | 31 |
23443
3f1bf237908b
maint: Eliminate <cfloat.h> header from liboctave files.
Rik <rik@octave.org>
parents:
23398
diff
changeset
|
32 #include "Array-util.h" |
3 | 33 #include "Range.h" |
7458 | 34 #include "lo-error.h" |
2383 | 35 #include "lo-mappers.h" |
36 #include "lo-utils.h" | |
37 | |
38 bool | |
39 Range::all_elements_are_ints (void) const | |
40 { | |
41 // If the base and increment are ints, the final value in the range | |
21751
b571fc85953f
maint: Use two spaces after period to indicate sentence break.
Rik <rik@octave.org>
parents:
21724
diff
changeset
|
42 // will also be an integer, even if the limit is not. If there is one |
6457 | 43 // or fewer elements only the base needs to be an integer |
2383 | 44 |
21782
2aef506f3fec
use namespace for lo-mappers.h functions
John W. Eaton <jwe@octave.org>
parents:
21751
diff
changeset
|
45 return (! (octave::math::isnan (rng_base) || octave::math::isnan (rng_inc)) |
2aef506f3fec
use namespace for lo-mappers.h functions
John W. Eaton <jwe@octave.org>
parents:
21751
diff
changeset
|
46 && (octave::math::nint_big (rng_base) == rng_base || rng_numel < 1) |
2aef506f3fec
use namespace for lo-mappers.h functions
John W. Eaton <jwe@octave.org>
parents:
21751
diff
changeset
|
47 && (octave::math::nint_big (rng_inc) == rng_inc || rng_numel <= 1)); |
2383 | 48 } |
645 | 49 |
50 Matrix | |
51 Range::matrix_value (void) const | |
52 { | |
23577
80c42f4cca13
maint: Deprecate is_empty and replace with isempty.
Rik <rik@octave.org>
parents:
23487
diff
changeset
|
53 if (rng_numel > 0 && cache.isempty ()) |
645 | 54 { |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
55 cache.resize (1, rng_numel); |
20531
dcfbf4c1c3c8
eliminate trailing whitespace and tabs from sources
John W. Eaton <jwe@octave.org>
parents:
20513
diff
changeset
|
56 |
20513 | 57 // The first element must always be *exactly* the base. |
58 // E.g, -0 would otherwise become +0 in the loop (-0 + 0*increment). | |
59 cache(0) = rng_base; | |
60 | |
645 | 61 double b = rng_base; |
62 double increment = rng_inc; | |
20513 | 63 for (octave_idx_type i = 1; i < rng_numel - 1; i++) |
64 cache(i) = b + i * increment; | |
4791 | 65 |
20513 | 66 cache(rng_numel - 1) = rng_limit; |
645 | 67 } |
68 | |
4810 | 69 return cache; |
645 | 70 } |
3 | 71 |
9986
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
72 double |
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
73 Range::checkelem (octave_idx_type i) const |
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
74 { |
24780
0d21e2a1cdfc
new element access operators for Range objects
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
75 // Ranges are row vectors. |
0d21e2a1cdfc
new element access operators for Range objects
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
76 |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
77 if (i < 0 || i >= rng_numel) |
24780
0d21e2a1cdfc
new element access operators for Range objects
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
78 octave::err_index_out_of_range (2, 2, i+1, rng_numel); |
9986
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
79 |
16169
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
80 if (i == 0) |
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
81 return rng_base; |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
82 else if (i < rng_numel - 1) |
16169
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
83 return rng_base + i * rng_inc; |
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
84 else |
20513 | 85 return rng_limit; |
9986
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
86 } |
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
87 |
16169
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
88 double |
24780
0d21e2a1cdfc
new element access operators for Range objects
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
89 Range::checkelem (octave_idx_type i, octave_idx_type j) const |
0d21e2a1cdfc
new element access operators for Range objects
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
90 { |
0d21e2a1cdfc
new element access operators for Range objects
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
91 if (i != 0) |
0d21e2a1cdfc
new element access operators for Range objects
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
92 octave::err_index_out_of_range (1, 1, i+1, rng_numel); |
0d21e2a1cdfc
new element access operators for Range objects
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
93 |
0d21e2a1cdfc
new element access operators for Range objects
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
94 return checkelem (j); |
0d21e2a1cdfc
new element access operators for Range objects
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
95 } |
0d21e2a1cdfc
new element access operators for Range objects
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
96 |
0d21e2a1cdfc
new element access operators for Range objects
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
97 double |
16169
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
98 Range::elem (octave_idx_type i) const |
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
99 { |
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
100 if (i == 0) |
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
101 return rng_base; |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
102 else if (i < rng_numel - 1) |
16169
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
103 return rng_base + i * rng_inc; |
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
104 else |
20513 | 105 return rng_limit; |
16169
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
106 } |
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
107 |
24780
0d21e2a1cdfc
new element access operators for Range objects
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
108 double |
0d21e2a1cdfc
new element access operators for Range objects
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
109 Range::elem (octave_idx_type i, octave_idx_type j) const |
0d21e2a1cdfc
new element access operators for Range objects
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
110 { |
0d21e2a1cdfc
new element access operators for Range objects
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
111 return elem (j); |
0d21e2a1cdfc
new element access operators for Range objects
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
112 } |
0d21e2a1cdfc
new element access operators for Range objects
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
113 |
16186
b4a6895a9863
Use proper OO-class for __rangeidx_helper().
Rik <rik@octave.org>
parents:
16169
diff
changeset
|
114 // Helper class used solely for idx_vector.loop () function call |
b4a6895a9863
Use proper OO-class for __rangeidx_helper().
Rik <rik@octave.org>
parents:
16169
diff
changeset
|
115 class __rangeidx_helper |
9986
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
116 { |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
117 public: |
16186
b4a6895a9863
Use proper OO-class for __rangeidx_helper().
Rik <rik@octave.org>
parents:
16169
diff
changeset
|
118 __rangeidx_helper (double *a, double b, double i, double l, octave_idx_type n) |
16169
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
119 : array (a), base (b), inc (i), limit (l), nmax (n-1) { } |
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
120 |
9986
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
121 void operator () (octave_idx_type i) |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
122 { |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
123 if (i == 0) |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
124 *array++ = base; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
125 else if (i < nmax) |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
126 *array++ = base + i * inc; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
127 else |
20513 | 128 *array++ = limit; |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
129 } |
16186
b4a6895a9863
Use proper OO-class for __rangeidx_helper().
Rik <rik@octave.org>
parents:
16169
diff
changeset
|
130 |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
131 private: |
16186
b4a6895a9863
Use proper OO-class for __rangeidx_helper().
Rik <rik@octave.org>
parents:
16169
diff
changeset
|
132 |
b4a6895a9863
Use proper OO-class for __rangeidx_helper().
Rik <rik@octave.org>
parents:
16169
diff
changeset
|
133 double *array, base, inc, limit; |
b4a6895a9863
Use proper OO-class for __rangeidx_helper().
Rik <rik@octave.org>
parents:
16169
diff
changeset
|
134 octave_idx_type nmax; |
b4a6895a9863
Use proper OO-class for __rangeidx_helper().
Rik <rik@octave.org>
parents:
16169
diff
changeset
|
135 |
9986
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
136 }; |
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
137 |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
138 Array<double> |
9986
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
139 Range::index (const idx_vector& i) const |
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
140 { |
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
141 Array<double> retval; |
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
142 |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
143 octave_idx_type n = rng_numel; |
9986
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
144 |
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
145 if (i.is_colon ()) |
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
146 { |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
147 retval = matrix_value ().reshape (dim_vector (rng_numel, 1)); |
9986
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
148 } |
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
149 else |
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
150 { |
10366
e5ae13b8b2c2
improve Array indexing error messages
Jaroslav Hajek <highegg@gmail.com>
parents:
10314
diff
changeset
|
151 if (i.extent (n) != n) |
22327
d0562b3159c7
move more classes inside octave namespace
John W. Eaton <jwe@octave.org>
parents:
22323
diff
changeset
|
152 octave::err_index_out_of_range (1, 1, i.extent (n), n); // throws |
10366
e5ae13b8b2c2
improve Array indexing error messages
Jaroslav Hajek <highegg@gmail.com>
parents:
10314
diff
changeset
|
153 |
9986
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
154 dim_vector rd = i.orig_dimensions (); |
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
155 octave_idx_type il = i.length (n); |
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
156 |
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
157 // taken from Array.cc. |
23592
80e3bfb7bd5a
maint: Deprecate is_vector and replace with isvector.
Rik <rik@octave.org>
parents:
23588
diff
changeset
|
158 if (n != 1 && rd.isvector ()) |
9986
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
159 rd = dim_vector (1, il); |
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
160 |
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
161 retval.clear (rd); |
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
162 |
16186
b4a6895a9863
Use proper OO-class for __rangeidx_helper().
Rik <rik@octave.org>
parents:
16169
diff
changeset
|
163 // idx_vector loop across all values in i, |
b4a6895a9863
Use proper OO-class for __rangeidx_helper().
Rik <rik@octave.org>
parents:
16169
diff
changeset
|
164 // executing __rangeidx_helper (i) for each i |
b4a6895a9863
Use proper OO-class for __rangeidx_helper().
Rik <rik@octave.org>
parents:
16169
diff
changeset
|
165 i.loop (n, __rangeidx_helper (retval.fortran_vec (), |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
166 rng_base, rng_inc, rng_limit, rng_numel)); |
9986
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
167 } |
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
168 |
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
169 return retval; |
672e1b49e01e
optimize indexing of ranges by single subscripts
Jaroslav Hajek <highegg@gmail.com>
parents:
8971
diff
changeset
|
170 } |
4810 | 171 |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
172 // NOTE: max and min only return useful values if numel > 0. |
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
173 // do_minmax_body() in max.cc avoids calling Range::min/max if numel == 0. |
208 | 174 |
175 double | |
176 Range::min (void) const | |
177 { | |
178 double retval = 0.0; | |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
179 if (rng_numel > 0) |
208 | 180 { |
181 if (rng_inc > 0) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
182 retval = rng_base; |
208 | 183 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
184 { |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
185 retval = rng_base + (rng_numel - 1) * rng_inc; |
4791 | 186 |
20513 | 187 // Require '<=' test. See note in max (). |
16169
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
188 if (retval <= rng_limit) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
189 retval = rng_limit; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
190 } |
4791 | 191 |
208 | 192 } |
193 return retval; | |
194 } | |
195 | |
196 double | |
197 Range::max (void) const | |
198 { | |
199 double retval = 0.0; | |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
200 if (rng_numel > 0) |
208 | 201 { |
202 if (rng_inc > 0) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
203 { |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
204 retval = rng_base + (rng_numel - 1) * rng_inc; |
4791 | 205 |
20513 | 206 // On some machines (x86 with extended precision floating point |
207 // arithmetic, for example) it is possible that we can overshoot the | |
208 // limit by approximately the machine precision even though we were | |
209 // very careful in our calculation of the number of elements. | |
210 // Therefore, we clip the result to the limit if it overshoots. | |
211 // The test also includes equality (>= rng_limit) to have expressions | |
212 // such as -5:1:-0 result in a -0 endpoint. | |
16169
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
213 if (retval >= rng_limit) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
214 retval = rng_limit; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
215 } |
208 | 216 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
217 retval = rng_base; |
208 | 218 } |
219 return retval; | |
220 } | |
221 | |
222 void | |
7458 | 223 Range::sort_internal (bool ascending) |
208 | 224 { |
20513 | 225 if ((ascending && rng_base > rng_limit && rng_inc < 0.0) |
226 || (! ascending && rng_base < rng_limit && rng_inc > 0.0)) | |
208 | 227 { |
20513 | 228 std::swap (rng_base, rng_limit); |
7458 | 229 rng_inc = -rng_inc; |
230 clear_cache (); | |
231 } | |
232 } | |
233 | |
234 void | |
235 Range::sort_internal (Array<octave_idx_type>& sidx, bool ascending) | |
236 { | |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
237 octave_idx_type nel = numel (); |
7458 | 238 |
239 sidx.resize (dim_vector (1, nel)); | |
240 | |
241 octave_idx_type *psidx = sidx.fortran_vec (); | |
242 | |
243 bool reverse = false; | |
244 | |
20513 | 245 if ((ascending && rng_base > rng_limit && rng_inc < 0.0) |
246 || (! ascending && rng_base < rng_limit && rng_inc > 0.0)) | |
7458 | 247 { |
20513 | 248 std::swap (rng_base, rng_limit); |
7458 | 249 rng_inc = -rng_inc; |
250 clear_cache (); | |
251 reverse = true; | |
252 } | |
253 | |
23450
855122b993da
maint: Wrap tertiary operator in parentheses "(COND ? x : y)".
Rik <rik@octave.org>
parents:
23443
diff
changeset
|
254 octave_idx_type tmp = (reverse ? nel - 1 : 0); |
855122b993da
maint: Wrap tertiary operator in parentheses "(COND ? x : y)".
Rik <rik@octave.org>
parents:
23443
diff
changeset
|
255 octave_idx_type stp = (reverse ? -1 : 1); |
7458 | 256 |
7467 | 257 for (octave_idx_type i = 0; i < nel; i++, tmp += stp) |
7458 | 258 psidx[i] = tmp; |
259 | |
260 } | |
261 | |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
262 Matrix |
7620
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7467
diff
changeset
|
263 Range::diag (octave_idx_type k) const |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7467
diff
changeset
|
264 { |
8971 | 265 return matrix_value ().diag (k); |
7620
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7467
diff
changeset
|
266 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7467
diff
changeset
|
267 |
7458 | 268 Range |
269 Range::sort (octave_idx_type dim, sortmode mode) const | |
270 { | |
271 Range retval = *this; | |
272 | |
273 if (dim == 1) | |
274 { | |
7463
2467639bd8c0
eliminate UNDEFINED sort mode
John W. Eaton <jwe@octave.org>
parents:
7458
diff
changeset
|
275 if (mode == ASCENDING) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
276 retval.sort_internal (true); |
7463
2467639bd8c0
eliminate UNDEFINED sort mode
John W. Eaton <jwe@octave.org>
parents:
7458
diff
changeset
|
277 else if (mode == DESCENDING) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
278 retval.sort_internal (false); |
7458 | 279 } |
280 else if (dim != 0) | |
281 (*current_liboctave_error_handler) ("Range::sort: invalid dimension"); | |
282 | |
283 return retval; | |
284 } | |
285 | |
286 Range | |
287 Range::sort (Array<octave_idx_type>& sidx, octave_idx_type dim, | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
288 sortmode mode) const |
7458 | 289 { |
290 Range retval = *this; | |
291 | |
292 if (dim == 1) | |
293 { | |
7463
2467639bd8c0
eliminate UNDEFINED sort mode
John W. Eaton <jwe@octave.org>
parents:
7458
diff
changeset
|
294 if (mode == ASCENDING) |
16169
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
295 retval.sort_internal (sidx, true); |
7463
2467639bd8c0
eliminate UNDEFINED sort mode
John W. Eaton <jwe@octave.org>
parents:
7458
diff
changeset
|
296 else if (mode == DESCENDING) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
297 retval.sort_internal (sidx, false); |
7458 | 298 } |
299 else if (dim != 0) | |
300 (*current_liboctave_error_handler) ("Range::sort: invalid dimension"); | |
301 | |
302 return retval; | |
208 | 303 } |
304 | |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8589
diff
changeset
|
305 sortmode |
23588
0549061d35b9
maint: Deprecate is_sorted and replace with issorted.
Rik <rik@octave.org>
parents:
23577
diff
changeset
|
306 Range::issorted (sortmode mode) const |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8589
diff
changeset
|
307 { |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
308 if (rng_numel > 1 && rng_inc > 0) |
16169
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
309 mode = (mode == DESCENDING) ? UNSORTED : ASCENDING; |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
310 else if (rng_numel > 1 && rng_inc < 0) |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8589
diff
changeset
|
311 mode = (mode == ASCENDING) ? UNSORTED : DESCENDING; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8589
diff
changeset
|
312 else |
23450
855122b993da
maint: Wrap tertiary operator in parentheses "(COND ? x : y)".
Rik <rik@octave.org>
parents:
23443
diff
changeset
|
313 mode = (mode ? mode : ASCENDING); |
8742
d2b06871afac
add missing return statement
Jaroslav Hajek <highegg@gmail.com>
parents:
8721
diff
changeset
|
314 |
d2b06871afac
add missing return statement
Jaroslav Hajek <highegg@gmail.com>
parents:
8721
diff
changeset
|
315 return mode; |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8589
diff
changeset
|
316 } |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8589
diff
changeset
|
317 |
20513 | 318 void |
319 Range::set_base (double b) | |
320 { | |
321 if (rng_base != b) | |
322 { | |
323 rng_base = b; | |
324 | |
21321
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
325 init (); |
20513 | 326 } |
327 } | |
328 | |
329 void | |
330 Range::set_limit (double l) | |
331 { | |
332 if (rng_limit != l) | |
333 { | |
334 rng_limit = l; | |
335 | |
21321
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
336 init (); |
20513 | 337 } |
338 } | |
339 | |
340 void | |
341 Range::set_inc (double i) | |
342 { | |
343 if (rng_inc != i) | |
344 { | |
345 rng_inc = i; | |
346 | |
21321
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
347 init (); |
20513 | 348 } |
349 } | |
350 | |
3504 | 351 std::ostream& |
352 operator << (std::ostream& os, const Range& a) | |
3 | 353 { |
354 double b = a.base (); | |
355 double increment = a.inc (); | |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
356 octave_idx_type num_elem = a.numel (); |
3 | 357 |
16169
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
358 if (num_elem > 1) |
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
359 { |
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
360 // First element must be the base *exactly* (-0). |
23807
336f89b6208b
Use character literals 'c' rather than string literals "c" when possible.
Rik <rik@octave.org>
parents:
23662
diff
changeset
|
361 os << b << ' '; |
16169
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
362 for (octave_idx_type i = 1; i < num_elem-1; i++) |
23807
336f89b6208b
Use character literals 'c' rather than string literals "c" when possible.
Rik <rik@octave.org>
parents:
23662
diff
changeset
|
363 os << b + i * increment << ' '; |
16169
0303fda3e929
Fix range behavior with -0 endpoints (bug #38423)
Rik <rik@octave.org>
parents:
15271
diff
changeset
|
364 } |
3 | 365 |
20513 | 366 // Print out exactly the last element, rather than a calculated last element. |
367 os << a.rng_limit << "\n"; | |
3 | 368 |
369 return os; | |
370 } | |
371 | |
3504 | 372 std::istream& |
373 operator >> (std::istream& is, Range& a) | |
3 | 374 { |
208 | 375 is >> a.rng_base; |
3 | 376 if (is) |
377 { | |
20513 | 378 double tmp_rng_limit; |
379 is >> tmp_rng_limit; | |
380 | |
3 | 381 if (is) |
20513 | 382 is >> a.rng_inc; |
383 | |
384 // Clip the rng_limit to the true limit and rebuild numel, clear cache | |
385 a.set_limit (tmp_rng_limit); | |
3 | 386 } |
387 | |
388 return is; | |
389 } | |
390 | |
2599 | 391 Range |
392 operator - (const Range& r) | |
393 { | |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
394 return Range (-r.base (), -r.limit (), -r.inc (), r.numel ()); |
2599 | 395 } |
396 | |
8553
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
397 Range operator + (double x, const Range& r) |
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
398 { |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
399 Range result (x + r.base (), x + r.limit (), r.inc (), r.numel ()); |
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
400 if (result.rng_numel < 0) |
8971 | 401 result.cache = x + r.matrix_value (); |
402 | |
403 return result; | |
8553
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
404 } |
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
405 |
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
406 Range operator + (const Range& r, double x) |
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
407 { |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
408 Range result (r.base () + x, r.limit () + x, r.inc (), r.numel ()); |
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
409 if (result.rng_numel < 0) |
8971 | 410 result.cache = r.matrix_value () + x; |
411 | |
412 return result; | |
8553
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
413 } |
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
414 |
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
415 Range operator - (double x, const Range& r) |
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
416 { |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
417 Range result (x - r.base (), x - r.limit (), -r.inc (), r.numel ()); |
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
418 if (result.rng_numel < 0) |
8971 | 419 result.cache = x - r.matrix_value (); |
420 | |
421 return result; | |
8553
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
422 } |
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
423 |
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
424 Range operator - (const Range& r, double x) |
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
425 { |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
426 Range result (r.base () - x, r.limit () - x, r.inc (), r.numel ()); |
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
427 if (result.rng_numel < 0) |
8971 | 428 result.cache = r.matrix_value () - x; |
429 | |
430 return result; | |
8553
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
431 } |
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
432 |
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
433 Range operator * (double x, const Range& r) |
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
434 { |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
435 Range result (x * r.base (), x * r.limit (), x * r.inc (), r.numel ()); |
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
436 if (result.rng_numel < 0) |
8971 | 437 result.cache = x * r.matrix_value (); |
438 | |
439 return result; | |
8553
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
440 } |
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
441 |
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
442 Range operator * (const Range& r, double x) |
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
443 { |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
444 Range result (r.base () * x, r.limit () * x, r.inc () * x, r.numel ()); |
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
445 if (result.rng_numel < 0) |
8971 | 446 result.cache = r.matrix_value () * x; |
447 | |
448 return result; | |
8553
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
449 } |
c7ff200e45f5
optimize range-scalar ops
Jaroslav Hajek <highegg@gmail.com>
parents:
7620
diff
changeset
|
450 |
1546 | 451 // C See Knuth, Art Of Computer Programming, Vol. 1, Problem 1.2.4-5. |
452 // C | |
453 // C===Tolerant FLOOR function. | |
454 // C | |
455 // C X - is given as a Double Precision argument to be operated on. | |
456 // C It is assumed that X is represented with M mantissa bits. | |
457 // C CT - is given as a Comparison Tolerance such that | |
458 // C 0.LT.CT.LE.3-SQRT(5)/2. If the relative difference between | |
459 // C X and A whole number is less than CT, then TFLOOR is | |
460 // C returned as this whole number. By treating the | |
461 // C floating-point numbers as a finite ordered set note that | |
462 // C the heuristic EPS=2.**(-(M-1)) and CT=3*EPS causes | |
463 // C arguments of TFLOOR/TCEIL to be treated as whole numbers | |
464 // C if they are exactly whole numbers or are immediately | |
465 // C adjacent to whole number representations. Since EPS, the | |
466 // C "distance" between floating-point numbers on the unit | |
467 // C interval, and M, the number of bits in X'S mantissa, exist | |
468 // C on every floating-point computer, TFLOOR/TCEIL are | |
469 // C consistently definable on every floating-point computer. | |
470 // C | |
471 // C For more information see the following references: | |
472 // C (1) P. E. Hagerty, "More On Fuzzy Floor And Ceiling," APL QUOTE | |
473 // C QUAD 8(4):20-24, June 1978. Note that TFLOOR=FL5. | |
474 // C (2) L. M. Breed, "Definitions For Fuzzy Floor And Ceiling", APL | |
475 // C QUOTE QUAD 8(3):16-23, March 1978. This paper cites FL1 through | |
476 // C FL5, the history of five years of evolutionary development of | |
477 // C FL5 - the seven lines of code below - by open collaboration | |
478 // C and corroboration of the mathematical-computing community. | |
479 // C | |
480 // C Penn State University Center for Academic Computing | |
481 // C H. D. Knoble - August, 1978. | |
482 | |
483 static inline double | |
484 tfloor (double x, double ct) | |
485 { | |
486 // C---------FLOOR(X) is the largest integer algebraically less than | |
487 // C or equal to X; that is, the unfuzzy FLOOR function. | |
488 | |
489 // DINT (X) = X - DMOD (X, 1.0); | |
490 // FLOOR (X) = DINT (X) - DMOD (2.0 + DSIGN (1.0, X), 3.0); | |
491 | |
492 // C---------Hagerty's FL5 function follows... | |
493 | |
494 double q = 1.0; | |
495 | |
496 if (x < 0.0) | |
497 q = 1.0 - ct; | |
498 | |
499 double rmax = q / (2.0 - ct); | |
500 | |
21942
aab79a1885cc
limit gnulib headers to liboctave/wrappers directory
John W. Eaton <jwe@octave.org>
parents:
21782
diff
changeset
|
501 double t1 = 1.0 + std::floor (x); |
1546 | 502 t1 = (ct / q) * (t1 < 0.0 ? -t1 : t1); |
23450
855122b993da
maint: Wrap tertiary operator in parentheses "(COND ? x : y)".
Rik <rik@octave.org>
parents:
23443
diff
changeset
|
503 t1 = (rmax < t1 ? rmax : t1); |
855122b993da
maint: Wrap tertiary operator in parentheses "(COND ? x : y)".
Rik <rik@octave.org>
parents:
23443
diff
changeset
|
504 t1 = (ct > t1 ? ct : t1); |
21942
aab79a1885cc
limit gnulib headers to liboctave/wrappers directory
John W. Eaton <jwe@octave.org>
parents:
21782
diff
changeset
|
505 t1 = std::floor (x + t1); |
1546 | 506 |
1555 | 507 if (x <= 0.0 || (t1 - x) < rmax) |
1546 | 508 return t1; |
509 else | |
510 return t1 - 1.0; | |
511 } | |
512 | |
3753 | 513 static inline bool |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
514 teq (double u, double v, |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
515 double ct = 3.0 * std::numeric_limits<double>::epsilon ()) |
3753 | 516 { |
517 double tu = fabs (u); | |
518 double tv = fabs (v); | |
519 | |
520 return fabs (u - v) < ((tu > tv ? tu : tv) * ct); | |
521 } | |
522 | |
5275 | 523 octave_idx_type |
20228
00cf2847355d
Deprecate Array::nelem() and Range::nelem() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
19697
diff
changeset
|
524 Range::numel_internal (void) const |
1360 | 525 { |
5275 | 526 octave_idx_type retval = -1; |
3 | 527 |
3858 | 528 if (rng_inc == 0 |
529 || (rng_limit > rng_base && rng_inc < 0) | |
530 || (rng_limit < rng_base && rng_inc > 0)) | |
531 { | |
532 retval = 0; | |
533 } | |
534 else | |
535 { | |
15220
61822c866ba1
use std::numeric_limits<T>::epsilon in C++ code
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
536 double ct = 3.0 * std::numeric_limits<double>::epsilon (); |
3 | 537 |
3858 | 538 double tmp = tfloor ((rng_limit - rng_base + rng_inc) / rng_inc, ct); |
539 | |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
540 octave_idx_type n_elt = (tmp > 0.0 ? static_cast<octave_idx_type> (tmp) |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
541 : 0); |
398 | 542 |
3858 | 543 // If the final element that we would compute for the range is |
544 // equal to the limit of the range, or is an adjacent floating | |
545 // point number, accept it. Otherwise, try a range with one | |
546 // fewer element. If that fails, try again with one more | |
547 // element. | |
548 // | |
549 // I'm not sure this is very good, but it seems to work better than | |
550 // just using tfloor as above. For example, without it, the | |
551 // expression 1.8:0.05:1.9 fails to produce the expected result of | |
552 // [1.8, 1.85, 1.9]. | |
3753 | 553 |
3858 | 554 if (! teq (rng_base + (n_elt - 1) * rng_inc, rng_limit)) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
555 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
556 if (teq (rng_base + (n_elt - 2) * rng_inc, rng_limit)) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
557 n_elt--; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
558 else if (teq (rng_base + n_elt * rng_inc, rng_limit)) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
559 n_elt++; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
560 } |
3858 | 561 |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
562 retval = (n_elt < std::numeric_limits<octave_idx_type>::max () - 1) |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
563 ? n_elt : -1; |
3753 | 564 } |
565 | |
3858 | 566 return retval; |
3 | 567 } |
21321
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
568 |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
569 double |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
570 Range::limit_internal (void) const |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
571 { |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
572 double tmp_limit = rng_limit; |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
573 |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
574 if (rng_inc > 0) |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
575 tmp_limit = max (); |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
576 else |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
577 tmp_limit = min (); |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
578 |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
579 return (tmp_limit != rng_limit) ? tmp_limit : rng_limit; |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
580 } |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
581 |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
582 void |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
583 Range::init (void) |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
584 { |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
585 rng_numel = numel_internal (); |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
586 rng_limit = limit_internal (); |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
587 |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
588 clear_cache (); |
79a51b7e00b6
eliminate some copy and paste code fragments in the Range class
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
589 } |