comparison 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
comparison
equal deleted inserted replaced
0:22412e3a4641 1:78fd87e624cb
1 // Very simple integer vectors for indexing -*- C++ -*-
2 /*
3
4 Copyright (C) 1992, 1993 John W. Eaton
5
6 This file is part of Octave.
7
8 Octave is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
11 later version.
12
13 Octave is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, write to the Free
20 Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 */
23
24 #ifdef __GNUG__
25 #pragma implementation
26 #endif
27
28 #include "idx-vector.h"
29 #include "error.h"
30 #include "user-prefs.h"
31 #include "utils.h"
32
33 idx_vector::idx_vector (const idx_vector& a)
34 {
35 len = a.len;
36 if (len > 0)
37 {
38 data = new int [len];
39 for (int i = 0; i < len; i++)
40 data[i] = a.data[i];
41
42 num_zeros = a.num_zeros;
43 num_ones = a.num_ones;
44 one_zero = a.one_zero;
45
46 max_val = a.max_val;
47 min_val = a.min_val;
48 }
49 else
50 data = 0;
51 }
52
53 static inline int
54 tree_to_mat_idx (double x)
55 {
56 if (x > 0)
57 return ((int) (x + 0.5) - 1);
58 else
59 return ((int) (x - 0.5) - 1);
60 }
61
62 idx_vector::idx_vector (Matrix& m, int do_ftn_idx, char *rc, int z_len = 0)
63 {
64 int nr = m.rows ();
65 int nc = m.columns ();
66
67 if (nr == 0 || nc == 0)
68 {
69 len = 0;
70 data = 0;
71 num_zeros = 0;
72 num_ones = 0;
73 one_zero = 0;
74 return;
75 }
76 else if (nr > 1 && nc > 1 && do_ftn_idx)
77 {
78 double *cop_out = m.fortran_vec ();
79 len = nr * nc;
80 data = new int [len];
81 for (int i = 0; i < len; i++)
82 data[i] = tree_to_mat_idx (*cop_out++);
83 }
84 else if (nr == 1 && nc > 0)
85 {
86 len = nc;
87 data = new int [len];
88 for (int i = 0; i < len; i++)
89 data[i] = tree_to_mat_idx (m.elem (0, i));
90 }
91 else if (nc == 1 && nr > 0)
92 {
93 len = nr;
94 data = new int [len];
95 for (int i = 0; i < len; i++)
96 data[i] = tree_to_mat_idx (m.elem (i, 0));
97 }
98 else
99 {
100 message ((char *) NULL, "invalid matrix index");
101 jump_to_top_level ();
102 }
103
104 init_state (rc, z_len);
105 }
106
107 idx_vector::idx_vector (const Range& r)
108 {
109 len = r.nelem ();
110
111 assert (len != 0);
112
113 double b = r.base ();
114 double step = r.inc ();
115
116 data = new int [len];
117
118 for (int i = 0; i < len; i++)
119 {
120 double val = b + i * step;
121 data[i] = tree_to_mat_idx (val);
122 }
123
124 init_state ();
125 }
126
127 idx_vector&
128 idx_vector::operator = (const idx_vector& a)
129 {
130 if (this != &a)
131 {
132 delete [] data;
133 len = a.len;
134 data = new int [len];
135 for (int i = 0; i < len; i++)
136 data[i] = a.data[i];
137
138 num_zeros = a.num_zeros;
139 num_ones = a.num_ones;
140 one_zero = a.one_zero;
141
142 max_val = a.max_val;
143 min_val = a.min_val;
144 }
145 return *this;
146 }
147
148 void
149 idx_vector::init_state (char *rc, int z_len = 0)
150 {
151 one_zero = 1;
152 num_zeros = 0;
153 num_ones = 0;
154
155 min_val = max_val = data[0];
156
157 int i = 0;
158 do
159 {
160 if (data[i] == -1)
161 num_zeros++;
162 else if (data[i] == 0)
163 num_ones++;
164
165 if (one_zero && data[i] != -1 && data[i] != 0)
166 one_zero = 0;
167
168 if (data[i] > max_val)
169 max_val = data[i];
170
171 if (data[i] < min_val)
172 min_val = data[i];
173 }
174 while (++i < len);
175
176 if (one_zero && z_len == len)
177 {
178 if (num_zeros == len)
179 {
180 delete [] data;
181 len = 0;
182 data = 0;
183 num_zeros = 0;
184 num_ones = 0;
185 one_zero = 0;
186 }
187 else if (num_ones != len || user_pref.prefer_zero_one_indexing)
188 convert_one_zero_to_idx ();
189 }
190 else if (min_val < 0)
191 {
192 error ("%s index %d out of range", rc, min_val+1);
193 jump_to_top_level ();
194 }
195 }
196
197 void
198 idx_vector::convert_one_zero_to_idx (void)
199 {
200 if (num_ones == 0)
201 {
202 len = 0;
203 max_val = 0;
204 min_val = 0;
205 delete [] data;
206 }
207 else
208 {
209 assert (num_ones + num_zeros == len);
210
211 int *new_data = new int [num_ones];
212 int count = 0;
213 for (int i = 0; i < len; i++)
214 if (data[i] == 0)
215 new_data[count++] = i;
216
217 delete [] data;
218 len = num_ones;
219 data = new_data;
220
221 min_val = max_val = data[0];
222
223 i = 0;
224 do
225 {
226 if (data[i] > max_val)
227 max_val = data[i];
228
229 if (data[i] < min_val)
230 min_val = data[i];
231 }
232 while (++i < len);
233 }
234 }
235
236 ostream&
237 operator << (ostream& os, const idx_vector& a)
238 {
239 for (int i = 0; i < a.len; i++)
240 os << a.data[i] << "\n";
241 return os;
242 }
243
244 /*
245 ;;; Local Variables: ***
246 ;;; mode: C++ ***
247 ;;; page-delimiter: "^/\\*" ***
248 ;;; End: ***
249 */