Edinburgh Speech Tools  2.4-release
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends Pages
EST_TMatrix.h
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  /* */
34  /* Author : Paul Taylor */
35  /* Rewritten : Richard Caley */
36  /* --------------------------------------------------------------------- */
37  /* Matrix class */
38  /* */
39  /*************************************************************************/
40 
41 #ifndef __TMatrix_H__
42 #define __TMatrix_H__
43 
44 #include <iostream>
45 
46 using namespace std;
47 
48 #include "EST_rw_status.h"
49 #include "EST_TVector.h"
50 #include "instantiate/EST_TMatrixI.h"
51 
52 /* When set bounds checks (safe but slow) are done on matrix access */
53 #ifndef TMATRIX_BOUNDS_CHECKING
54 # define TMATRIX_BOUNDS_CHECKING 0
55 #endif
56 
57 #if TMATRIX_BOUNDS_CHECKING
58 #define A_CHECK a_check
59 #else
60 #define A_CHECK a_no_check
61 #endif
62 
63 #define INLINE inline
64 
65 /* This doesn't work as I thought so I have disabled it for now.
66  */
67 
68 #if defined(__GNUC__) && 0
69 # define mx_move_pointer(P, TY, STEP, N) \
70  ((TY *)\
71  ((void *) (((char (*) [sizeof(TY)*STEP])P) + N) ) \
72  )
73 # define fast_a_m_gcc(R,C) \
74  ( * mx_move_pointer(mx_move_pointer(p_memory,T,p_column_step,C),T,p_row_step,R))
75 # define fast_a_m_x(R,C) (fast_a_m_gcc(R,C))
76 #else
77 # define fast_a_m_x(R,C) (fast_a_m(R,C))
78 #endif
79 
80 
81 
82 /** Template Matrix class.
83  *
84  * This is an extension of the EST_TVector class to two dimensions.
85  *
86  * @see matrix_example
87  * @see EST_TVector
88  */
89 
90 template <class T>
91 class EST_TMatrix : public EST_TVector<T>
92 {
93 
94 protected:
95  /// Visible shape
96  unsigned int p_num_rows;
97 
98  /// How to access the memory
99  unsigned int p_row_step;
100 
101  INLINE unsigned int mcell_pos(int r, int c,
102  int rs, int cs) const
103  { return (rs==1?r:(r*rs)) + (cs==1?c:(c*cs));}
104 
105 
106  INLINE unsigned int mcell_pos(int r, int c) const
107  {
108 
109  return mcell_pos(r, c,
110  this->p_row_step, this->p_column_step);
111  }
112 
113  INLINE unsigned int mcell_pos_1(int r, int c) const
114  {
115 
116  (void)r;
117  return c;
118  }
119 
120  /// quick method for returning {\tt x[m][n]}
121  INLINE const T &fast_a_m(int r, int c) const
122  { return this->p_memory[mcell_pos(r,c)]; }
123  INLINE T &fast_a_m(int r, int c)
124  { return this->p_memory[mcell_pos(r,c)]; }
125 
126  INLINE const T &fast_a_1(int r, int c) const
127  { return this->p_memory[mcell_pos_1(r,c)]; }
128  INLINE T &fast_a_1(int r, int c)
129  { return this->p_memory[mcell_pos_1(r,c)]; }
130 
131 
132  /// Get and set values from array
133  void set_values(const T *data,
134  int r_step, int c_step,
135  int start_r, int num_r,
136  int start_c, int num_c
137  );
138  void get_values(T *data,
139  int r_step, int c_step,
140  int start_r, int num_r,
141  int start_c, int num_c
142  ) const;
143 
144  /// private resize and copy function.
145  void copy(const EST_TMatrix<T> &a);
146  /// just copy data, no resizing, no size check.
147  void copy_data(const EST_TMatrix<T> &a);
148 
149  /// resize the memory and reset the bounds, but don't set values.
150  void just_resize(int new_rows, int new_cols, T** old_vals);
151 
152  /// sets data and length to default values (0 in both cases).
153  void default_vals();
154 public:
155 
156  ///default constructor
157  EST_TMatrix();
158 
159  /// copy constructor
160  EST_TMatrix(const EST_TMatrix<T> &m);
161 
162  /// "size" constructor
163  EST_TMatrix(int rows, int cols);
164 
165  /// construct from memory supplied by caller
166  EST_TMatrix(int rows, int cols,
167  T *memory, int offset=0, int free_when_destroyed=0);
168 
169  /// EST_TMatrix
170 
171  ~EST_TMatrix();
172 
173  /**@name access
174  * Basic access methods for matrices.
175  */
176  //@{
177 
178  /// return number of rows
179  int num_rows() const {return this->p_num_rows;}
180  /// return number of columns
181  int num_columns() const {return this->p_num_columns;}
182 
183  /// const access with no bounds check, care recommend
184  INLINE const T &a_no_check(int row, int col) const
185  { return fast_a_m_x(row,col); }
186  /// access with no bounds check, care recommend
187  INLINE T &a_no_check(int row, int col)
188  { return fast_a_m_x(row,col); }
189 
190  INLINE const T &a_no_check_1(int row, int col) const { return fast_a_1(row,col); }
191  INLINE T &a_no_check_1(int row, int col) { return fast_a_1(row,col); }
192 
193  /// const element access function
194  const T &a_check(int row, int col) const;
195  /// non-const element access function
196  T &a_check(int row, int col);
197 
198  const T &a(int row, int col) const { return A_CHECK(row,col); }
199  T &a(int row, int col) { return A_CHECK(row,col); }
200 
201  /// const element access operator
202  const T &operator () (int row, int col) const { return a(row,col); }
203  /// non-const element access operator
204  T &operator () (int row, int col) { return a(row,col); }
205 
206  //@}
207 
208  bool have_rows_before(int n) const;
209  bool have_columns_before(int n) const;
210 
211  /** resize matrix. If {\tt set=1}, then the current values in
212  the matrix are preserved up to the new size {\tt n}. If the
213  new size exceeds the old size, the rest of the matrix is
214  filled with the {\tt def_val}
215  */
216  void resize(int rows, int cols, int set=1);
217 
218  /// fill matrix with value v
219  void fill(const T &v);
220  void fill() { fill(*this->def_val); }
221 
222  /// assignment operator
223  EST_TMatrix &operator=(const EST_TMatrix &s);
224 
225  /// The two versions of what might have been operator +=
226  EST_TMatrix &add_rows(const EST_TMatrix &s);
227  EST_TMatrix &add_columns(const EST_TMatrix &s);
228 
229  /**@name Sub-Matrix/Vector Extraction
230  *
231  * All of these return matrices and vectors which share
232  * memory with the original, so altering values them alters
233  * the original.
234  */
235  //@{
236 
237  /// Make the vector {\tt rv} a window onto row {\tt r}
238  void row(EST_TVector<T> &rv, int r, int start_c=0, int len=-1);
239  /// Make the vector {\tt cv} a window onto column {\tt c}
240  void column(EST_TVector<T> &cv, int c, int start_r=0, int len=-1);
241  /// Make the matrix {\tt sm} a window into this matrix.
242  void sub_matrix(EST_TMatrix<T> &sm,
243  int r=0, int numr=EST_ALL,
244  int c=0, int numc=EST_ALL);
245  //@}
246 
247  /**@name Copy in and out
248  * Copy data between buffers and the matrix.
249  */
250  //@{
251  /** Copy row {\tt r} of matrix to {\tt buf}. {\tt buf}
252  should be pre-malloced to the correct size.
253  */
254  void copy_row(int r, T *buf, int offset=0, int num=-1) const;
255 
256  /** Copy row <parameter>r</parameter> of matrix to
257  <parameter>buf</parameter>. <parameter>buf</parameter> should be
258  pre-malloced to the correct size. */
259 
260  void copy_row(int r, EST_TVector<T> &t, int offset=0, int num=-1) const;
261 
262  /** Copy column {\tt c} of matrix to {\tt buf}. {\tt buf}
263  should be pre-malloced to the correct size.
264  */
265  void copy_column(int c, T *buf, int offset=0, int num=-1) const;
266 
267  /** Copy column <parameter>c</parameter> of matrix to
268  <parameter>buf</parameter>. <parameter>buf</parameter> should
269  be pre-malloced to the correct size. */
270 
271  void copy_column(int c, EST_TVector<T> &t, int offset=0, int num=-1)const;
272 
273  /** Copy buf into row {\tt n} of matrix.
274  */
275  void set_row(int n, const T *buf, int offset=0, int num=-1);
276 
277  void set_row(int n, const EST_TVector<T> &t, int offset=0, int num=-1)
278  { set_row(n, t.memory(), offset, num); }
279 
280  void set_row(int r,
281  const EST_TMatrix<T> &from, int from_r, int from_offset=0,
282  int offset=0, int num=-1); // set nth row
283 
284 
285  /** Copy buf into column {\tt n} of matrix.
286  */
287  void set_column(int n, const T *buf, int offset=0, int num=-1);
288 
289  void set_column(int n, const EST_TVector<T> &t, int offset=0, int num=-1)
290  { set_column(n, t.memory(), offset, num); }
291 
292  void set_column(int c,
293  const EST_TMatrix<T> &from, int from_c, int from_offset=0,
294  int offset=0, int num=-1); // set nth column
295 
296  /** For when you absolutely have to have access to the memory.
297  */
298  void set_memory(T *buffer, int offset, int rows, int columns,
299  int free_when_destroyed=0);
300 
301  //@}
302 
303  /**@name io
304  * Matrix file io.
305  */
306  //@{
307  /// load Matrix from file - Not currently implemented.
308  EST_read_status load(const class EST_String &filename);
309  /// save Matrix to file {\tt filename}
310  EST_write_status save(const class EST_String &filename) const;
311 
312  /// print matrix.
313  friend ostream& operator << (ostream &st,const EST_TMatrix<T> &a)
314  {int i, j;
315  for (i = 0; i < a.num_rows(); ++i) {
316  for (j = 0; j < a.num_columns(); ++j)
317  st << a.a_no_check(i, j) << " "; st << endl;
318  }
319  return st;
320  }
321  //@}
322 
323 };
324 
325 #undef A_CHECK
326 
327 #endif
328