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 #define VEC_PRINTF(v, _n) { \
00022 printf("%s:%u <|%s| %lf", \
00023 __FILE__, __LINE__, #v, v[0]); \
00024 for (u32 _i = 1; _i < _n; _i++) printf(", %lf", v[_i]); \
00025 printf(">\n"); \
00026 }
00027
00028 #define MAT_PRINTF(m, _r, _c) { \
00029 printf("%s:%u <|%s|", \
00030 __FILE__, __LINE__, #m); \
00031 for (u32 _i = 0; _i < _r; _i++) { \
00032 printf(" [%lf", m[_i*_c + 0]); \
00033 for (u32 _j = 1; _j < _c; _j++) \
00034 printf(" %lf", m[_i*_c + _j]); \
00035 printf("]"); \
00036 if (_r > 2 && _i < _r - 1) printf("\n\t\t\t"); \
00037 } \
00038 printf(">\n"); \
00039 }
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00072 #define MATRIX_EPSILON (1e-11)
00073
00074
00075
00103 s32 qrdecomp(const double *a, u32 rows, u32 cols, double *qt, double *r) {
00104 s32 sing = 0;
00105 u32 i, j, k;
00106
00107 double c[cols], d[cols];
00108 double scale, sigma, sum, tau;
00109
00110 memcpy(r, a, rows*cols * sizeof(*r));
00111
00112 for (k = 0; k < cols; k++) {
00113 if (k > cols-1) printf("%d: k (%u) > cols - 1 (%u)\n",
00114 __LINE__, (unsigned int) k, (unsigned int) cols - 1);
00115
00116 scale = 0.0;
00117
00118 for (i = k; i < rows; i++) scale = fmax(scale, fabs(r[i*cols + k]));
00119
00120 if (fabs(scale) < MATRIX_EPSILON) {
00121 sing = -1;
00122 c[k] = d[k] = 0.0;
00123 printf("Column %u is singular to machine precision.\n", (unsigned int) k);
00124 } else {
00125
00126 for (i = k; i < rows; i++) r[i*cols + k] /= scale;
00127
00128 for (sum = 0.0, i = k; i < rows; i++) sum += r[i*cols + k]*r[i*cols + k];
00129
00130
00131
00132 sigma = copysign(sqrt(sum), r[k*cols + k]);
00133 r[k*cols + k] += sigma;
00134
00135 c[k] = sigma * r[k*cols + k];
00136 d[k] = -scale * sigma;
00137 printf("d[%u] = %lf\n", (unsigned int) k, d[k]);
00138 for (j = k + 1; j < cols; j++) {
00139 if (j > cols-1) printf("%d: j (%u) > cols - 1 (%u)\n",
00140 __LINE__, (unsigned int) j,
00141 (unsigned int) cols - 1);
00142
00143
00144 for (sum = 0.0, i = k; i < rows; i++) sum += r[i*cols + k]*r[i*cols + j];
00145 tau = sum / c[k];
00146 for (i = k; i < rows; i++) r[i*cols + j] -= tau*r[i*cols + k];
00147 }
00148 }
00149 }
00150 VEC_PRINTF(d, cols);
00151 VEC_PRINTF(c, cols);
00152 MAT_PRINTF(r, rows, cols);
00153
00154
00155 printf("bottom corner: r[%u] = d[%u] = %lf\n",
00156 (unsigned int) ((rows - 1)*cols + cols - 1),
00157 (unsigned int) (cols - 1), r[(rows - 1)*cols + cols - 1]);
00158
00159
00160 if (fabs(d[cols - 1]) < MATRIX_EPSILON) sing = -1;
00161
00162 for (i = 0; i < rows; i++) {
00163 for (j = 0; j < rows; j++) qt[i*rows + j] = 0.0;
00164 qt[i*rows + i] = 1.0;
00165 }
00166 for (k = 0; k < cols; k++) {
00167 if (k > cols-1) printf("%d: k (%u) > cols - 1 (%u)\n",
00168 __LINE__, (unsigned int) k, (unsigned int) cols - 1);
00169
00170 if (fabs(c[k]) > MATRIX_EPSILON)
00171
00172 for (j = 0; j < rows; j++) {
00173
00174 sum = 0.0;
00175 for (i = k; i < rows; i++) sum += r[i*cols + k]*qt[i*rows + j];
00176 sum /= c[k];
00177 for (i = k; i < rows; i++) qt[i*rows + j] -= sum*r[i*cols + k];
00178 }
00179 MAT_PRINTF(qt, rows, rows);
00180 }
00181 for (i = 0; i < cols; i++) {
00182 if (i > cols-1) printf("%d: i (%u) > cols - 1 (%u)\n",
00183 __LINE__, (unsigned int) i, (unsigned int) cols - 1);
00184
00185 r[i*cols + i] = d[i];
00186 printf("r[%u] = d[%u] = %lf\n", (unsigned int) (i*cols + i),
00187 (unsigned int) i, r[i*cols+i]);
00188 }
00189 for (i = 0; i < rows; i++)
00190
00191 for (j = 0; j < i && j < cols; j++) {
00192 if (j > cols-1) printf("%d: j (%u) > cols - 1 (%u)\n",
00193 __LINE__, (unsigned int) j,
00194 (unsigned int) cols - 1);
00195
00196 r[i*cols + j] = 0.0;
00197 }
00198 return sing;
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
00238
00239
00240
00241
00242
00243
00257 s32 qrdecomp_square(const double *a, u32 rows, double *qt, double *r) {
00258 s32 sing = 0;
00259 u32 i, j, k;
00260
00261 double c[rows], d[rows];
00262 double scale, sigma, sum, tau;
00263 memcpy(r, a, rows*rows * sizeof(*r));
00264
00265 for (k = 0; k < rows - 1; k++) {
00266 scale = 0.0;
00267 for (i = k; i < rows; i++) scale = fmax(scale, fabs(r[i*rows + k]));
00268 if (scale == 0.0) {
00269 sing = -11;
00270 c[k] = d[k] = 0.0;
00271 } else {
00272 for (i = k; i < rows; i++) r[i*rows + k] /= scale;
00273 for (sum = 0.0, i = k; i < rows; i++) sum += r[i*rows + k]*r[i*rows + k];
00274 sigma = copysign(sqrt(sum), r[k*rows+k]);
00275 r[k*rows + k] += sigma;
00276 c[k] = sigma * r[k*rows + k];
00277 d[k] = -scale * sigma;
00278 for (j = k + 1; j < rows; j++) {
00279 for (sum = 0.0, i = k; i < rows; i++) sum += r[i*rows + k]*r[i*rows+j];
00280 tau = sum / c[k];
00281 for (i = k; i < rows; i++) r[i*rows + j] -= tau*r[i*rows + k];
00282 }
00283 }
00284 }
00285 d[rows - 1] = r[(rows - 1)*rows + rows - 1];
00286 if (d[rows - 1] == 0.0) sing = -11;
00287 for (i = 0; i < rows; i++) {
00288 for (j = 0; j < rows; j++) qt[i*rows + j] = 0.0;
00289 qt[i*rows + i] = 1.0;
00290 }
00291 for (k = 0; k < rows - 1; k++) {
00292 if (c[k] != 0.0)
00293 for (j = 0; j < rows; j++) {
00294 sum = 0.0;
00295 for (i = k; i < rows; i++) sum += r[i*rows + k]*qt[i*rows + j];
00296 sum /= c[k];
00297 for (i = k; i < rows; i++) qt[i*rows + j] -= sum*r[i*rows + k];
00298 }
00299 }
00300 for (i = 0; i < rows; i++) {
00301 r[i*rows + i] = d[i];
00302 for (j = 0; j < i; j++) r[i*rows + j] = 0.0;
00303 }
00304 return sing;
00305 }
00306
00317 void qtmult(const double *qt, u32 n, const double *b, double *x) {
00318 u32 i, j;
00319 double sum;
00320 for (i = 0; i < n; i++) {
00321 sum = 0.0;
00322 for (j = 0; j < n; j++) sum += qt[i*n + j]*b[j];
00323 x[i] = sum;
00324 }
00325 }
00326
00341 void rsolve(const double *r, u32 rows, u32 cols, const double *b, double *x) {
00342 s32 i, j;
00343 double sum;
00344 for (i = rows - 1; i >= 0; i--) {
00345 sum = b[i];
00346 for (j = i + 1; j < (int) rows; j++) sum -= r[i*cols + j]*x[j];
00347 x[i] = sum / r[i*cols + i];
00348 }
00349 }
00350
00365 s32 qrsolve(const double *a, u32 rows, u32 cols, const double *b, double *x) {
00366 double qt[rows * rows], r[rows * cols];
00367 s32 sing = qrdecomp_square(a, rows, qt, r);
00368 if (sing != 0) return sing;
00369 qtmult(qt, rows, b, x);
00370 rsolve(r, rows, cols, x, x);
00371 return sing;
00372 }
00373
00374
00375
00384 static inline int inv2(const double *a, double *b) {
00385 double det = a[0]*a[3] - a[1]*a[2];
00386 if (det < MATRIX_EPSILON)
00387 return -1;
00388 b[0] = a[3]/det;
00389 b[1] = -a[1]/det;
00390 b[2] = -a[2]/det;
00391 b[3] = a[0]/det;
00392 return 0;
00393 }
00394
00403 static inline int inv3(const double *a, double *b) {
00404 double det = ((a[3*1 + 0]*-(a[3*0 + 1]*a[3*2 + 2]-a[3*0 + 2]*a[3*2 + 1])
00405 +a[3*1 + 1]*(a[3*0 + 0]*a[3*2 + 2]-a[3*0 + 2]*a[3*2 + 0]))
00406 +a[3*1 + 2]*-(a[3*0 + 0]*a[3*2 + 1]-a[3*0 + 1]*a[3*2 + 0]));
00407
00408 if (det < MATRIX_EPSILON)
00409 return -1;
00410
00411 b[3*0 + 0] = (a[3*1 + 1]*a[3*2 + 2]-a[3*1 + 2]*a[3*2 + 1])/det;
00412 b[3*1 + 0] = -(a[3*1 + 0]*a[3*2 + 2]-a[3*1 + 2]*a[3*2 + 0])/det;
00413 b[3*2 + 0] = (a[3*1 + 0]*a[3*2 + 1]-a[3*1 + 1]*a[3*2 + 0])/det;
00414
00415 b[3*0 + 1] = -(a[3*0 + 1]*a[3*2 + 2]-a[3*0 + 2]*a[3*2 + 1])/det;
00416 b[3*1 + 1] = (a[3*0 + 0]*a[3*2 + 2]-a[3*0 + 2]*a[3*2 + 0])/det;
00417 b[3*2 + 1] = -(a[3*0 + 0]*a[3*2 + 1]-a[3*0 + 1]*a[3*2 + 0])/det;
00418
00419 b[3*0 + 2] = (a[3*0 + 1]*a[3*1 + 2]-a[3*0 + 2]*a[3*1 + 1])/det;
00420 b[3*1 + 2] = -(a[3*0 + 0]*a[3*1 + 2]-a[3*0 + 2]*a[3*1 + 0])/det;
00421 b[3*2 + 2] = (a[3*0 + 0]*a[3*1 + 1]-a[3*0 + 1]*a[3*1 + 0])/det;
00422
00423 return 0;
00424 }
00425
00434 static inline int inv4(const double *a, double *b) {
00435 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])));
00436
00437 if (det < MATRIX_EPSILON)
00438 return -1;
00439
00440 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;
00441 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;
00442 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;
00443 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;
00444
00445 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;
00446 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;
00447 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;
00448 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;
00449
00450 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;
00451 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;
00452 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;
00453 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;
00454
00455 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;
00456 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;
00457 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;
00458 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;
00459
00460 return 0;
00461 }
00462
00463
00464
00465
00466
00467
00468 static void row_swap(double *a, double *b, u32 size) {
00469 double tmp;
00470 for (u32 i = 0; i < size; i++) {
00471 tmp = a[i];
00472 a[i] = b[i];
00473 b[i] = tmp;
00474 }
00475 }
00476
00477
00478
00479 static int rref(u32 order, u32 cols, double *m) {
00480 int i, j, k, maxrow;
00481 double tmp;
00482
00483 for (i = 0; i < (int) order; i++) {
00484 maxrow = i;
00485 for (j = i+1; j < (int) order; j++) {
00486
00487 if (fabs(m[j*cols+i]) > fabs(m[maxrow*cols+i]))
00488 maxrow = j;
00489 }
00490 row_swap(&m[i*cols], &m[maxrow*cols], cols);
00491 if (fabs(m[i*cols+i]) <= MATRIX_EPSILON) {
00492
00493
00494 return -1;
00495 }
00496 for (j = i+1; j < (int) order; j++) {
00497
00498 tmp = m[j*cols+i] / m[i*cols+i];
00499 for (k = i; k < (int) cols; k++) {
00500 m[j*cols+k] -= m[i*cols+k] * tmp;
00501 }
00502 }
00503 }
00504 for (i = order-1; i >= 0; i--) {
00505
00506 tmp = m[i*cols+i];
00507 for (j = 0; j < i; j++) {
00508 for (k = cols-1; k > i-1; k--) {
00509 m[j*cols+k] -= m[i*cols+k] * m[j*cols+i] / tmp;
00510 }
00511 }
00512 m[i*cols+i] /= tmp;
00513 for (j = order; j < (int) cols; j++) {
00514
00515 m[i*cols+j] /= tmp;
00516 }
00517 }
00518 return 0;
00519 }
00520
00534 inline int matrix_inverse(u32 n, const double const *a, double *b) {
00535
00536
00537
00538
00539
00540
00541
00542 int res;
00543 u32 i, j, k, cols = n*2;
00544 double m[n*cols];
00545
00546
00547
00548
00549 switch (n) {
00550 case 2:
00551 return inv2(a, b);
00552 break;
00553 case 3:
00554 return inv3(a, b);
00555 break;
00556 case 4:
00557 return inv4(a, b);
00558 break;
00559 default:
00560
00561 for (i = 0; i < n; i++) {
00562 for (j = 0; j < cols; j++) {
00563 if (j >= n) {
00564 if (j-n == i) {
00565 m[i*cols+j] = 1.0;
00566 } else {
00567 m[i*cols+j] = 0;
00568 }
00569 } else {
00570 m[i*cols+j] = a[i*n+j];
00571 }
00572 }
00573 }
00574
00575 if ((res = rref(n, cols, m)) < 0) {
00576
00577 return res;
00578 }
00579
00580
00581 for (i = 0; i < n; i++) {
00582 for (j = n, k = 0; j < cols; j++, k++) {
00583 b[i*n+k] = m[i*cols+j];
00584 }
00585 }
00586
00587 return 0;
00588 break;
00589 }
00590 }
00591
00622 int matrix_pseudoinverse(u32 n, u32 m, const double *a, double *b) {
00623 if (n == m)
00624 return matrix_inverse(n, a, b);
00625 if (n > m)
00626 return matrix_ataiat(n, m, a, b);
00627 if (n < m)
00628 return matrix_ataati(n, m, a, b);
00629 return -1;
00630 }
00631
00647 inline int matrix_atwaiat(u32 n, u32 m, const double *a,
00648 const double *w, double *b) {
00649 u32 i, j, k;
00650 double c[m*m], inv[m*m];
00651
00652 if (n <= m) return -1;
00653
00654
00655
00656 for (i = 0; i < m; i++)
00657 for (j = i; j < m; j++) {
00658 c[m*i + j] = 0;
00659 if (i == j) {
00660
00661
00662 for (k = 0; k < n; k++)
00663 c[m*i + j] += w[k]*a[m*k + j]*a[m*k + j];
00664 } else {
00665
00666 for (k = 0; k < n; k++)
00667 c[m*i + j] = c[m*j + i] = w[k]*a[m*k + j]*a[m*k + i];
00668 c[m*j + i] = c[m*i + j];
00669 }
00670 }
00671 if (matrix_inverse(m, c, inv) < 0) return -1;
00672 for (i = 0; i < m; i++)
00673 for (j = 0; j < n; j++) {
00674 b[n*i + j] = 0;
00675 for (k = 0; k < m; k++)
00676 b[n*i + j] += inv[n*i+k] * a[m*j + k];
00677 }
00678 return 0;
00679 }
00680
00696 inline int matrix_atawati(u32 n, u32 m, const double *a,
00697 const double *w, double *b) {
00698 u32 i, j, k;
00699 double c[m*m], inv[m*m];
00700
00701 if (n <= m) return -1;
00702
00703
00704
00705
00706 for (i = 0; i < m; i++)
00707 for (j = i; j < m; j++) {
00708 c[m*i + j] = 0;
00709 if (i == j) {
00710
00711
00712 for (k = 0; k < n; k++)
00713 c[m*i + j] += w[k]*a[m*k + j]*a[m*k + j];
00714 } else {
00715
00716 for (k = 0; k < n; k++)
00717 c[m*i + j] = c[m*j + i] = w[k]*a[m*k + j]*a[m*k + i];
00718 c[m*j + i] = c[m*i + j];
00719 }
00720 }
00721 if (matrix_inverse(m, c, inv) < 0) return -1;
00722 for (i = 0; i < m; i++)
00723 for (j = 0; j < n; j++) {
00724 b[n*i + j] = 0;
00725 for (k = 0; k < m; k++)
00726 b[n*i + j] += inv[n*i+k] * a[m*j + k];
00727 }
00728 return 0;
00729 }
00730
00743 inline int matrix_ataiat(u32 n, u32 m, const double *a, double *b) {
00744 u32 i;
00745 double w[n];
00746 for (i = 0; i < n; i++) w[i] = 1;
00747 return matrix_atwaiat(n, m, a, w, b);
00748 }
00749
00762 inline int matrix_ataati(u32 n, u32 m, const double *a, double *b) {
00763 u32 i;
00764 double w[n];
00765 for (i = 0; i < n; i++) w[i] = 1;
00766 return matrix_atawati(n, m, a, w, b);
00767 }
00768
00782 inline void matrix_multiply(u32 n, u32 m, u32 p, const double *a,
00783 const double *b, double *c) {
00784 u32 i, j, k;
00785 for (i = 0; i < n; i++)
00786 for (j = 0; j < p; j++) {
00787 c[p*i + j] = 0;
00788 for (k = 0; k < m; k++)
00789 c[p*i + j] += a[m*i+k] * b[p*k + j];
00790 }
00791 }
00792
00805 void matrix_add_sc(u32 n, u32 m, const double *a,
00806 const double *b, double gamma, double *c) {
00807 u32 i, j;
00808 for (i = 0; i < n; i++)
00809 for (j = 0; j < m; j++)
00810 c[m*i + j] = a[m*i + j] + gamma * b[m*i + j];
00811 }
00812
00823 void matrix_transpose(u32 n, u32 m,
00824 const double *a, double *b) {
00825 u32 i, j;
00826 for (i = 0; i < n; i++)
00827 for (j = 0; j < m; j++)
00828 b[n*j+i] = a[m*i+j];
00829 }
00830
00840 void matrix_copy(u32 n, u32 m, const double *a,
00841 double *b) {
00842 u32 i, j;
00843 for (i = 0; i < n; i++)
00844 for (j = 0; j < m; j++)
00845 b[m*i+j] = a[m*i+j];
00846 }
00847
00848
00849
00865 double vector_dot(u32 n, const double *a,
00866 const double *b) {
00867 u32 i;
00868 double out = 0;
00869 for (i = 0; i < n; i++)
00870 out += a[i]*b[i];
00871 return out;
00872 }
00873
00883 double vector_norm(u32 n, const double *a) {
00884 u32 i;
00885 double out = 0;
00886 for (i = 0; i < n; i++)
00887 out += a[i]*a[i];
00888 return sqrt(out);
00889 }
00890
00899 double vector_mean(u32 n, const double *a) {
00900 u32 i;
00901 double out = 0;
00902 for (i = 0; i < n; i++)
00903 out += a[i];
00904 return out / n;
00905 }
00906
00914 void vector_normalize(u32 n, double *a) {
00915 u32 i;
00916 double norm = vector_norm(n, a);
00917 for (i = 0; i < n; i++)
00918 a[i] /= norm;
00919 }
00920
00932 void vector_add_sc(u32 n, const double *a,
00933 const double *b, double gamma,
00934 double *c) {
00935 u32 i;
00936 for (i = 0; i < n; i++)
00937 c[i] = a[i] + gamma * b[i];
00938 }
00939
00949 void vector_add(u32 n, const double *a,
00950 const double *b, double *c) {
00951 vector_add_sc(n, a, b, 1, c);
00952 }
00953
00963 void vector_subtract(u32 n, const double *a,
00964 const double *b, double *c) {
00965 vector_add_sc(n, a, b, -1, c);
00966 }
00967
00977 void vector_cross(const double a[3], const double b[3],
00978 double c[3]) {
00979 c[0] = a[1]*b[2] - a[2]*b[1];
00980 c[1] = a[2]*b[0] - a[0]*b[2];
00981 c[2] = a[0]*b[1] - a[1]*b[0];
00982 }
00983
00984
00985
00986