Mercurial > hg > octave-lyh
changeset 9772:3ac8ea48279b
improve index reduction rules
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Tue, 03 Nov 2009 07:44:20 +0100 |
parents | 4634a0e9ea1b |
children | 01f897d8a130 |
files | liboctave/ChangeLog liboctave/idx-vector.cc |
diffstat | 2 files changed, 78 insertions(+), 33 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,8 @@ +2009-11-03 Jaroslav Hajek <highegg@gmail.com> + + * idx-vector.cc (idx_vector::maybe_reduce): Implement (i:k:end, :) + and (i:k:end, p:q) reductions. + 2009-11-02 Jaroslav Hajek <highegg@gmail.com> * mx-inlines.cc (twosum_accum): Remove FLOAT_TRUNCATE.
--- a/liboctave/idx-vector.cc +++ b/liboctave/idx-vector.cc @@ -420,43 +420,83 @@ switch (j.idx_class ()) { case class_colon: - if (rep->is_colon_equiv (n)) + switch (rep->idx_class ()) { + case class_colon: // (:,:) reduces to (:) - *this = colon; reduced = true; - } - else if (rep->idx_class () == class_scalar) - { - // (i,:) reduces to a range. - idx_scalar_rep * r = dynamic_cast<idx_scalar_rep *> (rep); - octave_idx_type k = r->get_data (); - *this = new idx_range_rep (k, nj, n, DIRECT); - reduced = true; + break; + case class_scalar: + { + // (i,:) reduces to a range. + idx_scalar_rep * r = dynamic_cast<idx_scalar_rep *> (rep); + octave_idx_type k = r->get_data (); + *this = new idx_range_rep (k, nj, n, DIRECT); + reduced = true; + break; + } + case class_range: + { + // (i:k:end,:) reduces to a range if i <= k and k divides n. + idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep); + octave_idx_type s = r->get_start (), l = r->length (n); + octave_idx_type t = r->get_step (); + if (l*t == n) + { + *this = new idx_range_rep (s, l * nj, t, DIRECT); + reduced = true; + } + break; + } + default: + break; } break; case class_range: - if (rep->is_colon_equiv (n)) + switch (rep->idx_class ()) { - // (:,i:j) reduces to a range (the step must be 1) - idx_range_rep * rj = dynamic_cast<idx_range_rep *> (j.rep); - if (rj->get_step () == 1) - { - octave_idx_type s = rj->get_start (), l = rj->length (nj); - *this = new idx_range_rep (s * n, l * n, 1, DIRECT); - reduced = true; - } - } - else if (rep->idx_class () == class_scalar) - { - // (k,i:d:j) reduces to a range. - idx_scalar_rep * r = dynamic_cast<idx_scalar_rep *> (rep); - idx_range_rep * rj = dynamic_cast<idx_range_rep *> (j.rep); - octave_idx_type k = r->get_data (); - octave_idx_type s = rj->get_start (), l = rj->length (nj); - octave_idx_type t = rj->get_step (); - *this = new idx_range_rep (n * s + k, l, n * t, DIRECT); - reduced = true; + case class_colon: + { + // (:,i:j) reduces to a range (the step must be 1) + idx_range_rep * rj = dynamic_cast<idx_range_rep *> (j.rep); + if (rj->get_step () == 1) + { + octave_idx_type sj = rj->get_start (), lj = rj->length (nj); + *this = new idx_range_rep (sj * n, lj * n, 1, DIRECT); + reduced = true; + } + break; + } + case class_scalar: + { + // (k,i:d:j) reduces to a range. + idx_scalar_rep * r = dynamic_cast<idx_scalar_rep *> (rep); + idx_range_rep * rj = dynamic_cast<idx_range_rep *> (j.rep); + octave_idx_type k = r->get_data (); + octave_idx_type sj = rj->get_start (), lj = rj->length (nj); + octave_idx_type tj = rj->get_step (); + *this = new idx_range_rep (n * sj + k, lj, n * tj, DIRECT); + reduced = true; + break; + } + case class_range: + { + // (i:k:end,p:q) reduces to a range if i <= k and k divides n. + idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep); + octave_idx_type s = r->get_start (), l = r->length (n); + octave_idx_type t = r->get_step (); + idx_range_rep * rj = dynamic_cast<idx_range_rep *> (j.rep); + octave_idx_type sj = rj->get_start (), lj = rj->length (nj); + octave_idx_type tj = rj->get_step (); + if (l*t == n && tj == 1) + { + *this = new idx_range_rep (s + n * sj, l * lj, t, DIRECT); + reduced = true; + } + break; + } + default: + break; } break; case class_scalar: @@ -470,8 +510,8 @@ octave_idx_type k = r->get_data () + n * rj->get_data (); *this = new idx_scalar_rep (k, DIRECT); reduced = true; + break; } - break; case class_range: { // (i:d:j,k) reduces to a range. @@ -482,8 +522,8 @@ octave_idx_type k = rj->get_data (); *this = new idx_range_rep (n * k + s, l, t, DIRECT); reduced = true; + break; } - break; case class_colon: { // (:,k) reduces to a range. @@ -491,8 +531,8 @@ octave_idx_type k = rj->get_data (); *this = new idx_range_rep (n * k, n, 1, DIRECT); reduced = true; + break; } - break; default: break; }