Edinburgh Speech Tools  2.1-release
EST_TMatrix.cc
Go to the documentation of this file.
1  /*************************************************************************/
2  /* */
3  /* Centre for Speech Technology Research */
4  /* University of Edinburgh, UK */
5  /* Copyright (c) 1995,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  /* Template EST_TMatrix Class */
38  /* */
39  /*************************************************************************/
40 
41 #include "EST_TMatrix.h"
42 #include <fstream>
43 #include <iostream>
44 #include "EST_bool.h"
45 #include "EST_matrix_support.h"
46 #include "EST_TVector.h"
47 #include "EST_cutils.h"
48 #include "EST_error.h"
49 
50 /* Construction and destruction
51  */
52 
53 template<class T>
55 {
57  p_num_rows = 0;
58  p_row_step=0;
59 }
60 
61 template<class T>
63 {
64  default_vals();
65 }
66 
67 template<class T>
69 {
70  default_vals();
71  copy(in);
72 }
73 
74 template<class T>
76 {
77  default_vals();
78  resize(rows, cols);
79 }
80 
81 template<class T>
83  T *memory, ptrdiff_t offset, int free_when_destroyed)
84 {
85  default_vals();
86  set_memory(memory, offset, rows, cols, free_when_destroyed);
87 }
88 
89 template<class T>
91 {
92  p_num_rows = 0;
93  p_row_step=0;
94 }
95 
96 /* Basic access
97  */
98 
99 template<class T>
101 {
102 
103  if (!EST_matrix_bounds_check(row, col, num_rows(), num_columns(), FALSE))
104  return *this->error_return;
105 
106  return a_no_check(row,col);
107 }
108 
109 /* Since we know a() itself doesn't change the matrix, we can cast away
110  * the const here. Isn't the C++ syntax beautiful!
111  */
112 template<class T>
114 {
115  return ((EST_TMatrix<T> *)this)->a(row,col);
116 }
117 
118 template<class T>
120 {
121 
124  0, a.num_rows(),
125  0, a.num_columns());
126 }
127 
128 template<class T>
129 void EST_TMatrix<T>::set_values(const T *data,
130  ssize_t r_step, ssize_t c_step,
131  ssize_t start_r, ssize_t num_r,
132  ssize_t start_c, ssize_t num_c
133  )
134 {
135  for(ssize_t r=start_r, i=0, rp=0; i< num_r; i++, r++, rp+=r_step)
136  for(ssize_t c=start_c, j=0, cp=0; j< num_c; j++, c++, cp+=c_step)
137  a_no_check(r,c) = data[rp+cp];
138 }
139 
140 template<class T>
142  ssize_t r_step, ssize_t c_step,
143  ssize_t start_r, ssize_t num_r,
144  ssize_t start_c, ssize_t num_c
145  ) const
146 {
147  for(ssize_t r=start_r, i=0, rp=0; i< num_r; i++, r++, rp+=r_step)
148  for(ssize_t c=start_c, j=0, cp=0; j< num_c; j++, c++, cp+=c_step)
149  data[rp+cp] = a_no_check(r,c);
150 }
151 
152 template<class T>
154 {
155  resize(a.num_rows(), a.num_columns(), 0);
156  copy_data(a);
157 }
158 
159 template<class T>
161 {
162  copy(in);
163  return *this;
164 }
165 
166 template<class T>
168 {
169  if (in.num_columns() != num_columns())
170  EST_error("Can't add rows with different number of columns (%d vs %d)",
171  in.num_columns(),
172  num_columns()
173  );
174  else
175  {
176  int old_num_rows = num_rows();
178 
179  for(int i=old_num_rows, i1=0; i<num_rows(); i++, i1++)
180  for(int j=0; j<num_columns(); j++)
181  a(i,j) = in.a(i1,j);
182 
183  }
184  return *this;
185 }
186 
187 template<class T>
189 {
190  if (in.num_rows() != num_rows())
191  EST_error("Can't add columns with differnet number of rows (%d vs %d)",
192  in.num_rows(),
193  num_rows()
194  );
195  else
196  {
197  int old_num_columns = num_columns();
199 
200  for(int i=old_num_columns, i1=0; i<num_columns(); i++, i1++)
201  for(int j=0; j<num_rows(); j++)
202  a(i,j) = in.a(i1,j);
203 
204  }
205  return *this;
206 }
207 
208 template<class T>
210  ssize_t new_cols,
211  T** old_vals)
212 {
213  T *new_m;
214 
215  if (num_rows() != new_rows || num_columns() != new_cols || this->p_memory == NULL )
216  {
217  if (this->p_sub_matrix)
218  EST_error("Attempt to resize Sub-Matrix");
219 
220  if (new_cols < 0 || new_rows < 0)
221  EST_error("Attempt to resize matrix to negative size: %d x %d",
222  new_rows,
223  new_cols);
224 
225 
226  new_m = new T[new_rows*new_cols];
227 
228  if (this->p_memory != NULL)
229  {
230  if (old_vals != NULL)
231  *old_vals = this->p_memory;
232  else if (!this->p_sub_matrix)
233  delete [] (this->p_memory-this->p_offset);
234  }
235 
236  p_num_rows = new_rows;
237  this->p_num_columns = new_cols;
238  this->p_offset=0;
239  p_row_step=this->p_num_columns;
240  this->p_column_step=1;
241 
242  this->p_memory = new_m;
243  }
244  else
245  *old_vals = this->p_memory;
246 
247 }
248 
249 template<class T>
250 void EST_TMatrix<T>::resize(ssize_t new_rows, ssize_t new_cols, ssize_t set)
251 {
252  ssize_t i,j;
253  T * old_vals = this->p_memory;
254  ssize_t old_rows = num_rows();
255  ssize_t old_cols = num_columns();
256  ssize_t old_row_step = p_row_step;
257  ptrdiff_t old_offset = this->p_offset;
258  ssize_t old_column_step = this->p_column_step;
259 
260  if (new_rows<0)
261  new_rows = old_rows;
262  if (new_cols<0)
263  new_cols = old_cols;
264 
265  just_resize(new_rows, new_cols, &old_vals);
266 
267  if (set)
268  {
269  ssize_t copy_r = 0;
270  ssize_t copy_c = 0;
271 
272  if (old_vals != NULL)
273  {
274  copy_r = Lof(num_rows(), old_rows);
275  copy_c = Lof(num_columns(), old_cols);
276 
277  set_values(old_vals,
278  old_row_step, old_column_step,
279  0, copy_r,
280  0, copy_c);
281  }
282  else
283  {
284  copy_r = old_rows;
285  copy_c = old_cols;
286  }
287 
288  for(i=0; i<copy_r; i++)
289  for(j=copy_c; j<new_cols; j++)
290  a_no_check(i,j) = *this->def_val;
291 
292  for(i=copy_r; i<new_rows; i++)
293  for(j=0; j<new_cols; j++)
294  a_no_check(i,j) = *this->def_val;
295  }
296 
297  if (old_vals && old_vals != this->p_memory && !this->p_sub_matrix)
298  delete [] (old_vals-old_offset);
299 }
300 
301 template<class T>
303 {
304  return this->p_offset >= n*p_row_step;
305 }
306 
307 template<class T>
309 {
310  return this->p_offset >= n*this->p_column_step;
311 }
312 
313 template<class T>
314 void EST_TMatrix<T>::fill(const T &v)
315 {
316  ssize_t i, j;
317  for (i = 0; i < num_rows(); ++i)
318  for (j = 0; j < num_columns(); ++j)
319  fast_a_m(i,j) = v;
320 }
321 
322 
323 template<class T>
325 {
326  ssize_t i, j;
327  ostream *outf;
328  if (filename == "-" || filename == "")
329  outf = &std::cout;
330  else
331  outf = new std::ofstream(filename);
332 
333  for (i = 0; i < num_rows(); ++i)
334  {
335  for (j = 0; j < num_columns(); ++j)
336  {
337  *outf
338 #if 0
339  << "{" <<i<<","<<j
340  <<",m="<<((int)this->p_memory)<<","
341  <<"r'="<<((int)((T *) mx_move_pointer_f(this->p_memory, sizeof(T)*p_row_step, i)))<<","
342  <<"r="<<((int)mx_move_pointer(this->p_memory, T, p_row_step, i))<<","
343  <<"c="<<((int)mx_move_pointer(this->p_memory, T, this->p_column_step, j))<<","
344  <<((int)(&fast_a_m_gcc(i,j)))
345  <<"}"
346 #endif
347  << a_no_check(i,j) << "\t";
348  }
349  *outf << std::endl;
350  }
351 
352  if (outf != &std::cout)
353  delete outf;
354 
355  return write_ok;
356 }
357 
358 template<class T>
361 {
362  // this function can only be written if we can find a way of parsing
363  // an unknown type;
364  (void) filename;
365  EST_error("Matrix loading not implemented yet.");
366  return misc_read_error;
367 
368 }
369 
370 template<class T>
371 void EST_TMatrix<T>::set_memory(T *buffer, ptrdiff_t offset,
372  ssize_t rows, ssize_t columns,
373  int free_when_destroyed)
374 {
375  EST_TVector<T>::set_memory(buffer, offset, columns, free_when_destroyed);
376  p_num_rows = rows;
377  p_row_step = columns;
378 }
379 
380 template<class T>
382  ptrdiff_t offset, int num) const
383 {
384  ssize_t to = num >= 0 ? offset + num : num_columns();
385 
387  {
388  if (num_rows()>0)
389  r=0;
390  else
391  return;
392  }
393 
394  for (ssize_t j = offset; j < to; j++)
395  buf[j-offset] = fast_a_m(r, j);
396 }
397 
398 template<class T>
400  ptrdiff_t offset, int num) const
401 {
402  ssize_t to = num >= 0 ? offset + num : num_columns();
403 
405  {
406  if (num_rows()>0)
407  r=0;
408  else
409  return;
410  }
411 
412  buf.resize(to - offset);
413 
414  for (ssize_t j = offset; j < to; j++)
415  buf[j - offset] = fast_a_m(r, j);
416 }
417 
418 
419 template<class T>
421  ptrdiff_t offset, int num) const
422 {
423  if (num_rows() == 0)
424  return;
425 
426  ssize_t to = num >= 0 ? offset + num : num_rows();
427 
429  {
430  if (num_columns()>0)
431  c=0;
432  else
433  return;
434  }
435 
436  for (ssize_t i = offset; i < to; i++)
437  buf[i-offset] = fast_a_m(i, c);
438 }
439 
440 
441 template<class T>
443  ptrdiff_t offset, int num) const
444 {
445  if (num_rows() == 0)
446  return;
447 
448  ssize_t to = num >= 0 ? offset + num : num_rows();
449 
451  {
452  if( num_columns()>0 )
453  c=0;
454  else
455  return;
456  }
457 
458  buf.resize(to - offset);
459 
460  for (ssize_t i = offset; i < to; i++)
461  buf[i-offset] = fast_a_m(i, c);
462 }
463 
464 
465 template<class T>
466 void EST_TMatrix<T>::set_row(ssize_t r, const T *buf, ptrdiff_t offset, int num)
467 {
468  ssize_t to = num>=0?offset+num:num_columns();
469 
471  return;
472 
473  for(ssize_t j=offset; j<to; j++)
474  fast_a_m(r, j) = buf[j-offset];
475 }
476 
477 template<class T>
478 void EST_TMatrix<T>::set_column(ssize_t c, const T *buf, ptrdiff_t offset, int num)
479 {
480  ssize_t to = num>=0?offset+num:num_rows();
481 
483  return;
484 
485  for(ssize_t i=offset; i<to; i++)
486  fast_a_m(i, c) = buf[i-offset];
487 }
488 
489 template<class T>
491  const EST_TMatrix<T> &from, ssize_t from_r, ssize_t from_offset,
492  ptrdiff_t offset, int num)
493 {
494  int to = num>=0?offset+num:num_columns();
495 
497  return;
498 
499  if (!EST_matrix_bounds_check(from_r, 0, from.num_rows(), from.num_columns(), FALSE))
500  {
501  if (from.num_rows()>0)
502  from_r=0;
503  else
504  return;
505  }
506 
507  for(int j=offset; j<to; j++)
508  fast_a_m(r, j) = from.fast_a_m(from_r, (j-offset)+from_offset);
509 }
510 
511 template<class T>
513  const EST_TMatrix<T> &from, ssize_t from_c, ssize_t from_offset,
514  ptrdiff_t offset, int num)
515 {
516  int to = num>=0?offset+num:num_rows();
517 
519  return;
520 
521  if (!EST_matrix_bounds_check(0, from_c, from.num_rows(), from.num_columns(), FALSE))
522  {
523  if (from.num_columns()>0)
524  from_c=0;
525  else
526  return;
527  }
528 
529  for(int i=offset; i<to; i++)
530  fast_a_m(i, c) = from.fast_a_m((i-offset)+from_offset, from_c);
531 }
532 
533 template<class T>
534 void EST_TMatrix<T>::row(EST_TVector<T> &rv, ssize_t r, ssize_t start_c, int len)
535 {
536  if (len < 0)
537  len = num_columns()-start_c;
538 
539  if (!EST_matrix_bounds_check(r, 1, start_c, len, num_rows(), num_columns(), 0))
540  return;
541 
542  if (rv.p_memory != NULL && ! rv.p_sub_matrix)
543  delete [] (rv.p_memory - rv.p_offset);
544 
545  rv.p_sub_matrix = TRUE;
546  rv.p_num_columns = len;
547  rv.p_offset = this->p_offset + start_c*this->p_column_step + r*p_row_step;
548  rv.p_memory = this->p_memory - this->p_offset + rv.p_offset;
549 // std::cout << "mrow: mem: " << rv.p_memory << " (" << (int)rv.p_memory << ")\n";
550 // std::cout << "mrow: ofset: " << rv.p_offset << " (" << (int)rv.p_offset << ")\n";
551 
552  rv.p_column_step=this->p_column_step;
553 }
554 
555 template<class T>
556 void EST_TMatrix<T>::column(EST_TVector<T> &cv, ssize_t c, ssize_t start_r, int len)
557 {
558  if (len < 0)
559  len = num_rows()-start_r;
560 
561  if (!EST_matrix_bounds_check(start_r, len, c, 1,num_rows(), num_columns(), 0))
562  return;
563 
564  if (cv.p_memory != NULL && ! cv.p_sub_matrix)
565  delete [] (cv.p_memory - cv.p_offset);
566 
567  cv.p_sub_matrix = TRUE;
568  cv.p_num_columns = len;
569  cv.p_offset = this->p_offset + c*this->p_column_step + start_r*p_row_step;
570  cv.p_memory = this->p_memory - this->p_offset + cv.p_offset;
571 // std::cout << "mcol: mem: " << cv.p_memory << " (" << (int)cv.p_memory << ")\n";
572 // std::cout << "mcol: offset: " << cv.p_offset << " (" << (int)cv.p_offset << ")\n";
573 
575 }
576 
577 template<class T>
579  ssize_t r, ptrdiff_t len_r, ssize_t c, ptrdiff_t len_c)
580 {
581  if (len_r < 0)
582  len_r = num_rows()-r;
583  if (len_c < 0)
584  len_c = num_columns()-c;
585 
586  if (!EST_matrix_bounds_check(r, len_r, c, len_c, num_rows(), num_columns(), 0))
587  return;
588 
589  if (sm.p_memory != NULL && ! sm.p_sub_matrix)
590  delete [] (sm.p_memory - sm.p_offset);
591 
592  sm.p_sub_matrix = TRUE;
593  sm.p_offset = this->p_offset + c*this->p_column_step + r*p_row_step;
594  sm.p_memory = this->p_memory - this->p_offset + sm.p_offset;
596  sm.p_column_step=this->p_column_step;
597  sm.p_num_rows = len_r;
598  sm.p_num_columns = len_c;
599 
600 }
601 
void set_column(ssize_t n, const T *buf, ptrdiff_t offset=0, int num=-1)
Definition: EST_TMatrix.cc:478
ssize_t p_column_step
Definition: EST_TVector.h:159
bool have_rows_before(ssize_t n) const
Definition: EST_TMatrix.cc:302
bool have_columns_before(ssize_t n) const
Definition: EST_TMatrix.cc:308
ssize_t p_num_columns
Visible shape.
Definition: EST_TVector.h:155
Template Matrix class. This is an extension of the EST_TVector class to two dimensions.
Definition: EST_TMatrix.h:89
EST_write_status
EST_DMatrix * error_return
void copy_column(ssize_t c, T *buf, ptrdiff_t offset=0, int num=-1) const
Definition: EST_TMatrix.cc:420
EST_TMatrix & add_rows(const EST_TMatrix &s)
The two versions of what might have been operator +=.
Definition: EST_TMatrix.cc:167
ssize_t num_columns() const
return number of columns
Definition: EST_TMatrix.h:179
bool EST_matrix_bounds_check(int r, int c, int num_rows, int num_columns, bool set)
void set_row(ssize_t n, const T *buf, ptrdiff_t offset=0, int num=-1)
Definition: EST_TMatrix.cc:466
INLINE const T & fast_a_m(ssize_t r, ssize_t c) const
quick method for returning x[m][n]
Definition: EST_TMatrix.h:119
bool p_sub_matrix
Definition: EST_TVector.h:161
ssize_t p_num_rows
Visible shape.
Definition: EST_TMatrix.h:94
EST_TMatrix()
default constructor
Definition: EST_TMatrix.cc:62
void copy(const EST_TMatrix< T > &a)
private resize and copy function.
Definition: EST_TMatrix.cc:153
EST_TMatrix & add_columns(const EST_TMatrix &s)
Definition: EST_TMatrix.cc:188
ssize_t num_rows() const
return number of rows
Definition: EST_TMatrix.h:177
int ssize_t
const T & a(ssize_t row, ssize_t col) const
Definition: EST_TMatrix.h:196
void default_vals()
sets data and length to default values (0 in both cases).
Definition: EST_TVector.cc:50
#define Lof(a, b)
Definition: EST_cutils.h:97
const EST_DMatrix * def_val
void column(EST_TVector< T > &cv, ssize_t c, ssize_t start_r=0, int len=-1)
Make the vector cv a window onto column c
Definition: EST_TMatrix.cc:556
void just_resize(ssize_t new_rows, ssize_t new_cols, T **old_vals)
resize the memory and reset the bounds, but don&#39;t set values.
Definition: EST_TMatrix.cc:209
void copy_data(const EST_TMatrix< T > &a)
just copy data, no resizing, no size check.
Definition: EST_TMatrix.cc:119
void resize(ssize_t n, int set=1)
Definition: EST_TVector.cc:196
EST_write_status save(const class EST_String &filename) const
save Matrix to file filename
Definition: EST_TMatrix.cc:324
The file was written successfully.
void default_vals()
sets data and length to default values (0 in both cases).
Definition: EST_TMatrix.cc:54
#define FALSE
Definition: EST_bool.h:119
void sub_matrix(EST_TMatrix< T > &sm, ssize_t r=0, ptrdiff_t numr=EST_ALL, ssize_t c=0, ptrdiff_t numc=EST_ALL)
Make the matrix sm a window into this matrix.
Definition: EST_TMatrix.cc:578
EST_read_status load(const class EST_String &filename)
load Matrix from file - Not currently implemented.
Definition: EST_TMatrix.cc:360
#define misc_read_error
NULL
Definition: EST_WFST.cc:55
~EST_TMatrix()
EST_TMatrix.
Definition: EST_TMatrix.cc:90
#define EST_error
Definition: EST_error.h:104
getString int
Definition: EST_item_aux.cc:50
void row(EST_TVector< T > &rv, ssize_t r, ssize_t start_c=0, int len=-1)
Make the vector rv a window onto row r
Definition: EST_TMatrix.cc:534
void copy_row(ssize_t r, T *buf, ptrdiff_t offset=0, int num=-1) const
Definition: EST_TMatrix.cc:381
EST_TMatrix & operator=(const EST_TMatrix &s)
assignment operator
Definition: EST_TMatrix.cc:160
EST_read_status
const T * memory() const
Definition: EST_TVector.h:238
const T & a_check(ssize_t row, ssize_t col) const
const element access function
Definition: EST_TMatrix.cc:113
void set_memory(T *buffer, ptrdiff_t offset, ssize_t rows, ssize_t columns, int free_when_destroyed=0)
Definition: EST_TMatrix.cc:371
Template vector.
Definition: EST_TVector.h:145
void get_values(T *data, ssize_t r_step, ssize_t c_step, ssize_t start_r, ssize_t num_r, ssize_t start_c, ssize_t num_c) const
Definition: EST_TMatrix.cc:141
void resize(ssize_t rows, ssize_t cols, ssize_t set=1)
Definition: EST_TMatrix.cc:250
INLINE const T & a_no_check(ssize_t row, ssize_t col) const
const access with no bounds check, care recommend
Definition: EST_TMatrix.h:182
void set_values(const T *data, ssize_t r_step, ssize_t c_step, ssize_t start_r, ssize_t num_r, ssize_t start_c, ssize_t num_c)
Get and set values from array.
Definition: EST_TMatrix.cc:129
#define TRUE
Definition: EST_bool.h:118
INLINE ssize_t n() const
number of items in vector.
Definition: EST_TVector.h:251
void fill()
Definition: EST_TMatrix.h:218
void set_memory(T *buffer, int offset, ssize_t columns, int free_when_destroyed=0)
Definition: EST_TVector.cc:112
ssize_t p_offset
How to access the memory.
Definition: EST_TVector.h:158
ssize_t p_row_step
How to access the memory.
Definition: EST_TMatrix.h:97