summaryrefslogtreecommitdiffstats
path: root/SD-VBS/benchmarks/pca/src
diff options
context:
space:
mode:
authorLeo Chan <leochanj@live.unc.edu>2020-10-22 01:53:21 -0400
committerJoshua Bakita <jbakita@cs.unc.edu>2020-10-22 01:56:35 -0400
commitd17b33131c14864bd1eae275f49a3f148e21cf29 (patch)
tree0d8f77922e8d193cb0f6edab83018f057aad64a0 /SD-VBS/benchmarks/pca/src
parent601ed25a4c5b66cb75315832c15613a727db2c26 (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-xSD-VBS/benchmarks/pca/src/pcabin0 -> 21446 bytes
-rw-r--r--SD-VBS/benchmarks/pca/src/pca.c694
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
17Author:
18F. Murtagh
19Phone: + 49 89 32006298 (work)
20+ 49 89 965307 (home)
21Earn/Bitnet: fionn@dgaeso51, fim@dgaipp1s, murtagh@stsci
22Span: esomc1::fionn
23Internet: murtagh@scivax.stsci.edu
24
25F. 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
34main(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"); }
244return;
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
278void 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
374void 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
432void 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
460void 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
472float *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
487float **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
514void 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
524void 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
540void 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.
545Algorithm: Martin et al., Num. Math. 11, 181-195, 1968.
546Ref: Smith et al., Matrix Eigensystem Routines -- EISPACK Guide
547Springer-Verlag, 1976, pp. 489-494.
548W H Press et al., Numerical Recipes in C, Cambridge U P,
5491988, 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
627void 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