![]() |
GeneralBrokenLines
V01-11-00
|
00001 /* 00002 * VMatrix.cpp 00003 * 00004 * Created on: Feb 15, 2012 00005 * Author: kleinwrt 00006 */ 00007 00008 #include "VMatrix.h" 00009 00010 /*********** simple Matrix based on std::vector<double> **********/ 00011 00012 VMatrix::VMatrix(const unsigned int nRows, const unsigned int nCols) : 00013 numRows(nRows), numCols(nCols), theVec(nRows * nCols) { 00014 // TODO Auto-generated constructor stub 00015 } 00016 00017 VMatrix::VMatrix(const VMatrix &aMatrix) : 00018 numRows(aMatrix.numRows), numCols(aMatrix.numCols), theVec( 00019 aMatrix.theVec) { 00020 00021 } 00022 00023 VMatrix::~VMatrix() { 00024 // TODO Auto-generated destructor stub 00025 } 00026 00028 00032 void VMatrix::resize(const unsigned int nRows, const unsigned int nCols) { 00033 numRows = nRows; 00034 numCols = nCols; 00035 theVec.resize(nRows * nCols); 00036 } 00037 00039 00042 VMatrix VMatrix::transpose() const { 00043 VMatrix aResult(numCols, numRows); 00044 for (unsigned int i = 0; i < numRows; i++) { 00045 for (unsigned int j = 0; j < numCols; j++) { 00046 aResult(j, i) = theVec[numCols * i + j]; 00047 } 00048 } 00049 return aResult; 00050 } 00051 00053 00056 unsigned int VMatrix::getNumRows() const { 00057 return numRows; 00058 } 00059 00061 00064 unsigned int VMatrix::getNumCols() const { 00065 return numCols; 00066 } 00067 00069 void VMatrix::print() const { 00070 std::cout << " VMatrix: " << numRows << "*" << numCols << std::endl; 00071 for (unsigned int i = 0; i < numRows; i++) { 00072 for (unsigned int j = 0; j < numCols; j++) { 00073 if (j % 5 == 0) { 00074 std::cout << std::endl << std::setw(4) << i << "," 00075 << std::setw(4) << j << "-" << std::setw(4) 00076 << std::min(j + 4, numCols) << ": "; 00077 } 00078 std::cout << std::setw(13) << theVec[numCols * i + j]; 00079 } 00080 } 00081 std::cout << std::endl << std::endl; 00082 } 00083 00085 VVector VMatrix::operator*(const VVector &aVector) const { 00086 VVector aResult(numRows); 00087 for (unsigned int i = 0; i < this->numRows; i++) { 00088 double sum = 0.0; 00089 for (unsigned int j = 0; j < this->numCols; j++) { 00090 sum += theVec[numCols * i + j] * aVector(j); 00091 } 00092 aResult(i) = sum; 00093 } 00094 return aResult; 00095 } 00096 00098 VMatrix VMatrix::operator*(const VMatrix &aMatrix) const { 00099 00100 VMatrix aResult(numRows, aMatrix.numCols); 00101 for (unsigned int i = 0; i < numRows; i++) { 00102 for (unsigned int j = 0; j < aMatrix.numCols; j++) { 00103 double sum = 0.0; 00104 for (unsigned int k = 0; k < numCols; k++) { 00105 sum += theVec[numCols * i + k] * aMatrix(k, j); 00106 } 00107 aResult(i, j) = sum; 00108 } 00109 } 00110 return aResult; 00111 } 00112 00114 VMatrix VMatrix::operator+(const VMatrix &aMatrix) const { 00115 VMatrix aResult(numRows, numCols); 00116 for (unsigned int i = 0; i < numRows; i++) { 00117 for (unsigned int j = 0; j < numCols; j++) { 00118 aResult(i, j) = theVec[numCols * i + j] + aMatrix(i, j); 00119 } 00120 } 00121 return aResult; 00122 } 00123 00124 /*********** simple symmetric Matrix based on std::vector<double> **********/ 00125 00126 VSymMatrix::VSymMatrix(const unsigned int nRows) : 00127 numRows(nRows), theVec((nRows * nRows + nRows) / 2) { 00128 // TODO Auto-generated constructor stub 00129 } 00130 00131 VSymMatrix::~VSymMatrix() { 00132 // TODO Auto-generated destructor stub 00133 } 00134 00136 00139 void VSymMatrix::resize(const unsigned int nRows) { 00140 numRows = nRows; 00141 theVec.resize((nRows * nRows + nRows) / 2); 00142 } 00143 00145 00148 unsigned int VSymMatrix::getNumRows() const { 00149 return numRows; 00150 } 00151 00153 void VSymMatrix::print() const { 00154 std::cout << " VSymMatrix: " << numRows << "*" << numRows << std::endl; 00155 for (unsigned int i = 0; i < numRows; i++) { 00156 for (unsigned int j = 0; j <= i; j++) { 00157 if (j % 5 == 0) { 00158 std::cout << std::endl << std::setw(4) << i << "," 00159 << std::setw(4) << j << "-" << std::setw(4) 00160 << std::min(j + 4, i) << ": "; 00161 } 00162 std::cout << std::setw(13) << theVec[(i * i + i) / 2 + j]; 00163 } 00164 } 00165 std::cout << std::endl << std::endl; 00166 } 00167 00169 VSymMatrix VSymMatrix::operator-(const VMatrix &aMatrix) const { 00170 VSymMatrix aResult(numRows); 00171 for (unsigned int i = 0; i < numRows; i++) { 00172 for (unsigned int j = 0; j <= i; j++) { 00173 aResult(i, j) = theVec[(i * i + i) / 2 + j] - aMatrix(i, j); 00174 } 00175 } 00176 return aResult; 00177 } 00178 00180 VVector VSymMatrix::operator*(const VVector &aVector) const { 00181 VVector aResult(numRows); 00182 for (unsigned int i = 0; i < numRows; i++) { 00183 aResult(i) = theVec[(i * i + i) / 2 + i] * aVector(i); 00184 for (unsigned int j = 0; j < i; j++) { 00185 aResult(j) += theVec[(i * i + i) / 2 + j] * aVector(i); 00186 aResult(i) += theVec[(i * i + i) / 2 + j] * aVector(j); 00187 } 00188 } 00189 return aResult; 00190 } 00191 00193 VMatrix VSymMatrix::operator*(const VMatrix &aMatrix) const { 00194 unsigned int nCol = aMatrix.getNumCols(); 00195 VMatrix aResult(numRows, nCol); 00196 for (unsigned int l = 0; l < nCol; l++) { 00197 for (unsigned int i = 0; i < numRows; i++) { 00198 aResult(i, l) = theVec[(i * i + i) / 2 + i] * aMatrix(i, l); 00199 for (unsigned int j = 0; j < i; j++) { 00200 aResult(j, l) += theVec[(i * i + i) / 2 + j] * aMatrix(i, l); 00201 aResult(i, l) += theVec[(i * i + i) / 2 + j] * aMatrix(j, l); 00202 } 00203 } 00204 } 00205 return aResult; 00206 } 00207 00208 /*********** simple Vector based on std::vector<double> **********/ 00209 00210 VVector::VVector(const unsigned int nRows) : 00211 numRows(nRows), theVec(nRows) { 00212 // TODO Auto-generated constructor stub 00213 } 00214 00215 VVector::VVector(const VVector &aVector) : 00216 numRows(aVector.numRows), theVec(aVector.theVec) { 00217 00218 } 00219 00220 VVector::~VVector() { 00221 // TODO Auto-generated destructor stub 00222 } 00223 00225 00228 void VVector::resize(const unsigned int nRows) { 00229 numRows = nRows; 00230 theVec.resize(nRows); 00231 } 00232 00234 00239 VVector VVector::getVec(unsigned int len, unsigned int start) const { 00240 VVector aResult(len); 00241 std::memcpy(&aResult.theVec[0], &theVec[start], sizeof(double) * len); 00242 return aResult; 00243 } 00244 00246 00250 void VVector::putVec(const VVector &aVector, unsigned int start) { 00251 std::memcpy(&theVec[start], &aVector.theVec[0], 00252 sizeof(double) * aVector.numRows); 00253 } 00254 00256 00259 unsigned int VVector::getNumRows() const { 00260 return numRows; 00261 } 00262 00264 void VVector::print() const { 00265 std::cout << " VVector: " << numRows << std::endl; 00266 for (unsigned int i = 0; i < numRows; i++) { 00267 00268 if (i % 5 == 0) { 00269 std::cout << std::endl << std::setw(4) << i << "-" << std::setw(4) 00270 << std::min(i + 4, numRows) << ": "; 00271 } 00272 std::cout << std::setw(13) << theVec[i]; 00273 } 00274 std::cout << std::endl << std::endl; 00275 } 00276 00278 VVector VVector::operator-(const VVector &aVector) const { 00279 VVector aResult(numRows); 00280 for (unsigned int i = 0; i < numRows; i++) { 00281 aResult(i) = theVec[i] - aVector(i); 00282 } 00283 return aResult; 00284 } 00285 00286 /*============================================================================ 00287 from mpnum.F (MillePede-II by V. Blobel, Univ. Hamburg) 00288 ============================================================================*/ 00290 00302 unsigned int VSymMatrix::invert() { 00303 00304 const double eps = 1.0E-10; 00305 unsigned int aSize = numRows; 00306 std::vector<int> next(aSize); 00307 std::vector<double> diag(aSize); 00308 int nSize = aSize; 00309 00310 int first = 1; 00311 for (int i = 1; i <= nSize; i++) { 00312 next[i - 1] = i + 1; // set "next" pointer 00313 diag[i - 1] = fabs(theVec[(i * i + i) / 2 - 1]); // save abs of diagonal elements 00314 } 00315 next[aSize - 1] = -1; // end flag 00316 00317 unsigned int nrank = 0; 00318 for (int i = 1; i <= nSize; i++) { // start of loop 00319 int k = 0; 00320 double vkk = 0.0; 00321 00322 int j = first; 00323 int previous = 0; 00324 int last = previous; 00325 // look for pivot 00326 while (j > 0) { 00327 int jj = (j * j + j) / 2 - 1; 00328 if (fabs(theVec[jj]) > std::max(fabs(vkk), eps * diag[j - 1])) { 00329 vkk = theVec[jj]; 00330 k = j; 00331 last = previous; 00332 } 00333 previous = j; 00334 j = next[j - 1]; 00335 } 00336 // pivot found 00337 if (k > 0) { 00338 int kk = (k * k + k) / 2 - 1; 00339 if (last <= 0) { 00340 first = next[k - 1]; 00341 } else { 00342 next[last - 1] = next[k - 1]; 00343 } 00344 next[k - 1] = 0; // index is used, reset 00345 nrank++; // increase rank and ... 00346 00347 vkk = 1.0 / vkk; 00348 theVec[kk] = -vkk; 00349 int jk = kk - k; 00350 int jl = -1; 00351 for (int j = 1; j <= nSize; j++) { // elimination 00352 if (j == k) { 00353 jk = kk; 00354 jl += j; 00355 } else { 00356 if (j < k) { 00357 jk++; 00358 } else { 00359 jk += j - 1; 00360 } 00361 00362 double vjk = theVec[jk]; 00363 theVec[jk] = vkk * vjk; 00364 int lk = kk - k; 00365 if (j >= k) { 00366 for (int l = 1; l <= k - 1; l++) { 00367 jl++; 00368 lk++; 00369 theVec[jl] -= theVec[lk] * vjk; 00370 } 00371 jl++; 00372 lk = kk; 00373 for (int l = k + 1; l <= j; l++) { 00374 jl++; 00375 lk += l - 1; 00376 theVec[jl] -= theVec[lk] * vjk; 00377 } 00378 } else { 00379 for (int l = 1; l <= j; l++) { 00380 jl++; 00381 lk++; 00382 theVec[jl] -= theVec[lk] * vjk; 00383 } 00384 } 00385 } 00386 } 00387 } else { 00388 for (int k = 1; k <= nSize; k++) { 00389 if (next[k - 1] >= 0) { 00390 int kk = (k * k - k) / 2 - 1; 00391 for (int j = 1; j <= nSize; j++) { 00392 if (next[j - 1] >= 0) { 00393 theVec[kk + j] = 0.0; // clear matrix row/col 00394 } 00395 } 00396 } 00397 } 00398 throw 1; // singular 00399 } 00400 } 00401 for (int ij = 0; ij < (nSize * nSize + nSize) / 2; ij++) { 00402 theVec[ij] = -theVec[ij]; // finally reverse sign of all matrix elements 00403 } 00404 return nrank; 00405 } 00406
1.7.6.1