File indexing completed on 2025-08-05 08:18:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 #include "VMatrix.h"
0031
0032
0033 namespace gbl {
0034
0035
0036
0037 VMatrix::VMatrix(const unsigned int nRows, const unsigned int nCols) :
0038 numRows(nRows), numCols(nCols), theVec(nRows * nCols) {
0039 }
0040
0041 VMatrix::VMatrix(const VMatrix &aMatrix) :
0042 numRows(aMatrix.numRows), numCols(aMatrix.numCols), theVec(
0043 aMatrix.theVec) {
0044
0045 }
0046
0047 VMatrix::~VMatrix() {
0048 }
0049
0050
0051
0052
0053
0054
0055 void VMatrix::resize(const unsigned int nRows, const unsigned int nCols) {
0056 numRows = nRows;
0057 numCols = nCols;
0058 theVec.resize(nRows * nCols);
0059 }
0060
0061
0062
0063
0064
0065 VMatrix VMatrix::transpose() const {
0066 VMatrix aResult(numCols, numRows);
0067 for (unsigned int i = 0; i < numRows; ++i) {
0068 for (unsigned int j = 0; j < numCols; ++j) {
0069 aResult(j, i) = theVec[numCols * i + j];
0070 }
0071 }
0072 return aResult;
0073 }
0074
0075
0076
0077
0078
0079 unsigned int VMatrix::getNumRows() const {
0080 return numRows;
0081 }
0082
0083
0084
0085
0086
0087 unsigned int VMatrix::getNumCols() const {
0088 return numCols;
0089 }
0090
0091
0092 void VMatrix::print() const {
0093 std::cout << " VMatrix: " << numRows << "*" << numCols << std::endl;
0094 for (unsigned int i = 0; i < numRows; ++i) {
0095 for (unsigned int j = 0; j < numCols; ++j) {
0096 if (j % 5 == 0) {
0097 std::cout << std::endl << std::setw(4) << i << ","
0098 << std::setw(4) << j << "-" << std::setw(4)
0099 << std::min(j + 4, numCols) << ":";
0100 }
0101 std::cout << std::setw(13) << theVec[numCols * i + j];
0102 }
0103 }
0104 std::cout << std::endl << std::endl;
0105 }
0106
0107
0108 VVector VMatrix::operator*(const VVector &aVector) const {
0109 VVector aResult(numRows);
0110 for (unsigned int i = 0; i < this->numRows; ++i) {
0111 double sum = 0.0;
0112 for (unsigned int j = 0; j < this->numCols; ++j) {
0113 sum += theVec[numCols * i + j] * aVector(j);
0114 }
0115 aResult(i) = sum;
0116 }
0117 return aResult;
0118 }
0119
0120
0121 VMatrix VMatrix::operator*(const VMatrix &aMatrix) const {
0122
0123 VMatrix aResult(numRows, aMatrix.numCols);
0124 for (unsigned int i = 0; i < numRows; ++i) {
0125 for (unsigned int j = 0; j < aMatrix.numCols; ++j) {
0126 double sum = 0.0;
0127 for (unsigned int k = 0; k < numCols; ++k) {
0128 sum += theVec[numCols * i + k] * aMatrix(k, j);
0129 }
0130 aResult(i, j) = sum;
0131 }
0132 }
0133 return aResult;
0134 }
0135
0136
0137 VMatrix VMatrix::operator+(const VMatrix &aMatrix) const {
0138 VMatrix aResult(numRows, numCols);
0139 for (unsigned int i = 0; i < numRows; ++i) {
0140 for (unsigned int j = 0; j < numCols; ++j) {
0141 aResult(i, j) = theVec[numCols * i + j] + aMatrix(i, j);
0142 }
0143 }
0144 return aResult;
0145 }
0146
0147
0148 VMatrix &VMatrix::operator=(const VMatrix &aMatrix) {
0149 if (this != &aMatrix) {
0150 numRows = aMatrix.getNumRows();
0151 numCols = aMatrix.getNumCols();
0152 theVec.resize(numRows * numCols);
0153 for (unsigned int i = 0; i < numRows; ++i) {
0154 for (unsigned int j = 0; j < numCols; ++j) {
0155 theVec[numCols * i + j] = aMatrix(i, j);
0156 }
0157 }
0158 }
0159 return *this;
0160 }
0161
0162
0163
0164 VSymMatrix::VSymMatrix(const unsigned int nRows) :
0165 numRows(nRows), theVec((nRows * nRows + nRows) / 2) {
0166 }
0167
0168 VSymMatrix::~VSymMatrix() {
0169 }
0170
0171
0172
0173
0174
0175 void VSymMatrix::resize(const unsigned int nRows) {
0176 numRows = nRows;
0177 theVec.resize((nRows * nRows + nRows) / 2);
0178 }
0179
0180
0181
0182
0183
0184 unsigned int VSymMatrix::getNumRows() const {
0185 return numRows;
0186 }
0187
0188
0189 void VSymMatrix::print() const {
0190 std::cout << " VSymMatrix: " << numRows << "*" << numRows << std::endl;
0191 for (unsigned int i = 0; i < numRows; ++i) {
0192 for (unsigned int j = 0; j <= i; ++j) {
0193 if (j % 5 == 0) {
0194 std::cout << std::endl << std::setw(4) << i << ","
0195 << std::setw(4) << j << "-" << std::setw(4)
0196 << std::min(j + 4, i) << ":";
0197 }
0198 std::cout << std::setw(13) << theVec[(i * i + i) / 2 + j];
0199 }
0200 }
0201 std::cout << std::endl << std::endl;
0202 }
0203
0204
0205 VSymMatrix VSymMatrix::operator-(const VMatrix &aMatrix) const {
0206 VSymMatrix aResult(numRows);
0207 for (unsigned int i = 0; i < numRows; ++i) {
0208 for (unsigned int j = 0; j <= i; ++j) {
0209 aResult(i, j) = theVec[(i * i + i) / 2 + j] - aMatrix(i, j);
0210 }
0211 }
0212 return aResult;
0213 }
0214
0215
0216 VVector VSymMatrix::operator*(const VVector &aVector) const {
0217 VVector aResult(numRows);
0218 for (unsigned int i = 0; i < numRows; ++i) {
0219 aResult(i) = theVec[(i * i + i) / 2 + i] * aVector(i);
0220 for (unsigned int j = 0; j < i; ++j) {
0221 aResult(j) += theVec[(i * i + i) / 2 + j] * aVector(i);
0222 aResult(i) += theVec[(i * i + i) / 2 + j] * aVector(j);
0223 }
0224 }
0225 return aResult;
0226 }
0227
0228
0229 VMatrix VSymMatrix::operator*(const VMatrix &aMatrix) const {
0230 unsigned int nCol = aMatrix.getNumCols();
0231 VMatrix aResult(numRows, nCol);
0232 for (unsigned int l = 0; l < nCol; ++l) {
0233 for (unsigned int i = 0; i < numRows; ++i) {
0234 aResult(i, l) = theVec[(i * i + i) / 2 + i] * aMatrix(i, l);
0235 for (unsigned int j = 0; j < i; ++j) {
0236 aResult(j, l) += theVec[(i * i + i) / 2 + j] * aMatrix(i, l);
0237 aResult(i, l) += theVec[(i * i + i) / 2 + j] * aMatrix(j, l);
0238 }
0239 }
0240 }
0241 return aResult;
0242 }
0243
0244
0245
0246 VVector::VVector(const unsigned int nRows) :
0247 numRows(nRows), theVec(nRows) {
0248 }
0249
0250 VVector::VVector(const VVector &aVector) :
0251 numRows(aVector.numRows), theVec(aVector.theVec) {
0252
0253 }
0254
0255 VVector::~VVector() {
0256 }
0257
0258
0259
0260
0261
0262 void VVector::resize(const unsigned int nRows) {
0263 numRows = nRows;
0264 theVec.resize(nRows);
0265 }
0266
0267
0268
0269
0270
0271
0272
0273 VVector VVector::getVec(unsigned int len, unsigned int start) const {
0274 VVector aResult(len);
0275 std::memcpy(&aResult.theVec[0], &theVec[start], sizeof(double) * len);
0276 return aResult;
0277 }
0278
0279
0280
0281
0282
0283
0284 void VVector::putVec(const VVector &aVector, unsigned int start) {
0285 std::memcpy(&theVec[start], &aVector.theVec[0],
0286 sizeof(double) * aVector.numRows);
0287 }
0288
0289
0290
0291
0292
0293 unsigned int VVector::getNumRows() const {
0294 return numRows;
0295 }
0296
0297
0298 void VVector::print() const {
0299 std::cout << " VVector: " << numRows << std::endl;
0300 for (unsigned int i = 0; i < numRows; ++i) {
0301
0302 if (i % 5 == 0) {
0303 std::cout << std::endl << std::setw(4) << i << "-" << std::setw(4)
0304 << std::min(i + 4, numRows) << ":";
0305 }
0306 std::cout << std::setw(13) << theVec[i];
0307 }
0308 std::cout << std::endl << std::endl;
0309 }
0310
0311
0312 VVector VVector::operator-(const VVector &aVector) const {
0313 VVector aResult(numRows);
0314 for (unsigned int i = 0; i < numRows; ++i) {
0315 aResult(i) = theVec[i] - aVector(i);
0316 }
0317 return aResult;
0318 }
0319
0320
0321 VVector &VVector::operator=(const VVector &aVector) {
0322 if (this != &aVector) {
0323 numRows = aVector.getNumRows();
0324 theVec.resize(numRows);
0325 for (unsigned int i = 0; i < numRows; ++i) {
0326 theVec[i] = aVector(i);
0327 }
0328 }
0329 return *this;
0330 }
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348 unsigned int VSymMatrix::invert() {
0349
0350 const double eps = 1.0E-10;
0351 unsigned int aSize = numRows;
0352 std::vector<int> next(aSize);
0353 std::vector<double> diag(aSize);
0354 int nSize = aSize;
0355
0356 int first = 1;
0357 for (int i = 1; i <= nSize; ++i) {
0358 next[i - 1] = i + 1;
0359 diag[i - 1] = fabs(theVec[(i * i + i) / 2 - 1]);
0360 }
0361 next[aSize - 1] = -1;
0362
0363 unsigned int nrank = 0;
0364 for (int i = 1; i <= nSize; ++i) {
0365 int k = 0;
0366 double vkk = 0.0;
0367
0368 int j = first;
0369 int previous = 0;
0370 int last = previous;
0371
0372 while (j > 0) {
0373 int jj = (j * j + j) / 2 - 1;
0374 if (fabs(theVec[jj]) > std::max(fabs(vkk), eps * diag[j - 1])) {
0375 vkk = theVec[jj];
0376 k = j;
0377 last = previous;
0378 }
0379 previous = j;
0380 j = next[j - 1];
0381 }
0382
0383 if (k > 0) {
0384 int kk = (k * k + k) / 2 - 1;
0385 if (last <= 0) {
0386 first = next[k - 1];
0387 } else {
0388 next[last - 1] = next[k - 1];
0389 }
0390 next[k - 1] = 0;
0391 nrank++;
0392
0393 vkk = 1.0 / vkk;
0394 theVec[kk] = -vkk;
0395 int jk = kk - k;
0396 int jl = -1;
0397 for (int m = 1; m <= nSize; ++m) {
0398 if (m == k) {
0399 jk = kk;
0400 jl += m;
0401 } else {
0402 if (m < k) {
0403 ++jk;
0404 } else {
0405 jk += m - 1;
0406 }
0407
0408 double vjk = theVec[jk];
0409 theVec[jk] = vkk * vjk;
0410 int lk = kk - k;
0411 if (m >= k) {
0412 for (int l = 1; l <= k - 1; ++l) {
0413 ++jl;
0414 ++lk;
0415 theVec[jl] -= theVec[lk] * vjk;
0416 }
0417 ++jl;
0418 lk = kk;
0419 for (int l = k + 1; l <= m; ++l) {
0420 ++jl;
0421 lk += l - 1;
0422 theVec[jl] -= theVec[lk] * vjk;
0423 }
0424 } else {
0425 for (int l = 1; l <= m; ++l) {
0426 ++jl;
0427 ++lk;
0428 theVec[jl] -= theVec[lk] * vjk;
0429 }
0430 }
0431 }
0432 }
0433 } else {
0434 for (int m = 1; m <= nSize; ++m) {
0435 if (next[m - 1] >= 0) {
0436 int kk = (m * m - m) / 2 - 1;
0437 for (int n = 1; n <= nSize; ++n) {
0438 if (next[n - 1] >= 0) {
0439 theVec[kk + n] = 0.0;
0440 }
0441 }
0442 }
0443 }
0444 throw 1;
0445 }
0446 }
0447 for (int ij = 0; ij < (nSize * nSize + nSize) / 2; ++ij) {
0448 theVec[ij] = -theVec[ij];
0449 }
0450 return nrank;
0451 }
0452 }