00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <math.h>
00014 #include <string.h>
00015 #include <stdio.h>
00016
00017 #include "common.h"
00018
00019 #include "linear_algebra.h"
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00053 #define MATRIX_EPSILON (1e-60)
00054
00055
00056
00057 void dmtx_printf(double *mtx, u32 m, u32 n)
00058 {
00059 for (u32 i = 0; i < m; i++) {
00060 printf(" [% 12lf", mtx[i*n + 0]);
00061 for (u32 j = 1; j < n; j++)
00062 printf(" % 12lf", mtx[i*n + j]);
00063 printf("]\n");
00064 }
00065 }
00066
00067
00068
00069
00097 s32 qrdecomp(const double *a, u32 rows, u32 cols, double *qt, double *r) {
00098 s32 sing = 0;
00099 u32 i, j, k;
00100
00101 double c[cols], d[cols];
00102 double scale, sigma, sum, tau;
00103
00104 memcpy(r, a, rows*cols * sizeof(*r));
00105
00106 for (k = 0; k < cols; k++) {
00107 if (k > cols-1) printf("%d: k (%u) > cols - 1 (%u)\n",
00108 __LINE__, (unsigned int) k, (unsigned int) cols - 1);
00109
00110 scale = 0.0;
00111
00112 for (i = k; i < rows; i++) scale = fmax(scale, fabs(r[i*cols + k]));
00113
00114 if (fabs(scale) < MATRIX_EPSILON) {
00115 sing = -1;
00116 c[k] = d[k] = 0.0;
00117 printf("Column %u is singular to machine precision.\n", (unsigned int) k);
00118 } else {
00119
00120 for (i = k; i < rows; i++) r[i*cols + k] /= scale;
00121
00122 for (sum = 0.0, i = k; i < rows; i++) sum += r[i*cols + k]*r[i*cols + k];
00123
00124
00125
00126 sigma = copysign(sqrt(sum), r[k*cols + k]);
00127 r[k*cols + k] += sigma;
00128
00129 c[k] = sigma * r[k*cols + k];
00130 d[k] = -scale * sigma;
00131 printf("d[%u] = %lf\n", (unsigned int) k, d[k]);
00132 for (j = k + 1; j < cols; j++) {
00133 if (j > cols-1) printf("%d: j (%u) > cols - 1 (%u)\n",
00134 __LINE__, (unsigned int) j,
00135 (unsigned int) cols - 1);
00136
00137
00138 for (sum = 0.0, i = k; i < rows; i++) sum += r[i*cols + k]*r[i*cols + j];
00139 tau = sum / c[k];
00140 for (i = k; i < rows; i++) r[i*cols + j] -= tau*r[i*cols + k];
00141 }
00142 }
00143 }
00144 VEC_PRINTF(d, cols);
00145 VEC_PRINTF(c, cols);
00146 MAT_PRINTF(r, rows, cols);
00147
00148
00149 printf("bottom corner: r[%u] = d[%u] = %lf\n",
00150 (unsigned int) ((rows - 1)*cols + cols - 1),
00151 (unsigned int) (cols - 1), r[(rows - 1)*cols + cols - 1]);
00152
00153
00154 if (fabs(d[cols - 1]) < MATRIX_EPSILON) sing = -1;
00155
00156 for (i = 0; i < rows; i++) {
00157 for (j = 0; j < rows; j++) qt[i*rows + j] = 0.0;
00158 qt[i*rows + i] = 1.0;
00159 }
00160 for (k = 0; k < cols; k++) {
00161 if (k > cols-1) printf("%d: k (%u) > cols - 1 (%u)\n",
00162 __LINE__, (unsigned int) k, (unsigned int) cols - 1);
00163
00164 if (fabs(c[k]) > MATRIX_EPSILON)
00165
00166 for (j = 0; j < rows; j++) {
00167
00168 sum = 0.0;
00169 for (i = k; i < rows; i++) sum += r[i*cols + k]*qt[i*rows + j];
00170 sum /= c[k];
00171 for (i = k; i < rows; i++) qt[i*rows + j] -= sum*r[i*cols + k];
00172 }
00173 MAT_PRINTF(qt, rows, rows);
00174 }
00175 for (i = 0; i < cols; i++) {
00176 if (i > cols-1) printf("%d: i (%u) > cols - 1 (%u)\n",
00177 __LINE__, (unsigned int) i, (unsigned int) cols - 1);
00178
00179 r[i*cols + i] = d[i];
00180 printf("r[%u] = d[%u] = %lf\n", (unsigned int) (i*cols + i),
00181 (unsigned int) i, r[i*cols+i]);
00182 }
00183 for (i = 0; i < rows; i++)
00184
00185 for (j = 0; j < i && j < cols; j++) {
00186 if (j > cols-1) printf("%d: j (%u) > cols - 1 (%u)\n",
00187 __LINE__, (unsigned int) j,
00188 (unsigned int) cols - 1);
00189
00190 r[i*cols + j] = 0.0;
00191 }
00192 return sing;
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00251 s32 qrdecomp_square(const double *a, u32 rows, double *qt, double *r) {
00252 s32 sing = 0;
00253 u32 i, j, k;
00254
00255 double c[rows], d[rows];
00256 double scale, sigma, sum, tau;
00257 memcpy(r, a, rows*rows * sizeof(*r));
00258
00259 for (k = 0; k < rows - 1; k++) {
00260 scale = 0.0;
00261 for (i = k; i < rows; i++) scale = fmax(scale, fabs(r[i*rows + k]));
00262 if (scale == 0.0) {
00263 sing = -11;
00264 c[k] = d[k] = 0.0;
00265 } else {
00266 for (i = k; i < rows; i++) r[i*rows + k] /= scale;
00267 for (sum = 0.0, i = k; i < rows; i++) sum += r[i*rows + k]*r[i*rows + k];
00268 sigma = copysign(sqrt(sum), r[k*rows+k]);
00269 r[k*rows + k] += sigma;
00270 c[k] = sigma * r[k*rows + k];
00271 d[k] = -scale * sigma;
00272 for (j = k + 1; j < rows; j++) {
00273 for (sum = 0.0, i = k; i < rows; i++) sum += r[i*rows + k]*r[i*rows+j];
00274 tau = sum / c[k];
00275 for (i = k; i < rows; i++) r[i*rows + j] -= tau*r[i*rows + k];
00276 }
00277 }
00278 }
00279 d[rows - 1] = r[(rows - 1)*rows + rows - 1];
00280 if (d[rows - 1] == 0.0) sing = -11;
00281 for (i = 0; i < rows; i++) {
00282 for (j = 0; j < rows; j++) qt[i*rows + j] = 0.0;
00283 qt[i*rows + i] = 1.0;
00284 }
00285 for (k = 0; k < rows - 1; k++) {
00286 if (c[k] != 0.0)
00287 for (j = 0; j < rows; j++) {
00288 sum = 0.0;
00289 for (i = k; i < rows; i++) sum += r[i*rows + k]*qt[i*rows + j];
00290 sum /= c[k];
00291 for (i = k; i < rows; i++) qt[i*rows + j] -= sum*r[i*rows + k];
00292 }
00293 }
00294 for (i = 0; i < rows; i++) {
00295 r[i*rows + i] = d[i];
00296 for (j = 0; j < i; j++) r[i*rows + j] = 0.0;
00297 }
00298 return sing;
00299 }
00300
00311 void qtmult(const double *qt, u32 n, const double *b, double *x) {
00312 u32 i, j;
00313 double sum;
00314 for (i = 0; i < n; i++) {
00315 sum = 0.0;
00316 for (j = 0; j < n; j++) sum += qt[i*n + j]*b[j];
00317 x[i] = sum;
00318 }
00319 }
00320
00335 void rsolve(const double *r, u32 rows, u32 cols, const double *b, double *x) {
00336 s32 i, j;
00337 double sum;
00338 for (i = rows - 1; i >= 0; i--) {
00339 sum = b[i];
00340 for (j = i + 1; j < (int) rows; j++) sum -= r[i*cols + j]*x[j];
00341 x[i] = sum / r[i*cols + i];
00342 }
00343 }
00344
00359 s32 qrsolve(const double *a, u32 rows, u32 cols, const double *b, double *x) {
00360 double qt[rows * rows], r[rows * cols];
00361 s32 sing = qrdecomp_square(a, rows, qt, r);
00362 if (sing != 0) return sing;
00363 qtmult(qt, rows, b, x);
00364 rsolve(r, rows, cols, x, x);
00365 return sing;
00366 }
00367
00368
00369
00378 static inline int inv2(const double *a, double *b) {
00379 double det = a[0]*a[3] - a[1]*a[2];
00380 if (fabs(det) < MATRIX_EPSILON)
00381 return -1;
00382 b[0] = a[3]/det;
00383 b[1] = -a[1]/det;
00384 b[2] = -a[2]/det;
00385 b[3] = a[0]/det;
00386 return 0;
00387 }
00388
00397 static inline int inv3(const double *a, double *b) {
00398 double det = ((a[3*1 + 0]*-(a[3*0 + 1]*a[3*2 + 2]-a[3*0 + 2]*a[3*2 + 1])
00399 +a[3*1 + 1]*(a[3*0 + 0]*a[3*2 + 2]-a[3*0 + 2]*a[3*2 + 0]))
00400 +a[3*1 + 2]*-(a[3*0 + 0]*a[3*2 + 1]-a[3*0 + 1]*a[3*2 + 0]));
00401
00402 if (fabs(det) < MATRIX_EPSILON)
00403 return -1;
00404
00405 b[3*0 + 0] = (a[3*1 + 1]*a[3*2 + 2]-a[3*1 + 2]*a[3*2 + 1])/det;
00406 b[3*1 + 0] = -(a[3*1 + 0]*a[3*2 + 2]-a[3*1 + 2]*a[3*2 + 0])/det;
00407 b[3*2 + 0] = (a[3*1 + 0]*a[3*2 + 1]-a[3*1 + 1]*a[3*2 + 0])/det;
00408
00409 b[3*0 + 1] = -(a[3*0 + 1]*a[3*2 + 2]-a[3*0 + 2]*a[3*2 + 1])/det;
00410 b[3*1 + 1] = (a[3*0 + 0]*a[3*2 + 2]-a[3*0 + 2]*a[3*2 + 0])/det;
00411 b[3*2 + 1] = -(a[3*0 + 0]*a[3*2 + 1]-a[3*0 + 1]*a[3*2 + 0])/det;
00412
00413 b[3*0 + 2] = (a[3*0 + 1]*a[3*1 + 2]-a[3*0 + 2]*a[3*1 + 1])/det;
00414 b[3*1 + 2] = -(a[3*0 + 0]*a[3*1 + 2]-a[3*0 + 2]*a[3*1 + 0])/det;
00415 b[3*2 + 2] = (a[3*0 + 0]*a[3*1 + 1]-a[3*0 + 1]*a[3*1 + 0])/det;
00416
00417 return 0;
00418 }
00419
00428 static inline int inv4(const double *a, double *b) {
00429 double det = (((a[4*1 + 0]*-((a[4*2 + 1]*-(a[4*0 + 2]*a[4*3 + 3]-a[4*0 + 3]*a[4*3 + 2])+a[4*2 + 2]*(a[4*0 + 1]*a[4*3 + 3]-a[4*0 + 3]*a[4*3 + 1]))+a[4*2 + 3]*-(a[4*0 + 1]*a[4*3 + 2]-a[4*0 + 2]*a[4*3 + 1]))+a[4*1 + 1]*((a[4*2 + 0]*-(a[4*0 + 2]*a[4*3 + 3]-a[4*0 + 3]*a[4*3 + 2])+a[4*2 + 2]*(a[4*0 + 0]*a[4*3 + 3]-a[4*0 + 3]*a[4*3 + 0]))+a[4*2 + 3]*-(a[4*0 + 0]*a[4*3 + 2]-a[4*0 + 2]*a[4*3 + 0])))+a[4*1 + 2]*-((a[4*2 + 0]*-(a[4*0 + 1]*a[4*3 + 3]-a[4*0 + 3]*a[4*3 + 1])+a[4*2 + 1]*(a[4*0 + 0]*a[4*3 + 3]-a[4*0 + 3]*a[4*3 + 0]))+a[4*2 + 3]*-(a[4*0 + 0]*a[4*3 + 1]-a[4*0 + 1]*a[4*3 + 0])))+a[4*1 + 3]*((a[4*2 + 0]*-(a[4*0 + 1]*a[4*3 + 2]-a[4*0 + 2]*a[4*3 + 1])+a[4*2 + 1]*(a[4*0 + 0]*a[4*3 + 2]-a[4*0 + 2]*a[4*3 + 0]))+a[4*2 + 2]*-(a[4*0 + 0]*a[4*3 + 1]-a[4*0 + 1]*a[4*3 + 0])));
00430
00431 if (fabs(det) < MATRIX_EPSILON)
00432 return -1;
00433
00434 b[4*0 + 0] = ((a[4*2 + 1]*-(a[4*1 + 2]*a[4*3 + 3]-a[4*1 + 3]*a[4*3 + 2])+a[4*2 + 2]*(a[4*1 + 1]*a[4*3 + 3]-a[4*1 + 3]*a[4*3 + 1]))+a[4*2 + 3]*-(a[4*1 + 1]*a[4*3 + 2]-a[4*1 + 2]*a[4*3 + 1]))/det;
00435 b[4*1 + 0] = -((a[4*2 + 0]*-(a[4*1 + 2]*a[4*3 + 3]-a[4*1 + 3]*a[4*3 + 2])+a[4*2 + 2]*(a[4*1 + 0]*a[4*3 + 3]-a[4*1 + 3]*a[4*3 + 0]))+a[4*2 + 3]*-(a[4*1 + 0]*a[4*3 + 2]-a[4*1 + 2]*a[4*3 + 0]))/det;
00436 b[4*2 + 0] = ((a[4*2 + 0]*-(a[4*1 + 1]*a[4*3 + 3]-a[4*1 + 3]*a[4*3 + 1])+a[4*2 + 1]*(a[4*1 + 0]*a[4*3 + 3]-a[4*1 + 3]*a[4*3 + 0]))+a[4*2 + 3]*-(a[4*1 + 0]*a[4*3 + 1]-a[4*1 + 1]*a[4*3 + 0]))/det;
00437 b[4*3 + 0] = -((a[4*2 + 0]*-(a[4*1 + 1]*a[4*3 + 2]-a[4*1 + 2]*a[4*3 + 1])+a[4*2 + 1]*(a[4*1 + 0]*a[4*3 + 2]-a[4*1 + 2]*a[4*3 + 0]))+a[4*2 + 2]*-(a[4*1 + 0]*a[4*3 + 1]-a[4*1 + 1]*a[4*3 + 0]))/det;
00438
00439 b[4*0 + 1] = -((a[4*2 + 1]*-(a[4*0 + 2]*a[4*3 + 3]-a[4*0 + 3]*a[4*3 + 2])+a[4*2 + 2]*(a[4*0 + 1]*a[4*3 + 3]-a[4*0 + 3]*a[4*3 + 1]))+a[4*2 + 3]*-(a[4*0 + 1]*a[4*3 + 2]-a[4*0 + 2]*a[4*3 + 1]))/det;
00440 b[4*1 + 1] = ((a[4*2 + 0]*-(a[4*0 + 2]*a[4*3 + 3]-a[4*0 + 3]*a[4*3 + 2])+a[4*2 + 2]*(a[4*0 + 0]*a[4*3 + 3]-a[4*0 + 3]*a[4*3 + 0]))+a[4*2 + 3]*-(a[4*0 + 0]*a[4*3 + 2]-a[4*0 + 2]*a[4*3 + 0]))/det;
00441 b[4*2 + 1] = -((a[4*2 + 0]*-(a[4*0 + 1]*a[4*3 + 3]-a[4*0 + 3]*a[4*3 + 1])+a[4*2 + 1]*(a[4*0 + 0]*a[4*3 + 3]-a[4*0 + 3]*a[4*3 + 0]))+a[4*2 + 3]*-(a[4*0 + 0]*a[4*3 + 1]-a[4*0 + 1]*a[4*3 + 0]))/det;
00442 b[4*3 + 1] = ((a[4*2 + 0]*-(a[4*0 + 1]*a[4*3 + 2]-a[4*0 + 2]*a[4*3 + 1])+a[4*2 + 1]*(a[4*0 + 0]*a[4*3 + 2]-a[4*0 + 2]*a[4*3 + 0]))+a[4*2 + 2]*-(a[4*0 + 0]*a[4*3 + 1]-a[4*0 + 1]*a[4*3 + 0]))/det;
00443
00444 b[4*0 + 2] = ((a[4*1 + 1]*-(a[4*0 + 2]*a[4*3 + 3]-a[4*0 + 3]*a[4*3 + 2])+a[4*1 + 2]*(a[4*0 + 1]*a[4*3 + 3]-a[4*0 + 3]*a[4*3 + 1]))+a[4*1 + 3]*-(a[4*0 + 1]*a[4*3 + 2]-a[4*0 + 2]*a[4*3 + 1]))/det;
00445 b[4*1 + 2] = -((a[4*1 + 0]*-(a[4*0 + 2]*a[4*3 + 3]-a[4*0 + 3]*a[4*3 + 2])+a[4*1 + 2]*(a[4*0 + 0]*a[4*3 + 3]-a[4*0 + 3]*a[4*3 + 0]))+a[4*1 + 3]*-(a[4*0 + 0]*a[4*3 + 2]-a[4*0 + 2]*a[4*3 + 0]))/det;
00446 b[4*2 + 2] = ((a[4*1 + 0]*-(a[4*0 + 1]*a[4*3 + 3]-a[4*0 + 3]*a[4*3 + 1])+a[4*1 + 1]*(a[4*0 + 0]*a[4*3 + 3]-a[4*0 + 3]*a[4*3 + 0]))+a[4*1 + 3]*-(a[4*0 + 0]*a[4*3 + 1]-a[4*0 + 1]*a[4*3 + 0]))/det;
00447 b[4*3 + 2] = -((a[4*1 + 0]*-(a[4*0 + 1]*a[4*3 + 2]-a[4*0 + 2]*a[4*3 + 1])+a[4*1 + 1]*(a[4*0 + 0]*a[4*3 + 2]-a[4*0 + 2]*a[4*3 + 0]))+a[4*1 + 2]*-(a[4*0 + 0]*a[4*3 + 1]-a[4*0 + 1]*a[4*3 + 0]))/det;
00448
00449 b[4*0 + 3] = -((a[4*1 + 1]*-(a[4*0 + 2]*a[4*2 + 3]-a[4*0 + 3]*a[4*2 + 2])+a[4*1 + 2]*(a[4*0 + 1]*a[4*2 + 3]-a[4*0 + 3]*a[4*2 + 1]))+a[4*1 + 3]*-(a[4*0 + 1]*a[4*2 + 2]-a[4*0 + 2]*a[4*2 + 1]))/det;
00450 b[4*1 + 3] = ((a[4*1 + 0]*-(a[4*0 + 2]*a[4*2 + 3]-a[4*0 + 3]*a[4*2 + 2])+a[4*1 + 2]*(a[4*0 + 0]*a[4*2 + 3]-a[4*0 + 3]*a[4*2 + 0]))+a[4*1 + 3]*-(a[4*0 + 0]*a[4*2 + 2]-a[4*0 + 2]*a[4*2 + 0]))/det;
00451 b[4*2 + 3] = -((a[4*1 + 0]*-(a[4*0 + 1]*a[4*2 + 3]-a[4*0 + 3]*a[4*2 + 1])+a[4*1 + 1]*(a[4*0 + 0]*a[4*2 + 3]-a[4*0 + 3]*a[4*2 + 0]))+a[4*1 + 3]*-(a[4*0 + 0]*a[4*2 + 1]-a[4*0 + 1]*a[4*2 + 0]))/det;
00452 b[4*3 + 3] = ((a[4*1 + 0]*-(a[4*0 + 1]*a[4*2 + 2]-a[4*0 + 2]*a[4*2 + 1])+a[4*1 + 1]*(a[4*0 + 0]*a[4*2 + 2]-a[4*0 + 2]*a[4*2 + 0]))+a[4*1 + 2]*-(a[4*0 + 0]*a[4*2 + 1]-a[4*0 + 1]*a[4*2 + 0]))/det;
00453
00454 return 0;
00455 }
00456
00457
00458
00459
00460
00461
00462 static void row_swap(double *a, double *b, u32 size) {
00463 double tmp;
00464 for (u32 i = 0; i < size; i++) {
00465 tmp = a[i];
00466 a[i] = b[i];
00467 b[i] = tmp;
00468 }
00469 }
00470
00471
00472
00473 static int rref(u32 order, u32 cols, double *m) {
00474 int i, j, k, maxrow;
00475 double tmp;
00476
00477 for (i = 0; i < (int) order; i++) {
00478 maxrow = i;
00479 for (j = i+1; j < (int) order; j++) {
00480
00481 if (fabs(m[j*cols+i]) > fabs(m[maxrow*cols+i]))
00482 maxrow = j;
00483 }
00484 row_swap(&m[i*cols], &m[maxrow*cols], cols);
00485 if (fabs(m[i*cols+i]) <= MATRIX_EPSILON) {
00486
00487
00488 return -1;
00489 }
00490 for (j = i+1; j < (int) order; j++) {
00491
00492 tmp = m[j*cols+i] / m[i*cols+i];
00493 for (k = i; k < (int) cols; k++) {
00494 m[j*cols+k] -= m[i*cols+k] * tmp;
00495 }
00496 }
00497 }
00498 for (i = order-1; i >= 0; i--) {
00499
00500 tmp = m[i*cols+i];
00501 for (j = 0; j < i; j++) {
00502 for (k = cols-1; k > i-1; k--) {
00503 m[j*cols+k] -= m[i*cols+k] * m[j*cols+i] / tmp;
00504 }
00505 }
00506 m[i*cols+i] /= tmp;
00507 for (j = order; j < (int) cols; j++) {
00508
00509 m[i*cols+j] /= tmp;
00510 }
00511 }
00512 return 0;
00513 }
00514
00528 inline int matrix_inverse(u32 n, const double *const a, double *b){
00529
00530
00531
00532
00533
00534
00535
00536 int res;
00537 u32 i, j, k, cols = n*2;
00538 double m[n*cols];
00539
00540
00541
00542
00543 switch (n) {
00544 case 2:
00545 return inv2(a, b);
00546 break;
00547 case 3:
00548 return inv3(a, b);
00549 break;
00550 case 4:
00551 return inv4(a, b);
00552 break;
00553 default:
00554
00555 for (i = 0; i < n; i++) {
00556 for (j = 0; j < cols; j++) {
00557 if (j >= n) {
00558 if (j-n == i) {
00559 m[i*cols+j] = 1.0;
00560 } else {
00561 m[i*cols+j] = 0;
00562 }
00563 } else {
00564 m[i*cols+j] = a[i*n+j];
00565 }
00566 }
00567 }
00568
00569 if ((res = rref(n, cols, m)) < 0) {
00570
00571 return res;
00572 }
00573
00574
00575 for (i = 0; i < n; i++) {
00576 for (j = n, k = 0; j < cols; j++, k++) {
00577 b[i*n+k] = m[i*cols+j];
00578 }
00579 }
00580
00581 return 0;
00582 break;
00583 }
00584 }
00585
00616 int matrix_pseudoinverse(u32 n, u32 m, const double *a, double *b) {
00617 if (n == m)
00618 return matrix_inverse(n, a, b);
00619 if (n > m)
00620 return matrix_ataiat(n, m, a, b);
00621 if (n < m)
00622 return matrix_ataati(n, m, a, b);
00623 return -1;
00624 }
00625
00641 inline int matrix_atwaiat(u32 n, u32 m, const double *a,
00642 const double *w, double *b) {
00643 u32 i, j, k;
00644 double c[m*m], inv[m*m];
00645
00646 if (n <= m) return -1;
00647
00648
00649
00650 for (i = 0; i < m; i++)
00651 for (j = i; j < m; j++) {
00652 c[m*i + j] = 0;
00653 if (i == j) {
00654
00655
00656 for (k = 0; k < n; k++)
00657 c[m*i + j] += w[k]*a[m*k + j]*a[m*k + j];
00658 } else {
00659
00660 for (k = 0; k < n; k++)
00661 c[m*i + j] = c[m*j + i] = w[k]*a[m*k + j]*a[m*k + i];
00662 c[m*j + i] = c[m*i + j];
00663 }
00664 }
00665 if (matrix_inverse(m, c, inv) < 0) return -1;
00666 for (i = 0; i < m; i++)
00667 for (j = 0; j < n; j++) {
00668 b[n*i + j] = 0;
00669 for (k = 0; k < m; k++)
00670 b[n*i + j] += inv[n*i+k] * a[m*j + k];
00671 }
00672 return 0;
00673 }
00674
00690 inline int matrix_atawati(u32 n, u32 m, const double *a,
00691 const double *w, double *b) {
00692 u32 i, j, k;
00693 double c[m*m], inv[m*m];
00694
00695 if (n <= m) return -1;
00696
00697
00698
00699
00700 for (i = 0; i < m; i++)
00701 for (j = i; j < m; j++) {
00702 c[m*i + j] = 0;
00703 if (i == j) {
00704
00705
00706 for (k = 0; k < n; k++)
00707 c[m*i + j] += w[k]*a[m*k + j]*a[m*k + j];
00708 } else {
00709
00710 for (k = 0; k < n; k++)
00711 c[m*i + j] = c[m*j + i] = w[k]*a[m*k + j]*a[m*k + i];
00712 c[m*j + i] = c[m*i + j];
00713 }
00714 }
00715 if (matrix_inverse(m, c, inv) < 0) return -1;
00716 for (i = 0; i < m; i++)
00717 for (j = 0; j < n; j++) {
00718 b[n*i + j] = 0;
00719 for (k = 0; k < m; k++)
00720 b[n*i + j] += inv[n*i+k] * a[m*j + k];
00721 }
00722 return 0;
00723 }
00724
00737 inline int matrix_ataiat(u32 n, u32 m, const double *a, double *b) {
00738 u32 i;
00739 double w[n];
00740 for (i = 0; i < n; i++) w[i] = 1;
00741 return matrix_atwaiat(n, m, a, w, b);
00742 }
00743
00756 inline int matrix_ataati(u32 n, u32 m, const double *a, double *b) {
00757 u32 i;
00758 double w[n];
00759 for (i = 0; i < n; i++) w[i] = 1;
00760 return matrix_atawati(n, m, a, w, b);
00761 }
00762
00776 inline void matrix_multiply(u32 n, u32 m, u32 p, const double *a,
00777 const double *b, double *c) {
00778 u32 i, j, k;
00779 for (i = 0; i < n; i++)
00780 for (j = 0; j < p; j++) {
00781 c[p*i + j] = 0;
00782 for (k = 0; k < m; k++)
00783 c[p*i + j] += a[m*i+k] * b[p*k + j];
00784 }
00785 }
00786
00797 void matrix_triu(u32 n, double *M)
00798 {
00799
00800
00801 for (u32 i=1; i<n; i++) {
00802 for (u32 j=0; j<i; j++) {
00803 M[i*n + j] = 0;
00804 }
00805 }
00806 }
00807
00815 void matrix_eye(u32 n, double *M)
00816 {
00817
00818
00819 memset(M, 0, n * n * sizeof(double));
00820 for (u32 i=0; i<n; i++) {
00821 M[i*n + i] = 1;
00822 }
00823 }
00824
00845 void matrix_udu(u32 n, double *M, double *U, double *D)
00846 {
00847
00848
00849
00850 double alpha, beta;
00851 matrix_triu(n, M);
00852 matrix_eye(n, U);
00853 memset(D, 0, n * sizeof(double));
00854
00855 for (u32 j=n; j>=2; j--) {
00856 D[j - 1] = M[(j-1)*n + j-1];
00857 if (D[j-1] != 0) {
00858 alpha = 1.0 / D[j-1];
00859 } else {
00860 alpha = 0.0;
00861 }
00862 for (u32 k=1; k<j; k++) {
00863 beta = M[(k-1)*n + j-1];
00864 U[(k-1)*n + j-1] = alpha * beta;
00865 for (u32 kk = 0; kk < k; kk++) {
00866 M[kk*n + k-1] = M[kk*n + k-1] - beta * U[kk*n + j-1];
00867 }
00868 }
00869 }
00870 D[0] = M[0];
00871 }
00872
00889 void matrix_reconstruct_udu(u32 n, double *U, double *D, double *M)
00890 {
00891 memset(M, 0, n * n * sizeof(double));
00892
00893 for (u32 i=0; i<n; i++) {
00894 for (u32 k=i; k<n; k++) {
00895 for (u32 j=k; j<n; j++) {
00896
00897
00898
00899
00900 M[i*n + k] += U[i*n +j] * D[j] * U[k*n + j];
00901 }
00902 M[k*n + i] = M[i*n + k];
00903 }
00904 }
00905 }
00906
00907
00920 void matrix_add_sc(u32 n, u32 m, const double *a,
00921 const double *b, double gamma, double *c) {
00922 u32 i, j;
00923 for (i = 0; i < n; i++)
00924 for (j = 0; j < m; j++)
00925 c[m*i + j] = a[m*i + j] + gamma * b[m*i + j];
00926 }
00927
00938 void matrix_transpose(u32 n, u32 m,
00939 const double *a, double *b) {
00940 u32 i, j;
00941 for (i = 0; i < n; i++)
00942 for (j = 0; j < m; j++)
00943 b[n*j+i] = a[m*i+j];
00944 }
00945
00955 void matrix_copy(u32 n, u32 m, const double *a,
00956 double *b) {
00957 u32 i, j;
00958 for (i = 0; i < n; i++)
00959 for (j = 0; j < m; j++)
00960 b[m*i+j] = a[m*i+j];
00961 }
00962
00963
00964
00980 double vector_dot(u32 n, const double *a,
00981 const double *b) {
00982 u32 i;
00983 double out = 0;
00984 for (i = 0; i < n; i++)
00985 out += a[i]*b[i];
00986 return out;
00987 }
00988
00998 double vector_norm(u32 n, const double *a) {
00999 u32 i;
01000 double out = 0;
01001 for (i = 0; i < n; i++)
01002 out += a[i]*a[i];
01003 return sqrt(out);
01004 }
01005
01014 double vector_mean(u32 n, const double *a) {
01015 u32 i;
01016 double out = 0;
01017 for (i = 0; i < n; i++)
01018 out += a[i];
01019 return out / n;
01020 }
01021
01029 void vector_normalize(u32 n, double *a) {
01030 u32 i;
01031 double norm = vector_norm(n, a);
01032 for (i = 0; i < n; i++)
01033 a[i] /= norm;
01034 }
01035
01047 void vector_add_sc(u32 n, const double *a,
01048 const double *b, double gamma,
01049 double *c) {
01050 u32 i;
01051 for (i = 0; i < n; i++)
01052 c[i] = a[i] + gamma * b[i];
01053 }
01054
01064 void vector_add(u32 n, const double *a,
01065 const double *b, double *c) {
01066 vector_add_sc(n, a, b, 1, c);
01067 }
01068
01078 void vector_subtract(u32 n, const double *a,
01079 const double *b, double *c) {
01080 vector_add_sc(n, a, b, -1, c);
01081 }
01082
01092 void vector_cross(const double a[3], const double b[3],
01093 double c[3]) {
01094 c[0] = a[1]*b[2] - a[2]*b[1];
01095 c[1] = a[2]*b[0] - a[0]*b[2];
01096 c[2] = a[0]*b[1] - a[1]*b[0];
01097 }
01098
01099
01100
01101