GeneralBrokenLines  V01-11-00
VMatrix.cpp
Go to the documentation of this file.
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 
 All Classes Files Functions Variables Typedefs