00001 #include "matrix.h"
00002
00003 #define DBL_EPSILON 2.22045e-16
00004
00005 double *V_Zero (double *v, const int n)
00006 {
00007 for (int i = 0; i < n; i++) {
00008 v[i] = 0.0;
00009 }
00010 return v;
00011 }
00012
00013 double *V_Unit (double *v, const int n, const int k)
00014 {
00015 for (int i = 0; i < n; i++) {
00016 v[i] = 0.0;
00017 }
00018 v[k] = 1.0;
00019 return v;
00020 }
00021
00022 void V_Print (const double *v, const int n)
00023 {
00024
00025 for (int i = 0; i < n; i++) {
00026 std::cout << v[i];
00027 }
00028 std::cout << std::endl;
00029 return;
00030 }
00031
00032 void V_Print (const double *v, const double *w, const int n)
00033 {
00034
00035 for (int i = 0; i < n; i++) {
00036 std::cout << v[i] << " | " << w[i];
00037 }
00038 std::cout << std::endl;
00039 return;
00040 }
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 double UNorm (const double *A, int n, const int m)
00052 {
00053 int counter;
00054 double help, Max = 0.0;
00055 const double *B = A;
00056 while (n--) {
00057 counter = m;
00058 while (counter--) {
00059 B = A + n + counter;
00060 if (Max < (help = fabs (*(B))))
00061 Max = help;
00062 }
00063 }
00064 return Max;
00065 }
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 double *M_Cholesky (double *B, double *q, const int n)
00077 {
00078 int i, j, k;
00079 double sum, min;
00080 double *C = B;
00081 double A[n][n];
00082 double p[n],*pp;
00083
00084 for(i=0;i<n;i++){
00085 for(j=0;j<n;j++){
00086 A[i][j]=*C;
00087 C++;
00088 }
00089 }
00090
00091 min = UNorm (B, n, n) * n * DBL_EPSILON;
00092 for( i = 0; i < n; i++ ) {
00093 for( j = i; j < n; j++ ) {
00094 sum = A[i][j];
00095 for( k = i-1; k >= 0; k-- )
00096 sum -= A[i][k] * A[j][k];
00097 if( i == j ) {
00098 if( sum < min ) {
00099 return 0;
00100 }
00101 p[i] = sqrt(sum);
00102 } else
00103 A[j][i] = sum/p[i];
00104 }
00105 }
00106 C = B;
00107 pp=q;
00108 for(i=0;i<n;i++){
00109 *p = p[i];
00110 pp++;
00111 for(j=0;j<n;j++){
00112 *C = A[i][j];
00113 C++;
00114 }
00115 }
00116 C = B;
00117 pp = q;
00118 return B;
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 void RowMult (const double a, double *A, const double b, const double *B, const int n)
00131 {
00132 for (int i = 0; i < n; i++)
00133 A[i] = a*A[i] + b*B[i];
00134
00135 return;
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 void M_Print (const double *A, const int n)
00148 {
00149
00150 for (int i = 0; i < n; i++) {
00151 std::cout << "[";
00152 for (int j = 0; j < n; j++) {
00153 std::cout << A[i*n+j] << ' ';
00154 }
00155 std::cout << ']' << std::endl;
00156 }
00157 std::cout << std::endl;
00158
00159 return;
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 void M_Print (const double *A, const double *B, const int n)
00172 {
00173
00174 for (int i = 0; i < n; i++) {
00175 std::cout << "[";
00176 for (int j = 0; j < n; j++) {
00177 std::cout << A[i*n+j] << ' ';
00178 }
00179 std::cout << '|' ;
00180 for (int j = 0; j < n; j++) {
00181 std::cout << B[i*n+j] << ' ';
00182 }
00183 std::cout << ']' << std::endl;
00184 }
00185 std::cout << std::endl;
00186
00187 return;
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 double *M_Unit (double *A, const int n)
00200 {
00201 for (int i = 0; i < n; i++) {
00202 for (int j = 0; j < n; j++) {
00203 A[i*n+j] = 0;
00204 }
00205 A[i*n+i] = 1;
00206 }
00207
00208 return A;
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 double *M_Zero (double *A, const int n)
00221 {
00222 for (int i = 0; i < n; i++) {
00223 for (int j = 0; j < n; j++) {
00224 A[i*n+j] = 0;
00225 }
00226 }
00227
00228 return A;
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 double* M_Invert (double *Ap, double *Bp, const int n)
00241 {
00242 double *row1, *row2;
00243 double a, b;
00244
00245
00246 M_Unit (Bp, n);
00247
00248
00249
00250
00251
00252
00253 if (n == 2) {
00254 double det = (Ap[0] * Ap[3]) - (Ap[1] * Ap[2]);
00255 Bp[0] = Ap[0] / det;
00256 Bp[1] = -Ap[1] / det;
00257 Bp[2] = -Ap[2] / det;
00258 Bp[3] = Ap[3] / det;
00259 }
00260
00261 if (n == 4) {
00262
00263
00264
00265
00266 for (int i = 1; i < n; i++) {
00267 a = -(Ap[0]);
00268 b = Ap[i*n];
00269 row1 = &(Ap[i*n]);
00270 row2 = &(Ap[0]);
00271 RowMult(a, row1, b, row2, 4);
00272 row1 = &(Bp[i*n]);
00273 row2 = &(Bp[0]);
00274 RowMult(a, row1, b, row2, 4);
00275 }
00276
00277
00278 for (int i = 2; i < n; i++) {
00279 a = -(Ap[5]);
00280 b = Ap[i*n+1];
00281 row1 = &(Ap[i*n]);
00282 row2 = &(Ap[4]);
00283 RowMult(a, row1, b, row2, 4);
00284 row1 = &(Bp[i*n]);
00285 row2 = &(Bp[4]);
00286 RowMult(a, row1, b, row2, 4);
00287 }
00288
00289
00290 a = -(Ap[10]);
00291 b = Ap[14];
00292 row1 = &(Ap[12]);
00293 row2 = &(Ap[8]);
00294 RowMult(a, row1, b, row2, 4);
00295 row1 = &(Bp[12]);
00296 row2 = &(Bp[8]);
00297 RowMult(a, row1, b, row2, 4);
00298
00299
00300
00301
00302 a = 1/(Ap[15]);
00303 row1 = &(Ap[12]);
00304 RowMult(a, row1, 0, row2, 4);
00305 row1 = &(Bp[12]);
00306 RowMult(a, row1, 0, row2, 4);
00307
00308
00309 for (int i = 0; i < n-1; i++) {
00310 a = -(Ap[15]);
00311 b = Ap[i*n+3];
00312 row1 = &(Ap[i*n]);
00313 row2 = &(Ap[12]);
00314 RowMult(a, row1, b, row2, 4);
00315 row1 = &(Bp[i*n]);
00316 row2 = &(Bp[12]);
00317 RowMult(a, row1, b, row2, 4);
00318 }
00319
00320
00321 a = 1/(Ap[10]);
00322 row1 = &(Ap[8]);
00323 RowMult(a, row1, 0, row2, 4);
00324 row1 = &(Bp[8]);
00325 RowMult(a, row1, 0, row2, 4);
00326
00327
00328 for (int i = 0; i < 2; i++) {
00329 a = -(Ap[10]);
00330 b = Ap[i*n+2];
00331 row1 = &(Ap[i*n]);
00332 row2 = &(Ap[8]);
00333 RowMult(a, row1, b, row2, 4);
00334 row1 = &(Bp[i*n]);
00335 row2 = &(Bp[8]);
00336 RowMult(a, row1, b, row2, 4);
00337 }
00338
00339
00340 a = 1/(Ap[5]);
00341 row1 = &(Ap[4]);
00342 RowMult(a, row1, 0, row2, n);
00343 row1 = &(Bp[4]);
00344 RowMult(a, row1, 0, row2, n);
00345
00346
00347 a = -(Ap[5]);
00348 b = Ap[1];
00349 row1 = &(Ap[0]);
00350 row2 = &(Ap[4]);
00351 RowMult(a, row1, b, row2, n);
00352 row1 = &(Bp[0]);
00353 row2 = &(Bp[4]);
00354 RowMult(a, row1, b, row2, n);
00355
00356
00357 a = 1/(Ap[0]);
00358 row1 = &(Ap[0]);
00359 RowMult(a, row1, 0, row2, n);
00360 row1 = &(Bp[0]);
00361 RowMult(a, row1, 0, row2, n);
00362 }
00363
00364 return Bp;
00365 }
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 double *M_InvertPos (double *B, const int n)
00377 {
00378 double sum;
00379 double p[n];
00380 double q[n];
00381 double inv[n][n];
00382 double *pp = NULL;
00383 double A[n][n],*C;
00384
00385
00386 if (M_Cholesky(B, pp, n)) {
00387
00388 C = B;
00389 for (int i = 0; i < n; i++) {
00390 p[i] = *q;
00391 for (int j = 0; j < n; j++ ) {
00392 A[i][j] = *C;
00393 C++;
00394 }
00395 }
00396
00397 for (int i = 0; i < n; i++) {
00398 A[i][i] = 1.0 / p[i];
00399 for (int j = i+1; j < n; j++) {
00400 sum = 0;
00401 for (int k = i; k < j; k++)
00402 sum -= A[j][k] * A[k][i];
00403 A[j][i] = sum / p[j];
00404 }
00405 }
00406
00407 for (int i = 0; i < n; i++) {
00408 for (int j = i; j < n; j++) {
00409 sum = 0;
00410 for (int k = j; k < n; k++)
00411 sum += A[k][i] * A[k][j];
00412 inv[i][j] = inv[j][i] = sum;
00413 }
00414 }
00415
00416 C = B;
00417 for (int i = 0; i < n; i++) {
00418 for (int j = 0; j < n; j++) {
00419 *C = inv[i][j];
00420 C++;
00421 }
00422 }
00423
00424 } else {
00425 B = 0;
00426 std::cout << "Cholesky decomposition failed!" << std::endl;
00427 }
00428
00429 C = B;
00430
00431 return B;
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443 double *M_A_times_b (double *y, const double *A, const int n, const int m, const double *b)
00444 {
00445 for (int i = 0; i < n; i++) {
00446 y[i] = 0;
00447 for (int j = 0; j < m; j++) {
00448 y[i] += A[i*n+j] * b[j];
00449 }
00450 }
00451 return y;
00452 }