"Fossies" - the Fresh Open Source Software Archive 
1 /*************************************************************************/
2 /* */
3 /* Centre for Speech Technology Research */
4 /* University of Edinburgh, UK */
5 /* Copyright (c) 1996 */
6 /* All Rights Reserved. */
7 /* */
8 /* Permission is hereby granted, free of charge, to use and distribute */
9 /* this software and its documentation without restriction, including */
10 /* without limitation the rights to use, copy, modify, merge, publish, */
11 /* distribute, sublicense, and/or sell copies of this work, and to */
12 /* permit persons to whom this work is furnished to do so, subject to */
13 /* the following conditions: */
14 /* 1. The code must retain the above copyright notice, this list of */
15 /* conditions and the following disclaimer. */
16 /* 2. Any modifications must be clearly marked as such. */
17 /* 3. Original authors' names are not deleted. */
18 /* 4. The authors' names are not used to endorse or promote products */
19 /* derived from this software without specific prior written */
20 /* permission. */
21 /* */
22 /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
23 /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
24 /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
25 /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
26 /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
27 /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
28 /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
29 /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
30 /* THIS SOFTWARE. */
31 /* */
32 /*************************************************************************/
33 /* Author : Paul Taylor */
34 /* Date : April 1996 */
35 /*-----------------------------------------------------------------------*/
36 /* Vector class */
37 /* */
38 /*=======================================================================*/
39
40 #ifndef __EST_TVector_H__
41 #define __EST_TVector_H__
42
43 #include <iostream>
44 using namespace std;
45 #include "EST_bool.h"
46 #include "EST_rw_status.h"
47
48 #include "instantiate/EST_TVectorI.h"
49
50 template<class T> class EST_TMatrix;
51 template<class T> class EST_TList;
52 class EST_String;
53
54 /* A constants to make it clearer what is going on when we pass `-1'
55 * meaning `current size' or `all the rest'
56 */
57
58 extern const int EST_CURRENT;
59 extern const int EST_ALL;
60
61 /* When set bounds checks (safe but slow) are done on vector access */
62 #ifndef TVECTOR_BOUNDS_CHECKING
63 # define TVECTOR_BOUNDS_CHECKING 0
64 #endif
65
66 #if TVECTOR_BOUNDS_CHECKING
67 #define A_CHECK a_check
68 #else
69 #define A_CHECK a_no_check
70 #endif
71
72 #define INLINE inline
73
74 /* This doesn't work as I thought so I have disabled it for now.
75 */
76
77 #if defined(__GNUC__) && 0
78 # define fast_a_v_gcc(C) \
79 ( *((T *)\
80 (((char (*) [sizeof(T)*p_column_step])p_memory) + (C))\
81 ))
82 # define fast_a_v_x(C) (fast_a_v_gcc(C))
83 #else
84 # define fast_a_v_x(C) (fast_a_v(C))
85 #endif
86
87
88 /**@name Template vector
89
90 This serves as a base class for a vector
91 of type <type>T</type>. This acts as a higher level
92 version of a normal C array as defined as <type>float *x</type> etc.
93
94 The vector can be resized after declaration, access can be
95 with or without bounds checking. Round brackets denote read-only
96 access (for consts) while square brackets are for read-write access.
97 In both cases references are returned.
98
99 The standard operators () and [] should be thought of as
100 having no bounds checking, though they may do so optionally
101 as a compile time option. The methods <method>a_check</method> and
102 <method>a_nocheck</method> provide explicit boundary checking/nonchecking,
103 both const and non-const versions are provided.
104
105 Access through () and [] are guaranteed to be as fast as standard
106 C arrays (assuming a reasonable optimizing compiler).
107
108 <programlisting>
109 EST_FVector x(10);
110 int i;
111
112 for (i=0; i < x.length(); ++i)
113 x[i] = sqrt((float)i);
114
115 x.resize(20);
116
117 for (i=10; i < x.length(); ++i)
118 x[i] = sqrt((float)i);
119
120 </programlisting>
121
122 To instantiate a template for a a vector of type {FooBar}
123
124 <programlisting>
125 #include "../base_class/EST_TVector.cc"
126 // If you want List to vector conversion (and defined a TList)
127 #include "../base_class/EST_Tvectlist.cc"
128
129 template class EST_TVector<FooBar>;
130 template ostream& operator <<
131 (ostream &st, const EST_TVector<FooBar> &v);
132 </programlisting>
133
134 The EST library already has template vector instantiations for
135 <type>int</type>, <type>float</type>, <type>double</type> and
136 <docppRef linkend='EST_String'>. Also types are defined for them
137 in <docppRef linkend='EST_types.h'> as <docppRef
138 linkend='EST_IVector'>, <docppRef linkend='EST_FVector'>,
139 <docppRef linkend='EST_DVector'> and <docppRef
140 linkend='EST_StrVector'> for <type>int</type>s,
141 <type>float</type>s, <type>doubles</type>s and <docppRef
142 linkend='EST_String'>s respectively.
143
144 * @see matrix_example */
145 //@{
146 template <class T>
147 class EST_TVector
148 {
149 // protected:
150 public:
151 /** Pointer to the start of the vector.
152 * The start of allocated memory is p_memory-p_offset.
153 */
154 T *p_memory;
155
156 /// Visible shape
157 unsigned int p_num_columns;
158
159 /// How to access the memory
160 unsigned int p_offset;
161 unsigned int p_column_step;
162
163 bool p_sub_matrix;
164
165
166 /// The memory access rule, in one place for easy reference
167 INLINE unsigned int vcell_pos(unsigned int c,
168 unsigned int cs) const
169 {return cs==1?c:c*cs;}
170
171 INLINE unsigned int vcell_pos(unsigned int c) const
172 {
173 return vcell_pos(c,
174 p_column_step);
175 }
176
177 INLINE unsigned int vcell_pos_1(unsigned int c) const
178 {
179 return c;
180 }
181
182 /// quick method for returning \(x[n]\)
183 INLINE const T &fast_a_v(int c) const { return p_memory[vcell_pos(c)]; }
184
185 INLINE T &fast_a_v(int c) { return p_memory[vcell_pos(c)]; }
186
187 INLINE const T &fast_a_1(int c) const { return p_memory[vcell_pos_1(c)]; }
188 INLINE T &fast_a_1(int c) { return p_memory[vcell_pos_1(c)]; }
189
190 /// Get and set values from array
191 void set_values(const T *data, int step, int start_c, int num_c);
192 void get_values(T *data, int step, int start_c, int num_c) const;
193
194 /// private copy function, called from all other copying functions.
195 void copy(const EST_TVector<T> &a);
196 /// just copy data, no resizing, no size check.
197 void copy_data(const EST_TVector<T> &a);
198
199 /// resize the memory and reset the bounds, but don't set values.
200 void just_resize(int new_cols, T** old_vals);
201
202 /// sets data and length to default values (0 in both cases).
203 void default_vals();
204
205 public:
206 ///default constructor
207 EST_TVector();
208
209 /// copy constructor
210 EST_TVector(const EST_TVector<T> &v);
211
212 /// "size" constructor - make vector of size n.
213 EST_TVector(int n);
214
215 /// construct from memory supplied by caller
216 EST_TVector(int,
217 T *memory, int offset=0, int free_when_destroyed=0);
218
219 /// destructor.
220 ~EST_TVector();
221
222 /// default value, used for filling matrix after resizing
223 static const T *def_val;
224
225 /** A reference to this variable is returned if you try and access
226 * beyond the bounds of the matrix. The value is undefined, but you
227 * can check for the reference you get having the same address as
228 * this variable to test for an error.
229 */
230 static T *error_return;
231
232 /** resize vector. If <expr>set=1</expr>, then the current values in
233 the vector are preserved up to the new length <parameter>n</parameter>. If the
234 new length exceeds the old length, the rest of the vector is
235 filled with the <variable>def_val</variable>
236 */
237 void resize(int n, int set=1);
238
239 /** For when you absolutely have to have access to the memory.
240 */
241 const T * memory() const { return p_memory; }
242 T * memory(){ return p_memory; }
243
244 /**@name access
245 * Basic access methods for vectors.
246 */
247 //@{
248
249 /// number of items in vector.
250 INLINE int num_columns() const {return p_num_columns;}
251 /// number of items in vector.
252 INLINE int length() const {return num_columns();}
253 /// number of items in vector.
254 INLINE int n() const {return num_columns();}
255
256 /// read-only const access operator: without bounds checking
257 INLINE const T &a_no_check(int n) const { return fast_a_v_x(n); }
258 /// read/write non-const access operator: without bounds checking
259 INLINE T &a_no_check(int n) { return fast_a_v_x(n); }
260 /// read-only const access operator: without bounds checking
261 INLINE const T &a_no_check_1(int n) const { return fast_a_1(n); }
262 /// read/write non-const access operator: without bounds checking
263 INLINE T &a_no_check_1(int n) { return fast_a_1(n); }
264
265 // #define pp_a_no_check(V,N) (pp_fast_a(V,N))
266
267 /// read-only const access operator: with bounds checking
268 const T &a_check(int n) const;
269 /// read/write non-const access operator: with bounds checking
270 T &a_check(int n);
271
272 const T &a(int n) const { return A_CHECK(n); }
273 T &a(int n) { return A_CHECK(n); }
274
275 /// read-only const access operator: return reference to nth member
276 const T &operator () (int n) const {return A_CHECK(n);}
277
278 // PT
279 // /// non const access operator: return reference to nth member
280 // T &operator () (int n) const {return a(n);}
281
282 /// read/write non const access operator: return reference to nth member
283 T &operator [] (int n) { return A_CHECK(n); }
284
285 //@}
286
287 void set_memory(T *buffer, int offset, int columns,
288 int free_when_destroyed=0);
289
290 /// assignment operator
291 EST_TVector &operator=(const EST_TVector &s);
292
293 /// Fill entire array will value <parameter>v</parameter>.
294 void fill(const T &v);
295
296 /// Fill vector with default value
297 void empty() { fill(*def_val); }
298
299 /// is true if vectors are equal size and all elements are equal.
300 int operator == (const EST_TVector &v) const;
301 /// is true if vectors are not equal size or a single elements isn't equal.
302 int operator != (const EST_TVector &v) const
303 { return ! ((*this) == v); }
304
305 /// Copy data in and out. Subclassed by SimpleVector for speed.
306
307 void copy_section(T* dest, int offset=0, int num=-1) const;
308 void set_section(const T* src, int offset=0, int num=-1);
309
310 /// Create a sub vector.
311 void sub_vector(EST_TVector<T> &sv, int start_c=0, int len=-1);
312 /// print out vector.
313 friend ostream& operator << (ostream &st, const EST_TVector<T> &m)
314 {
315 int i;
316 for (i = 0; i < m.n(); ++i)
317 st << m(i) << " ";
318 st << endl;
319 return st;
320 }
321
322 /// Matrix must be friend to set up subvectors
323 friend class EST_TMatrix<T>;
324
325 void integrity() const;
326
327 };
328
329 //@}
330 /// assignment operator: fill track with values in list <parameter>s</parameter>.
331
332 // This appears unuset and potentially causes a namespace clashes with std::set
333 // is sparrowhawk is used.
334 // template<class T>
335 // extern EST_TVector<T> &set(EST_TVector<T> &v, const EST_TList<T> &s);
336
337 #undef A_CHECK
338 #endif