qavrg 0.0.28
|
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 }