00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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;
00042 int rowCount=0;
00043
00044
00045 String buffer;
00046 String item;
00047 item.reserve (20);
00048
00049
00050 int rowCnt = 0;
00051 while (fgetS (in, buffer) != -1) {
00052 buffer.chop();
00053 Vector* prow = new Vector (cols);
00054 int itemIndex=0;
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
00068 make (rowCnt,cols);
00069
00070
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
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256