matrix.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. /**************************************************************************
  2. **
  3. ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved.
  4. **
  5. ** Meschach Library
  6. **
  7. ** This Meschach Library is provided "as is" without any express
  8. ** or implied warranty of any kind with respect to this software.
  9. ** In particular the authors shall not be liable for any direct,
  10. ** indirect, special, incidental or consequential damages arising
  11. ** in any way from use of the software.
  12. **
  13. ** Everyone is granted permission to copy, modify and redistribute this
  14. ** Meschach Library, provided:
  15. ** 1. All copies contain this copyright notice.
  16. ** 2. All modified copies shall carry a notice stating who
  17. ** made the last modification and the date of such modification.
  18. ** 3. No charge is made for this software or works derived from it.
  19. ** This clause shall not be construed as constraining other software
  20. ** distributed on the same medium as this software, nor is a
  21. ** distribution fee considered a charge.
  22. **
  23. ***************************************************************************/
  24. /*
  25. Type definitions for general purpose maths package
  26. */
  27. #ifndef MATRIXH
  28. /* RCS id: $Id: matrix.h,v 1.18 1994/04/16 00:33:37 des Exp $ */
  29. #define MATRIXH
  30. #include "machine.h"
  31. #include "err.h"
  32. #include "meminfo.h"
  33. /* unsigned integer type */
  34. /************************************************************
  35. #ifndef U_INT_DEF
  36. typedef unsigned int u_int;
  37. #define U_INT_DEF
  38. #endif
  39. ************************************************************/
  40. /* vector definition */
  41. typedef struct {
  42. unsigned int dim, max_dim;
  43. Real *ve;
  44. } VEC;
  45. /* matrix definition */
  46. typedef struct {
  47. unsigned int m, n;
  48. unsigned int max_m, max_n, max_size;
  49. Real **me,*base; /* base is base of alloc'd mem */
  50. } MAT;
  51. /* band matrix definition */
  52. typedef struct {
  53. MAT *mat; /* matrix */
  54. int lb,ub; /* lower and upper bandwidth */
  55. } BAND;
  56. /* permutation definition */
  57. typedef struct {
  58. unsigned int size, max_size, *pe;
  59. } PERM;
  60. /* integer vector definition */
  61. typedef struct {
  62. unsigned int dim, max_dim;
  63. int *ive;
  64. } IVEC;
  65. #ifndef MALLOCDECL
  66. #ifndef ANSI_C
  67. extern char *malloc(), *calloc(), *realloc();
  68. #else
  69. extern void *malloc(size_t),
  70. *calloc(size_t,size_t),
  71. *realloc(void *,size_t);
  72. #endif
  73. #endif /* MALLOCDECL */
  74. /* For creating MEX files (for use with Matlab) using Meschach
  75. See also: mexmesch.h */
  76. #ifdef MEX
  77. #include "mex.h"
  78. #define malloc(len) mxMalloc(len)
  79. #define calloc(n,len) mxCalloc(n,len)
  80. #define realloc(ptr,len) mxRealloc(ptr,len)
  81. #define free(ptr) mxFree(ptr)
  82. #define printf mexPrintf
  83. #ifndef THREADSAFE /* for use as a shared library */
  84. #define THREADSAFE 1
  85. #endif
  86. #endif /* MEX */
  87. #ifdef THREADSAFE
  88. #define STATIC
  89. #else
  90. #define STATIC static
  91. #endif /* THREADSAFE */
  92. #ifndef ANSI_C
  93. extern void m_version();
  94. #else
  95. void m_version( void );
  96. #endif
  97. #ifndef ANSI_C
  98. /* allocate one object of given type */
  99. #define NEW(type) ((type *)calloc((size_t)1,sizeof(type)))
  100. /* allocate num objects of given type */
  101. #define NEW_A(num,type) ((type *)calloc((size_t)(num),sizeof(type)))
  102. /* re-allocate arry to have num objects of the given type */
  103. #define RENEW(var,num,type) \
  104. ((var)=(type *)((var) ? \
  105. realloc((char *)(var),(size_t)(num)*sizeof(type)) : \
  106. calloc((size_t)(num),sizeof(type))))
  107. #define MEMCOPY(from,to,n_items,type) \
  108. MEM_COPY((char *)(from),(char *)(to),(size_t)(n_items)*sizeof(type))
  109. #else
  110. /* allocate one object of given type */
  111. #define NEW(type) ((type *)calloc((size_t)1,(size_t)sizeof(type)))
  112. /* allocate num objects of given type */
  113. #define NEW_A(num,type) ((type *)calloc((size_t)(num),(size_t)sizeof(type)))
  114. /* re-allocate arry to have num objects of the given type */
  115. #define RENEW(var,num,type) \
  116. ((var)=(type *)((var) ? \
  117. realloc((char *)(var),(size_t)((num)*sizeof(type))) : \
  118. calloc((size_t)(num),(size_t)sizeof(type))))
  119. #define MEMCOPY(from,to,n_items,type) \
  120. MEM_COPY((char *)(from),(char *)(to),(unsigned)(n_items)*sizeof(type))
  121. #endif /* ANSI_C */
  122. /* type independent min and max operations */
  123. #ifndef max
  124. #define max(a,b) ((a) > (b) ? (a) : (b))
  125. #endif /* max */
  126. #ifndef min
  127. #define min(a,b) ((a) > (b) ? (b) : (a))
  128. #endif /* min */
  129. #undef TRUE
  130. #define TRUE 1
  131. #undef FALSE
  132. #define FALSE 0
  133. /* for input routines */
  134. #define MAXLINE 81
  135. /* Dynamic memory allocation */
  136. /* Should use M_FREE/V_FREE/PX_FREE in programs instead of m/v/px_free()
  137. as this is considerably safer -- also provides a simple type check ! */
  138. #ifndef ANSI_C
  139. extern VEC *v_get(), *v_resize();
  140. extern MAT *m_get(), *m_resize();
  141. extern PERM *px_get(), *px_resize();
  142. extern IVEC *iv_get(), *iv_resize();
  143. extern int m_free(),v_free();
  144. extern int px_free();
  145. extern int iv_free();
  146. extern BAND *bd_get(), *bd_resize();
  147. extern int bd_free();
  148. #else
  149. /* get/resize vector to given dimension */
  150. extern VEC *v_get(int), *v_resize(VEC *,int);
  151. /* get/resize matrix to be m x n */
  152. extern MAT *m_get(int,int), *m_resize(MAT *,int,int);
  153. /* get/resize permutation to have the given size */
  154. extern PERM *px_get(int), *px_resize(PERM *,int);
  155. /* get/resize an integer vector to given dimension */
  156. extern IVEC *iv_get(int), *iv_resize(IVEC *,int);
  157. /* get/resize a band matrix to given dimension */
  158. extern BAND *bd_get(int,int,int), *bd_resize(BAND *,int,int,int);
  159. /* free (de-allocate) (band) matrices, vectors, permutations and
  160. integer vectors */
  161. extern int iv_free(IVEC *);
  162. extern int m_free(MAT *),v_free(VEC *),px_free(PERM *);
  163. extern int bd_free(BAND *);
  164. #endif /* ANSI_C */
  165. /* MACROS */
  166. /* macros that also check types and sets pointers to NULL */
  167. #define M_FREE(mat) ( m_free(mat), (mat)=(MAT *)NULL )
  168. #define V_FREE(vec) ( v_free(vec), (vec)=(VEC *)NULL )
  169. #define PX_FREE(px) ( px_free(px), (px)=(PERM *)NULL )
  170. #define IV_FREE(iv) ( iv_free(iv), (iv)=(IVEC *)NULL )
  171. #define MAXDIM 10000001
  172. /* Entry level access to data structures */
  173. /* routines to check indexes */
  174. #define m_chk_idx(A,i,j) ((i)>=0 && (i)<(A)->m && (j)>=0 && (j)<=(A)->n)
  175. #define v_chk_idx(x,i) ((i)>=0 && (i)<(x)->dim)
  176. #define bd_chk_idx(A,i,j) ((i)>=max(0,(j)-(A)->ub) && \
  177. (j)>=max(0,(i)-(A)->lb) && (i)<(A)->mat->n && (j)<(A)->mat->n)
  178. #define m_entry(A,i,j) m_get_val(A,i,j)
  179. #define v_entry(x,i) v_get_val(x,i)
  180. #define bd_entry(A,i,j) bd_get_val(A,i,j)
  181. #ifdef DEBUG
  182. #define m_set_val(A,i,j,val) ( m_chk_idx(A,i,j) ? \
  183. (A)->me[(i)][(j)] = (val) : (error(E_BOUNDS,"m_set_val"), 0.0))
  184. #define m_add_val(A,i,j,val) ( m_chk_idx(A,i,j) ? \
  185. (A)->me[(i)][(j)] += (val) : (error(E_BOUNDS,"m_add_val"), 0.0))
  186. #define m_sub_val(A,i,j,val) ( m_chk_idx(A,i,j) ? \
  187. (A)->me[(i)][(j)] -= (val) : (error(E_BOUNDS,"m_sub_val"), 0.0))
  188. #define m_get_val(A,i,j) ( m_chk_idx(A,i,j) ? \
  189. (A)->me[(i)][(j)] : (error(E_BOUNDS,"m_get_val"), 0.0))
  190. #define v_set_val(x,i,val) ( v_chk_idx(x,i) ? (x)->ve[(i)] = (val) : \
  191. (error(E_BOUNDS,"v_set_val"), 0.0))
  192. #define v_add_val(x,i,val) ( v_chk_idx(x,i) ? (x)->ve[(i)] += (val) : \
  193. (error(E_BOUNDS,"v_set_val"), 0.0))
  194. #define v_sub_val(x,i,val) ( v_chk_idx(x,i) ? (x)->ve[(i)] -= (val) : \
  195. (error(E_BOUNDS,"v_set_val"), 0.0))
  196. #define v_get_val(x,i) ( v_chk_idx(x,i) ? (x)->ve[(i)] : \
  197. (error(E_BOUNDS,"v_get_val"), 0.0))
  198. #define bd_set_val(A,i,j,val) ( bd_chk_idx(A,i,j) ? \
  199. (A)->mat->me[(A)->lb+(j)-(i)][(j)] = (val) : \
  200. (error(E_BOUNDS,"bd_set_val"), 0.0))
  201. #define bd_add_val(A,i,j,val) ( bd_chk_idx(A,i,j) ? \
  202. (A)->mat->me[(A)->lb+(j)-(i)][(j)] += (val) : \
  203. (error(E_BOUNDS,"bd_set_val"), 0.0))
  204. #define bd_get_val(A,i,j) ( bd_chk_idx(A,i,j) ? \
  205. (A)->mat->me[(A)->lb+(j)-(i)][(j)] : \
  206. (error(E_BOUNDS,"bd_get_val"), 0.0))
  207. #else /* no DEBUG */
  208. #define m_set_val(A,i,j,val) ((A)->me[(i)][(j)] = (val))
  209. #define m_add_val(A,i,j,val) ((A)->me[(i)][(j)] += (val))
  210. #define m_sub_val(A,i,j,val) ((A)->me[(i)][(j)] -= (val))
  211. #define m_get_val(A,i,j) ((A)->me[(i)][(j)])
  212. #define v_set_val(x,i,val) ((x)->ve[(i)] = (val))
  213. #define v_add_val(x,i,val) ((x)->ve[(i)] += (val))
  214. #define v_sub_val(x,i,val) ((x)->ve[(i)] -= (val))
  215. #define v_get_val(x,i) ((x)->ve[(i)])
  216. #define bd_set_val(A,i,j,val) ((A)->mat->me[(A)->lb+(j)-(i)][(j)] = (val))
  217. #define bd_add_val(A,i,j,val) ((A)->mat->me[(A)->lb+(j)-(i)][(j)] += (val))
  218. #define bd_get_val(A,i,j) ((A)->mat->me[(A)->lb+(j)-(i)][(j)])
  219. #endif /* DEBUG */
  220. /* I/O routines */
  221. #ifndef ANSI_C
  222. extern void v_foutput(),m_foutput(),px_foutput();
  223. extern void iv_foutput();
  224. extern VEC *v_finput();
  225. extern MAT *m_finput();
  226. extern PERM *px_finput();
  227. extern IVEC *iv_finput();
  228. extern int fy_or_n(), fin_int(), yn_dflt(), skipjunk();
  229. extern double fin_double();
  230. #else
  231. /* print x on file fp */
  232. void v_foutput(FILE *fp,const VEC *x),
  233. /* print A on file fp */
  234. m_foutput(FILE *fp,const MAT *A),
  235. /* print px on file fp */
  236. px_foutput(FILE *fp,const PERM *px);
  237. /* print ix on file fp */
  238. void iv_foutput(FILE *fp,const IVEC *ix);
  239. /* Note: if out is NULL, then returned object is newly allocated;
  240. Also: if out is not NULL, then that size is assumed */
  241. /* read in vector from fp */
  242. VEC *v_finput(FILE *fp,VEC *out);
  243. /* read in matrix from fp */
  244. MAT *m_finput(FILE *fp,MAT *out);
  245. /* read in permutation from fp */
  246. PERM *px_finput(FILE *fp,PERM *out);
  247. /* read in int vector from fp */
  248. IVEC *iv_finput(FILE *fp,IVEC *out);
  249. /* fy_or_n -- yes-or-no to question in string s
  250. -- question written to stderr, input from fp
  251. -- if fp is NOT a tty then return y_n_dflt */
  252. int fy_or_n(FILE *fp, const char *s);
  253. /* yn_dflt -- sets the value of y_n_dflt to val */
  254. int yn_dflt(int val);
  255. /* fin_int -- return integer read from file/stream fp
  256. -- prompt s on stderr if fp is a tty
  257. -- check that x lies between low and high: re-prompt if
  258. fp is a tty, error exit otherwise
  259. -- ignore check if low > high */
  260. int fin_int(FILE *fp,const char *s,int low,int high);
  261. /* fin_double -- return double read from file/stream fp
  262. -- prompt s on stderr if fp is a tty
  263. -- check that x lies between low and high: re-prompt if
  264. fp is a tty, error exit otherwise
  265. -- ignore check if low > high */
  266. double fin_double(FILE *fp,const char *s,double low,double high);
  267. /* it skips white spaces and strings of the form #....\n
  268. Here .... is a comment string */
  269. int skipjunk(FILE *fp);
  270. #endif /* ANSI_C */
  271. /* MACROS */
  272. /* macros to use stdout and stdin instead of explicit fp */
  273. #define v_output(vec) v_foutput(stdout,vec)
  274. #define v_input(vec) v_finput(stdin,vec)
  275. #define m_output(mat) m_foutput(stdout,mat)
  276. #define m_input(mat) m_finput(stdin,mat)
  277. #define px_output(px) px_foutput(stdout,px)
  278. #define px_input(px) px_finput(stdin,px)
  279. #define iv_output(iv) iv_foutput(stdout,iv)
  280. #define iv_input(iv) iv_finput(stdin,iv)
  281. /* general purpose input routine; skips comments # ... \n */
  282. #define finput(fp,prompt,fmt,var) \
  283. ( ( isatty(fileno(fp)) ? fprintf(stderr,prompt) : skipjunk(fp) ), \
  284. fscanf(fp,fmt,var) )
  285. #define input(prompt,fmt,var) finput(stdin,prompt,fmt,var)
  286. #define fprompter(fp,prompt) \
  287. ( isatty(fileno(fp)) ? fprintf(stderr,prompt) : skipjunk(fp) )
  288. #define prompter(prompt) fprompter(stdin,prompt)
  289. #define y_or_n(s) fy_or_n(stdin,s)
  290. #define in_int(s,lo,hi) fin_int(stdin,s,lo,hi)
  291. #define in_double(s,lo,hi) fin_double(stdin,s,lo,hi)
  292. /* special purpose access routines */
  293. /* Copying routines */
  294. #ifndef ANSI_C
  295. extern MAT *_m_copy(), *m_move(), *vm_move();
  296. extern VEC *_v_copy(), *v_move(), *mv_move();
  297. extern PERM *px_copy();
  298. extern IVEC *iv_copy(), *iv_move();
  299. extern BAND *bd_copy();
  300. #else
  301. /* copy in to out starting at out[i0][j0] */
  302. extern MAT *_m_copy(const MAT *in,MAT *out,unsigned int i0,unsigned int j0),
  303. * m_move(const MAT *in, int, int, int, int, MAT *out, int, int),
  304. *vm_move(const VEC *in, int, MAT *out, int, int, int, int);
  305. /* copy in to out starting at out[i0] */
  306. extern VEC *_v_copy(const VEC *in,VEC *out,unsigned int i0),
  307. * v_move(const VEC *in, int, int, VEC *out, int),
  308. *mv_move(const MAT *in, int, int, int, int, VEC *out, int);
  309. extern PERM *px_copy(const PERM *in,PERM *out);
  310. extern IVEC *iv_copy(const IVEC *in,IVEC *out),
  311. *iv_move(const IVEC *in, int, int, IVEC *out, int);
  312. extern BAND *bd_copy(const BAND *in,BAND *out);
  313. #endif /* ANSI_C */
  314. /* MACROS */
  315. #define m_copy(in,out) _m_copy(in,out,0,0)
  316. #define v_copy(in,out) _v_copy(in,out,0)
  317. /* Initialisation routines -- to be zero, ones, random or identity */
  318. #ifndef ANSI_C
  319. extern VEC *v_zero(), *v_rand(), *v_ones();
  320. extern MAT *m_zero(), *m_ident(), *m_rand(), *m_ones();
  321. extern PERM *px_ident();
  322. extern IVEC *iv_zero();
  323. #else
  324. extern VEC *v_zero(VEC *), *v_rand(VEC *), *v_ones(VEC *);
  325. extern MAT *m_zero(MAT *), *m_ident(MAT *), *m_rand(MAT *),
  326. *m_ones(MAT *);
  327. extern PERM *px_ident(PERM *);
  328. extern IVEC *iv_zero(IVEC *);
  329. #endif /* ANSI_C */
  330. /* Basic vector operations */
  331. #ifndef ANSI_C
  332. extern VEC *sv_mlt(), *mv_mlt(), *vm_mlt(), *v_add(), *v_sub(),
  333. *px_vec(), *pxinv_vec(), *v_mltadd(), *v_map(), *_v_map(),
  334. *v_lincomb(), *v_linlist();
  335. extern double v_min(), v_max(), v_sum();
  336. extern VEC *v_star(), *v_slash(), *v_sort();
  337. extern double _in_prod(), __ip__();
  338. extern void __mltadd__(), __add__(), __sub__(),
  339. __smlt__(), __zero__();
  340. #else
  341. extern VEC *sv_mlt(double s,const VEC *x,VEC *out), /* out <- s.x */
  342. *mv_mlt(const MAT *A,const VEC *s,VEC *out), /* out <- A.x */
  343. *vm_mlt(const MAT *A,const VEC *x,VEC *out), /* out^T <- x^T.A */
  344. *v_add(const VEC *x,const VEC *y,VEC *out), /* out <- x + y */
  345. *v_sub(const VEC *x,const VEC *y,VEC *out), /* out <- x - y */
  346. *px_vec(PERM *px,const VEC *x,VEC *out), /* out <- P.x */
  347. *pxinv_vec(PERM *px,const VEC *x,VEC *out), /* out <- P^{-1}.x */
  348. *v_mltadd(const VEC *x,const VEC *y,double s,VEC *out), /* out <- x + s.y */
  349. #ifdef PROTOTYPES_IN_STRUCT
  350. *v_map(double (*f)(double),const VEC *x,VEC *y),
  351. /* out[i] <- f(x[i]) */
  352. *_v_map(double (*f)(void *,double),void *p,const VEC *x,VEC *y),
  353. #else
  354. *v_map(double (*f)(),const VEC *,VEC *), /* out[i] <- f(x[i]) */
  355. *_v_map(double (*f)(),void *,const VEC *,VEC *),
  356. #endif /* PROTOTYPES_IN_STRUCT */
  357. *v_lincomb(int,const VEC **,const Real *,VEC *),
  358. /* out <- sum_i s[i].x[i] */
  359. *v_linlist(VEC *out,VEC *v1,double a1,...);
  360. /* out <- s1.x1 + s2.x2 + ... */
  361. /* returns min_j x[j] (== x[i]) */
  362. extern double v_min(const VEC *, int *),
  363. /* returns max_j x[j] (== x[i]) */
  364. v_max(const VEC *, int *),
  365. /* returns sum_i x[i] */
  366. v_sum(const VEC *);
  367. /* Hadamard product: out[i] <- x[i].y[i] */
  368. extern VEC *v_star(const VEC *, const VEC *, VEC *),
  369. /* out[i] <- x[i] / y[i] */
  370. *v_slash(const VEC *, const VEC *, VEC *),
  371. /* sorts x, and sets order so that sorted x[i] = x[order[i]] */
  372. *v_sort(VEC *, PERM *);
  373. /* returns inner product starting at component i0 */
  374. extern double _in_prod(const VEC *x, const VEC *y,unsigned int i0),
  375. /* returns sum_{i=0}^{len-1} x[i].y[i] */
  376. __ip__(const Real *,const Real *,int);
  377. /* see v_mltadd(), v_add(), v_sub() and v_zero() */
  378. extern void __mltadd__(Real *,const Real *,double,int),
  379. __add__(const Real *,const Real *,Real *,int),
  380. __sub__(const Real *,const Real *,Real *,int),
  381. __smlt__(const Real *,double,Real *,int),
  382. __zero__(Real *,int);
  383. #endif /* ANSI_C */
  384. /* MACRO */
  385. /* usual way of computing the inner product */
  386. #define in_prod(a,b) _in_prod(a,b,0)
  387. /* Norms */
  388. /* scaled vector norms -- scale == NULL implies unscaled */
  389. #ifndef ANSI_C
  390. extern double _v_norm1(), _v_norm2(), _v_norm_inf(),
  391. m_norm1(), m_norm_inf(), m_norm_frob();
  392. #else
  393. /* returns sum_i |x[i]/scale[i]| */
  394. extern double _v_norm1(const VEC *x,const VEC *scale),
  395. /* returns (scaled) Euclidean norm */
  396. _v_norm2(const VEC *x,const VEC *scale),
  397. /* returns max_i |x[i]/scale[i]| */
  398. _v_norm_inf(const VEC *x,const VEC *scale);
  399. /* unscaled matrix norms */
  400. extern double m_norm1(const MAT *A),
  401. m_norm_inf(const MAT *A),
  402. m_norm_frob(const MAT *A);
  403. #endif /* ANSI_C */
  404. /* MACROS */
  405. /* unscaled vector norms */
  406. #define v_norm1(x) _v_norm1(x,VNULL)
  407. #define v_norm2(x) _v_norm2(x,VNULL)
  408. #define v_norm_inf(x) _v_norm_inf(x,VNULL)
  409. /* Basic matrix operations */
  410. #ifndef ANSI_C
  411. extern MAT *sm_mlt(), *m_mlt(), *mmtr_mlt(), *mtrm_mlt(), *m_add(), *m_sub(),
  412. *sub_mat(), *m_transp(), *ms_mltadd();
  413. extern BAND *bd_transp(), *sbd_mlt(), *bds_mltadd(), *bd_zero();
  414. extern MAT *px_rows(), *px_cols(), *swap_rows(), *swap_cols(),
  415. *_set_row(), *_set_col();
  416. extern VEC *get_row(), *get_col(), *sub_vec(),
  417. *mv_mltadd(), *vm_mltadd(), *bdv_mltadd();
  418. #else
  419. extern MAT *sm_mlt(double s, const MAT *A,MAT *out), /* out <- s.A */
  420. *m_mlt(const MAT *A,const MAT *B,MAT *out), /* out <- A.B */
  421. *mmtr_mlt(const MAT *A,const MAT *B,MAT *out), /* out <- A.B^T */
  422. *mtrm_mlt(const MAT *A,const MAT *B,MAT *out), /* out <- A^T.B */
  423. *m_add(const MAT *A,const MAT *B,MAT *out), /* out <- A + B */
  424. *m_sub(const MAT *A,const MAT *B,MAT *out), /* out <- A - B */
  425. *sub_mat(const MAT *A,unsigned int,unsigned int,unsigned int,
  426. unsigned int,MAT *out),
  427. *m_transp(const MAT *A,MAT *out), /* out <- A^T */
  428. /* out <- A + s.B */
  429. *ms_mltadd(const MAT *A,const MAT *B,double s,MAT *out);
  430. extern BAND *bd_transp(const BAND *in, BAND *out), /* out <- A^T */
  431. *sbd_mlt(Real s, const BAND *A, BAND *OUT), /* OUT <- s.A */
  432. *bds_mltadd(const BAND *A, const BAND *B,double alpha, BAND *OUT),
  433. /* OUT <- A+alpha.B */
  434. *bd_zero(BAND *A); /* A <- 0 */
  435. extern MAT *px_rows(const PERM *px,const MAT *A,MAT *out), /* out <- P.A */
  436. *px_cols(const PERM *px,const MAT *A,MAT *out), /* out <- A.P^T */
  437. *swap_rows(MAT *,int,int,int,int),
  438. *swap_cols(MAT *,int,int,int,int),
  439. /* A[i][j] <- out[j], j >= j0 */
  440. *_set_col(MAT *A,unsigned int i,const VEC *col,unsigned int j0),
  441. /* A[i][j] <- out[i], i >= i0 */
  442. *_set_row(MAT *A,unsigned int j,const VEC *row,unsigned int i0);
  443. extern VEC *get_row(const MAT *,unsigned int,VEC *),
  444. *get_col(const MAT *,unsigned int,VEC *),
  445. *sub_vec(const VEC *,int,int,VEC *),
  446. /* mv_mltadd: out <- x + s.A.y */
  447. *mv_mltadd(const VEC *x,const VEC *y,const MAT *A,
  448. double s,VEC *out),
  449. /* vm_mltadd: out^T <- x^T + s.y^T.A */
  450. *vm_mltadd(const VEC *x,const VEC *y,const MAT *A,
  451. double s,VEC *out),
  452. /* bdv_mltadd: out <- x + s.A.y */
  453. *bdv_mltadd(const VEC *x,const VEC *y,const BAND *A,
  454. double s,VEC *out);
  455. #endif /* ANSI_C */
  456. /* MACROS */
  457. /* row i of A <- vec */
  458. #define set_row(mat,row,vec) _set_row(mat,row,vec,0)
  459. /* col j of A <- vec */
  460. #define set_col(mat,col,vec) _set_col(mat,col,vec,0)
  461. /* Basic permutation operations */
  462. #ifndef ANSI_C
  463. extern PERM *px_mlt(), *px_inv(), *px_transp();
  464. extern int px_sign();
  465. #else
  466. extern PERM *px_mlt(const PERM *px1,const PERM *px2,PERM *out), /* out <- px1.px2 */
  467. *px_inv(const PERM *px,PERM *out), /* out <- px^{-1} */
  468. /* swap px[i] and px[j] */
  469. *px_transp(PERM *px,unsigned int i,unsigned int j);
  470. /* returns sign(px) = +1 if px product of even # transpositions
  471. -1 if ps product of odd # transpositions */
  472. extern int px_sign(const PERM *);
  473. #endif /* ANSI_C */
  474. /* Basic integer vector operations */
  475. #ifndef ANSI_C
  476. extern IVEC *iv_add(), *iv_sub(), *iv_sort();
  477. #else
  478. extern IVEC *iv_add(const IVEC *ix,const IVEC *iy,IVEC *out),
  479. /* out <- ix + iy */
  480. *iv_sub(const IVEC *ix,const IVEC *iy,IVEC *out),
  481. /* out <- ix - iy */
  482. /* sorts ix & sets order so that sorted ix[i] = old ix[order[i]] */
  483. *iv_sort(IVEC *ix, PERM *order);
  484. #endif /* ANSI_C */
  485. /* miscellaneous functions */
  486. #ifndef ANSI_C
  487. extern double square(), cube(), mrand();
  488. extern void smrand(), mrandlist();
  489. extern void m_dump(), px_dump(), v_dump(), iv_dump();
  490. extern MAT *band2mat();
  491. extern BAND *mat2band();
  492. #else
  493. double square(double x), /* returns x^2 */
  494. cube(double x), /* returns x^3 */
  495. mrand(void); /* returns random # in [0,1) */
  496. void smrand(int seed), /* seeds mrand() */
  497. mrandlist(Real *x, int len); /* generates len random numbers */
  498. void m_dump(FILE *fp,const MAT *a), px_dump(FILE *fp, const PERM *px),
  499. v_dump(FILE *fp,const VEC *x), iv_dump(FILE *fp, const IVEC *ix);
  500. MAT *band2mat(const BAND *bA, MAT *A);
  501. BAND *mat2band(const MAT *A, int lb,int ub, BAND *bA);
  502. #endif /* ANSI_C */
  503. /* miscellaneous constants */
  504. #define VNULL ((VEC *)NULL)
  505. #define MNULL ((MAT *)NULL)
  506. #define PNULL ((PERM *)NULL)
  507. #define IVNULL ((IVEC *)NULL)
  508. #define BDNULL ((BAND *)NULL)
  509. /* varying number of arguments */
  510. #ifdef ANSI_C
  511. #include <stdarg.h>
  512. /* prototypes */
  513. int v_get_vars(int dim,...);
  514. int iv_get_vars(int dim,...);
  515. int m_get_vars(int m,int n,...);
  516. int px_get_vars(int dim,...);
  517. int v_resize_vars(int new_dim,...);
  518. int iv_resize_vars(int new_dim,...);
  519. int m_resize_vars(int m,int n,...);
  520. int px_resize_vars(int new_dim,...);
  521. int v_free_vars(VEC **,...);
  522. int iv_free_vars(IVEC **,...);
  523. int px_free_vars(PERM **,...);
  524. int m_free_vars(MAT **,...);
  525. #elif VARARGS
  526. /* old varargs is used */
  527. #include <varargs.h>
  528. /* prototypes */
  529. int v_get_vars();
  530. int iv_get_vars();
  531. int m_get_vars();
  532. int px_get_vars();
  533. int v_resize_vars();
  534. int iv_resize_vars();
  535. int m_resize_vars();
  536. int px_resize_vars();
  537. int v_free_vars();
  538. int iv_free_vars();
  539. int px_free_vars();
  540. int m_free_vars();
  541. #endif /* ANSI_C */
  542. #endif /* MATRIXH */