00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <UTILS/matrix.h>
00011
00012
00013
00014
00015
00016
00017
00018 extern FILE* gcheck;
00019
00020 static float at,bt,ct;
00021
00022
00023
00024
00025
00026
00027
00028 void mat_null(a, n_rank, n, K2)
00029 MATRIX *a, *n;
00030 int *n_rank;
00031 float *K2;
00032 {
00033 MATRIX *a_sqr,
00034 *v,
00035 *S_temp;
00036 float **U, *S, **V,
00037 *vector(),
00038 **conv_2_nric_ptr();
00039 float s_min, s_max, temp;
00040 void free_vector(),
00041 free_ivector();
00042 int i, j, R, C, *order;
00043 int *ivector();
00044
00045 R = a->rows;
00046 C = a->cols;
00047
00048 if ((R==0) || (C==0)) {
00049 fprintf(stderr, "Can't calculate null-space of a 0x0 matrix.\n");
00050 return;
00051 }
00052
00053 S_temp = mat_malloc(C+1,1);
00054 v = mat_malloc(C,C);
00055 V = conv_2_nric_ptr(v);
00056 S = vector(1,C);
00057 order = ivector(1,C);
00058
00059
00060 if (R < C)
00061 {
00062 a_sqr = mat_malloc(C,C);
00063 for (i=0; i<R; i++)
00064 for (j=0; j<C; j++)
00065 a_sqr->p[i][j]=a->p[i][j];
00066 for (i=R; i<C; i++)
00067 for (j=0; j<C; j++)
00068 a_sqr->p[i][j]=0.0;
00069 }
00070 else
00071 {
00072 a_sqr = mat_malloc(R,C);
00073 mat_cp(a, a_sqr);
00074 }
00075
00076 U = conv_2_nric_ptr(a_sqr);
00077
00078 svdcmp(U, C, C, S, V);
00079
00080 for (i=1; i<(C+1); i++)
00081 {
00082 S_temp->p[i][0] = S[i];
00083 order[i] = i;
00084 }
00085 for (i=C; i>1; i--)
00086 for (j=i-1; j>=1; j--)
00087 if (fabs(S_temp->p[i][0])>fabs(S_temp->p[j][0]))
00088 {
00089 temp = S_temp->p[i][0];
00090 S_temp->p[i][0] = S_temp->p[j][0];
00091 S_temp->p[j][0] = temp;
00092 temp = order[i];
00093 order[i] = order[j];
00094 order[j] = temp;
00095 }
00096 if (R<=C)
00097 s_min = fabs(S_temp->p[R][0]);
00098 else
00099 s_min = fabs(S_temp->p[C][0]);
00100 s_max = fabs(S_temp->p[1][0]);
00101
00102 *n_rank = 0;
00103 while (fabs(S_temp->p[C-*n_rank][0]) < SV_SMALL)
00104 {
00105 for (j=1; j<=C; j++)
00106 n->p[j-1][*n_rank]
00107 = V[j][order[C-*n_rank]];
00108 *n_rank = *n_rank + 1;
00109 }
00110
00111 if ((fabs(s_min)>=SV_SMALL) && (fabs(s_min/s_max) < SV_SMALL))
00112 {
00113 for (j=1; j<=C; j++)
00114 n->p[j-1][*n_rank] = V[order[j]][C-*n_rank];
00115 *n_rank = *n_rank+1;
00116 }
00117
00118 *K2 = s_max/s_min;
00119
00120 mat_free(v);
00121 mat_free(a_sqr);
00122 mat_free(S_temp);
00123 free_vector(S,1,C);
00124 free_ivector(order,1,C);
00125 free(V);
00126 free(U);
00127 }
00128
00129
00130
00131 void ludcmp(a,n,indx,d)
00132 int n,*indx;
00133 float **a,*d;
00134 {
00135 int i,imax,j,k;
00136 float big,dum,sum,temp;
00137 float *vv,*vector();
00138 void nrerror(),free_vector();
00139
00140 vv=vector(1,n);
00141 *d=1.0;
00142 for (i=1;i<=n;i++) {
00143 big=0.0;
00144 for (j=1;j<=n;j++)
00145 if ((temp=fabs(a[i][j])) > big) big=temp;
00146 if (big == 0.0) nrerror("Singular matrix in routine LUDCMP");
00147 vv[i]=1.0/big;
00148 }
00149 for (j=1;j<=n;j++) {
00150 for (i=1;i<j;i++) {
00151 sum=a[i][j];
00152 for (k=1;k<i;k++) sum -= a[i][k]*a[k][j];
00153 a[i][j]=sum;
00154 }
00155 big=0.0;
00156 for (i=j;i<=n;i++) {
00157 sum=a[i][j];
00158 for (k=1;k<j;k++)
00159 sum -= a[i][k]*a[k][j];
00160 a[i][j]=sum;
00161 if ( (dum=vv[i]*fabs(sum)) >= big) {
00162 big=dum;
00163 imax=i;
00164 }
00165 }
00166 if (j != imax) {
00167 for (k=1;k<=n;k++) {
00168 dum=a[imax][k];
00169 a[imax][k]=a[j][k];
00170 a[j][k]=dum;
00171 }
00172 *d = -(*d);
00173 vv[imax]=vv[j];
00174 }
00175 indx[j]=imax;
00176 if (a[j][j] == 0.0) a[j][j]=TINY;
00177 if (j != n) {
00178 dum=1.0/(a[j][j]);
00179 for (i=j+1;i<=n;i++) a[i][j] *= dum;
00180 }
00181 }
00182 free_vector(vv,1,n);
00183 }
00184
00185
00186 void lubksb(a,n,indx,b)
00187 float **a,b[];
00188 int n,*indx;
00189 {
00190 int i,ii=0,ip,j;
00191 float sum;
00192
00193 for (i=1;i<=n;i++) {
00194 ip=indx[i];
00195 sum=b[ip];
00196 b[ip]=b[i];
00197 if (ii)
00198 for (j=ii;j<=i-1;j++) sum -= a[i][j]*b[j];
00199 else if (sum) ii=i;
00200 b[i]=sum;
00201 }
00202 for (i=n;i>=1;i--) {
00203 sum=b[i];
00204 for (j=i+1;j<=n;j++) sum -= a[i][j]*b[j];
00205 b[i]=sum/a[i][i];
00206 }
00207 }
00208
00209
00210 void svbksb(u,w,v,m,n,b,x)
00211 float **u,w[],**v,b[],x[];
00212 int m,n;
00213 {
00214 int jj,j,i;
00215 float s,*tmp,*vector();
00216 void free_vector();
00217
00218 tmp=vector(1,n);
00219 for (j=1;j<=n;j++) {
00220 s=0.0;
00221 if (w[j]) {
00222 for (i=1;i<=m;i++) s += u[i][j]*b[i];
00223 s /= w[j];
00224 }
00225 tmp[j]=s;
00226 }
00227 for (j=1;j<=n;j++) {
00228 s=0.0;
00229 for (jj=1;jj<=n;jj++) s += v[j][jj]*tmp[jj];
00230 x[j]=s;
00231 }
00232 free_vector(tmp,1,n);
00233 }
00234
00235
00236 void svdcmp(a, m, n, w, v)
00237 float **a, *w, **v;
00238 int m, n;
00239 {
00240 int flag, i, its, j, jj, k, l, nm;
00241 float c, f, h, s, x, y, z;
00242 float anorm = 0.0, g = 0.0, scale = 0.0;
00243 float *rv1, *vector();
00244 void nrerror(), free_vector();
00245 if (m < n)
00246 nrerror("SVDCMP: You must augment A with extra zero rows");
00247 rv1 = vector(1, n);
00248 for (i = 1; i <= n; i++)
00249 {
00250 l = i + 1;
00251 rv1[i] = scale * g;
00252 g = s = scale = 0.0;
00253 if (i <= m)
00254 {
00255 for (k = i; k <= m; k++)
00256 scale += fabs(a[k][i]);
00257 if (scale)
00258 {
00259 for (k = i; k <= m; k++)
00260 {
00261 a[k][i] /= scale;
00262 s += a[k][i] * a[k][i];
00263 }
00264 f = a[i][i];
00265 g = -SIGN(sqrt(s), f);
00266 h = f * g - s;
00267 a[i][i] = f - g;
00268 if (i != n)
00269 {
00270 for (j = l; j <= n; j++)
00271 {
00272 for (s = 0.0, k = i; k <= m; k++)
00273 s += a[k][i] * a[k][j];
00274 f = s / h;
00275 for (k = i; k <= m; k++)
00276 a[k][j] += f * a[k][i];
00277 }
00278 }
00279 for (k = i; k <= m; k++)
00280 a[k][i] *= scale;
00281 }
00282 }
00283 w[i] = scale * g;
00284 g = s = scale = 0.0;
00285 if (i <= m && i != n)
00286 {
00287 for (k = l; k <= n; k++)
00288 scale += fabs(a[i][k]);
00289 if (scale)
00290 {
00291 for (k = l; k <= n; k++)
00292 {
00293 a[i][k] /= scale;
00294 s += a[i][k] * a[i][k];
00295 }
00296 f = a[i][l];
00297 g = -SIGN(sqrt(s), f);
00298 h = f * g - s;
00299 a[i][l] = f - g;
00300 for (k = l; k <= n; k++)
00301 rv1[k] = a[i][k] / h;
00302 if (i != m)
00303 {
00304 for (j = l; j <= m; j++)
00305 {
00306 for (s = 0.0, k = l; k <= n; k++)
00307 s += a[j][k] * a[i][k];
00308 for (k = l; k <= n; k++)
00309 a[j][k] += s * rv1[k];
00310 }
00311 }
00312 for (k = l; k <= n; k++)
00313 a[i][k] *= scale;
00314 }
00315 }
00316 anorm = MAX(anorm, (fabs(w[i]) + fabs(rv1[i])));
00317 }
00318 for (i = n; i >= 1; i--)
00319 {
00320 if (i < n)
00321 {
00322 if (g)
00323 {
00324 for (j = l; j <= n; j++)
00325 v[j][i] = (a[i][j] / a[i][l]) / g;
00326 for (j = l; j <= n; j++)
00327 {
00328 for (s = 0.0, k = l; k <= n; k++)
00329 s += a[i][k] * v[k][j];
00330 for (k = l; k <= n; k++)
00331 v[k][j] += s * v[k][i];
00332 }
00333 }
00334 for (j = l; j <= n; j++)
00335 v[i][j] = v[j][i] = 0.0;
00336 }
00337 v[i][i] = 1.0;
00338 g = rv1[i];
00339 l = i;
00340 }
00341 for (i = n; i >= 1; i--)
00342 {
00343 l = i + 1;
00344 g = w[i];
00345 if (i < n)
00346 for (j = l; j <= n; j++)
00347 a[i][j] = 0.0;
00348 if (g)
00349 {
00350 g = 1.0 / g;
00351 if (i != n)
00352 {
00353 for (j = l; j <= n; j++)
00354 {
00355 for (s = 0.0, k = l; k <= m; k++)
00356 s += a[k][i] * a[k][j];
00357 f = (s / a[i][i]) * g;
00358 for (k = i; k <= m; k++)
00359 a[k][j] += f * a[k][i];
00360 }
00361 }
00362 for (j = i; j <= m; j++)
00363 a[j][i] *= g;
00364 }
00365 else
00366 {
00367 for (j = i; j <= m; j++)
00368 a[j][i] = 0.0;
00369 }
00370 ++a[i][i];
00371 }
00372 for (k = n; k >= 1; k--)
00373 {
00374 for (its = 1; its <= 30; its++)
00375 {
00376 flag = 1;
00377 for (l = k; l >= 1; l--)
00378 {
00379 nm = l - 1;
00380 if (fabs(rv1[l]) + anorm == anorm)
00381 {
00382 flag = 0;
00383 break;
00384 }
00385 if (fabs(w[nm]) + anorm == anorm)
00386 break;
00387 }
00388 if (flag)
00389 {
00390 c = 0.0;
00391 s = 1.0;
00392 for (i = l; i <= k; i++)
00393 {
00394 f = s * rv1[i];
00395 if (fabs(f) + anorm != anorm)
00396 {
00397 g = w[i];
00398 h = PYTHAG(f, g);
00399 w[i] = h;
00400 h = 1.0 / h;
00401 c = g * h;
00402 s = (-f * h);
00403 for (j = 1; j <= m; j++)
00404 {
00405 y = a[j][nm];
00406 z = a[j][i];
00407 a[j][nm] = y * c + z * s;
00408 a[j][i] = z * c - y * s;
00409 }
00410 }
00411 }
00412 }
00413 z = w[k];
00414 if (l == k)
00415 {
00416 if (z < 0.0)
00417 {
00418 w[k] = -z;
00419 for (j = 1; j <= n; j++)
00420 v[j][k] = (-v[j][k]);
00421 }
00422 break;
00423 }
00424 if (its == 30)
00425 nrerror("No convergence in 30 SVDCMP iterations");
00426 x = w[l];
00427 nm = k - 1;
00428 y = w[nm];
00429 g = rv1[nm];
00430 h = rv1[k];
00431 f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y);
00432 g = PYTHAG(f, 1.0);
00433 f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x;
00434 c = s = 1.0;
00435 for (j = l; j <= nm; j++)
00436 {
00437 i = j + 1;
00438 g = rv1[i];
00439 y = w[i];
00440 h = s * g;
00441 g = c * g;
00442 z = PYTHAG(f, h);
00443 rv1[j] = z;
00444 c = f / z;
00445 s = h / z;
00446 f = x * c + g * s;
00447 g = g * c - x * s;
00448 h = y * s;
00449 y = y * c;
00450 for (jj = 1; jj <= n; jj++)
00451 {
00452 x = v[jj][j];
00453 z = v[jj][i];
00454 v[jj][j] = x * c + z * s;
00455 v[jj][i] = z * c - x * s;
00456 }
00457 z = PYTHAG(f, h);
00458 w[j] = z;
00459 if (z)
00460 {
00461 z = 1.0 / z;
00462 c = f * z;
00463 s = h * z;
00464 }
00465 f = (c * g) + (s * y);
00466 x = (c * y) - (s * g);
00467 for (jj = 1; jj <= m; jj++)
00468 {
00469 y = a[jj][j];
00470 z = a[jj][i];
00471 a[jj][j] = y * c + z * s;
00472 a[jj][i] = z * c - y * s;
00473 }
00474 }
00475 rv1[l] = 0.0;
00476 rv1[k] = f;
00477 w[k] = x;
00478 }
00479 }
00480 free_vector(rv1, 1, n);
00481 }
00482
00483
00484 #undef SIGN
00485 #undef PYTHAG
00486 #undef TINY
00487
00488
00489
00490
00491 MATRIX *mat_malloc(rows, cols)
00492 int rows, cols;
00493 {
00494 int i;
00495 float *mat, **row;
00496 MATRIX *matrix;
00497
00498
00499
00500
00501
00502
00503 if ((rows > 0) && (cols > 0)) {
00504 mat = (float * ) malloc(rows * cols * sizeof(float));
00505 row = (float **) malloc((MAX(rows, cols)) * sizeof(float *));
00506 }
00507 else {
00508 mat = (float * ) malloc(sizeof(float));
00509 row = (float **) malloc(sizeof(float *));
00510 row[0]=mat;
00511 }
00512 matrix = (MATRIX *) malloc( sizeof( MATRIX ) );
00513
00514 if(!mat || !row || !matrix)
00515 {
00516
00517 fprintf(stderr, "Matrix allocation failed\n");
00518 return(NULL);
00519 }
00520
00521 matrix->p = row;
00522 matrix->rows = rows;
00523 matrix->cols = cols;
00524
00525
00526
00527
00528
00529
00530
00531
00532 for(i = 0; i < rows; i++)
00533 {
00534 row[i] = mat;
00535 mat += cols;
00536 }
00537
00538 return(matrix);
00539 }
00540
00541
00542
00543 void mat_free(m)
00544 MATRIX *m;
00545 {
00546 free( (char *) *m->p);
00547 free( (char *) m->p);
00548 free( (char *) m);
00549 }
00550
00551
00552 void mat_pr(a)
00553 MATRIX *a;
00554 {
00555 int i, j;
00556
00557 printf("\n");
00558 for (i = 0; i < a->rows; i++)
00559 {
00560 for (j = 0; j < a->cols; j++)
00561 {
00562 if (fabs(a->p[i][j]) >= PrintIfBiggerThan)
00563 printf("\t% .8f", a->p[i][j]);
00564 else
00565 printf("\t - ");
00566 }
00567 printf("\n");
00568 }
00569 printf("\n");
00570 }
00571
00572
00573 void mat_prf(a)
00574 MATRIX *a;
00575 {
00576 int i, j;
00577
00578 printf("\n");
00579 for (i = 0; i < a->rows; i++)
00580 {
00581 for (j = 0; j < a->cols; j++)
00582 {
00583 printf("\t% f", a->p[i][j]);
00584 }
00585 printf("\n");
00586 }
00587 printf("\n");
00588 }
00589
00590
00591
00592
00593 void mat_LU_inv(a)
00594 MATRIX *a;
00595 {
00596 MATRIX *y;
00597 float **A, **Y, d, *col;
00598 int N, i, j, *indx;
00599 float **conv_2_nric_ptr();
00600
00601 N = a->rows;
00602
00603
00604
00605
00606 y = mat_malloc(a->rows, a->cols);
00607 col = vector(1, N);
00608 indx = (int *) malloc(N * sizeof(int));
00609
00610
00611
00612
00613 A = conv_2_nric_ptr(a);
00614 Y = conv_2_nric_ptr(y);
00615
00616
00617
00618 ludcmp(A, N, indx, &d);
00619
00620
00621
00622 for (j = 1; j <= N; j++)
00623 {
00624 for (i = 1; i <= N; i++)
00625 col[i] = 0.0;
00626
00627 col[j] = 1.0;
00628 lubksb(A, N, indx, col);
00629
00630 for (i = 1; i <= N; i++)
00631 Y[i][j] = col[i];
00632 }
00633
00634
00635
00636 mat_cp(y, a);
00637
00638 mat_free(y);
00639 free_vector(col, 1, N);
00640 free( (char *) indx);
00641 free( (char *) A);
00642 free( (char *) Y);
00643 }
00644
00645
00646
00647
00648
00649
00650
00651 void mat_pseudoinv(a)
00652 MATRIX *a;
00653 {
00654 MATRIX *q2, *z, *tmp;
00655 float **A, **Q2, *Z;
00656 float z_min, z_max;
00657 int M, N, i, j;
00658 float **conv_2_nric_ptr();
00659
00660 M = a->rows; N = a->cols;
00661
00662
00663
00664 q2 = mat_malloc(N, N);
00665 z = mat_malloc(N, N);
00666 Z = vector(1, N);
00667
00668
00669
00670 A = conv_2_nric_ptr(a);
00671 Q2 = conv_2_nric_ptr(q2);
00672
00673
00674
00675
00676
00677
00678
00679
00680 svdcmp(A, M, N, Z, Q2);
00681
00682
00683
00684 z_max = 0.0;
00685 for (i = 1; i <= N; i++) if (Z[i] > z_max) z_max = Z[i];
00686
00687
00688
00689
00690 z_min = z_max*SVD_THRESHOLD;
00691
00692
00693
00694
00695 for (i = 0; i < N; i++)
00696 for (j = 0; j < N; j++)
00697 z->p[i][j] = ((i == j) && Z[i+1] > z_min) ? 1.0/Z[i+1] : 0.0;
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718 mat_tra(a);
00719 tmp = mat_mul2(z, a);
00720 mat_mul(q2, tmp, a);
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733 mat_free(q2);
00734 mat_free(z);
00735 mat_free(tmp);
00736 free_vector(Z, 1, N);
00737 free( (char *) A);
00738 free( (char *) Q2);
00739
00740 }
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750 double mat_det(a)
00751 MATRIX *a;
00752 {
00753 MATRIX *q2, *cp;
00754 float **A, **Q2, *Z;
00755 int M, N, i, j;
00756 float **conv_2_nric_ptr();
00757 double det;
00758
00759 M = a->rows; N = a->cols;
00760
00761
00762 cp = mat_cp2(a);
00763 q2 = mat_malloc(N, N);
00764 Z = vector(1, N);
00765
00766
00767
00768 A = conv_2_nric_ptr(cp);
00769 Q2 = conv_2_nric_ptr(q2);
00770
00771
00772
00773
00774
00775
00776
00777
00778 svdcmp(A, M, N, Z, Q2);
00779
00780
00781
00782 for(det=1.0,i=1;i<=N;i++)
00783 det *= (double) Z[i];
00784
00785 mat_free(q2);
00786 mat_free(cp);
00787 free( (char *) A);
00788 free( (char *) Q2);
00789 free_vector(Z, 1, N);
00790
00791 return(det);
00792 }
00793
00794
00795 double mat_eigen(a)
00796 MATRIX *a;
00797 {
00798 MATRIX *q2;
00799 float **A, **Q2, *Z;
00800 float z_min, z_max;
00801 int M, N, i, j;
00802 float **conv_2_nric_ptr();
00803
00804 M = a->rows; N = a->cols;
00805
00806
00807
00808 q2 = mat_malloc(N, N);
00809 Z = vector(1, N);
00810
00811
00812
00813 A = conv_2_nric_ptr(a);
00814 Q2 = conv_2_nric_ptr(q2);
00815
00816
00817
00818
00819
00820
00821
00822
00823 svdcmp(A, M, N, Z, Q2);
00824
00825
00826
00827 z_max = 0.0;
00828 for (i = 1; i <= N; i++) if (Z[i] > z_max) z_max = Z[i];
00829
00830 mat_free(q2);
00831 free_vector(Z, 1, N);
00832 free( (char *) A);
00833 free( (char *) Q2);
00834
00835 return(z_max);
00836 }
00837
00838
00839
00840
00841
00842
00843 void mat_mul(a, b, c)
00844 MATRIX *a, *b, *c;
00845 {
00846 int i, j, k;
00847
00848 for (k = 0; k < b->cols; k++)
00849 for (i = 0; i < a->rows; i++)
00850 {
00851 c->p[i][k] = 0;
00852 for (j = 0; j < a->cols; j++)
00853 c->p[i][k] += a->p[i][j]*b->p[j][k];
00854 }
00855 }
00856
00857
00858
00859
00860
00861 MATRIX *mat_mul2(a, b)
00862 MATRIX *a, *b;
00863 {
00864 MATRIX *c;
00865
00866 c = mat_malloc(a->rows, b->cols);
00867
00868 mat_mul(a, b, c);
00869
00870 return(c);
00871 }
00872
00873
00874
00875
00876
00877
00878 void mat_add(a, b, c)
00879 MATRIX *a, *b, *c;
00880 {
00881 float *p, *q, *r;
00882 int i;
00883
00884 p = *a->p; q = *b->p; r = *c->p;
00885
00886 for (i = a->rows*a->cols; i--;)
00887 *r++ = *p++ + *q++;
00888 }
00889
00890
00891
00892
00893
00894
00895
00896 MATRIX *mat_add2(a, b)
00897 MATRIX *a, *b;
00898 {
00899 MATRIX *c;
00900
00901 c = mat_malloc(a->rows, a->cols);
00902
00903 mat_add(a, b, c);
00904
00905 return(c);
00906 }
00907
00908
00909
00910
00911
00912
00913 void mat_sub(a, b, c)
00914 MATRIX *a, *b, *c;
00915 {
00916 float *p, *q, *r;
00917 int i;
00918
00919 p = *a->p; q = *b->p; r = *c->p;
00920
00921 for (i = a->rows*a->cols; i--;)
00922 *r++ = *p++ - *q++;
00923 }
00924
00925
00926
00927
00928
00929
00930
00931
00932 MATRIX *mat_sub2(a, b)
00933 MATRIX *a, *b;
00934 {
00935 MATRIX *c;
00936
00937 c = mat_malloc(a->rows, a->cols);
00938
00939 mat_sub(a, b, c);
00940
00941 return(c);
00942 }
00943
00944
00945
00946
00947
00948 void mat_sca(a, c)
00949 MATRIX *a;
00950 float c;
00951 {
00952 float *p;
00953 int i;
00954
00955 p = *a->p;
00956
00957 for (i = a->rows*a->cols; i--;)
00958 *p++ *= c;
00959 }
00960
00961
00962
00963
00964
00965 void mat_tra(a)
00966 MATRIX *a;
00967 {
00968 int i, j, temp;
00969 float *p;
00970
00971 if (a->rows == a->cols)
00972 {
00973 for (i = a->rows-1; i--;)
00974 for (j = a->cols-1; j > i; j--)
00975 SWAP(a->p[i][j], a->p[j][i]);
00976 }
00977 else
00978 {
00979 temp = a->rows;
00980 a->rows = a->cols;
00981 a->cols = temp;
00982
00983
00984
00985 p = *a->p;
00986 for(i = 0; i < a->rows; i++)
00987 {
00988 a->p[i] = p;
00989 p += a->cols;
00990 }
00991
00992
00993
00994 if (!((a->rows == 1) || (a->cols == 1)))
00995 {
00996 MATRIX *m;
00997
00998
00999
01000
01001 m = mat_malloc(a->rows, a->cols);
01002 mat_cp(a,m);
01003 p = *m->p;
01004
01005 for (j = 0; j < a->cols; j++)
01006 for (i = 0; i < a->rows; i++)
01007 a->p[i][j] = *p++;
01008
01009 mat_free(m);
01010 }
01011 }
01012 }
01013
01014
01015
01016
01017
01018
01019 MATRIX *mat_tra2(A)
01020 MATRIX *A;
01021 {
01022 int i, j;
01023 MATRIX *At;
01024
01025 At = mat_malloc(A->cols, A->rows);
01026
01027 for (i = A->rows-1; i--;)
01028 for (j = A->cols-1; j > i; j--)
01029 At->p[i][j] = A->p[j][i];
01030
01031 return(At);
01032 }
01033
01034
01035
01036
01037
01038 void mat_cp(a, cpy)
01039 MATRIX *a, *cpy;
01040 {
01041 float *p, *q;
01042 int i;
01043
01044 p = *a->p; q = *cpy->p;
01045
01046 for (i = a->rows*a->cols; i--;)
01047 *q++ = *p++;
01048 }
01049
01050
01051
01052
01053
01054
01055 MATRIX *mat_cp2(a)
01056 MATRIX *a;
01057 {
01058 int i;
01059 float *p, *q;
01060 MATRIX *cpy;
01061
01062 cpy = mat_malloc(a->rows, a->cols);
01063
01064 mat_cp(a, cpy);
01065
01066 return(cpy);
01067 }
01068
01069
01070
01071
01072
01073
01074
01075 float **conv_2_nric_ptr(a)
01076 MATRIX *a;
01077 {
01078 float **new_ptr_2_row;
01079 int i;
01080
01081
01082
01083 new_ptr_2_row = (float **) malloc((a->rows + 1) * sizeof(float *));
01084
01085
01086
01087 for (i = 0; i < a->rows; i++)
01088 new_ptr_2_row[i+1] = a->p[i] - 1;
01089
01090
01091
01092 new_ptr_2_row[0] = a->p[0];
01093
01094 return( new_ptr_2_row );
01095 }
01096
01097
01098
01099
01100
01101 void free_nric_ptr(p)
01102 float **p;
01103 {
01104 free( (char *) p);
01105 }
01106
01107
01108
01109
01110
01111 float mat_vec_dot(a, ar, b, br)
01112 MATRIX *a, *b;
01113 int ar, br;
01114 {
01115 int i;
01116 float d = 0;
01117
01118 for (i = 0; i < a->cols; i++)
01119 d += a->p[ar][i] * b->p[br][i];
01120
01121 return( d );
01122 }
01123
01124
01125
01126
01127
01128
01129 void mat_vec_cross(a, ar, b, br, c)
01130 MATRIX *a, *b, *c;
01131 int ar, br;
01132 {
01133 c->p[0][0] = a->p[ar][1] * b->p[br][2] - a->p[ar][2] * b->p[br][1];
01134 c->p[0][1] = a->p[ar][2] * b->p[br][0] - a->p[ar][0] * b->p[br][2];
01135 c->p[0][2] = a->p[ar][0] * b->p[br][1] - a->p[ar][1] * b->p[br][0];
01136 }
01137
01138
01139
01140
01141
01142 float mat_vec_abs(a, r)
01143 MATRIX *a;
01144 int r;
01145 {
01146 int i;
01147 float d = 0;
01148
01149 for (i = 0; i < a->cols; i++)
01150 d += a->p[r][i] * a->p[r][i];
01151
01152 return( sqrt(d) );
01153 }