Logo Search packages:      
Sourcecode: speech-tools version File versions  Download package

EST_DMatrix.cc

/*************************************************************************/
/*                                                                       */
/*                Centre for Speech Technology Research                  */
/*                     University of Edinburgh, UK                       */
/*                      Copyright (c) 1995,1996                          */
/*                        All Rights Reserved.                           */
/*                                                                       */
/*  Permission is hereby granted, free of charge, to use and distribute  */
/*  this software and its documentation without restriction, including   */
/*  without limitation the rights to use, copy, modify, merge, publish,  */
/*  distribute, sublicense, and/or sell copies of this work, and to      */
/*  permit persons to whom this work is furnished to do so, subject to   */
/*  the following conditions:                                            */
/*   1. The code must retain the above copyright notice, this list of    */
/*      conditions and the following disclaimer.                         */
/*   2. Any modifications must be clearly marked as such.                */
/*   3. Original authors' names are not deleted.                         */
/*   4. The authors' names are not used to endorse or promote products   */
/*      derived from this software without specific prior written        */
/*      permission.                                                      */
/*                                                                       */
/*  THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK        */
/*  DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING      */
/*  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT   */
/*  SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE     */
/*  FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES    */
/*  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN   */
/*  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,          */
/*  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF       */
/*  THIS SOFTWARE.                                                       */
/*                                                                       */
 /*************************************************************************/
 /*                                                                       */
 /*                     Author :  Simon King                              */
 /*                     Date   :  February 1999                           */
 /* --------------------------------------------------------------------- */
 /*          Double matrix class - copied from DMatrix !                  */
 /*                                                                       */
 /*************************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <fstream.h>
#include <math.h>
#include <limits.h>
#include "EST_String.h"
#include "EST_types.h"
#include "EST_FileType.h"
#include "EST_Option.h"
#include "EST_DMatrix.h"
#include "EST_cutils.h"  // for swap functions 
#include "EST_Token.h"
#include "rateconv.h"

EST_String EST_DMatrix::default_file_type = "est_ascii";

00057 EST_DMatrix::EST_DMatrix(const EST_DMatrix &a, int b)
:EST_TSimpleMatrix<double>(a.num_rows(), a.num_columns())
{
    double vv = 0.0;
    if (b < 0)
      return;
    if (b == 0)
      fill(vv);
}

00067 EST_DMatrix & EST_DMatrix::operator+=(const EST_DMatrix &a)
{
    int i, j;
    if (a.num_columns() != num_columns())
    {
      cerr <<"Matrix addition error: bad number of columns\n";
      return *this;
    }
    if (a.num_rows() != num_rows())
    {
      cerr <<"Matrix addition error: bad number of rows\n";
      return *this;
    }
    for (i = 0; i < num_rows(); ++i)
      for (j = 0; j < num_columns(); ++j)
          a_no_check(i, j) += a.a_no_check(i,j);

    return *this;
}

00087 EST_DMatrix & EST_DMatrix::operator-=(const EST_DMatrix &a)
{
    int i, j;
    if (a.num_columns() != num_columns())
    {
      cerr <<"Matrix subtraction error: bad number of columns\n";
      return *this;
    }
    if (a.num_rows() != num_rows())
    {
      cerr <<"Matrix subtraction error: bad number of rows\n";
      return *this;
    }
    for (i = 0; i < num_rows(); ++i)
      for (j = 0; j < num_columns(); ++j)
          a_no_check(i, j) -= a.a_no_check(i,j);

    return *this;
}

00107 EST_DMatrix & EST_DMatrix::operator*=(const double f)
{

    int i,j;
    for (i = 0; i < num_rows(); ++i)
      for (j = 0; j < num_columns(); ++j)
          a_no_check(i, j) *= f;

    return *this;
}

00118 EST_DMatrix & EST_DMatrix::operator/=(const double f)
{

    int i,j;
    for (i = 0; i < num_rows(); ++i)
      for (j = 0; j < num_columns(); ++j)
          a_no_check(i, j) /= f;

    return *this;
}

EST_DMatrix operator+(const EST_DMatrix &a, const EST_DMatrix &b)
{
    EST_DMatrix ab;
    int i, j;
    if (a.num_columns() != b.num_columns())
    {
      cerr <<"Matrix addition error: bad number of columns\n";
      return ab;
    }
    if (a.num_rows() != b.num_rows())
    {
      cerr <<"Matrix addition error: bad number of rows\n";
      return ab;
    }
    ab.resize(a.num_rows(), a.num_columns());
    for (i = 0; i < a.num_rows(); ++i)
      for (j = 0; j < a.num_columns(); ++j)
          ab.a_no_check(i, j) = a.a_no_check(i, j) + b.a_no_check(i, j);

    return ab;
}

EST_DMatrix operator-(const EST_DMatrix &a,const EST_DMatrix &b)
{
    EST_DMatrix ab;
    int i, j;

    if (a.num_columns() != b.num_columns())
    {
      cerr <<"Matrix subtraction error: bad number of columns:" <<
          a.num_columns() << " and " << b.num_columns() << endl;
      return ab;
    }
    if (a.num_rows() != b.num_rows())
    {
      cerr <<"Matrix subtraction error: bad number of rows\n";
      return ab;
    }
    ab.resize(a.num_rows(), a.num_columns());
    for (i = 0; i < a.num_rows(); ++i)
      for (j = 0; j < a.num_columns(); ++j)
          ab.a_no_check(i, j) = a.a_no_check(i, j) - b.a_no_check(i, j);

    return ab;
}

00175 EST_DMatrix operator*(const EST_DMatrix &a, const double x)
{
    EST_DMatrix b(a, 0);
    int i, j;

    for (i = 0; i < a.num_rows(); ++i)
      for (j = 0; j < a.num_columns(); ++j)
          b.a_no_check(i,j) = a.a_no_check(i,j) * x;

    return b;
}

00187 EST_DVector operator*(const EST_DMatrix &a, const EST_DVector &v)
{    
    // treat the vector as a column vector
    // multiply each row of the matrix in turn by the vector

    EST_DVector b;
    b.resize(a.num_rows());
    
    if(a.num_columns() != v.n())
    {
      cerr <<"Matrix-vector multiplication error: matrix rows != vector size"
           << endl;
      return b;
    }

    int i, j;
    for (i = 0; i < a.num_rows(); ++i){
      b[i] = 0.0;
      for (j = 0; j < a.num_columns(); ++j)
          b.a_no_check(i) += a.a_no_check(i,j) * v.a_no_check(j);
    }
    return b;
}

EST_DVector operator+(const EST_DVector &a, const EST_DVector &b)
{
    EST_DVector ab;
    int i;
    if (a.length() != b.length())
    {
      cerr <<"Vector addition error: mismatched lengths\n";
      return ab;
    }

    ab.resize(a.length());
    for (i = 0; i < a.length(); ++i)
      ab.a_no_check(i) = a.a_no_check(i) + b.a_no_check(i);

    return ab;
}

EST_DVector operator-(const EST_DVector &a, const EST_DVector &b)
{
    EST_DVector ab;
    int i;
    if (a.length() != b.length())
    {
      cerr <<"Vector subtraction error: mismatched lengths\n";
      return ab;
    }

    ab.resize(a.length());
    for (i = 0; i < a.length(); ++i)
      ab.a_no_check(i) = a.a_no_check(i) - b.a_no_check(i);

    return ab;
}


00246 EST_DVector operator*(const EST_DVector &v,const EST_DMatrix &a)
{    
    // treat the vector as a row vector
    // multiply the vector by each column of the matrix in turn

    EST_DVector b;
    b.resize(a.num_columns());
    
    if(a.num_columns() != v.n())
    {
      cerr <<"Matrix-vector multiplication error: matrix rows != vector size"
           << endl;
      return b;
    }

    int i, j;
    for (j = 0; j < a.num_columns(); ++j){
      b[j] = 0.0;
      for (i = 0; i < a.num_rows(); ++i)
          b.a_no_check(i) += a.a_no_check(i,j) * v.a_no_check(j);
    }
    return b;
}


#if 0
EST_DMatrix operator/(const EST_DMatrix &a, double x)
{
    return (a * (1/x));
}
#endif

00278 EST_DMatrix operator*(const EST_DMatrix &a, const EST_DMatrix &b)
{
    EST_DMatrix ab;
    multiply(a,b,ab);
    return ab;
}

void multiply(const EST_DMatrix &a, const EST_DMatrix &b, EST_DMatrix &ab)
{

    if (a.num_columns() != b.num_rows())
    {
      cerr <<"Matrix multiply error: a.num_columns() != b.num_rows()\n";
      return;
    }

    ab.resize(a.num_rows(), b.num_columns());
    int i, j, k, n;
    n = a.num_columns();      // could also be b.num_rows()
    
    for (i = 0; i < a.num_rows(); ++i)
      for (k = 0; k < b.num_columns(); ++k)
      {
          ab.a_no_check(i, k) = 0.0;
          for (j = 0; j < n; ++j)
            ab.a_no_check(i, k) += 
                a.a_no_check(i, j) * b.a_no_check(j, k);
      }
}

00308 void EST_DMatrix::copyin(double **inx, int rows, int cols)
{
    int i, j;

    resize(rows, cols);

    for (i = 0; i < rows; ++i)
      for (j = 0; j < cols; ++j)
          a_no_check(i,j) = inx[i][j];
    
}

00320 EST_write_status EST_DMatrix::save(const EST_String &filename,
                           const EST_String &type)
{

    if ((type == "est_ascii") || (type == "est_binary"))
      return est_save(filename,type);
    else
    {   // the old stuff raw unheadered
      int i, j;
      ostream *outf;
      if (filename == "-")
          outf = &cout;
      else
          outf = new ofstream(filename);

      outf->precision(25);
      if (!(*outf))
      {
          cerr << "DMatrix: can't open file \"" << filename 
            <<"\" for writing" << endl;
          return misc_write_error;
      }
    
      for (i = 0; i < num_rows(); ++i)
      {
          for (j = 0; j < num_columns(); ++j)
            *outf << a_no_check(i,j) << " ";
          *outf << endl;
      }
      
      if (outf != &cout)
          delete outf;
      
      return write_ok;
    }
}

00357 EST_write_status EST_DMatrix::est_save(const EST_String &filename,
                               const EST_String &type)
{
    // Binary save with short header for byte swap and sizes
    int i,j;
    FILE *fd;
    if (filename == "-")
      fd = stdout;
    else if ((fd = fopen(filename, "wb")) == NULL)
    {
      cerr << "EST_DMatrix: binsave: failed to open \"" << filename << 
          "\" for writing" << endl;
      return misc_write_error;
    }

    fprintf(fd,"EST_File dmatrix\n");
    fprintf(fd,"version 1\n");
    if (type == "est_binary")
    {
      fprintf(fd,"DataType binary\n");
      if (EST_LITTLE_ENDIAN)
          fprintf(fd,"ByteOrder LittleEndian\n");
      else
          fprintf(fd,"ByteOrder BigEndian\n");
    }
    else
      fprintf(fd,"DataType ascii\n");

    fprintf(fd,"rows %d\n",num_rows());
    fprintf(fd,"columns %d\n",num_columns());

    fprintf(fd,"EST_Header_End\n");

    if (type == "est_binary")
    {
      for (i = 0; i < num_rows(); ++i)
          for (j=0; j < num_columns(); j++)
            if (fwrite(&a_no_check(i,j),sizeof(double),1,fd) != 1)
            {
                cerr << "EST_DMatrix: binsave: failed to write row " 
                  << i << " column " << j 
                      << " to \"" << filename << "\"" << endl;
                return misc_write_error;
            }
    }
    else
    {   // est_ascii
      for (i = 0; i < num_rows(); ++i)
      {
          for (j=0; j < num_columns(); j++)
            fprintf(fd,"%.25f ",a_no_check(i,j));
          fprintf(fd,"\n");
      }
    }
    
    if (fd != stdout)
      fclose(fd);

    return write_ok;
}

00418 EST_read_status EST_DMatrix::est_load(const EST_String &filename)
{

  // ascii/binary load with short header for byte swap and sizes
  int i,j,k;
  int rows, cols, swap;
  EST_TokenStream ts;
  EST_read_status r;
  EST_EstFileType t;
  EST_Option hinfo;
  bool ascii;
    
  if (((filename == "-") ? ts.open(cin) : ts.open(filename)) != 0)
    {
      cerr << "DMatrix: can't open DMatrix input file " 
         << filename << endl;
      return misc_read_error;
    }
  if ((r = read_est_header(ts, hinfo, ascii, t)) != format_ok)
    return r;
    if (t != est_file_dmatrix)
      return misc_read_error;
    if (hinfo.ival("version") != 1)
      {
      cerr << "DMatrix load: " << ts.pos_description() <<
        " wrong version of DMatrix format expected 1 but found " <<
        hinfo.ival("version") << endl;
      return misc_read_error;
      }
    rows = hinfo.ival("rows");
    cols = hinfo.ival("columns");
    resize(rows,cols);
    
    if (ascii)
      {   // an ascii file
      for (i = 0; i < num_rows(); ++i)
        {
          for (j = 0; j < num_columns(); ++j)
            a_no_check(i,j) = atof(ts.get().string());
          if (!ts.eoln())
            {
            cerr << "DMatrix load: " << ts.pos_description() <<
              " missing end of line at end of row " << i << endl;
            return misc_read_error;
            }
        }
      }
    else
      {   // a binary file
      double *buff;
      if ((EST_BIG_ENDIAN && (hinfo.sval("ByteOrder")=="LittleEndian")) ||
          (EST_LITTLE_ENDIAN && (hinfo.sval("ByteOrder") == "BigEndian")))
        swap = TRUE;
      else
        swap = FALSE;
      
      buff = walloc(double,rows*cols);
      // A single read is *much* faster than multiple reads
      if (ts.fread(buff,sizeof(double),rows*cols) != rows*cols)
        {
          cerr << "EST_DMatrix: binload: short file in \""  
             << filename << "\"" << endl;
          return misc_read_error;
        }
      if (swap)
        swap_bytes_double(buff,rows*cols);
      for (k = i = 0; i < num_rows(); ++i)
        for (j = 0; j < num_columns(); ++j)
          a_no_check(i,j) = buff[k++];
      wfree(buff);
      }
    
    ts.close();
    return read_ok;
}

00494 EST_read_status EST_DMatrix::load(const EST_String &filename)
{
    EST_read_status r;

    if ((r = est_load(filename)) == format_ok)
      return r;
    else if (r == wrong_format)
    {   // maybe its an acient ascii file
      EST_TokenStream ts, tt;
      EST_StrList sl;
      int i, j, n_rows=0, n_cols=0;
      EST_String t;
      EST_Litem *p;
      if (((filename == "-") ? ts.open(cin) : ts.open(filename)) != 0)
      {
          cerr << "Can't open DMatrix file " << filename << endl;
          return misc_read_error;
      }
      // set up the character constant values for this stream
      ts.set_SingleCharSymbols(";");
    
      // first read in as list
      for (n_rows = 0; !ts.eof(); ++n_rows)
          sl.append(ts.get_upto_eoln().string());

      if (n_rows > 0)
      {
          tt.open_string(sl.first());
          for (n_cols = 0; !tt.eof(); ++n_cols)
            tt.get().string();
      }

      // resize track and copy values in
      resize(n_rows, n_cols);
      
      for (p = sl.head(), i = 0; p != 0; ++i, p = next(p))
      {
          tt.open_string(sl(p));
          for (j = 0; !tt.eof(); ++j)
            a_no_check(i,j) = atof(tt.get().string());
          if (j != n_cols)
          {
            cerr << "Wrong number of points in row " << i << endl;
            cerr << "Expected " << n_cols << " got " << j << endl;
            return misc_read_error;
          }
      }
      return format_ok;
    }
    else
      return r;

    return format_ok;
}

00549 EST_read_status EST_DVector::est_load(const EST_String &filename)
{    
  // ascii/binary load with short header for byte swap and sizes
  int i,k;
  int l, swap;
  EST_TokenStream ts;
  EST_read_status r;
  EST_EstFileType t;
  EST_Option hinfo;
  bool ascii;
    
  if (((filename == "-") ? ts.open(cin) : ts.open(filename)) != 0)
    {
      cerr << "DVector: can't open DVector input file " 
         << filename << endl;
      return misc_read_error;
    }
  if ((r = read_est_header(ts, hinfo, ascii, t)) != format_ok)
    return r;
    if (t != est_file_dvector)
      return misc_read_error;
    if (hinfo.ival("version") != 1)
      {
      cerr << "DVector load: " << ts.pos_description() <<
        " wrong version of DVector format expected 1 but found " <<
        hinfo.ival("version") << endl;
      return misc_read_error;
      }
    l = hinfo.ival("length");
    resize(l);
    
    if (ascii)
      {   // an ascii file
      for (i = 0; i < length(); ++i)
        a_no_check(i) = atof(ts.get().string());
      }
    else
      {   // a binary file
      double *buff;
      if ((EST_BIG_ENDIAN && (hinfo.sval("ByteOrder")=="LittleEndian")) ||
          (EST_LITTLE_ENDIAN && (hinfo.sval("ByteOrder") == "BigEndian")))
        swap = TRUE;
      else
        swap = FALSE;
      
      buff = walloc(double,l);
      // A single read is *much* faster than multiple reads
      if (ts.fread(buff,sizeof(double),l) != l)
        {
          cerr << "EST_DVector: binload: short file in \""  
             << filename << "\"" << endl;
          return misc_read_error;
        }
      if (swap)
        swap_bytes_double(buff,l);
      for (k = i = 0; i < length(); ++i)
        a_no_check(i) = buff[k++];
      wfree(buff);
      }
    
    ts.close();
    return read_ok;
}

00613 EST_read_status EST_DVector::load(const EST_String &filename)
{    

    EST_read_status r;

    if ((r = est_load(filename)) == format_ok)
      return r;
    else if (r == wrong_format)
    {   // maybe its an acient ascii file
      EST_TokenStream ts;
      EST_String s;
      int i;

      i = 0;
      
      if (((filename == "-") ? ts.open(cin) : ts.open(filename)) != 0)
      {
        cerr << "can't open vector input file " << filename << endl;
        return misc_read_error;
      }
      ts.set_SingleCharSymbols(";");
      
      while (!ts.eof())
      {
        ts.get();
        ++i;
      }
      resize(i);
      
      ts.close();
      if (((filename == "-") ? ts.open(cin) : ts.open(filename)) != 0)
      {
        cerr << "can't open vector input file " << filename << endl;
        return misc_read_error;
      }
      
      for (i = 0; !ts.eof(); ++i)
      {
        s = ts.get().string();
        (*this)[i] = atof(s);  // actually returns double
      }
      ts.close();
      return format_ok;
    }
    else
      return r;

    return format_ok;

}


00665 EST_DVector & EST_DVector::operator+=(const EST_DVector &s)
{
    int i;
    if(n() != s.n()){
      cerr << "Cannot elementwise add vectors of differing lengths" 
          << endl;
      return *this;
    }
    
    for (i = 0; i < n(); ++i)
      (*this)[i] += s(i);

    
    return *this;
}


00682 EST_DVector& EST_DVector::operator*=(const EST_DVector &s)
{
    if(n() != s.n()){
      cerr << "Cannot elementwise multiply vectors of differing lengths" 
          << endl;
      return *this;
    }

    for (int i = 0; i < n(); ++i)
      (*this)[i] *= s(i);

    return *this;
}

00696 EST_DVector& EST_DVector::operator*=(const double f)
{
    for (int i = 0; i < n(); ++i)
      (*this)[i] *= f;

    return *this;
}

double operator*(const EST_DVector &v1, const EST_DVector &v2)
{
  if(v1.length() != v2.length())
    {
      cerr << "Can't do vector dot prod  - differing vector sizes !" << endl;
      return 0;
    }
  double p=0;
  for (int i = 0; i < v1.length(); ++i)
      p += v1.a_no_check(i) * v2.a_no_check(i);

    return p;
}


00719 EST_DVector& EST_DVector::operator/=(const double f)
{
    for (int i = 0; i < n(); ++i)
      (*this)[i] /= f;

    return *this;
}


00728 EST_write_status EST_DVector::save(const EST_String &filename,
                           const EST_String &type)
{

    if ((type == "est_ascii") || (type == "est_binary"))
      return est_save(filename,type);
    else
    {   // the old stuff raw unheadered
      int i;
      ostream *outf;
      if (filename == "-")
          outf = &cout;
      else
          outf = new ofstream(filename);

      outf->precision(25);
      if (!(*outf))
      {
          cerr << "DVector: can't open file \"" << filename 
            <<"\" for writing" << endl;
          return misc_write_error;
      }
    
      for (i = 0; i < length(); ++i)
          *outf << a_no_check(i) << " ";
      *outf << endl;
      
      if (outf != &cout)
          delete outf;
      
      return write_ok;
    }
}

EST_write_status EST_DVector::est_save(const EST_String &filename,
                              const EST_String &type)
{
    // Binary save with short header for byte swap and sizes
    int i;
    FILE *fd;
    if (filename == "-")
      fd = stdout;
    else if ((fd = fopen(filename, "wb")) == NULL)
    {
      cerr << "EST_DVector: binsave: failed to open \"" << filename << 
          "\" for writing" << endl;
      return misc_write_error;
    }

    fprintf(fd,"EST_File dvector\n");
    fprintf(fd,"version 1\n");
    if (type == "est_binary")
    {
      fprintf(fd,"DataType binary\n");
      if (EST_LITTLE_ENDIAN)
          fprintf(fd,"ByteOrder LittleEndian\n");
      else
          fprintf(fd,"ByteOrder BigEndian\n");
    }
    else
      fprintf(fd,"DataType ascii\n");

    fprintf(fd,"length %d\n",length());
    fprintf(fd,"EST_Header_End\n");

    if (type == "est_binary")
    {
      for (i = 0; i < length(); ++i)
          if (fwrite(&a_no_check(i),sizeof(double),1,fd) != 1)
          {
            cerr << "EST_DVector: binsave: failed to write item " 
                 << i << " to \"" << filename << "\"" << endl;
            return misc_write_error;
          }
    }
    else
    {   // est_ascii
      for (i = 0; i < length(); ++i)
          fprintf(fd,"%.25f ",a_no_check(i));
      fprintf(fd,"\n");
    }
    
    if (fd != stdout)
      fclose(fd);

    return write_ok;
}


Generated by  Doxygen 1.6.0   Back to index