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