diff options
| author | Leo Chan <leochanj@live.unc.edu> | 2020-10-22 01:53:21 -0400 |
|---|---|---|
| committer | Joshua Bakita <jbakita@cs.unc.edu> | 2020-10-22 01:56:35 -0400 |
| commit | d17b33131c14864bd1eae275f49a3f148e21cf29 (patch) | |
| tree | 0d8f77922e8d193cb0f6edab83018f057aad64a0 /SD-VBS/benchmarks/pca/src | |
| parent | 601ed25a4c5b66cb75315832c15613a727db2c26 (diff) | |
Squashed commit of the sb-vbs branch.
Includes the SD-VBS benchmarks modified to:
- Use libextra to loop as realtime jobs
- Preallocate memory before starting their main computation
- Accept input via stdin instead of via argc
Does not include the SD-VBS matlab code.
Fixes libextra execution in LITMUS^RT.
Diffstat (limited to 'SD-VBS/benchmarks/pca/src')
| -rwxr-xr-x | SD-VBS/benchmarks/pca/src/pca | bin | 0 -> 21446 bytes | |||
| -rw-r--r-- | SD-VBS/benchmarks/pca/src/pca.c | 694 |
2 files changed, 694 insertions, 0 deletions
diff --git a/SD-VBS/benchmarks/pca/src/pca b/SD-VBS/benchmarks/pca/src/pca new file mode 100755 index 0000000..15b5908 --- /dev/null +++ b/SD-VBS/benchmarks/pca/src/pca | |||
| Binary files differ | |||
diff --git a/SD-VBS/benchmarks/pca/src/pca.c b/SD-VBS/benchmarks/pca/src/pca.c new file mode 100644 index 0000000..4637e7c --- /dev/null +++ b/SD-VBS/benchmarks/pca/src/pca.c | |||
| @@ -0,0 +1,694 @@ | |||
| 1 | /*********************** Contents **************************************** | ||
| 2 | * Principal Components Analysis: C, 638 lines. **************************** | ||
| 3 | * Sample input data set (final 36 lines). ********************************* | ||
| 4 | *************************************************************************** | ||
| 5 | */ | ||
| 6 | |||
| 7 | /*********************************/ | ||
| 8 | /* Principal Components Analysis */ | ||
| 9 | /*********************************/ | ||
| 10 | |||
| 11 | /*********************************************************************/ | ||
| 12 | /* Principal Components Analysis or the Karhunen-Loeve expansion is a | ||
| 13 | classical method for dimensionality reduction or exploratory data | ||
| 14 | analysis. One reference among many is: F. Murtagh and A. Heck, | ||
| 15 | Multivariate Data Analysis, Kluwer Academic, Dordrecht, 1987. | ||
| 16 | |||
| 17 | Author: | ||
| 18 | F. Murtagh | ||
| 19 | Phone: + 49 89 32006298 (work) | ||
| 20 | + 49 89 965307 (home) | ||
| 21 | Earn/Bitnet: fionn@dgaeso51, fim@dgaipp1s, murtagh@stsci | ||
| 22 | Span: esomc1::fionn | ||
| 23 | Internet: murtagh@scivax.stsci.edu | ||
| 24 | |||
| 25 | F. Murtagh, Munich, 6 June 1989 */ | ||
| 26 | /*********************************************************************/ | ||
| 27 | |||
| 28 | #include <stdio.h> | ||
| 29 | #include <string.h> | ||
| 30 | #include <math.h> | ||
| 31 | |||
| 32 | #define SIGN(a, b) ( (b) < 0 ? -fabs(a) : fabs(a) ) | ||
| 33 | |||
| 34 | main(argc, argv) | ||
| 35 | int argc; | ||
| 36 | char *argv[]; | ||
| 37 | |||
| 38 | { | ||
| 39 | FILE *stream; | ||
| 40 | int n, m, i, j, k, k2; | ||
| 41 | float **data, **matrix(), **symmat, **symmat2, *vector(), *evals, *interm; | ||
| 42 | void free_matrix(), free_vector(), corcol(), covcol(), scpcol(); | ||
| 43 | void tred2(), tqli(); | ||
| 44 | float in_value; | ||
| 45 | char option, *strncpy(); | ||
| 46 | |||
| 47 | /********************************************************************* | ||
| 48 | Get from command line: | ||
| 49 | input data file name, #rows, #cols, option. | ||
| 50 | |||
| 51 | Open input file: fopen opens the file whose name is stored in the | ||
| 52 | pointer argv[argc-1]; if unsuccessful, error message is printed to | ||
| 53 | stderr. | ||
| 54 | *********************************************************************/ | ||
| 55 | |||
| 56 | if (argc != 5) | ||
| 57 | { | ||
| 58 | printf("Syntax help: PCA filename #rows #cols option\n\n"); | ||
| 59 | printf("(filename -- give full path name,\n"); | ||
| 60 | printf(" #rows \n"); | ||
| 61 | printf(" #cols -- integer values,\n"); | ||
| 62 | printf(" option -- R (recommended) for correlation analysis,\n"); | ||
| 63 | printf(" V for variance/covariance analysis\n"); | ||
| 64 | printf(" S for SSCP analysis.)\n"); | ||
| 65 | exit(1); | ||
| 66 | } | ||
| 67 | |||
| 68 | n = atoi(argv[2]); /* # rows */ | ||
| 69 | m = atoi(argv[3]); /* # columns */ | ||
| 70 | strncpy(&option,argv[4],1); /* Analysis option */ | ||
| 71 | |||
| 72 | printf("No. of rows: %d, no. of columns: %d.\n",n,m); | ||
| 73 | printf("Input file: %s.\n",argv[1]); | ||
| 74 | |||
| 75 | if ((stream = fopen(argv[1],"r")) == NULL) | ||
| 76 | { | ||
| 77 | fprintf(stderr, "Program %s : cannot open file %s\n", | ||
| 78 | argv[0], argv[1]); | ||
| 79 | fprintf(stderr, "Exiting to system."); | ||
| 80 | exit(1); | ||
| 81 | /* Note: in versions of DOS prior to 3.0, argv[0] contains the | ||
| 82 | string "C". */ | ||
| 83 | } | ||
| 84 | |||
| 85 | /* Now read in data. */ | ||
| 86 | |||
| 87 | data = matrix(n, m); /* Storage allocation for input data */ | ||
| 88 | |||
| 89 | for (i = 1; i <= n; i++) | ||
| 90 | { | ||
| 91 | for (j = 1; j <= m; j++) | ||
| 92 | { | ||
| 93 | fscanf(stream, "%f", &in_value); | ||
| 94 | data[i][j] = in_value; | ||
| 95 | printf("at row %d column %d is %lf\n",i,j,data[i][j]); | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 99 | |||
| 100 | |||
| 101 | /* Check on (part of) input data. | ||
| 102 | for (i = 1; i <= 18; i++) {for (j = 1; j <= 8; j++) { | ||
| 103 | printf("%7.1f", data[i][j]); } printf("\n"); } | ||
| 104 | */ | ||
| 105 | |||
| 106 | |||
| 107 | |||
| 108 | symmat = matrix(m, m); /* Allocation of correlation (etc.) matrix */ | ||
| 109 | |||
| 110 | /* Look at analysis option; branch in accordance with this. */ | ||
| 111 | |||
| 112 | switch(option) | ||
| 113 | { | ||
| 114 | case 'R': | ||
| 115 | case 'r': | ||
| 116 | printf("Analysis of correlations chosen.\n"); | ||
| 117 | corcol(data, n, m, symmat); | ||
| 118 | |||
| 119 | /* Output correlation matrix. | ||
| 120 | for (i = 1; i <= m; i++) { | ||
| 121 | for (j = 1; j <= 8; j++) { | ||
| 122 | printf("%7.4f", symmat[i][j]); } | ||
| 123 | printf("\n"); } | ||
| 124 | */ | ||
| 125 | break; | ||
| 126 | case 'V': | ||
| 127 | case 'v': | ||
| 128 | printf("Analysis of variances-covariances chosen.\n"); | ||
| 129 | covcol(data, n, m, symmat); | ||
| 130 | |||
| 131 | /* Output variance-covariance matrix. | ||
| 132 | for (i = 1; i <= m; i++) { | ||
| 133 | for (j = 1; j <= 8; j++) { | ||
| 134 | printf("%7.1f", symmat[i][j]); } | ||
| 135 | printf("\n"); } | ||
| 136 | */ | ||
| 137 | break; | ||
| 138 | case 'S': | ||
| 139 | case 's': | ||
| 140 | printf("Analysis of sums-of-squares-cross-products"); | ||
| 141 | printf(" matrix chosen.\n"); | ||
| 142 | scpcol(data, n, m, symmat); | ||
| 143 | |||
| 144 | /* Output SSCP matrix. | ||
| 145 | for (i = 1; i <= m; i++) { | ||
| 146 | for (j = 1; j <= 8; j++) { | ||
| 147 | printf("%7.1f", symmat[i][j]); } | ||
| 148 | printf("\n"); } | ||
| 149 | */ | ||
| 150 | break; | ||
| 151 | default: | ||
| 152 | printf("Option: %s\n",option); | ||
| 153 | printf("For option, please type R, V, or S\n"); | ||
| 154 | printf("(upper or lower case).\n"); | ||
| 155 | printf("Exiting to system.\n"); | ||
| 156 | exit(1); | ||
| 157 | break; | ||
| 158 | } | ||
| 159 | |||
| 160 | /********************************************************************* | ||
| 161 | Eigen-reduction | ||
| 162 | **********************************************************************/ | ||
| 163 | |||
| 164 | /* Allocate storage for dummy and new vectors. */ | ||
| 165 | evals = vector(m); /* Storage alloc. for vector of eigenvalues */ | ||
| 166 | printf("the vector storage size is %d\n",m); | ||
| 167 | interm = vector(m); /* Storage alloc. for 'intermediate' vector */ | ||
| 168 | symmat2 = matrix(m, m); /* Duplicate of correlation (etc.) matrix */ | ||
| 169 | for (i = 1; i <= m; i++) { | ||
| 170 | for (j = 1; j <= m; j++) { | ||
| 171 | symmat2[i][j] = symmat[i][j]; /* Needed below for col. projections */ | ||
| 172 | } | ||
| 173 | } | ||
| 174 | tred2(symmat, m, evals, interm); /* Triangular decomposition */ | ||
| 175 | printf("eval value at 0 is %lf\n",evals[0]); | ||
| 176 | printf("eval value at 1 is %lf\n",evals[1]); | ||
| 177 | printf("eval value at 2 is %lf\n",evals[2]); | ||
| 178 | |||
| 179 | printf("m/height is %lf \n",m); | ||
| 180 | |||
| 181 | printf("m/height is %d \n",m); | ||
| 182 | printf("m/height is %d \n",n); | ||
| 183 | printf("m/height is %d \n",n); | ||
| 184 | |||
| 185 | |||
| 186 | tqli(evals, interm, m, symmat); /* Reduction of sym. trid. matrix */ | ||
| 187 | /* evals now contains the eigenvalues, | ||
| 188 | columns of symmat now contain the associated eigenvectors. */ | ||
| 189 | |||
| 190 | printf("\nEigenvalues:\n"); | ||
| 191 | for (j = m; j >= 1; j--) { | ||
| 192 | printf("%18.5f\n", evals[j]); } | ||
| 193 | printf("\n(Eigenvalues should be strictly positive; limited\n"); | ||
| 194 | printf("precision machine arithmetic may affect this.\n"); | ||
| 195 | printf("Eigenvalues are often expressed as cumulative\n"); | ||
| 196 | printf("percentages, representing the 'percentage variance\n"); | ||
| 197 | printf("explained' by the associated axis or principal component.)\n"); | ||
| 198 | |||
| 199 | printf("\nEigenvectors:\n"); | ||
| 200 | printf("(First three; their definition in terms of original vbes.)\n"); | ||
| 201 | for (j = 1; j <= m; j++) { | ||
| 202 | for (i = 1; i <= 3; i++) { | ||
| 203 | printf("%12.4f", symmat[j][m-i+1]); } | ||
| 204 | printf("\n"); } | ||
| 205 | |||
| 206 | |||
| 207 | |||
| 208 | |||
| 209 | /* Form projections of row-points on first three prin. components. */ | ||
| 210 | /* Store in 'data', overwriting original data. */ | ||
| 211 | for (i = 1; i <= n; i++) { | ||
| 212 | for (j = 1; j <= m; j++) { | ||
| 213 | interm[j] = data[i][j]; | ||
| 214 | printf("Iteration i=%d j=%d data = %lf\n\n", i,j,data[i][j]); | ||
| 215 | |||
| 216 | } | ||
| 217 | for (k = 1; k <= 3; k++) { | ||
| 218 | data[i][k] = 0.0; | ||
| 219 | for (k2 = 1; k2 <= m; k2++) { | ||
| 220 | data[i][k] += interm[k2] * symmat[k2][m-k+1]; | ||
| 221 | printf("Iteration i= %d, j = %d k=%d, k2=%d : data = %lf\n",i,j,k, k2,data[i][k]); | ||
| 222 | |||
| 223 | } | ||
| 224 | printf("\n"); | ||
| 225 | |||
| 226 | } | ||
| 227 | } | ||
| 228 | |||
| 229 | |||
| 230 | |||
| 231 | |||
| 232 | |||
| 233 | |||
| 234 | |||
| 235 | |||
| 236 | |||
| 237 | |||
| 238 | |||
| 239 | printf("\nProjections of row-points on first 3 prin. comps.:\n"); | ||
| 240 | for (i = 1; i <= n; i++) { | ||
| 241 | for (j = 1; j <= 3; j++) { | ||
| 242 | printf("%12.4f", data[i][j]); } | ||
| 243 | printf("\n"); } | ||
| 244 | return; | ||
| 245 | |||
| 246 | /* Form projections of col.-points on first three prin. components. */ | ||
| 247 | /* Store in 'symmat2', overwriting what was stored in this. */ | ||
| 248 | for (j = 1; j <= m; j++) { | ||
| 249 | for (k = 1; k <= m; k++) { | ||
| 250 | interm[k] = symmat2[j][k]; } /*symmat2[j][k] will be overwritten*/ | ||
| 251 | for (i = 1; i <= 3; i++) { | ||
| 252 | symmat2[j][i] = 0.0; | ||
| 253 | for (k2 = 1; k2 <= m; k2++) { | ||
| 254 | symmat2[j][i] += interm[k2] * symmat[k2][m-i+1]; } | ||
| 255 | if (evals[m-i+1] > 0.0005) /* Guard against zero eigenvalue */ | ||
| 256 | symmat2[j][i] /= sqrt(evals[m-i+1]); /* Rescale */ | ||
| 257 | else | ||
| 258 | symmat2[j][i] = 0.0; /* Standard kludge */ | ||
| 259 | } | ||
| 260 | } | ||
| 261 | |||
| 262 | printf("\nProjections of column-points on first 3 prin. comps.:\n"); | ||
| 263 | for (j = 1; j <= m; j++) { | ||
| 264 | for (k = 1; k <= 3; k++) { | ||
| 265 | printf("%12.4f", symmat2[j][k]); } | ||
| 266 | printf("\n"); } | ||
| 267 | |||
| 268 | free_matrix(data, n, m); | ||
| 269 | free_matrix(symmat, m, m); | ||
| 270 | free_matrix(symmat2, m, m); | ||
| 271 | free_vector(evals, m); | ||
| 272 | free_vector(interm, m); | ||
| 273 | |||
| 274 | } | ||
| 275 | |||
| 276 | /** Correlation matrix: creation ***********************************/ | ||
| 277 | |||
| 278 | void corcol(data, n, m, symmat) | ||
| 279 | float **data, **symmat; | ||
| 280 | int n, m; | ||
| 281 | /* Create m * m correlation matrix from given n * m data matrix. */ | ||
| 282 | { | ||
| 283 | float eps = 0.005; | ||
| 284 | float x, *mean, *stddev, *vector(); | ||
| 285 | int i, j, j1, j2; | ||
| 286 | |||
| 287 | /* Allocate storage for mean and std. dev. vectors */ | ||
| 288 | |||
| 289 | mean = vector(m); | ||
| 290 | stddev = vector(m); | ||
| 291 | |||
| 292 | /* Determine mean of column vectors of input data matrix */ | ||
| 293 | |||
| 294 | for (j = 1; j <= m; j++) | ||
| 295 | { | ||
| 296 | mean[j] = 0.0; | ||
| 297 | for (i = 1; i <= n; i++) | ||
| 298 | { | ||
| 299 | mean[j] += data[i][j]; | ||
| 300 | } | ||
| 301 | mean[j] /= (float)n; | ||
| 302 | } | ||
| 303 | |||
| 304 | printf("\nMeans of column vectors:\n"); | ||
| 305 | for (j = 1; j <= m; j++) { | ||
| 306 | printf("%7.1f",mean[j]); } printf("\n"); | ||
| 307 | |||
| 308 | /* Determine standard deviations of column vectors of data matrix. */ | ||
| 309 | |||
| 310 | for (j = 1; j <= m; j++) | ||
| 311 | { | ||
| 312 | stddev[j] = 0.0; | ||
| 313 | for (i = 1; i <= n; i++) | ||
| 314 | { | ||
| 315 | stddev[j] += ( ( data[i][j] - mean[j] ) * | ||
| 316 | ( data[i][j] - mean[j] ) ); | ||
| 317 | } | ||
| 318 | stddev[j] /= (float)n; | ||
| 319 | stddev[j] = sqrt(stddev[j]); | ||
| 320 | /* The following in an inelegant but usual way to handle | ||
| 321 | near-zero std. dev. values, which below would cause a zero- | ||
| 322 | divide. */ | ||
| 323 | if (stddev[j] <= eps) stddev[j] = 1.0; | ||
| 324 | } | ||
| 325 | |||
| 326 | printf("\nStandard deviations of columns:\n"); | ||
| 327 | for (j = 1; j <= m; j++) { printf("%7.1f", stddev[j]); } | ||
| 328 | printf("\n"); | ||
| 329 | |||
| 330 | /* Center and reduce the column vectors. */ | ||
| 331 | |||
| 332 | for (i = 1; i <= n; i++) | ||
| 333 | { | ||
| 334 | for (j = 1; j <= m; j++) | ||
| 335 | { | ||
| 336 | data[i][j] -= mean[j]; | ||
| 337 | x = sqrt((float)n); | ||
| 338 | x *= stddev[j]; | ||
| 339 | data[i][j] /= x; | ||
| 340 | printf("value is %lf\n",data[i][j]); | ||
| 341 | } | ||
| 342 | } | ||
| 343 | |||
| 344 | /* Calculate the m * m correlation matrix. */ | ||
| 345 | for (j1 = 1; j1 <= m-1; j1++) | ||
| 346 | { | ||
| 347 | symmat[j1][j1] = 1.0; | ||
| 348 | for (j2 = j1+1; j2 <= m; j2++) | ||
| 349 | { | ||
| 350 | symmat[j1][j2] = 0.0; | ||
| 351 | for (i = 1; i <= n; i++) | ||
| 352 | { | ||
| 353 | symmat[j1][j2] += ( data[i][j1] * data[i][j2]); | ||
| 354 | printf("multiplying values [%d][%d] * [%d][%d]\n",i,j1,i,j2); | ||
| 355 | printf("Multiplying %lf and %lf\n",data[i][j1],data[i][j2]); | ||
| 356 | |||
| 357 | printf("Value at %d %d = %lf\n",j1,j2,symmat[j1][j2]); | ||
| 358 | } | ||
| 359 | printf("**SPLIT**\n"); | ||
| 360 | printf("swapping [%d] [%d] = [%d] [%d]\n",j2,j1, j1,j2); | ||
| 361 | |||
| 362 | symmat[j2][j1] = symmat[j1][j2]; | ||
| 363 | } | ||
| 364 | } | ||
| 365 | symmat[m][m] = 1.0; | ||
| 366 | |||
| 367 | |||
| 368 | return; | ||
| 369 | |||
| 370 | } | ||
| 371 | |||
| 372 | /** Variance-covariance matrix: creation *****************************/ | ||
| 373 | |||
| 374 | void covcol(data, n, m, symmat) | ||
| 375 | float **data, **symmat; | ||
| 376 | int n, m; | ||
| 377 | /* Create m * m covariance matrix from given n * m data matrix. */ | ||
| 378 | { | ||
| 379 | float *mean, *vector(); | ||
| 380 | int i, j, j1, j2; | ||
| 381 | |||
| 382 | /* Allocate storage for mean vector */ | ||
| 383 | |||
| 384 | mean = vector(m); | ||
| 385 | |||
| 386 | /* Determine mean of column vectors of input data matrix */ | ||
| 387 | |||
| 388 | for (j = 1; j <= m; j++) | ||
| 389 | { | ||
| 390 | mean[j] = 0.0; | ||
| 391 | for (i = 1; i <= n; i++) | ||
| 392 | { | ||
| 393 | mean[j] += data[i][j]; | ||
| 394 | } | ||
| 395 | mean[j] /= (float)n; | ||
| 396 | } | ||
| 397 | |||
| 398 | printf("\nMeans of column vectors:\n"); | ||
| 399 | for (j = 1; j <= m; j++) { | ||
| 400 | printf("%7.1f",mean[j]); } printf("\n"); | ||
| 401 | |||
| 402 | /* Center the column vectors. */ | ||
| 403 | |||
| 404 | for (i = 1; i <= n; i++) | ||
| 405 | { | ||
| 406 | for (j = 1; j <= m; j++) | ||
| 407 | { | ||
| 408 | data[i][j] -= mean[j]; | ||
| 409 | } | ||
| 410 | } | ||
| 411 | |||
| 412 | /* Calculate the m * m covariance matrix. */ | ||
| 413 | for (j1 = 1; j1 <= m; j1++) | ||
| 414 | { | ||
| 415 | for (j2 = j1; j2 <= m; j2++) | ||
| 416 | { | ||
| 417 | symmat[j1][j2] = 0.0; | ||
| 418 | for (i = 1; i <= n; i++) | ||
| 419 | { | ||
| 420 | symmat[j1][j2] += data[i][j1] * data[i][j2]; | ||
| 421 | } | ||
| 422 | symmat[j2][j1] = symmat[j1][j2]; | ||
| 423 | } | ||
| 424 | } | ||
| 425 | |||
| 426 | return; | ||
| 427 | |||
| 428 | } | ||
| 429 | |||
| 430 | /** Sums-of-squares-and-cross-products matrix: creation **************/ | ||
| 431 | |||
| 432 | void scpcol(data, n, m, symmat) | ||
| 433 | float **data, **symmat; | ||
| 434 | int n, m; | ||
| 435 | /* Create m * m sums-of-cross-products matrix from n * m data matrix. */ | ||
| 436 | { | ||
| 437 | int i, j1, j2; | ||
| 438 | |||
| 439 | /* Calculate the m * m sums-of-squares-and-cross-products matrix. */ | ||
| 440 | |||
| 441 | for (j1 = 1; j1 <= m; j1++) | ||
| 442 | { | ||
| 443 | for (j2 = j1; j2 <= m; j2++) | ||
| 444 | { | ||
| 445 | symmat[j1][j2] = 0.0; | ||
| 446 | for (i = 1; i <= n; i++) | ||
| 447 | { | ||
| 448 | symmat[j1][j2] += data[i][j1] * data[i][j2]; | ||
| 449 | } | ||
| 450 | symmat[j2][j1] = symmat[j1][j2]; | ||
| 451 | } | ||
| 452 | } | ||
| 453 | |||
| 454 | return; | ||
| 455 | |||
| 456 | } | ||
| 457 | |||
| 458 | /** Error handler **************************************************/ | ||
| 459 | |||
| 460 | void erhand(err_msg) | ||
| 461 | char err_msg[]; | ||
| 462 | /* Error handler */ | ||
| 463 | { | ||
| 464 | fprintf(stderr,"Run-time error:\n"); | ||
| 465 | fprintf(stderr,"%s\n", err_msg); | ||
| 466 | fprintf(stderr,"Exiting to system.\n"); | ||
| 467 | exit(1); | ||
| 468 | } | ||
| 469 | |||
| 470 | /** Allocation of vector storage ***********************************/ | ||
| 471 | |||
| 472 | float *vector(n) | ||
| 473 | int n; | ||
| 474 | /* Allocates a float vector with range [1..n]. */ | ||
| 475 | { | ||
| 476 | |||
| 477 | float *v; | ||
| 478 | |||
| 479 | v = (float *) malloc ((unsigned) n*sizeof(float)); | ||
| 480 | if (!v) erhand("Allocation failure in vector()."); | ||
| 481 | return v-1; | ||
| 482 | |||
| 483 | } | ||
| 484 | |||
| 485 | /** Allocation of float matrix storage *****************************/ | ||
| 486 | |||
| 487 | float **matrix(n,m) | ||
| 488 | int n, m; | ||
| 489 | /* Allocate a float matrix with range [1..n][1..m]. */ | ||
| 490 | { | ||
| 491 | int i; | ||
| 492 | float **mat; | ||
| 493 | |||
| 494 | /* Allocate pointers to rows. */ | ||
| 495 | mat = (float **) malloc((unsigned) (n)*sizeof(float*)); | ||
| 496 | if (!mat) erhand("Allocation failure 1 in matrix()."); | ||
| 497 | mat -= 1; | ||
| 498 | |||
| 499 | /* Allocate rows and set pointers to them. */ | ||
| 500 | for (i = 1; i <= n; i++) | ||
| 501 | { | ||
| 502 | mat[i] = (float *) malloc((unsigned) (m)*sizeof(float)); | ||
| 503 | if (!mat[i]) erhand("Allocation failure 2 in matrix()."); | ||
| 504 | mat[i] -= 1; | ||
| 505 | } | ||
| 506 | |||
| 507 | /* Return pointer to array of pointers to rows. */ | ||
| 508 | return mat; | ||
| 509 | |||
| 510 | } | ||
| 511 | |||
| 512 | /** Deallocate vector storage *********************************/ | ||
| 513 | |||
| 514 | void free_vector(v,n) | ||
| 515 | float *v; | ||
| 516 | int n; | ||
| 517 | /* Free a float vector allocated by vector(). */ | ||
| 518 | { | ||
| 519 | free((char*) (v+1)); | ||
| 520 | } | ||
| 521 | |||
| 522 | /** Deallocate float matrix storage ***************************/ | ||
| 523 | |||
| 524 | void free_matrix(mat,n,m) | ||
| 525 | float **mat; | ||
| 526 | int n, m; | ||
| 527 | /* Free a float matrix allocated by matrix(). */ | ||
| 528 | { | ||
| 529 | int i; | ||
| 530 | |||
| 531 | for (i = n; i >= 1; i--) | ||
| 532 | { | ||
| 533 | free ((char*) (mat[i]+1)); | ||
| 534 | } | ||
| 535 | free ((char*) (mat+1)); | ||
| 536 | } | ||
| 537 | |||
| 538 | /** Reduce a real, symmetric matrix to a symmetric, tridiag. matrix. */ | ||
| 539 | |||
| 540 | void tred2(a, n, d, e) | ||
| 541 | float **a, *d, *e; | ||
| 542 | /* float **a, d[], e[]; */ | ||
| 543 | int n; | ||
| 544 | /* Householder reduction of matrix a to tridiagonal form. | ||
| 545 | Algorithm: Martin et al., Num. Math. 11, 181-195, 1968. | ||
| 546 | Ref: Smith et al., Matrix Eigensystem Routines -- EISPACK Guide | ||
| 547 | Springer-Verlag, 1976, pp. 489-494. | ||
| 548 | W H Press et al., Numerical Recipes in C, Cambridge U P, | ||
| 549 | 1988, pp. 373-374. */ | ||
| 550 | { | ||
| 551 | int l, k, j, i; | ||
| 552 | float scale, hh, h, g, f; | ||
| 553 | |||
| 554 | for (i = n; i >= 2; i--) | ||
| 555 | { | ||
| 556 | l = i - 1; | ||
| 557 | h = scale = 0.0; | ||
| 558 | if (l > 1) | ||
| 559 | { | ||
| 560 | for (k = 1; k <= l; k++) | ||
| 561 | scale += fabs(a[i][k]); | ||
| 562 | if (scale == 0.0) | ||
| 563 | e[i] = a[i][l]; | ||
| 564 | else | ||
| 565 | { | ||
| 566 | for (k = 1; k <= l; k++) | ||
| 567 | { | ||
| 568 | a[i][k] /= scale; | ||
| 569 | h += a[i][k] * a[i][k]; | ||
| 570 | } | ||
| 571 | f = a[i][l]; | ||
| 572 | g = f>0 ? -sqrt(h) : sqrt(h); | ||
| 573 | e[i] = scale * g; | ||
| 574 | h -= f * g; | ||
| 575 | a[i][l] = f - g; | ||
| 576 | f = 0.0; | ||
| 577 | for (j = 1; j <= l; j++) | ||
| 578 | { | ||
| 579 | a[j][i] = a[i][j]/h; | ||
| 580 | g = 0.0; | ||
| 581 | for (k = 1; k <= j; k++) | ||
| 582 | g += a[j][k] * a[i][k]; | ||
| 583 | for (k = j+1; k <= l; k++) | ||
| 584 | g += a[k][j] * a[i][k]; | ||
| 585 | e[j] = g / h; | ||
| 586 | f += e[j] * a[i][j]; | ||
| 587 | } | ||
| 588 | hh = f / (h + h); | ||
| 589 | for (j = 1; j <= l; j++) | ||
| 590 | { | ||
| 591 | f = a[i][j]; | ||
| 592 | e[j] = g = e[j] - hh * f; | ||
| 593 | for (k = 1; k <= j; k++) | ||
| 594 | a[j][k] -= (f * e[k] + g * a[i][k]); | ||
| 595 | } | ||
| 596 | } | ||
| 597 | } | ||
| 598 | else | ||
| 599 | e[i] = a[i][l]; | ||
| 600 | d[i] = h; | ||
| 601 | } | ||
| 602 | d[1] = 0.0; | ||
| 603 | e[1] = 0.0; | ||
| 604 | for (i = 1; i <= n; i++) | ||
| 605 | { | ||
| 606 | l = i - 1; | ||
| 607 | if (d[i]) | ||
| 608 | { | ||
| 609 | for (j = 1; j <= l; j++) | ||
| 610 | { | ||
| 611 | g = 0.0; | ||
| 612 | for (k = 1; k <= l; k++) | ||
| 613 | g += a[i][k] * a[k][j]; | ||
| 614 | for (k = 1; k <= l; k++) | ||
| 615 | a[k][j] -= g * a[k][i]; | ||
| 616 | } | ||
| 617 | } | ||
| 618 | d[i] = a[i][i]; | ||
| 619 | a[i][i] = 1.0; | ||
| 620 | for (j = 1; j <= l; j++) | ||
| 621 | a[j][i] = a[i][j] = 0.0; | ||
| 622 | } | ||
| 623 | } | ||
| 624 | |||
| 625 | /** Tridiagonal QL algorithm -- Implicit **********************/ | ||
| 626 | |||
| 627 | void tqli(d, e, n, z) | ||
| 628 | float d[], e[], **z; | ||
| 629 | int n; | ||
| 630 | { | ||
| 631 | int m, l, iter, i, k; | ||
| 632 | float s, r, p, g, f, dd, c, b; | ||
| 633 | void erhand(); | ||
| 634 | |||
| 635 | for (i = 2; i <= n; i++) | ||
| 636 | e[i-1] = e[i]; | ||
| 637 | e[n] = 0.0; | ||
| 638 | for (l = 1; l <= n; l++) | ||
| 639 | { | ||
| 640 | iter = 0; | ||
| 641 | do | ||
| 642 | { | ||
| 643 | for (m = l; m <= n-1; m++) | ||
| 644 | { | ||
| 645 | dd = fabs(d[m]) + fabs(d[m+1]); | ||
| 646 | if (fabs(e[m]) + dd == dd) break; | ||
| 647 | } | ||
| 648 | if (m != l) | ||
| 649 | { | ||
| 650 | if (iter++ == 30) erhand("No convergence in TLQI."); | ||
| 651 | g = (d[l+1] - d[l]) / (2.0 * e[l]); | ||
| 652 | r = sqrt((g * g) + 1.0); | ||
| 653 | g = d[m] - d[l] + e[l] / (g + SIGN(r, g)); | ||
| 654 | s = c = 1.0; | ||
| 655 | p = 0.0; | ||
| 656 | for (i = m-1; i >= l; i--) | ||
| 657 | { | ||
| 658 | f = s * e[i]; | ||
| 659 | b = c * e[i]; | ||
| 660 | if (fabs(f) >= fabs(g)) | ||
| 661 | { | ||
| 662 | c = g / f; | ||
| 663 | r = sqrt((c * c) + 1.0); | ||
| 664 | e[i+1] = f * r; | ||
| 665 | c *= (s = 1.0/r); | ||
| 666 | } | ||
| 667 | else | ||
| 668 | { | ||
| 669 | s = f / g; | ||
| 670 | r = sqrt((s * s) + 1.0); | ||
| 671 | e[i+1] = g * r; | ||
| 672 | s *= (c = 1.0/r); | ||
| 673 | } | ||
| 674 | g = d[i+1] - p; | ||
| 675 | r = (d[i] - g) * s + 2.0 * c * b; | ||
| 676 | p = s * r; | ||
| 677 | d[i+1] = g + p; | ||
| 678 | g = c * r - b; | ||
| 679 | for (k = 1; k <= n; k++) | ||
| 680 | { | ||
| 681 | f = z[k][i+1]; | ||
| 682 | z[k][i+1] = s * z[k][i] + c * f; | ||
| 683 | z[k][i] = c * z[k][i] - s * f; | ||
| 684 | } | ||
| 685 | } | ||
| 686 | d[l] = d[l] - p; | ||
| 687 | e[l] = g; | ||
| 688 | e[m] = 0.0; | ||
| 689 | } | ||
| 690 | } while (m != l); | ||
| 691 | } | ||
| 692 | } | ||
| 693 | |||
| 694 | |||
