qavrg 0.0.28
qavrgmatrix.cpp
Go to the documentation of this file.
00001 #include "qavrgmatrix.h"
00002 
00003 #include <math.h>
00004 #include <stdio.h>
00005 
00006 int QavrgMatrix::m_Errors = 0;
00007 
00008 QavrgMatrix::QavrgMatrix(int nr, int nc, QObject *parent)
00009   : QObject(parent),
00010   m_Matrix(nr*nc),
00011   m_NRows(nr),
00012   m_NCols(nc)
00013 {
00014 }
00015 
00016 void QavrgMatrix::resize(int nr, int nc)
00017 {
00018   m_NRows = nr;
00019   m_NCols = nc;
00020 
00021   m_Matrix.resize(nr*nc);
00022 }
00023 
00024 double& QavrgMatrix::operator()(int r, int c)
00025 {
00026   if (r >= 0 && r < m_NRows && c >= 0 && c < m_NCols) {
00027     return m_Matrix[r*m_NCols+c];
00028   } else {
00029     printf("Array access (%d,%d) outside bounds (%d,%d)\n", r,c, m_NRows, m_NCols);
00030     return m_Dummy;
00031   }
00032 }
00033 
00034 int QavrgMatrix::size(int d)
00035 {
00036   if (d==1) return m_NRows;
00037   if (d==2) return m_NCols;
00038   return 0;
00039 }
00040 
00041 QavrgMatrix& QavrgMatrix::operator=(const QavrgMatrix& m)
00042                                    {
00043   m_Matrix = m.m_Matrix;
00044 
00045   return *this;
00046 }
00047 
00048 void QavrgMatrix::fill(double val)
00049 {
00050   m_Matrix.fill(val);
00051 }
00052 
00053 void QavrgMatrix::dump()
00054 {
00055   printf("QavrgMatrix = (%d,%d) {\n", m_NRows, m_NCols);
00056 
00057   for (int i=0; i<m_NRows; i++) {
00058     if (i) printf(",\n");
00059     printf(" { ");
00060     for (int j=0; j<m_NCols; j++) {
00061       if (j) printf(",\t");
00062       printf("%g",operator()(i,j));
00063     }
00064     printf(" }");
00065   }
00066 
00067   printf("\n}\n");
00068 }
00069 
00070 void QavrgMatrix::test()
00071 {
00072   QavrgMatrix m(5,5);
00073 
00074   for (int i=0; i<5; i++) {
00075     for (int j=0; j<5; j++) {
00076       m(i,j) = 10*i+j;
00077     }
00078   }
00079 
00080   m.dump();
00081 }
00082 
00083 #define SWAP(a,b) { double temp=(a); (a)=(b); (b)=temp; }
00084 
00085 void QavrgMatrix::gaussj(QavrgMatrix &a, QVector<double> &b)
00086 {
00087   int n1= a.size(1);
00088   int n2= a.size(2);
00089   int n = b.size();
00090 
00091   if (n == n1 && n == n2) {
00092     int irow, icol;
00093     QVector<int> indxc(n), indxr(n), ipiv(n);
00094     ipiv.fill(-1);
00095 
00096     for (int i=0; i<n; i++) {
00097       double big=0;
00098 
00099       for (int j=0; j<n; j++) {
00100         if (ipiv[j] != 0) {
00101           for (int k=0; k<n; k++) {
00102             if (ipiv[k] == -1) {
00103               if (fabs(a(j,k)) >= big) {
00104                 big = fabs(a(j,k));
00105                 irow=j;
00106                 icol=k;
00107               }
00108             } else if (ipiv[k] > 0) {
00109               if (m_Errors < 10) {
00110                 m_Errors++;
00111                 printf("gaussj: Singular Matrix-1\n");
00112               }
00113 
00114               return;
00115             }
00116           }
00117         }
00118       }
00119 
00120       ++(ipiv[icol]);
00121       
00122       if (irow != icol) {
00123         for (int l=0; l<n; l++) {
00124           SWAP(a(irow,l),a(icol,l));
00125         }
00126         SWAP(b[irow],b[icol]);
00127       }
00128 
00129       indxr[i]=irow;
00130       indxc[i]=icol;
00131 
00132       if (a(icol,icol) == 0.0) {
00133         if (m_Errors < 10) {
00134           m_Errors++;
00135           printf("gaussj: Singular Matrix-2\n");
00136         }
00137 
00138         return;
00139       }
00140 
00141       double pivinv = 1.0/a(icol,icol);
00142       a(icol,icol) = 1.0;
00143 
00144       for (int l=0; l<n; l++) {
00145         a(icol,l) *= pivinv;
00146       }
00147       b[icol] *= pivinv;
00148 
00149       for (int ll=0; ll<n; ll++) {
00150         if (ll != icol) {
00151           double dum = a(ll,icol);
00152           a(ll,icol) = 0.0;
00153 
00154           for (int l=0; l<n; l++) {
00155             a(ll,l) -= a(icol,l)*dum;
00156           }
00157 
00158           b[ll] -= b[icol]*dum;
00159         }
00160       }
00161     }
00162 
00163     for (int l=n-1; l>=0; l--) {
00164       if (indxr[l] != indxc[l]) {
00165         for (int k=0; k<n; k++) {
00166           SWAP(a(k,indxr[l]), a(k,indxc[l]));
00167         }
00168       }
00169     }
00170   }
00171 }