home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / math / matrix.arc / MATRIX.S / text0000.txt < prev   
Encoding:
Text File  |  1985-01-13  |  11.4 KB  |  475 lines

  1. These might be of general interest. Sorry I don't have a makefile
  2. for it, but there are no complex dependency problems.
  3.  
  4. : Run this shell script with "sh" not "csh"
  5. PATH=:/bin:/usr/bin:/usr/ucb
  6. export PATH
  7. all=FALSE
  8. if [ $1x = -ax ]; then
  9.     all=TRUE
  10. fi
  11. /bin/echo 'Extracting matrix.3l'
  12. sed 's/^X//' <<'//go.sysin dd *' >matrix.3l
  13. X.TH MATRIX 3L 12-Oct-1982
  14. X.SH NAME
  15. m_cofactor,  m_copy, m_determ, m_invert, m_multiply, m_solve,
  16. m_transpose \- matrix manipulation subroutines
  17. X.SH SYNOPSIS
  18. X.B #include <local/mat.h>
  19. X.br
  20. X.B cc "*.c" -lmatrix
  21. X.PP
  22. X.B double m_cofactor(m, i, j);
  23. X.br
  24. X.B struct matrix *m;
  25. X.br
  26. X.B int i, j;
  27. X.PP
  28. X.B struct matrix *m_copy(m);
  29. X.br
  30. X.B struct matrix *m;
  31. X.br
  32. X.PP
  33. X.B double m_determ(m);
  34. X.br
  35. X.B struct matrix *m;
  36. X.PP
  37. X.B struct matrix *m_invert(m);
  38. X.br
  39. X.B struct matrix *m;
  40. X.PP
  41. X.B struct matrix *m_multiply(m1, m2);
  42. X.br
  43. X.B struct matrix *m1;
  44. X.br
  45. X.B struct matrix *m2;
  46. X.PP
  47. X.B struct matrix *m_solve(a, b);
  48. X.br
  49. X.B struct matrix *a;
  50. X.br
  51. X.B struct matrix *b;
  52. X.PP
  53. X.B struct matrix *m_transpose(m);
  54. X.br
  55. X.B struct matrix *m;
  56. X.SH DESCRIPTION
  57. This set of subroutines does several useful operations on matrices which are
  58. stored in a standard format (defined in /usr/include/local/matrix.h).
  59. Space for matrices is allocated and freed by the subroutines
  60. X.I malloc
  61. and
  62. X.I free.
  63. Matrices should be initialized by the macro
  64. X.I m_create,
  65. and can be disposed of by passing a pointer to the matrix to
  66. X.I free.
  67. X.PP
  68. X.I m_cofactor\c
  69. (m, i, j) returns the cofactor, as type
  70. X.I double,
  71. of element (i, j) of the matrix given by its first argument.
  72. That is: the determinant of the matrix obtained by deleting row
  73. X.I i
  74. and column
  75. X.I j
  76. from the matrix
  77. X.I m,
  78. multiplied by
  79. X.br
  80. (-1)**(i+j).
  81. X.PP
  82. X.I m_copy\c
  83. (m) returns a duplicate copy of the matrix
  84. X.I m.
  85. X.PP
  86. X.I m_determ\c
  87. (m) returns the determinant of the matrix m as type
  88. X.I double.
  89. X.PP
  90. X.I m_invert\c
  91. (m) returns a matrix (if it exists) which is the inverse of the matrix
  92. X.I m.
  93. X.PP
  94. X.I m_multiply\c
  95. (m1, m2) returns a matrix which is the result of multiplying matrix
  96. X.I m1
  97. by matrix
  98. X.I m2
  99. by the conventional definition of matrix multiplication. The number of
  100. columns in
  101. X.I m1
  102. must be the same as the number of rows in
  103. X.I m2.
  104. X.PP
  105. X.I m_solve\c
  106. (a, b) returns the matrix which results from computing: (a'\ a)**(-1)\ a'\ b.
  107. This is useful for solving a set of linear equations expressed as matrices:
  108. a\ x\ =\ b.
  109. X.PP
  110. X.I m_transpose\c
  111. (m) returns the matrix which is the transpose of
  112. X.I m.
  113. X.PP
  114. X.I m_create\c
  115. (m, r, c) (which is a macro, not a function) allocates space for,
  116. and initializes the matrix
  117. X.I
  118. m
  119. to have
  120. X.I r
  121. rows and
  122. X.I c
  123. columns.
  124. X.PP
  125. X.I m_v\c
  126. (m, r, c) is a macro used to access element
  127. X.I (r, c)
  128. of the matrix
  129. X.I m.
  130. The elements are always of type double.
  131. X.SH AUTHOR
  132. Fred Blonder <fred@umcp-cs>
  133. X.SH "SEE ALSO"
  134. malloc(3), free(3), printf(3)
  135. X.SH DIAGNOSTICS
  136. Most routines return the constant
  137. X.I M_NULL
  138. to report an error. Some also write messages to the standard output via
  139. X.I printf.
  140. X.SH FILES
  141. X/usr/include/local/matrix.h
  142. X.br
  143. X/usr/lib/libmatrix.a
  144. X.SH BUGS
  145. Error reporting via
  146. X.I printf
  147. should be an option.
  148. //go.sysin dd *
  149. made=TRUE
  150. if [ $made = TRUE ]; then
  151.     /bin/chmod 644 matrix.3l
  152.     /bin/echo -n '    '; /bin/ls -ld matrix.3l
  153. fi
  154. /bin/echo 'Extracting mat.h'
  155. sed 's/^X//' <<'//go.sysin dd *' >mat.h
  156. struct matrix {
  157.     int m_rows, m_cols;
  158.     };
  159.  
  160. struct m_ {
  161.     int m_rows, m_cols;
  162.     double m_value[1];
  163.     };
  164.  
  165. double m_cofactor(), m_determinant();
  166. struct matrix *m_copy(), *m_invert(), *m_transpose(), *m_multiply(), *m_solve();
  167.  
  168. #define    m_v(m, r, c)    ((struct m_ *)m)->m_value[r * (m->m_cols) + c]
  169. #define    M_NULL    ((struct matrix *)0)
  170.  
  171. #define    m_create(m, r, c) {\
  172.             if (((int)(m = (struct matrix *)malloc(sizeof(struct matrix) + (sizeof(double) * r * c)))) == 0) {\
  173.                 printf("Allocation error: %s\n", __FILE__);\
  174.                 exit(1);\
  175.                 }\
  176.             m->m_rows = r;\
  177.             m->m_cols = c;\
  178.             }
  179. //go.sysin dd *
  180. made=TRUE
  181. if [ $made = TRUE ]; then
  182.     /bin/chmod 644 mat.h
  183.     /bin/echo -n '    '; /bin/ls -ld mat.h
  184. fi
  185. /bin/echo 'Extracting m_cofactor.c'
  186. sed 's/^X//' <<'//go.sysin dd *' >m_cofactor.c
  187. static char *sccsid = "@(#)m_cofactor.c    4/5/82 (U of Maryland, FLB)";
  188.  
  189. #include "mat.h"
  190.  
  191. double
  192. m_cofactor(mat, i, j)
  193. register struct matrix *mat;
  194. register int i, j;
  195. {
  196. register struct matrix *result;
  197. register int row, col, o_row = 0, o_col = 0;
  198. double det;
  199.  
  200. m_create(result, mat->m_rows - 1, mat->m_cols - 1);
  201.  
  202. for (row = 0; row < mat->m_rows; row++)
  203.     for (col = 0; col < mat->m_cols; col++)
  204.         if (row != i && col != j)
  205.             m_v(result, o_row++, o_col++) = m_v(mat, row, col);
  206.  
  207. det = m_determinant(result);
  208. free(result);
  209.  
  210. return(((i + j) & 01)? -det: det);
  211. }
  212. //go.sysin dd *
  213. made=TRUE
  214. if [ $made = TRUE ]; then
  215.     /bin/chmod 644 m_cofactor.c
  216.     /bin/echo -n '    '; /bin/ls -ld m_cofactor.c
  217. fi
  218. /bin/echo 'Extracting m_copy.c'
  219. sed 's/^X//' <<'//go.sysin dd *' >m_copy.c
  220. static char *sccsid = "@(#)m_copy.c    4/5/82 (U of Maryland, FLB)";
  221.  
  222. #include "mat.h"
  223.  
  224. struct matrix *
  225. m_copy(mat)
  226. register struct matrix *mat;
  227. {
  228. register struct matrix *result;
  229. register int row, col;
  230.  
  231. m_create(result, mat->m_rows, mat->m_cols);
  232.  
  233. for (row = 0; row < mat->m_rows; row++)
  234.     for (col = 0; col < mat->m_cols; col++)
  235.         m_v(result, row, col) = m_v(mat, row, col);
  236.  
  237. return(result);
  238. }
  239. //go.sysin dd *
  240. made=TRUE
  241. if [ $made = TRUE ]; then
  242.     /bin/chmod 644 m_copy.c
  243.     /bin/echo -n '    '; /bin/ls -ld m_copy.c
  244. fi
  245. /bin/echo 'Extracting m_determ.c'
  246. sed 's/^X//' <<'//go.sysin dd *' >m_determ.c
  247. static char *sccsid = "@(#)m_determinant.c    4/5/82 (U of Maryland, FLB)";
  248.  
  249. #include "mat.h"
  250.  
  251. double
  252. m_determinant(mat)
  253. register struct matrix *mat;
  254. {
  255. register int col;
  256. double det = 0.0;
  257.  
  258. if (mat->m_rows == 1)
  259.     return(m_v(mat, 0, 0));
  260.  
  261. for (col = 0; col < mat->m_cols; col++)
  262.     det +=     m_v(mat, 0, col) * m_cofactor(mat, 0, col);
  263.  
  264. return(det);
  265. }
  266. //go.sysin dd *
  267. made=TRUE
  268. if [ $made = TRUE ]; then
  269.     /bin/chmod 644 m_determ.c
  270.     /bin/echo -n '    '; /bin/ls -ld m_determ.c
  271. fi
  272. /bin/echo 'Extracting m_dump.c'
  273. sed 's/^X//' <<'//go.sysin dd *' >m_dump.c
  274. static char *sccsid = "@(#)m_dump.c    4/6/82 (U of Maryland, FLB)";
  275.  
  276. #include "mat.h"
  277.  
  278. struct matrix *
  279. m_dump(mat)
  280. register struct matrix *mat;
  281. {
  282. register int row, col;
  283.  
  284. printf("%d X %d\n", mat->m_rows, mat->m_cols);
  285.  
  286. for (row = 0; row < mat->m_rows; row++) {
  287.     for (col = 0; col < mat->m_cols; col++)
  288.         printf("%f, ", m_v(mat, row, col));
  289.     putchar('\n');
  290.     }
  291. }
  292. //go.sysin dd *
  293. made=TRUE
  294. if [ $made = TRUE ]; then
  295.     /bin/chmod 644 m_dump.c
  296.     /bin/echo -n '    '; /bin/ls -ld m_dump.c
  297. fi
  298. /bin/echo 'Extracting m_invert.c'
  299. sed 's/^X//' <<'//go.sysin dd *' >m_invert.c
  300. static char *sccsid = "@(#)m_invert.c    4/7/82 (U of Maryland, FLB)";
  301.  
  302. #include "mat.h"
  303.  
  304. struct matrix *
  305. m_invert(mat)
  306. register struct matrix *mat;
  307. {
  308. register struct matrix *result;
  309. register int row, col;
  310. double det;
  311.  
  312. if((det = m_determinant(mat)) == 0.0) {
  313.     printf("m_invert: singular matrix\n");
  314.     return(M_NULL);
  315.     }
  316.  
  317. m_create(result, mat->m_cols, mat->m_rows);
  318.  
  319. for (row = 0; row < mat->m_rows; row++)
  320.     for (col = 0; col < mat->m_cols; col++)
  321.         m_v(result, col, row) = m_cofactor(mat, row, col) / det;
  322.  
  323. return(result);
  324. }
  325. //go.sysin dd *
  326. made=TRUE
  327. if [ $made = TRUE ]; then
  328.     /bin/chmod 644 m_invert.c
  329.     /bin/echo -n '    '; /bin/ls -ld m_invert.c
  330. fi
  331. /bin/echo 'Extracting m_multiply.c'
  332. sed 's/^X//' <<'//go.sysin dd *' >m_multiply.c
  333. static char *sccsid = "@(#)m_multiply.c    4/6/82 (U of Maryland, FLB)";
  334.  
  335. #include "mat.h"
  336.  
  337. struct matrix *
  338. m_multiply(mat1, mat2)
  339. register struct matrix *mat1, *mat2;
  340. {
  341. register struct matrix *result;
  342. register int row, col, ix;
  343. double sum;
  344.  
  345. if (mat1->m_cols != mat2->m_rows) {
  346.     printf("m_multiply: matrices not compatible.\n");
  347.     return(M_NULL);
  348.     }
  349.  
  350. m_create(result, mat1->m_rows, mat2->m_cols);
  351.  
  352. for (row = 0; row < mat1->m_rows; row++)
  353.     for (col = 0; col < mat2->m_cols; col++) {
  354.         sum = 0.0;
  355.         for (ix = 0; ix < mat1->m_cols; ix++)
  356.             sum += m_v(mat1, row, ix) * m_v(mat2, ix, col);
  357.         m_v(result, row, col) = sum;
  358.         }
  359.  
  360. return(result);
  361. }
  362. //go.sysin dd *
  363. made=TRUE
  364. if [ $made = TRUE ]; then
  365.     /bin/chmod 644 m_multiply.c
  366.     /bin/echo -n '    '; /bin/ls -ld m_multiply.c
  367. fi
  368. /bin/echo 'Extracting m_read.c'
  369. sed 's/^X//' <<'//go.sysin dd *' >m_read.c
  370. static char *sccsid = "@(#)m_read.c    4/6/82 (U of Maryland, FLB)";
  371.  
  372. #include <stdio.h>
  373. #include "mat.h"
  374.  
  375. struct matrix *
  376. m_read()
  377. {
  378. register struct matrix *result;
  379. register int row, col;
  380. int rows, cols;
  381.  
  382. scanf("%d%d", &rows, &cols);
  383. m_create(result, rows, cols);
  384.  
  385. for (row = 0; row < rows; row++)
  386.     for (col = 0; col < cols; col++)
  387.         scanf("%lf", &m_v(result, row, col));
  388.  
  389. return(result);
  390. }
  391. //go.sysin dd *
  392. made=TRUE
  393. if [ $made = TRUE ]; then
  394.     /bin/chmod 644 m_read.c
  395.     /bin/echo -n '    '; /bin/ls -ld m_read.c
  396. fi
  397. /bin/echo 'Extracting m_solve.c'
  398. sed 's/^X//' <<'//go.sysin dd *' >m_solve.c
  399. static char *sccsid = "@(#)m_solve.c    4/16/82 (U of Maryland, FLB)";
  400.  
  401. #include "mat.h"
  402.  
  403. struct matrix *
  404. m_solve(a, b)
  405. register struct matrix *a, *b;
  406. {
  407. register struct matrix *a_trans, *t, *t_inv, *t2, *x;
  408.  
  409. if ((a->m_rows) < (a->m_cols)) {
  410.     printf("m_solve: too few equations\n");
  411.     return(M_NULL);
  412.     }
  413.  
  414. if ((a->m_rows) != (b->m_rows)) {
  415.     printf("m_solve: arguments don't match: %d, %d.\n", a->m_rows, b->m_rows);
  416.     return(M_NULL);
  417.     }
  418.  
  419. if (b->m_cols != 1) {
  420.     printf("m_solve: arg2 must have 1 column.\n");
  421.     return(M_NULL);
  422.     }
  423.  
  424. a_trans = m_transpose(a);        /* A' */
  425. t = m_multiply(a_trans, a);        /* A' A */
  426. t_inv = m_invert(t);            /* (A' A)-1 */
  427. free(t);
  428. if (t_inv == M_NULL) {
  429.     printf("m_solve: no solution\n");
  430.     return(M_NULL);
  431.     }
  432. t2 = m_multiply(t_inv, a_trans);    /* (A' A)-1 A' */
  433. free(t_inv);
  434. free(a_trans);
  435. x = m_multiply(t2, b);            /* (A' A)-1 A' B */
  436. free(t2);
  437.  
  438. return(x);
  439. }
  440. //go.sysin dd *
  441. made=TRUE
  442. if [ $made = TRUE ]; then
  443.     /bin/chmod 644 m_solve.c
  444.     /bin/echo -n '    '; /bin/ls -ld m_solve.c
  445. fi
  446. /bin/echo 'Extracting m_transpose.c'
  447. sed 's/^X//' <<'//go.sysin dd *' >m_transpose.c
  448. static char *sccsid = "@(#)m_transpose.c    4/5/82 (U of Maryland, FLB)";
  449.  
  450. #include "mat.h"
  451.  
  452. struct matrix *
  453. m_transpose(mat)
  454. register struct matrix *mat;
  455. {
  456. register struct matrix *result;
  457. register int row, col;
  458.  
  459. m_create(result, mat->m_cols, mat->m_rows);
  460.  
  461. for (row = 0; row < mat->m_rows; row++)
  462.     for (col = 0; col < mat->m_cols; col++)
  463.         m_v(result, col, row) = m_v(mat, row, col);
  464.  
  465. return(result);
  466. }
  467. //go.sysin dd *
  468. made=TRUE
  469. if [ $made = TRUE ]; then
  470.     /bin/chmod 644 m_transpose.c
  471.     /bin/echo -n '    '; /bin/ls -ld m_transpose.c
  472. fi
  473.  
  474.  
  475.