Main Page   Class Hierarchy   Compound List   File List   Compound Members  

mmatrix.cc

00001 /***************************************************************************
00002  *   This file is part of the MagiC++ library.                             *
00003  *                                                                         *
00004  *   Copyright (C) 1998-2001 Marko Grönroos <magi@iki.fi>                  *
00005  *                                                                         *
00006  ***************************************************************************
00007  *                                                                         *
00008  *  This library is free software; you can redistribute it and/or          *
00009  *  modify it under the terms of the GNU Library General Public            *
00010  *  License as published by the Free Software Foundation; either           *
00011  *  version 2 of the License, or (at your option) any later version.       *
00012  *                                                                         *
00013  *  This library is distributed in the hope that it will be useful,        *
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *
00016  *  Library General Public License for more details.                       *
00017  *                                                                         *
00018  *  You should have received a copy of the GNU Library General Public      *
00019  *  License along with this library; see the file COPYING.LIB.  If         *
00020  *  not, write to the Free Software Foundation, Inc., 59 Temple Place      *
00021  *  - Suite 330, Boston, MA 02111-1307, USA.                               *
00022  *                                                                         *
00023  ***************************************************************************/
00024 
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include "magic/mmath.h"
00028 #include "magic/mmatrix.h"
00029 #include "magic/mstream.h"
00030 #include "magic/mlist.h"
00031 
00032 void Matrix::load (const String& filename) {
00033     FILE* in = fopen (filename, "r");
00034     if (!in)
00035         throw file_not_found (format("Matrix file '%s' not found", (CONSTR)filename));
00036     load (in);
00037     fclose (in);
00038 }
00039 
00040 void Matrix::load (FILE* in) {
00041     List<Vector*> rows;     // Will contain the rows in the input file
00042     int rowCount=0;         // Number of rows in the input file
00043 
00044     // Read the datafile
00045     String buffer;
00046     String item;        // One numeric or text item
00047     item.reserve (20);
00048 
00049     // Read one line at a time
00050     int rowCnt = 0;
00051     while (fgetS (in, buffer) != -1) {
00052         buffer.chop(); // Remove trailing newline
00053         Vector* prow = new Vector (cols);
00054         int itemIndex=0;    // Index of the above item within the row
00055         for (int i=0; i<buffer.length()+1; i++) {
00056             if (i==buffer.length() || buffer[i]==' ' || buffer[i]=='\t') {
00057                 if (itemIndex<cols)
00058                     (*prow)[itemIndex++] = (item=="x")? UNDEFINED_FLOAT : item.toDouble();
00059                 item = "";
00060             } else
00061                 item += buffer[i];
00062         }
00063         rows.add (prow);
00064         rowCnt++;
00065     }
00066 
00067     // Adjust our size
00068     make (rowCnt,cols);
00069 
00070     // Put the pattern list into the set
00071     int r=0;
00072     for (ListIter<Vector*> l (rows); !l.exhausted(); l.next(), r++) {
00073         for (int c=0; c<cols; c++)
00074             get(r,c) = (*l.get())[c];
00075     }
00076 }
00077 
00078 void Matrix::save (FILE* out) const {
00079     for (int r=0; r<rows; r++) {
00080         for (int c=0; c<cols; c++)
00081             fprintf (out, "%g ", get(r,c));
00082         fprintf (out, "\n");
00083     }
00084 }
00085 
00086 const Matrix& Matrix::transpose () {
00087     for (int i=0; i<rows; i++)
00088         for (int j=i; j<cols; j++)
00089             swap (get(i,j), get(j,i));
00090     return *this;
00091 }
00092  
00093 const Matrix& Matrix::multiplyToSum (double s) {
00094     double cs = sum ();
00095     ASSERTWITH (fabs(cs)>1E-10, "Tried to normalize a zero matrix");
00096 
00097     operator*= (1.0/cs);
00098     return *this;
00099 }
00100 
00101 double Matrix::sum () const {
00102     int size=rows*cols;
00103     double res=0.0;
00104     for (int i=0; i<size; i++)
00105         res += data[i];
00106     return res;
00107 }
00108 
00109 const Matrix& Matrix::operator= (double x) {
00110     int size=rows*cols;
00111     for (int i=0; i<size; i++)
00112         data[i]= x;
00113     return *this;
00114 }
00115 
00116 const Matrix& Matrix::operator= (const Matrix& orig) {
00117     make (orig.rows, orig.cols);
00118     int size=rows*cols;
00119     for (int i=0; i<size; i++)
00120         data[i]= orig.data[i];
00121     return *this;
00122 }
00123 
00124 const Matrix& Matrix::operator+= (const Matrix& other) {
00125     int size=rows*cols;
00126     for (int i=0; i<size; i++)
00127         data[i] += other.data[i];
00128     return *this;
00129 }
00130 
00131 const Matrix& Matrix::operator+= (double x) {
00132     int size=rows*cols;
00133     for (int i=0; i<size; i++)
00134         data[i] += x;
00135     return *this;
00136 }
00137 
00138 const Matrix& Matrix::operator*= (const Matrix& other) {
00139     int size=rows*cols;
00140     for (int i=0; i<size; i++)
00141         data[i] *= other.data[i];
00142     return *this;
00143 }
00144 
00145 const Matrix& Matrix::operator*= (double x) {
00146     int size=rows*cols;
00147     for (int i=0; i<size; i++)
00148         data[i] *= x;
00149     return *this;
00150 }
00151 
00152 void Matrix::operator>> (OStream& out) const {
00153     out.printf ("{");
00154     for (int i=0; i<rows; i++) {
00155         if (i>0)
00156             out.printf (" ");
00157         out.printf ("{");
00158         for (int j=0; j<cols; j++) {
00159             out.printf ("%2f", get (i,j));
00160             if (j<cols-1)
00161                 out.printf (",");
00162         }
00163         out.print ("}");
00164         if (i<rows-1)
00165             out.printf ("\n");
00166     }
00167     out.printf ("}\n");
00168 }
00169 
00170 void Matrix::splitVertical (Matrix& a, Matrix& b, int column) const {
00171     a.make (rows, column);
00172     b.make (rows, cols-column);
00173     for (int r=0; r<rows; r++) {
00174         for (int c=0; c<column; c++)
00175             a.get(r,c) = get(r,c);
00176         for (int c=0; c<cols-column; c++)
00177             b.get(r,c) = get(r,c+column);
00178     }
00179 }
00180 
00181 void Matrix::splitHorizontal (Matrix& a, Matrix& b, int row) const {
00182     a.make (row, cols);
00183     b.make (rows-row, cols);
00184     for (int c=0; c<cols; c++) {
00185         for (int r=0; r<row; r++)
00186             a.get(r,c) = get(r,c);
00187         for (int r=0; r<rows-row; r++)
00188             b.get(r,c) = get(r+row,c);
00189     }
00190 }
00191 
00192 void Matrix::joinVertical (const Matrix& a, const Matrix& b) {
00193     ASSERT (a.rows == b.rows);
00194     make (a.rows, a.cols + b.cols);
00195     for (int r=0; r<rows; r++) {
00196         for (int c=0; c<a.cols; c++)
00197             get(r,c) = a.get(r,c);
00198         for (int c=0; c<b.cols; c++)
00199             get(r,c+a.cols) = a.get(r,c);
00200     }
00201 }
00202 
00203 void Matrix::joinHorizontal (const Matrix& a, const Matrix& b) {
00204     ASSERT (a.cols == b.cols);
00205     make (a.rows+b.rows, a.cols);
00206     for (int c=0; c<cols; c++) {
00207         for (int r=0; r<a.rows; r++)
00208             get(r,c) = a.get(r,c);
00209         for (int r=0; r<b.rows; r++)
00210             get(r+a.rows,c) = a.get(r,c);
00211     }
00212 }
00213 
00214 Matrix Matrix::sub (int row0, int row1, int col0, int col1) const {
00215     ASSERT (row0>=0 && row0<rows);
00216     ASSERT ((row1>=-1 && row1<rows) || row1==-1);
00217     ASSERT (col0>=0 && col0<cols);
00218     ASSERT ((col1>=-1 && col1<cols) || col1==-1);
00219 
00220     if (row1==-1)
00221         row1 = rows-1;
00222     if (col1==-1)
00223         col1 = cols-1;
00224 
00225     Matrix result;
00226     result.make (row1-row0+1, col1-col0+1);
00227     for (int r=0; r<result.rows; r++)
00228         for (int c=0; c<result.cols; c++)
00229             result.get(r,c) = (*this).get(r+row0, c+col0);
00230     return result;
00231 }
00232 
00233 void Matrix::insertColumn (int cols) {
00234     
00235 }
00236 
00237 
00238 /*
00239 SubMatrix::SubMatrix (Matrix& m, int sr, int sc, int er, int ec) : matrix (m) {
00240     ASSERT (sr>0 && sc>0 && er>0 && ec>0);
00241     ASSERT (sr<m.rows);
00242     ASSERT (sc<m.cols);
00243     ASSERT (er<m.rows);
00244     ASSERT (ec<m.cols);
00245     ASSERT (sr<=er);
00246     ASSERT (sc<=ec);
00247     srow=sr, scol=sc, erow=er, ecol=ec;
00248     rows = erow-srow+1;
00249     cols = ecol-scol+1;
00250 
00251 }
00252 
00253 double& SubMatrix::get (int row, int col) {
00254     return matrix.PackTable<double>::get (row-srow, col-scol);
00255 }
00256 */

Generated at Tue Dec 4 19:53:26 2001 for MagiC++ by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001