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