matrix_solve.inl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #ifndef LASS_GUARDIAN_OF_INCLUSION_NUM_IMPL_MATRIX_SOLVE_INL
00046 #define LASS_GUARDIAN_OF_INCLUSION_NUM_IMPL_MATRIX_SOLVE_INL
00047
00048 #include "../num_common.h"
00049 #include "matrix_solve.h"
00050
00051 namespace lass
00052 {
00053 namespace num
00054 {
00055 namespace impl
00056 {
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 template
00080 <
00081 typename T,
00082 typename RandomIterator1,
00083 typename RandomIterator2
00084 >
00085 bool ludecomp(RandomIterator1 ioMatrix,
00086 RandomIterator2 oIndex,
00087 size_t iSize,
00088 int& iD)
00089 {
00090 typedef NumTraits<T> TNumTraits;
00091 typedef typename TNumTraits::baseType TBase;
00092 typedef NumTraits<TBase> TBaseTraits;
00093
00094 const TBase epsilon = static_cast<TBase>(1e-20);
00095
00096 std::vector<T> vv(iSize);
00097 iD = 1;
00098
00099 for (size_t i = 0; i < iSize; ++i)
00100 {
00101 RandomIterator1 rowI = ioMatrix + (i * iSize);
00102 TBase normMax = TBaseTraits::zero;
00103 size_t jMax = iSize;
00104 for (size_t j = 0; j < iSize; ++j)
00105 {
00106 const TBase temp = num::norm(rowI[j]);
00107 if (temp > normMax)
00108 {
00109 normMax = temp;
00110 jMax = j;
00111 }
00112 }
00113 if (normMax == TBaseTraits::zero)
00114 {
00115 return false;
00116 }
00117 LASS_ASSERT(jMax != iSize);
00118
00119 vv[i] = num::conj(rowI[jMax]) / normMax;
00120 }
00121
00122 for (size_t j = 0; j < iSize; ++j)
00123 {
00124 size_t i;
00125 for (i = 0; i < j; ++i)
00126 {
00127 RandomIterator1 rowI = ioMatrix + (i * iSize);
00128 T sum = rowI[j];
00129 for (size_t k = 0; k < i; ++k)
00130 {
00131 sum -= rowI[k] * ioMatrix[k * iSize + j];
00132 }
00133 rowI[j] = sum;
00134 }
00135
00136 TBase normMax = TBaseTraits::zero;
00137 size_t iMax = iSize;
00138 for (i = j; i < iSize; ++i)
00139 {
00140 RandomIterator1 rowI = ioMatrix + (i * iSize);
00141 T sum = rowI[j];
00142 for (size_t k = 0; k < j; ++k)
00143 {
00144 sum -= rowI[k] * ioMatrix[k * iSize + j];
00145 }
00146 rowI[j] = sum;
00147
00148 const T dum = vv[i] * sum;
00149 const TBase temp = num::norm(dum);
00150 if (temp >= normMax)
00151 {
00152 normMax = temp;
00153 iMax = i;
00154 }
00155 }
00156 LASS_ASSERT(iMax != iSize);
00157
00158 if (j != iMax)
00159 {
00160 for (size_t k = 0; k < iSize; ++k)
00161 {
00162 std::swap(ioMatrix[iMax * iSize + k], ioMatrix[j * iSize + k]);
00163 }
00164 iD = -iD;
00165 vv[iMax] = vv[j];
00166 }
00167 oIndex[j] = iMax;
00168
00169 TBase temp = num::norm(ioMatrix[j * iSize + j]);
00170 if (temp == TBaseTraits::zero)
00171 {
00172 ioMatrix[j * iSize + j] = TNumTraits::one;
00173 temp = epsilon;
00174 }
00175
00176 if (j != iSize - 1)
00177 {
00178 const T dum = num::conj(ioMatrix[j * iSize + j]) / temp;
00179 for (i = j + 1; i < iSize; ++i)
00180 {
00181 ioMatrix[i * iSize + j] *= dum;
00182 }
00183 }
00184 }
00185
00186 return true;
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 template
00216 <
00217 typename T,
00218 typename RandomIterator1,
00219 typename RandomIterator2,
00220 typename RandomIterator3
00221 >
00222 void lusolve(RandomIterator1 iMatrix,
00223 RandomIterator2 iIndex,
00224 RandomIterator3 ioColumn,
00225 size_t iSize)
00226 {
00227 typedef NumTraits<T> TNumTraits;
00228
00229 size_t ii = iSize;
00230 for (size_t i = 0; i < iSize; ++i)
00231 {
00232 RandomIterator1 rowI = iMatrix + (i * iSize);
00233 const size_t ip = iIndex[i];
00234 T sum = ioColumn[ip];
00235 ioColumn[ip] = ioColumn[i];
00236
00237 if (ii != iSize)
00238 {
00239 for (size_t j = ii; j < i; ++j)
00240 {
00241 sum -= rowI[j] * ioColumn[j];
00242 }
00243 }
00244 else
00245 {
00246 if (!(sum == TNumTraits::zero))
00247 {
00248 ii = i;
00249 }
00250 }
00251 ioColumn[i] = sum;
00252 }
00253
00254 for (size_t ic = iSize; ic > 0; --ic)
00255 {
00256 const size_t i = ic - 1;
00257 RandomIterator1 rowI = iMatrix + (i * iSize);
00258 T sum = ioColumn[i];
00259 for (size_t j = ic; j < iSize; ++j)
00260 {
00261 sum -= rowI[j] * ioColumn[j];
00262 }
00263 ioColumn[i] = sum / rowI[i];
00264 }
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288 template
00289 <
00290 typename T,
00291 typename RandomIterator1,
00292 typename RandomIterator2,
00293 typename RandomIterator3,
00294 typename RandomIterator4,
00295 typename RandomIterator5
00296 >
00297 void lumprove(RandomIterator1 iMatrix,
00298 RandomIterator2 iMatrixLU,
00299 RandomIterator3 iIndex,
00300 RandomIterator4 iColumn,
00301 RandomIterator5 ioX,
00302 size_t iSize)
00303 {
00304 typedef NumTraits<T> TNumTraits;
00305
00306 std::vector<T> r(iSize);
00307 size_t i;
00308 for (i = 0; i < iSize; ++i)
00309 {
00310 RandomIterator1 rowI = iMatrix + (i * iSize);
00311 r[i] = -iColumn[i];
00312 for (size_t j = 0; j < iSize; ++j)
00313 {
00314 r[i] += rowI[j] * ioX[j];
00315 }
00316 }
00317
00318 lusolve(iMatrixLU, iIndex, r.begin(), iSize);
00319
00320 for (i = 0; i < iSize; ++i)
00321 {
00322 ioX[i] -= r[i];
00323 }
00324 }
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 template
00339 <
00340 typename T,
00341 typename RandomIterator1,
00342 typename RandomIterator2
00343 >
00344 bool cramer2(RandomIterator1 iMatrixRowMajor,
00345 RandomIterator2 ioColumnFirst,
00346 RandomIterator2 ioColumnLast)
00347 {
00348 typedef NumTraits<T> TNumTraits;
00349 RandomIterator1 m = iMatrixRowMajor;
00350
00351 const T determinant = m[0] * m[3] - m[1] * m[2];
00352
00353 if (determinant == TNumTraits::zero)
00354 {
00355 return false;
00356 }
00357
00358 const T inverseDeterminant = num::inv(determinant);
00359
00360 for (RandomIterator2 column = ioColumnFirst; column != ioColumnLast; column += 2)
00361 {
00362 LASS_ASSERT(column + 1 != ioColumnLast);
00363 const T x = column[0];
00364 const T y = column[1];
00365 column[0] = inverseDeterminant * (x * m[3] - y * m[2]);
00366 column[1] = inverseDeterminant * (m[0] * y - m[1] * x);
00367 }
00368 return true;
00369 }
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 template
00385 <
00386 typename T,
00387 typename RandomIterator1,
00388 typename RandomIterator2
00389 >
00390 bool cramer3(RandomIterator1 iMatrixRowMajor,
00391 RandomIterator2 ioColumnFirst,
00392 RandomIterator2 ioColumnLast)
00393 {
00394 typedef NumTraits<T> TNumTraits;
00395 RandomIterator1 m = iMatrixRowMajor;
00396
00397 const T determinant =
00398 m[0] * (m[4] * m[8] - m[7] * m[5]) +
00399 m[3] * (m[7] * m[2] - m[1] * m[8]) +
00400 m[6] * (m[1] * m[5] - m[4] * m[2]);
00401
00402 if (determinant == TNumTraits::zero)
00403 {
00404 return false;
00405 }
00406
00407 const T inverseDeterminant = num::inv(determinant);
00408
00409 for (RandomIterator2 column = ioColumnFirst; column != ioColumnLast; column += 3)
00410 {
00411 LASS_ASSERT(column + 1 != ioColumnLast && column + 2 != ioColumnLast);
00412 const T x = column[0];
00413 const T y = column[1];
00414 const T z = column[2];
00415 column[0] = inverseDeterminant * (
00416 x * (m[4] * m[8] - m[7] * m[5]) +
00417 y * (m[7] * m[2] - m[1] * m[8]) +
00418 z * (m[1] * m[5] - m[4] * m[2]));
00419 column[1] = inverseDeterminant * (
00420 m[0] * (y * m[8] - z * m[5]) +
00421 m[3] * (z * m[2] - x * m[8]) +
00422 m[6] * (x * m[5] - y * m[2]));
00423 column[2] = inverseDeterminant * (
00424 m[0] * (m[4] * z - m[7] * y) +
00425 m[3] * (m[7] * x - m[1] * z) +
00426 m[6] * (m[1] * y - m[4] * x));
00427 }
00428
00429 return true;
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453 template
00454 <
00455 typename T,
00456 typename RandomIterator1,
00457 typename RandomIterator2,
00458 typename RandomIterator3
00459 >
00460 bool solveTridiagonal(RandomIterator1 iA, RandomIterator1 iB, RandomIterator1 iC,
00461 RandomIterator2 ioSolution, RandomIterator3 ioTemp,
00462 std::size_t iSize)
00463 {
00464 typedef NumTraits<T> TNumTraits;
00465
00466 T beta = iB[0];
00467 if (beta == TNumTraits::zero)
00468 {
00469 return false;
00470 }
00471 ioSolution[0] /= beta;
00472 for (std::size_t i = 1; i <iSize; ++i)
00473 {
00474 ioTemp[i] = iC[i - 1] / beta;
00475 beta = iB[i] - iA[i] * ioTemp[i];
00476 if (beta == TNumTraits::zero)
00477 {
00478 return false;
00479 }
00480 ioSolution[i] = (ioSolution[i] - iA[i] * ioSolution[i - 1]) / beta;
00481 }
00482 for (std::size_t i = iSize - 1; i > 0; --i)
00483 {
00484 ioSolution[i - 1] -= ioTemp[i] * ioSolution[i];
00485 }
00486 return true;
00487 }
00488
00489 }
00490
00491 }
00492
00493 }
00494
00495 #endif
00496
00497