Mercurial > hg > octave-lyh
comparison liboctave/Range.cc @ 8971:967a692ddfe2
fix range arithmetics
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Fri, 13 Mar 2009 12:18:50 +0100 |
parents | eb63fbe60fab |
children | 672e1b49e01e |
comparison
equal
deleted
inserted
replaced
8970:b37a6c27c23f | 8971:967a692ddfe2 |
---|---|
34 #include "lo-error.h" | 34 #include "lo-error.h" |
35 #include "lo-mappers.h" | 35 #include "lo-mappers.h" |
36 #include "lo-math.h" | 36 #include "lo-math.h" |
37 #include "lo-utils.h" | 37 #include "lo-utils.h" |
38 | 38 |
39 Range::Range (double b, double i, octave_idx_type n) | |
40 : rng_base (b), rng_limit (b + n * i), rng_inc (i), | |
41 rng_nelem (n), cache () | |
42 { | |
43 if (! xfinite (b) || ! xfinite (i)) | |
44 rng_nelem = -2; | |
45 } | |
46 | |
39 bool | 47 bool |
40 Range::all_elements_are_ints (void) const | 48 Range::all_elements_are_ints (void) const |
41 { | 49 { |
42 // If the base and increment are ints, the final value in the range | 50 // If the base and increment are ints, the final value in the range |
43 // will also be an integer, even if the limit is not. If there is one | 51 // will also be an integer, even if the limit is not. If there is one |
49 } | 57 } |
50 | 58 |
51 Matrix | 59 Matrix |
52 Range::matrix_value (void) const | 60 Range::matrix_value (void) const |
53 { | 61 { |
54 if (rng_nelem > 0 && cache.rows () == 0) | 62 if (rng_nelem > 0 && cache.nelem () == 0) |
55 { | 63 { |
56 cache.resize (1, rng_nelem); | 64 cache.resize (1, rng_nelem); |
57 double b = rng_base; | 65 double b = rng_base; |
58 double increment = rng_inc; | 66 double increment = rng_inc; |
59 for (octave_idx_type i = 0; i < rng_nelem; i++) | 67 for (octave_idx_type i = 0; i < rng_nelem; i++) |
179 } | 187 } |
180 | 188 |
181 Matrix | 189 Matrix |
182 Range::diag (octave_idx_type k) const | 190 Range::diag (octave_idx_type k) const |
183 { | 191 { |
184 octave_idx_type nnr = 1; | 192 return matrix_value ().diag (k); |
185 octave_idx_type nnc = nelem (); | |
186 Matrix d; | |
187 | |
188 if (nnr != 0) | |
189 { | |
190 octave_idx_type roff = 0; | |
191 octave_idx_type coff = 0; | |
192 if (k > 0) | |
193 { | |
194 roff = 0; | |
195 coff = k; | |
196 } | |
197 else if (k < 0) | |
198 { | |
199 roff = -k; | |
200 coff = 0; | |
201 } | |
202 | |
203 // Force cached matrix to be created | |
204 matrix_value (); | |
205 | |
206 octave_idx_type n = nnc + std::abs (k); | |
207 d = Matrix (n, n, Matrix::resize_fill_value ()); | |
208 for (octave_idx_type i = 0; i < nnc; i++) | |
209 d.xelem (i+roff, i+coff) = cache.xelem (i); | |
210 } | |
211 | |
212 return d; | |
213 } | 193 } |
214 | 194 |
215 Range | 195 Range |
216 Range::sort (octave_idx_type dim, sortmode mode) const | 196 Range::sort (octave_idx_type dim, sortmode mode) const |
217 { | 197 { |
303 return Range (-r.base (), -r.inc (), r.nelem ()); | 283 return Range (-r.base (), -r.inc (), r.nelem ()); |
304 } | 284 } |
305 | 285 |
306 Range operator + (double x, const Range& r) | 286 Range operator + (double x, const Range& r) |
307 { | 287 { |
308 return Range (x + r.base (), r.inc (), r.nelem ()); | 288 Range result (x + r.base (), r.inc (), r.nelem ()); |
289 if (result.rng_nelem < 0) | |
290 result.cache = x + r.matrix_value (); | |
291 | |
292 return result; | |
309 } | 293 } |
310 | 294 |
311 Range operator + (const Range& r, double x) | 295 Range operator + (const Range& r, double x) |
312 { | 296 { |
313 return Range (r.base () + x, r.inc (), r.nelem ()); | 297 Range result (r.base () + x, r.inc (), r.nelem ()); |
298 if (result.rng_nelem < 0) | |
299 result.cache = r.matrix_value () + x; | |
300 | |
301 return result; | |
314 } | 302 } |
315 | 303 |
316 Range operator - (double x, const Range& r) | 304 Range operator - (double x, const Range& r) |
317 { | 305 { |
318 return Range (x - r.base (), -r.inc (), r.nelem ()); | 306 Range result (x - r.base (), -r.inc (), r.nelem ()); |
307 if (result.rng_nelem < 0) | |
308 result.cache = x - r.matrix_value (); | |
309 | |
310 return result; | |
319 } | 311 } |
320 | 312 |
321 Range operator - (const Range& r, double x) | 313 Range operator - (const Range& r, double x) |
322 { | 314 { |
323 return Range (r.base () - x, r.inc (), r.nelem ()); | 315 Range result (r.base () - x, r.inc (), r.nelem ()); |
316 if (result.rng_nelem < 0) | |
317 result.cache = r.matrix_value () - x; | |
318 | |
319 return result; | |
324 } | 320 } |
325 | 321 |
326 Range operator * (double x, const Range& r) | 322 Range operator * (double x, const Range& r) |
327 { | 323 { |
328 return Range (x * r.base (), x * r.inc (), r.nelem ()); | 324 Range result (x * r.base (), x * r.inc (), r.nelem ()); |
325 if (result.rng_nelem < 0) | |
326 result.cache = x * r.matrix_value (); | |
327 | |
328 return result; | |
329 } | 329 } |
330 | 330 |
331 Range operator * (const Range& r, double x) | 331 Range operator * (const Range& r, double x) |
332 { | 332 { |
333 return Range (r.base () * x, r.inc () * x, r.nelem ()); | 333 Range result (r.base () * x, r.inc () * x, r.nelem ()); |
334 if (result.rng_nelem < 0) | |
335 result.cache = r.matrix_value () * x; | |
336 | |
337 return result; | |
334 } | 338 } |
335 | 339 |
336 | 340 |
337 // C See Knuth, Art Of Computer Programming, Vol. 1, Problem 1.2.4-5. | 341 // C See Knuth, Art Of Computer Programming, Vol. 1, Problem 1.2.4-5. |
338 // C | 342 // C |