  <sect1>
	<title>EST_TMatrix </title>

    <para>
 
 The EST_TMatrix class is a generl purpose 2 dimensional array
 container class. It handles memory allocation and (if required) bounds
 checking and is reasonably efficiant, so there should be little need
 to use bare &cpp; arays.
    </para>
      <formalpara>
        <title>See also</title><para>
        <itemizedlist>
        <listitem><para>EST_TMatrix</para></listitem>
        <listitem><para>EST_TVector</para></listitem>
        </itemizedlist>
      </para></formalpara>
    <programlisting arch='c'>#include "EST_TMatrix.h"
#include "EST_String.h"    </programlisting>
    <sect2>
      <title>Basic Matrix Use</title>
      <para>
 Instances of the TMatrix class are intended to behave as
 you would expect two dimensional arrays to work.
      </para>
      <simplesect>
        <title>Declaration</title>
      <para>
 
 Matrixes are declared by giving the type and the number of 
 rows and columns. Here we create a 10 row by 5 column matrix.
      </para>
      </simplesect>
      <programlisting arch='c'>  EST_TMatrix&lt;float&gt; m(10, 5);      </programlisting>
      <simplesect>
        <title>Access</title>
      <para>
 Access to values in the matrix is via the a() member function.
 This returns a reference, so you can assign values to matrix cells.
 As is usually the case in &cpp;, column and row indecies start from 0.
      </para>
      </simplesect>
      <programlisting arch='c'>  for(int i=0; i&lt;m.num_rows(); i++)
    for(int j=0; j&lt;m.num_columns(); j++)
      m.a(i,j) = i+j/100.0;	// <lineannotation>Just something easy to recognise</lineannotation>      </programlisting>
      <simplesect>
        <title>Output</title>
      <para>
 A simple output method is supplied, it just outputs a row at a time,
 tab separated to a named file. A filename of "-" means standard output.
      </para>
      </simplesect>
      <programlisting arch='c'>  cout &lt;&lt; "Initial Matrix\n";
  m.save("-");
  cout &lt;&lt; "\n";      </programlisting>
      <simplesect>
        <title>Resizing</title>
      <para>
 Resize to 20 rows by 10 columns This fills the new
 area with <parameter>def_val</parameter>, which is 0.0 for floats.
      </para>
      </simplesect>
      <programlisting arch='c'>  m.resize(20,10);      </programlisting>
    </sect2>
    <sect2>
      <title>Copying Data to/from a buffer</title>
      <para>
 
 Whole rows or columns can be extracted into a buffer, or can be
 filled with data from a buffer. The buffer must be pre-declared,
 and it is up to you to ensure it is big enough.
      </para>
      <para>

 Data can be extracted into a buffer in one operation
      </para>
      <programlisting arch='c'>  float *buf = new float[max(m.num_rows(),m.num_columns())];

  m.copy_row(5, buf);      </programlisting>
      <para>

 And data can be inserted in a similar manner.
      </para>
      <programlisting arch='c'>  m.set_column(5,buf);      </programlisting>
    </sect2>
    <sect2>
      <title>Sub-Matrices and Sub-Vectors</title>
      <para>
 A sub-vector or sub-matrix is a window onto a matrix. If you obtain a
 sub vector representing a row, for instance, you can treat it
 a normal vector, any changes you make affecting the underlying
 matrix.
      </para>
      <para>
Here is how we can create new variables which refer to the 11th
 row, 4th column and a 5X3 rectnagle with top left hand corner (8,2).
 (since the first column or row is numbered 0, the numbers may be one
 less than you expect).
      </para>
      <programlisting arch='c'>  EST_TVector&lt;float&gt; row;
  EST_TVector&lt;float&gt; column;
  EST_TMatrix&lt;float&gt; rectangle;
  
  m.row(row, 10);
  m.column(column, 3);
  m.sub_matrix(rectangle, 
	       8, 5, 
	       2, 3);      </programlisting>
      <para>
If we update the sub-vector, the main matrix changes.
      </para>
      <programlisting arch='c'>  // <lineannotation>10th row becomes squares of the index</lineannotation>
  for(int i2=0; i2&lt;row.n(); i2++)
    row[i2] = i2*i2;

  // <lineannotation>3rd column becomes cubes of the index</lineannotation>
  for(int i3=0; i3&lt;column.n(); i3++)
    column[i3] = i3*i3*i3;

  // <lineannotation>Central rectangle filled with -1</lineannotation>
  for(int i4=0; i4&lt;rectangle.num_rows(); i4++)
    for(int j4=0; j4&lt;rectangle.num_columns(); j4++)
      rectangle.a(i4, j4) = -1;      </programlisting>
      <para>
We can even extract rows and columns from a sub-matrix as follows.
      </para>
      <programlisting arch='c'>  EST_TVector&lt;float&gt; rrow;
  EST_TVector&lt;float&gt; rcolumn;

  // <lineannotation>3rd row of sub-matrix, part of 12th row of main matrix</lineannotation>
  rectangle.row(rrow, 2);
  // <lineannotation>2nd column of sub-matrix, part of 8th column of main matrix</lineannotation>
  rectangle.column(rcolumn, 1);      </programlisting>
    </sect2>
    <sect2>
      <title>Template Instantiation.</title>
      <para>
 
 Some &cpp; compilers requre explicit guidance about which types
 of Matrix will be used. For many common types, including float,
 this guidance is included in the &est; libraries. However, if you
 need to use matrecies of your own types, you will need to include
 declarations similar to the following.
      </para>
      <programlisting arch='c'>Declare_TMatrix(MyType)

#if defined(INSTANTIATE_TEMPLATES)

#include "../base_class/EST_TMatrix.cc"

Instantiate_TMatrix(MyType)

#endif      </programlisting>
      <para>
By using this form of declaration, you should ensure that your
 code will compile anywhere where the speech tools libraries will.
      </para>
    </sect2>
  </sect1>
