# HG changeset patch # User Jaroslav Hajek # Date 1257230660 -3600 # Node ID 3ac8ea48279b5ba6a2ba121d971c68bddc9df60a # Parent 4634a0e9ea1b43041cfa4ff2b2e3e2ad76206e83 improve index reduction rules diff -r 4634a0e9ea1b -r 3ac8ea48279b liboctave/ChangeLog --- a/liboctave/ChangeLog Mon Nov 02 21:34:04 2009 -0500 +++ b/liboctave/ChangeLog Tue Nov 03 07:44:20 2009 +0100 @@ -1,3 +1,8 @@ +2009-11-03 Jaroslav Hajek + + * idx-vector.cc (idx_vector::maybe_reduce): Implement (i:k:end, :) + and (i:k:end, p:q) reductions. + 2009-11-02 Jaroslav Hajek * mx-inlines.cc (twosum_accum): Remove FLOAT_TRUNCATE. diff -r 4634a0e9ea1b -r 3ac8ea48279b liboctave/idx-vector.cc --- a/liboctave/idx-vector.cc Mon Nov 02 21:34:04 2009 -0500 +++ b/liboctave/idx-vector.cc Tue Nov 03 07:44:20 2009 +0100 @@ -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 (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 (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 (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 (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 (rep); - idx_range_rep * rj = dynamic_cast (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 (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 (rep); + idx_range_rep * rj = dynamic_cast (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 (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 (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; }