matrix.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stddef.h>
  4. #include <math.h>
  5. #include "FEVtypes.h"
  6. #include "FEV.h"
  7. /***********simplified versions with ranges [0,N-1] **************/
  8. /*Vectors are columns*/
  9. dvec dvector(int n){
  10. return (dvec) malloc(n*sizeof(double));
  11. }
  12. void dvec_free(dvec v){
  13. free((char*) v);
  14. }
  15. /* dvec is double-precision vector data, used below for rows. dmat is
  16. double-precision matrix data, the third field of a matrix struct.*/
  17. /* create matrix by allocating r c-long vectors for the rows,
  18. a vector of pointers to rows, and a pointer to the latter vector. */
  19. matrix_t mat_new(int r,int c) /*r rows, c cols*/{
  20. int i;
  21. dmat m;
  22. matrix_t a;
  23. m = (dmat) malloc( r*sizeof(double *));
  24. if (m == NULL) return NULL;
  25. for (i= 0; i<r; i++)
  26. {
  27. m[i] = (dvec) malloc( c*sizeof(double));
  28. if (m[i] == NULL) return NULL;
  29. }
  30. a =(matrix_t) malloc ( sizeof(struct matrix));
  31. if ( a == NULL) return NULL;
  32. a->r = r;
  33. a->c = c;
  34. a->mat = m;
  35. a-> fev_type = MATRIX;
  36. return a;
  37. }
  38. /* can't just free the pointer to the matrix, there's no garbage collection */
  39. void mat_free(matrix_t m){
  40. int i,r;
  41. r =m->r;
  42. for (i = 0; i<r; i++) free ((char *) m->mat[i]);
  43. free((char *) m->mat);
  44. free((char *) m);
  45. }
  46. /* not much of an error function...*/
  47. void cberror (char *msg)
  48. {
  49. fprintf(stderr, "\n %s \n", msg);
  50. }
  51. /* print out a matrix in a human-readable form */
  52. int mat_pr(char *msg, matrix_t m, FILE *fout) {
  53. int i,j;
  54. int r,c;
  55. if (msg == NULL) {
  56. cberror("null message arg in mat_pr");
  57. return NILARG1;
  58. }
  59. if (m == NULL) {
  60. cberror("null matrix arg in mat_pr");
  61. return NILARG2;
  62. }
  63. r = m->r;
  64. c = m->c;
  65. if(fout == NULL){
  66. printf("MATRIX: %s Type: %d , Dims %d, %d\n", msg,m->fev_type,r,c);
  67. for (i=0; i<r; i++){
  68. for (j=0; j<c; j++)
  69. printf("%.2f ",m->mat[i][j]);
  70. printf("\n");
  71. }
  72. printf("~\n");
  73. return OK;
  74. } else {
  75. fprintf(fout, "MATRIX: %s Type: %d , Dims %d, %d\n", msg,m->fev_type,r,c);
  76. for (i=0; i<r; i++){
  77. for (j=0; j<c; j++)
  78. fprintf(fout, "%.2f ",m->mat[i][j]);
  79. fprintf(fout, "\n");
  80. }
  81. fprintf(fout, "~\n");
  82. return OK;
  83. }
  84. }
  85. /* create a matrix from the output of mat_pr, stored in a file (fname) */
  86. matrix_t mat_frd(char* fname){
  87. int i, j;
  88. float n;
  89. int r, c, assigned;
  90. matrix_t m;
  91. FILE *fmat;
  92. fmat = fopen(fname, "r");
  93. assigned = fscanf(fmat, "MATRIX: %*s Type: %*d , Dims %d, %d\n",
  94. &r, &c);
  95. if (assigned != 2) {
  96. cberror("incorrectly formatted matrix file");
  97. return (matrix_t) NULL;
  98. }
  99. m = mat_new(r, c);
  100. for (i = 0; i < r; i++) {
  101. for (j=0; j<c; j++) {
  102. /* get each number */
  103. assigned = fscanf(fmat, "%f ", &n);
  104. if(assigned != 1) {
  105. cberror("Formatting error");
  106. return (matrix_t) NULL;
  107. }
  108. e(m, i, j) = n;
  109. }
  110. fscanf(fmat, "\n"); //end of each row
  111. }
  112. fclose(fmat);
  113. return m;
  114. }
  115. /* multiply two matrices a and b; return the result as a new matrix */
  116. matrix_t mat_mpy(matrix_t a, matrix_t b){
  117. int i, j, k;
  118. int r, c, n;
  119. matrix_t m; //output matrix
  120. /* dims of output matrix*/
  121. r = a->r;
  122. c = b->c;
  123. if (a->c != b->r) {
  124. cberror("incompatible matrices; could not multiply");
  125. return (matrix_t) NULL;
  126. }
  127. n = a->c;
  128. m = mat_new(r, c);
  129. for (i=0; i<r; i++) {
  130. for (j=0; j<c; j++) {
  131. for (k=0; k<n; k++) {
  132. e(m, i, j) += e(a, i, k)*e(b, k, j);
  133. }
  134. }
  135. }
  136. return m;
  137. }
  138. /* add two matrices a and b: multiply b by scalar sign,
  139. add to a, and return result */
  140. matrix_t mat_add(matrix_t a, matrix_t b, int sign){
  141. int i, j;
  142. int r, c;
  143. matrix_t m;
  144. /* dims of output matrix - same as a and b */
  145. r = a->r;
  146. c = b->c;
  147. if ((r != b->r) || (c != a->c)) {
  148. cberror("matrices of different size; could not add");
  149. return (matrix_t) NULL;
  150. }
  151. m = mat_new(r, c);
  152. for (i=0; i<r; i++) {
  153. for (j=0; j<c; j++) {
  154. m->mat[i][j] = (e(b, i, j)*sign) + e(a, i, j);
  155. }
  156. }
  157. return m;
  158. }