Mercurial > hg > octave-nkf
diff liboctave/idx-vector.cc @ 1560:27a03373de41
[project @ 1995-10-12 07:22:26 by jwe]
author | jwe |
---|---|
date | Thu, 12 Oct 1995 07:24:52 +0000 |
parents | d1ddf54a79c2 |
children | f110a90eb183 |
line wrap: on
line diff
--- a/liboctave/idx-vector.cc +++ b/liboctave/idx-vector.cc @@ -34,17 +34,26 @@ #include <iostream.h> #include "Range.h" +#include "dColVector.h" #include "dMatrix.h" -#include "error.h" #include "idx-vector.h" -#include "user-prefs.h" -#include "utils.h" +#include "lo-error.h" -idx_vector::idx_vector (const idx_vector& a) +#define IDX_VEC_REP idx_vector::idx_vector_rep + +IDX_VEC_REP::idx_vector_rep (const IDX_VEC_REP& a) { data = 0; initialized = a.initialized; + frozen = a.frozen; + colon_equiv_checked = a.colon_equiv_checked; + colon_equiv = a.colon_equiv; + + colon = a.colon; + + orig_nr = a.orig_nr; + orig_nc = a.orig_nc; len = a.len; if (len > 0) @@ -71,65 +80,93 @@ return ((int) (x - 0.5) - 1); } -idx_vector::idx_vector (const Matrix& m, int do_ftn_idx, - const char *rc, int z_len) +IDX_VEC_REP::idx_vector_rep (const ColumnVector& v) { data = 0; initialized = 0; - - int nr = m.rows (); - int nc = m.columns (); + frozen = 0; + colon_equiv_checked = 0; + colon_equiv = 0; + colon = 0; - if (nr == 0 || nc == 0) + int len = v.length (); + + orig_nr = len; + orig_nc = 1; + + if (len == 0) { - len = 0; num_zeros = 0; num_ones = 0; one_zero = 0; + max_val = 0; + min_val = 0; initialized = 1; return; } - else if (nr > 1 && nc > 1 && do_ftn_idx) + else { - const double *cop_out = m.data (); - len = nr * nc; data = new int [len]; for (int i = 0; i < len; i++) - data[i] = tree_to_mat_idx (*cop_out++); + data[i] = tree_to_mat_idx (v.elem (i)); } - else if (nr == 1 && nc > 0) + + init_state (); +} + +IDX_VEC_REP::idx_vector_rep (const Matrix& m) +{ + data = 0; + initialized = 0; + frozen = 0; + colon_equiv_checked = 0; + colon_equiv = 0; + colon = 0; + + orig_nr = m.rows (); + orig_nc = m.columns (); + + len = orig_nr * orig_nc; + + if (len == 0) { - len = nc; - data = new int [len]; - for (int i = 0; i < len; i++) - data[i] = tree_to_mat_idx (m.elem (0, i)); - } - else if (nc == 1 && nr > 0) - { - len = nr; - data = new int [len]; - for (int i = 0; i < len; i++) - data[i] = tree_to_mat_idx (m.elem (i, 0)); + num_zeros = 0; + num_ones = 0; + one_zero = 0; + max_val = 0; + min_val = 0; + initialized = 1; + return; } else { - ::error ("invalid matrix used as index"); - return; + int k = 0; + data = new int [len]; + for (int j = 0; j < orig_nc; j++) + for (int i = 0; i < orig_nr; i++) + data[k++] = tree_to_mat_idx (m.elem (i, j)); } - init_state (rc, z_len); + init_state (); } -idx_vector::idx_vector (const Range& r) +IDX_VEC_REP::idx_vector_rep (const Range& r) { data = 0; initialized = 0; + frozen = 0; + colon_equiv_checked = 0; + colon_equiv = 0; + colon = 0; len = r.nelem (); + orig_nr = 1; + orig_nc = len; + if (len < 0) { - ::error ("invalid range used as index"); + (*current_liboctave_error_handler) ("invalid range used as index"); return; } else if (len == 0) @@ -137,6 +174,8 @@ num_zeros = 0; num_ones = 0; one_zero = 0; + max_val = 0; + min_val = 0; initialized = 1; return; } @@ -155,12 +194,38 @@ init_state (); } -idx_vector& -idx_vector::operator = (const idx_vector& a) +IDX_VEC_REP::idx_vector_rep (char c) +{ + assert (c == ':'); + + colon = 1; + len = 0; + num_zeros = 0; + num_ones = 0; + one_zero = 0; + initialized = 0; + frozen = 0; + colon_equiv_checked = 0; + colon_equiv = 0; + data = 0; + + init_state (); +} + +IDX_VEC_REP& +IDX_VEC_REP::operator = (const IDX_VEC_REP& a) { if (this != &a) { initialized = a.initialized; + frozen = a.frozen; + colon_equiv_checked = a.colon_equiv_checked; + colon_equiv = a.colon_equiv; + + colon = a.colon; + + orig_nr = a.orig_nr; + orig_nc = a.orig_nc; delete [] data; len = a.len; @@ -179,90 +244,33 @@ } void -idx_vector::init_state (const char *rc, int z_len) +IDX_VEC_REP::init_state (void) { - one_zero = 1; num_zeros = 0; num_ones = 0; - min_val = max_val = data[0]; - - int i = 0; - do - { - if (data[i] == -1) - num_zeros++; - else if (data[i] == 0) - num_ones++; - - if (one_zero && data[i] != -1 && data[i] != 0) - one_zero = 0; - - if (data[i] > max_val) - max_val = data[i]; - - if (data[i] < min_val) - min_val = data[i]; - } - while (++i < len); - - if (one_zero && z_len == len) - { - if (num_ones != len || user_pref.prefer_zero_one_indexing) - convert_one_zero_to_idx (); - } - else if (min_val < 0) + if (colon) { - ::error ("%s index %d out of range", rc, min_val+1); - initialized = 0; - return; - } -#if 0 - // Checking max index against size won't work right here unless we - // also look at resize on range error, and we have to do that later - // on anyway. - - else if (max_val >= z_len) - { - ::error ("%s index %d out of range", rc, max_val+1); - initialized = 0; - return; - } -#endif - - initialized = 1; -} - -void -idx_vector::convert_one_zero_to_idx (void) -{ - if (num_ones == 0) - { - len = 0; - max_val = 0; - min_val = 0; - delete [] data; - data = 0; + one_zero = 0; + min_val = max_val = 0; } else { - assert (num_ones + num_zeros == len); - - int *new_data = new int [num_ones]; - int count = 0; - for (int i = 0; i < len; i++) - if (data[i] == 0) - new_data[count++] = i; - - delete [] data; - len = num_ones; - data = new_data; + one_zero = 1; min_val = max_val = data[0]; int i = 0; do { + if (data[i] == -1) + num_zeros++; + else if (data[i] == 0) + num_ones++; + + if (one_zero && data[i] != -1 && data[i] != 0) + one_zero = 0; + if (data[i] > max_val) max_val = data[i]; @@ -271,14 +279,60 @@ } while (++i < len); } + + initialized = 1; +} + +void +IDX_VEC_REP::maybe_convert_one_zero_to_idx (int z_len, int prefer_zero_one) +{ + if (one_zero && z_len == len + && (num_ones != len || prefer_zero_one)) + { + if (num_ones == 0) + { + len = 0; + max_val = 0; + min_val = 0; + delete [] data; + data = 0; + } + else + { + assert (num_ones + num_zeros == len); + + int *new_data = new int [num_ones]; + int count = 0; + for (int i = 0; i < len; i++) + if (data[i] == 0) + new_data[count++] = i; + + delete [] data; + len = num_ones; + data = new_data; + + min_val = max_val = data[0]; + + int i = 0; + do + { + if (data[i] > max_val) + max_val = data[i]; + + if (data[i] < min_val) + min_val = data[i]; + } + while (++i < len); + } + } } int -idx_vector::checkelem (int n) const +IDX_VEC_REP::checkelem (int n) const { if (n < 0 || n >= len) { - ::error ("idx-vector: index out of range"); + (*current_liboctave_error_handler) ("idx-vector: index out of range"); return 0; } @@ -291,52 +345,147 @@ return (*i - *j); } -void -idx_vector::sort (void) +static inline void +sort_data (int *d, int len) +{ + qsort ((void *) d, len, sizeof (int), + (int (*)(const void*, const void*)) intcmp); +} + +static inline int +make_uniq (int *d, int len) +{ + int k = 0; + for (int i = 1; i < len; i++) + { + if (d[i] != d[k]) + { + k++; + d[k] = d[i]; + } + } + return k+1; +} + +static inline int * +copy_data (const int *d, int len) { - qsort ((void *) data, len, sizeof (int), - (int (*)(const void*, const void*)) intcmp); + int *new_data = new int [len]; + + for (int i = 0; i < len; i++) + new_data[i] = d[i]; + + return new_data; +} + +int +IDX_VEC_REP::is_colon_equiv (int n, int sort) +{ + if (! colon_equiv_checked) + { + if (colon) + { + colon_equiv = 1; + } + else if (len > 0) + { + int *tmp_data = copy_data (data, len); + + if (sort) + sort_data (tmp_data, len); + + int tmp_len = make_uniq (tmp_data, len); + + colon_equiv = ((tmp_len == 0 && n == 0) + || (tmp_len == n + && tmp_data[0] == 0 + && tmp_data[tmp_len-1] == tmp_len - 1)); + + delete [] tmp_data; + } + else + colon_equiv = 0; + + colon_equiv_checked = 1; + } + + return colon_equiv; } void -idx_vector::sort_uniq (void) -{ - if (len > 0) - { - sort (); - - int *new_data = new int [len]; - new_data[0] = data[0]; - int k = 0; - for (int i = 1; i < len; i++) - { - if (data[i] != new_data[k]) - { - k++; - new_data[k] = data[i]; - } - } - delete [] data; - len = k+1; - data = new_data; - } -} - -void -idx_vector::shorten (int n) +IDX_VEC_REP::shorten (int n) { if (n > 0 && n <= len) len = n; else - panic_impossible (); + (*current_liboctave_error_handler) + ("idx_vector::shorten: internal error!"); } ostream& -operator << (ostream& os, const idx_vector& a) +IDX_VEC_REP::print (ostream& os) const +{ + for (int i = 0; i < len; i++) + os << data[i] << "\n"; + return os; +} + +int +IDX_VEC_REP::freeze (int z_len, const char *tag, + int prefer_zero_one, int resize_ok) { - for (int i = 0; i < a.len; i++) - os << a.data[i] << "\n"; - return os; + if (frozen) + { + assert (frozen_at_z_len == z_len); + return frozen_len; + } + + frozen_len = -1; + + if (colon) + frozen_len = z_len; + else + { + if (len == 0) + frozen_len = 0; + else + { + maybe_convert_one_zero_to_idx (z_len, prefer_zero_one); + + int max_val = max (); + int min_val = min (); + + if (min_val < 0) + { + if (tag) + (*current_liboctave_error_handler) + ("invalid %s index = %d", tag, min_val+1); + else + (*current_liboctave_error_handler) + ("invalid index = %d", min_val+1); + + initialized = 0; + } + else if (! resize_ok && max_val >= z_len) + { + if (tag) + (*current_liboctave_error_handler) + ("invalid %s index = %d", tag, max_val+1); + else + (*current_liboctave_error_handler) + ("invalid index = %d", max_val+1); + + initialized = 0; + } + else + frozen_len = length (z_len); + } + } + + frozen = 1; + frozen_at_z_len = z_len; + + return frozen_len; } /*