Mercurial > hg > octave-jordi
diff liboctave/idx-vector.cc @ 1:78fd87e624cb
[project @ 1993-08-08 01:13:40 by jwe]
Initial revision
author | jwe |
---|---|
date | Sun, 08 Aug 1993 01:13:40 +0000 |
parents | |
children | e2c950dd96d2 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/liboctave/idx-vector.cc @@ -0,0 +1,249 @@ +// Very simple integer vectors for indexing -*- C++ -*- +/* + +Copyright (C) 1992, 1993 John W. Eaton + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, write to the Free +Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif + +#include "idx-vector.h" +#include "error.h" +#include "user-prefs.h" +#include "utils.h" + +idx_vector::idx_vector (const idx_vector& a) +{ + len = a.len; + if (len > 0) + { + data = new int [len]; + for (int i = 0; i < len; i++) + data[i] = a.data[i]; + + num_zeros = a.num_zeros; + num_ones = a.num_ones; + one_zero = a.one_zero; + + max_val = a.max_val; + min_val = a.min_val; + } + else + data = 0; +} + +static inline int +tree_to_mat_idx (double x) +{ + if (x > 0) + return ((int) (x + 0.5) - 1); + else + return ((int) (x - 0.5) - 1); +} + +idx_vector::idx_vector (Matrix& m, int do_ftn_idx, char *rc, int z_len = 0) +{ + int nr = m.rows (); + int nc = m.columns (); + + if (nr == 0 || nc == 0) + { + len = 0; + data = 0; + num_zeros = 0; + num_ones = 0; + one_zero = 0; + return; + } + else if (nr > 1 && nc > 1 && do_ftn_idx) + { + double *cop_out = m.fortran_vec (); + len = nr * nc; + data = new int [len]; + for (int i = 0; i < len; i++) + data[i] = tree_to_mat_idx (*cop_out++); + } + else if (nr == 1 && nc > 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)); + } + else + { + message ((char *) NULL, "invalid matrix index"); + jump_to_top_level (); + } + + init_state (rc, z_len); +} + +idx_vector::idx_vector (const Range& r) +{ + len = r.nelem (); + + assert (len != 0); + + double b = r.base (); + double step = r.inc (); + + data = new int [len]; + + for (int i = 0; i < len; i++) + { + double val = b + i * step; + data[i] = tree_to_mat_idx (val); + } + + init_state (); +} + +idx_vector& +idx_vector::operator = (const idx_vector& a) +{ + if (this != &a) + { + delete [] data; + len = a.len; + data = new int [len]; + for (int i = 0; i < len; i++) + data[i] = a.data[i]; + + num_zeros = a.num_zeros; + num_ones = a.num_ones; + one_zero = a.one_zero; + + max_val = a.max_val; + min_val = a.min_val; + } + return *this; +} + +void +idx_vector::init_state (char *rc, int z_len = 0) +{ + 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_zeros == len) + { + delete [] data; + len = 0; + data = 0; + num_zeros = 0; + num_ones = 0; + one_zero = 0; + } + else if (num_ones != len || user_pref.prefer_zero_one_indexing) + convert_one_zero_to_idx (); + } + else if (min_val < 0) + { + error ("%s index %d out of range", rc, min_val+1); + jump_to_top_level (); + } +} + +void +idx_vector::convert_one_zero_to_idx (void) +{ + if (num_ones == 0) + { + len = 0; + max_val = 0; + min_val = 0; + delete [] data; + } + 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]; + + i = 0; + do + { + if (data[i] > max_val) + max_val = data[i]; + + if (data[i] < min_val) + min_val = data[i]; + } + while (++i < len); + } +} + +ostream& +operator << (ostream& os, const idx_vector& a) +{ + for (int i = 0; i < a.len; i++) + os << a.data[i] << "\n"; + return os; +} + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; page-delimiter: "^/\\*" *** +;;; End: *** +*/