src/mat.c

Go to the documentation of this file.
00001 /*
00002    libit - Library for basic source and channel coding functions
00003    Copyright (C) 2005-2005 Vivien Chappelier, Herve Jegou
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public
00016    License along with this library; if not, write to the Free
00017    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 */
00019 
00020 /*
00021   Matrices functions
00022   Copyright (C) 2005 Vivien Chappelier, Herve Jegou
00023 */
00024 
00025 #include <it/mat.h>
00026 #include <it/math.h>
00027 #include <it/io.h>
00028 #include <it/random.h>
00029 
00030 #define __mat_c_my_min(x,y)  (x>y?y:x)
00031 
00032 
00033 /*---------------------------------------------------------------------------*/
00034 /* Basic vector allocation, initialization and deletion                      */
00035 /*---------------------------------------------------------------------------*/
00036 
00037 Mat __Mat_new_alloc (size_t elem_size, idx_t h, idx_t w,
00038          idx_t hmax, idx_t wmax) {
00039   idx_t i;
00040   Mat  m;
00041 
00042   if   (hmax <= 0)    /* The maximum height is at least 1 */
00043     hmax = 1;
00044   m = Vec_new_alloc (Vec, h, hmax);
00045   for  (i = 0; i < hmax; i++)
00046     m[i] = __Vec_new_alloc (elem_size, w, wmax);
00047   return (m);
00048 }
00049 
00050 
00051 Mat __Mat_new (size_t elem_size, idx_t h, idx_t w) {
00052   return (__Mat_new_alloc (elem_size, h, w, h, w));
00053 }
00054 
00055 
00056 void __Mat_delete (Mat m) {
00057   idx_t i;
00058   for (i = 0; i < Mat_height_max (m); i++)
00059     Vec_delete (m[i]);
00060   Vec_delete (m);
00061 }
00062 
00063 
00064 mat mat_new (idx_t h, idx_t w) {
00065   return (Mat_new (double, h, w));
00066 }
00067 
00068 
00069 imat imat_new (idx_t h, idx_t w) {
00070   return (Mat_new (int, h, w));
00071 }
00072 
00073 
00074 bmat bmat_new (idx_t h, idx_t w) {
00075   return (Mat_new (byte, h, w));
00076 }
00077 
00078 
00079 cmat cmat_new (idx_t h, idx_t w) {
00080   return (Mat_new (cplx, h, w));
00081 }
00082 
00083 
00084 mat mat_new_alloc (idx_t h, idx_t w, idx_t hmax, idx_t wmax) {
00085   return (Mat_new_alloc (double, h, w, hmax, wmax));
00086 }
00087 
00088 
00089 imat imat_new_alloc (idx_t h, idx_t w, idx_t hmax, idx_t wmax) {
00090   return (Mat_new_alloc (int, h, w, hmax, wmax));
00091 }
00092 
00093 
00094 bmat bmat_new_alloc (idx_t h, idx_t w, idx_t hmax, idx_t wmax) {
00095   return (Mat_new_alloc (byte, h, w, hmax, wmax));
00096 }
00097 
00098 
00099 cmat cmat_new_alloc (idx_t h, idx_t w, idx_t hmax, idx_t wmax) {
00100   return (Mat_new_alloc (cplx, h, w, hmax, wmax));
00101 }
00102 
00103 
00104 void mat_delete (mat m) {
00105   Mat_delete (m);
00106 }
00107 
00108 
00109 void imat_delete (imat m) {
00110   Mat_delete (m);
00111 }
00112 
00113 
00114 void bmat_delete (bmat m) {
00115   Mat_delete (m);
00116 }
00117 
00118 
00119 void cmat_delete (cmat m) {
00120   Mat_delete (m);
00121 }
00122 
00123 
00124 /*---------------------------------------------------------------------------*/
00125 /* Width and Height functions                                                */
00126 /*---------------------------------------------------------------------------*/
00127 
00128 idx_t mat_height (mat m) {
00129   return Mat_height (m);
00130 }
00131 
00132 
00133 idx_t mat_height_max (mat m) {
00134   return Mat_height_max (m);
00135 }
00136 
00137 
00138 idx_t mat_width (mat m) {
00139   return Mat_width (m);
00140 }
00141 
00142 
00143 idx_t mat_width_max (mat m) {
00144   return Mat_width_max (m);
00145 }
00146 
00147 
00148 idx_t imat_height (imat m) {
00149   return Mat_height (m);
00150 }
00151 
00152 
00153 idx_t imat_height_max (imat m) {
00154   return Mat_height_max (m);
00155 }
00156 
00157 
00158 idx_t imat_width (imat m) {
00159   return Mat_width (m);
00160 }
00161 
00162 
00163 idx_t imat_width_max (imat m) {
00164   return Mat_width_max (m);
00165 }
00166 
00167 
00168 idx_t bmat_height (bmat m) {
00169   return Mat_height (m);
00170 }
00171 
00172 
00173 idx_t bmat_height_max (bmat m) {
00174   return Mat_height_max (m);
00175 }
00176 
00177 
00178 idx_t bmat_width (bmat m) {
00179   return Mat_width (m);
00180 }
00181 
00182 
00183 idx_t bmat_width_max (bmat m) {
00184   return Mat_width_max (m);
00185 }
00186 
00187 
00188 idx_t cmat_height (cmat m) {
00189   return Mat_height (m);
00190 }
00191 
00192 
00193 idx_t cmat_height_max (cmat m) {
00194   return Mat_height_max (m);
00195 }
00196 
00197 
00198 idx_t cmat_width (cmat m) {
00199   return Mat_width (m);
00200 }
00201 
00202 
00203 idx_t cmat_width_max (cmat m) {
00204   return Mat_width_max (m);
00205 }
00206 
00207 
00208 mat _mat_set_height (mat m, idx_t h) {
00209   Mat_set_height (m, h);
00210   return m;
00211 }
00212 
00213 
00214 mat _mat_set_height_max (mat m, idx_t hmax) {
00215   Mat_set_height_max (m, hmax);
00216   return m;
00217 }
00218 
00219 
00220 imat _imat_set_height (imat m, idx_t h) {
00221   Mat_set_height (m, h);
00222   return m;
00223 }
00224 
00225 
00226 imat _imat_set_height_max (imat m, idx_t hmax) {
00227   Mat_set_height_max (m, hmax);
00228   return m;
00229 }
00230 
00231 
00232 bmat _bmat_set_height (bmat m, idx_t h) {
00233   Mat_set_height (m, h);
00234   return m;
00235 }
00236 
00237 
00238 bmat _bmat_set_height_max (bmat m, idx_t hmax) {
00239   Mat_set_height_max (m, hmax);
00240   return (m);
00241 }
00242 
00243 
00244 cmat _cmat_set_height (cmat m, idx_t h) {
00245   Mat_set_height (m, h);
00246   return m;
00247 }
00248 
00249 
00250 cmat _cmat_set_height_max (cmat m, idx_t hmax) {
00251   Mat_set_height_max (m, hmax);
00252   return (m);
00253 }
00254 
00255 
00256 /*---------------------------------------------------------------------------*/
00257 /* Basic vector initialization/modification                                  */
00258 /*---------------------------------------------------------------------------*/
00259 
00260 mat _mat_init (mat m, double *buf, idx_t w, idx_t h) {
00261   Mat_init (m, buf, w, h);
00262   return (m);
00263 }
00264 
00265 
00266 imat _imat_init (imat m, int *buf, idx_t w, idx_t h) {
00267   Mat_init (m, buf, w, h);
00268   return (m);
00269 }
00270 
00271 
00272 bmat _bmat_init (bmat m, byte * buf, idx_t w, idx_t h) {
00273   Mat_init (m, buf, w, h);
00274   return (m);
00275 }
00276 
00277 
00278 cmat _cmat_init (cmat m, cplx * buf, idx_t w, idx_t h) {
00279   Mat_init (m, buf, w, h);
00280   return (m);
00281 }
00282 
00283 mat mat_set (mat m, double val) {
00284   Mat_set (m, val);
00285   return m;
00286 }
00287 
00288 
00289 imat imat_set (imat m, int val) {
00290   Mat_set (m, val);
00291   return m;
00292 }
00293 
00294 
00295 bmat bmat_set (bmat m, byte val) {
00296   Mat_set (m, val);
00297   return m;
00298 }
00299 
00300 
00301 cmat cmat_set (cmat m, cplx val) {
00302   Mat_set (m, val);
00303   return m;
00304 }
00305 
00306 
00307 mat mat_set_between (mat m, idx_t r1, idx_t c1, idx_t r2,
00308          idx_t c2, double val) {
00309   Mat_set_between (m, r1, c1, r2, c2, val);
00310   return m;
00311 }
00312 
00313 
00314 imat imat_set_between (imat m, idx_t r1, idx_t c1, idx_t r2,
00315            idx_t c2, int val) {
00316   Mat_set_between (m, r1, c1, r2, c2, val);
00317   return m;
00318 }
00319 
00320 
00321 bmat bmat_set_between (bmat m, idx_t r1, idx_t c1, idx_t r2,
00322            idx_t c2, byte val) {
00323   Mat_set_between (m, r1, c1, r2, c2, val);
00324   return m;
00325 }
00326 
00327 
00328 cmat cmat_set_between (cmat m, idx_t r1, idx_t c1, idx_t r2,
00329            idx_t c2, cplx val) {
00330   Mat_set_between (m, r1, c1, r2, c2, val);
00331   return m;
00332 }
00333 
00334 
00335 void mat_void (mat m)
00336 {
00337   mat_set_height (m, 0);
00338 }
00339 
00340 
00341 void imat_void (imat m)
00342 {
00343   imat_set_height (m, 0);
00344 }
00345 
00346 
00347 void bmat_void (bmat m)
00348 {
00349   bmat_set_height (m, 0);
00350 }
00351 
00352 
00353 void cmat_void (cmat m)
00354 {
00355   cmat_set_height (m, 0);
00356 }
00357 
00358 
00359 /*----------------------------------------------------------------------------*/
00360 void mat_zeros (mat m)
00361 {
00362   mat_set (m, 0);
00363 }
00364 
00365 
00366 void imat_zeros (imat m)
00367 {
00368   imat_set (m, 0);
00369 }
00370 
00371 
00372 void bmat_zeros (bmat m)
00373 {
00374   bmat_set (m, 0);
00375 }
00376 
00377 
00378 void cmat_zeros (cmat m)
00379 {
00380   cmat_set (m, cplx_0);
00381 }
00382 
00383 
00384 mat mat_new_zeros (idx_t h, idx_t w) 
00385 {
00386   return (mat_new_set (0., h, w));
00387 }
00388 
00389 
00390 imat imat_new_zeros (idx_t h, idx_t w) {
00391   return (imat_new_set (0, h, w));
00392 }
00393 
00394 
00395 bmat bmat_new_zeros (idx_t h, idx_t w) {
00396   return (bmat_new_set (0, h, w));
00397 }
00398 
00399 
00400 cmat cmat_new_zeros (idx_t h, idx_t w) {
00401   return (cmat_new_set (cplx_0, h, w));
00402 }
00403 
00404 
00405 
00406 /*----------------------------------------------------------------------------*/
00407 void mat_eye (mat m)
00408 {
00409   idx_t i, mi;
00410   mat_set (m, 0);
00411   mi = (mat_height (m) > mat_width (m) ? mat_width (m) : mat_height (m));
00412   for (i = 0; i < mi; i++)
00413     m[i][i] = 1;
00414 }
00415 
00416 
00417 void imat_eye (imat m)
00418 {
00419   idx_t i, mi;
00420   imat_set (m, 0);
00421   mi = (imat_height (m) > imat_width (m) ? imat_width (m) : imat_height (m));
00422   for (i = 0; i < mi; i++)
00423     m[i][i] = 1;
00424 }
00425 
00426 
00427 void bmat_eye (bmat m)
00428 {
00429   idx_t i, mi;
00430   bmat_set (m, 0);
00431   mi = (bmat_height (m) > bmat_width (m) ? bmat_width (m) : bmat_height (m));
00432   for (i = 0; i < mi; i++)
00433     m[i][i] = 1;
00434 }
00435 
00436 
00437 void cmat_eye (cmat m)
00438 {
00439   idx_t i, mi;
00440   cmat_set (m, cplx_0);
00441   mi = (cmat_height (m) > cmat_width (m) ? cmat_width (m) : cmat_height (m));
00442   for (i = 0; i < mi; i++)
00443     m[i][i] = cplx_1;
00444 }
00445 
00446 
00447 /*----------------------------------------------------------------------------*/
00448 void mat_ones (mat m)
00449 {
00450   mat_set (m, 1);
00451 }
00452 
00453 
00454 void imat_ones (imat m)
00455 {
00456   imat_set (m, 1);
00457 }
00458 
00459 
00460 void bmat_ones (bmat m)
00461 {
00462   bmat_set (m, 1);
00463 }
00464 
00465 
00466 void cmat_ones (cmat m)
00467 {
00468   cmat_set (m, cplx_1);
00469 }
00470 
00471 
00472 mat mat_new_ones (idx_t h, idx_t w)
00473 {
00474   return (mat_new_set (1., h, w));
00475 }
00476 
00477 
00478 imat imat_new_ones (idx_t h, idx_t w)
00479 {
00480   return (imat_new_set (1, h, w));
00481 }
00482 
00483 
00484 bmat bmat_new_ones (idx_t h, idx_t w) 
00485 {
00486   return (bmat_new_set (1, h, w));
00487 }
00488 
00489 
00490 cmat cmat_new_ones (idx_t h, idx_t w) 
00491 {
00492   return (cmat_new_set (cplx_1, h, w));
00493 }
00494 
00495 
00496 /*----------------------------------------------------------------------------*/
00497 mat mat_new_void ()
00498 {
00499   mat  m = mat_new (0, 0);
00500   return m;
00501 }
00502 
00503 
00504 imat imat_new_void ()
00505 {
00506   imat m = imat_new (0, 0);
00507   return m;
00508 }
00509 
00510 
00511 bmat bmat_new_void ()
00512 {
00513   bmat m = bmat_new (0, 0);
00514   return m;
00515 }
00516 
00517 
00518 cmat cmat_new_void ()
00519 {
00520   cmat m = cmat_new (0, 0);
00521   return m;
00522 }
00523 
00524 
00525 /*---------------------------------------------------------------------------*/
00526 mat mat_new_set (double val, idx_t h, idx_t w)
00527 {
00528   mat  m = mat_new (h, w);
00529   mat_set (m, val);
00530   return m;
00531 }
00532 
00533 
00534 imat imat_new_set (int val, idx_t h, idx_t w)
00535 {
00536   imat m = imat_new (h, w);
00537   imat_set (m, val);
00538   return m;
00539 }
00540 
00541 
00542 bmat bmat_new_set (byte val, idx_t h, idx_t w)
00543 {
00544   bmat m = bmat_new (h, w);
00545   bmat_set (m, val);
00546   return m;
00547 }
00548 
00549 
00550 cmat cmat_new_set (cplx val, idx_t h, idx_t w)
00551 {
00552   cmat m = cmat_new (h, w);
00553   cmat_set (m, val);
00554   return m;
00555 }
00556 
00557 
00558 /*---------------------------------------------------------------------------*/
00559 mat mat_new_eye (idx_t n)
00560 {
00561   mat  m = mat_new (n, n);
00562   mat_eye (m);
00563   return m;
00564 }
00565 
00566 
00567 imat imat_new_eye (idx_t n)
00568 {
00569   imat m = imat_new (n, n);
00570   imat_eye (m);
00571   return m;
00572 }
00573 
00574 
00575 bmat bmat_new_eye (idx_t n)
00576 {
00577   bmat m = bmat_new (n, n);
00578   bmat_eye (m);
00579   return m;
00580 }
00581 
00582 
00583 cmat cmat_new_eye (idx_t n)
00584 {
00585   cmat m = cmat_new (n, n);
00586   cmat_eye (m);
00587   return m;
00588 }
00589 
00590 /*---------------------------------------------------------------------------*/
00591 mat mat_new_diag (vec v)
00592 {
00593   mat  m = mat_new (vec_length (v), vec_length (v));
00594   mat_diag (m, v);
00595   return m;
00596 }
00597 
00598 
00599 imat imat_new_diag (ivec v)
00600 {
00601   imat m = imat_new (ivec_length (v), ivec_length (v));
00602   imat_diag (m, v);
00603   return m;
00604 }
00605 
00606 
00607 bmat bmat_new_diag (bvec v)
00608 {
00609   bmat m = bmat_new (bvec_length (v), bvec_length (v));
00610   bmat_diag (m, v);
00611   return m;
00612 }
00613 
00614 
00615 cmat cmat_new_diag (cvec v)
00616 {
00617   cmat m = cmat_new (cvec_length (v), cvec_length (v));
00618   cmat_diag (m, v);
00619   return m;
00620 }
00621 
00622 
00623 /*---------------------------------------------------------------------------*/
00624 /*               Copy and Conversions Functions                              */
00625 /*---------------------------------------------------------------------------*/
00626 
00627 Mat __Mat_copy (Mat m1, Mat m2) {
00628   int  i;
00629   assert (m1);
00630   assert (m2);
00631   assert (Mat_element_size (m1) == Mat_element_size (m2));
00632   assert (Mat_height (m1) >= Mat_height (m2));
00633 
00634   for (i = 0; i < Mat_height (m2); i++)
00635     Vec_copy (m1[i], m2[i]);
00636   return (m1);
00637 }
00638 
00639 
00640 void mat_copy (mat dest, mat orig)
00641 {
00642   idx_t i, j;
00643   assert (dest);
00644   assert (orig);
00645   assert (mat_width_max (dest) >= mat_width (orig));
00646   assert (mat_height_max (dest) >= mat_height (orig));
00647   for (i = 0; i < mat_height (orig); i++)
00648     for (j = 0; j < mat_width (orig); j++)
00649       dest[i][j] = orig[i][j];
00650 }
00651 
00652 
00653 void imat_copy (imat dest, imat orig)
00654 {
00655   idx_t i, j;
00656   assert (dest);
00657   assert (orig);
00658   assert (imat_width_max (dest) >= imat_width (orig));
00659   assert (imat_height_max (dest) >= imat_height (orig));
00660   for (i = 0; i < imat_height (orig); i++)
00661     for (j = 0; j < imat_width (orig); j++)
00662       dest[i][j] = orig[i][j];
00663 }
00664 
00665 
00666 void bmat_copy (bmat dest, bmat orig)
00667 {
00668   idx_t i, j;
00669   assert (dest);
00670   assert (orig);
00671   assert (bmat_width_max (dest) >= bmat_width (orig));
00672   assert (bmat_height_max (dest) >= bmat_height (orig));
00673   for (i = 0; i < bmat_height (orig); i++)
00674     for (j = 0; j < bmat_width (orig); j++)
00675       dest[i][j] = orig[i][j];
00676 }
00677 
00678 void cmat_copy (cmat dest, cmat orig)
00679 {
00680   idx_t i, j;
00681   assert (dest);
00682   assert (orig);
00683   assert (cmat_width_max (dest) >= cmat_width (orig));
00684   assert (cmat_height_max (dest) >= cmat_height (orig));
00685   for (i = 0; i < cmat_height (orig); i++)
00686     for (j = 0; j < cmat_width (orig); j++)
00687       dest[i][j] = orig[i][j];
00688 }
00689 
00690 
00691 /*------------------------------------------------------------------*/
00692 Mat Mat_clone (Mat m)
00693 {
00694   Mat  cl;
00695   assert (m);
00696   cl = __Mat_new (Mat_element_size (m), Mat_height (m), Mat_width (m));
00697   if (cl == NULL)
00698     return NULL;
00699   Mat_copy (cl, m);
00700   return cl;
00701 }
00702 
00703 mat mat_clone (mat m)
00704 {
00705   mat  cl;
00706   assert (m);
00707   cl = mat_new (mat_height (m), mat_width (m));
00708   if (cl == NULL)
00709     return NULL;
00710   mat_copy (cl, m);
00711   return cl;
00712 }
00713 
00714 
00715 imat imat_clone (imat m)
00716 {
00717   imat cl;
00718   assert (m);
00719   cl = imat_new (imat_height (m), imat_width (m));
00720   if (cl == NULL)
00721     return NULL;
00722   imat_copy (cl, m);
00723   return cl;
00724 
00725 }
00726 
00727 
00728 bmat bmat_clone (bmat m)
00729 {
00730   bmat cl;
00731   assert (m);
00732   cl = bmat_new (bmat_height (m), bmat_width (m));
00733   if (cl == NULL)
00734     return NULL;
00735   bmat_copy (cl, m);
00736   return cl;
00737 }
00738 
00739 
00740 cmat cmat_clone (cmat m)
00741 {
00742   cmat cl;
00743   assert (m);
00744   cl = cmat_new (cmat_height (m), cmat_width (m));
00745   if (cl == NULL)
00746     return NULL;
00747   cmat_copy (cl, m);
00748   return cl;
00749 }
00750 
00751 
00752 vec mat_to_vec (mat m)
00753 {
00754   idx_t i, j;
00755   vec  v = vec_new (mat_height (m) * mat_width (m));
00756   for (i = 0; i < mat_height (m); i++)
00757     for (j = 0; j < mat_width (m); j++)
00758       v[i * mat_width (m) + j] = m[i][j];
00759   return v;
00760 }
00761 
00762 ivec imat_to_ivec (imat m)
00763 {
00764   idx_t i, j;
00765   ivec v = ivec_new (imat_height (m) * imat_width (m));
00766   for (i = 0; i < imat_height (m); i++)
00767     for (j = 0; j < imat_width (m); j++)
00768       v[i * imat_width (m) + j] = m[i][j];
00769   return v;
00770 }
00771 
00772 bvec bmat_to_bvec (bmat m)
00773 {
00774   idx_t i, j;
00775   bvec v = bvec_new (bmat_height (m) * bmat_width (m));
00776   for (i = 0; i < bmat_height (m); i++)
00777     for (j = 0; j < bmat_width (m); j++)
00778       v[i * bmat_width (m) + j] = m[i][j];
00779   return v;
00780 }
00781 
00782 cvec cmat_to_cvec (cmat m)
00783 {
00784   idx_t i, j;
00785   cvec v = cvec_new (cmat_height (m) * cmat_width (m));
00786   for (i = 0; i < cmat_height (m); i++)
00787     for (j = 0; j < cmat_width (m); j++)
00788       v[i * cmat_width (m) + j] = m[i][j];
00789   return v;
00790 }
00791 
00792 /*----------------------------------------------------------------------------*/
00793 mat vec_to_mat (vec v, idx_t width)
00794 {
00795   mat  m;
00796   idx_t i, j, k = 0;
00797   it_assert (vec_length (v) % width == 0,
00798        "Vector dimension does match the required matrix width\n");
00799 
00800   m = mat_new (vec_length (v) / width, width);
00801   for (i = 0; i < mat_height (m); i++)
00802     for (j = 0; j < mat_width (m); j++)
00803       m[i][j] = v[k++];
00804   return m;
00805 }
00806 
00807 imat ivec_to_imat (ivec v, idx_t width)
00808 {
00809   imat m;
00810   idx_t i, j, k = 0;
00811   it_assert (ivec_length (v) % width == 0,
00812        "Vector dimension does match the required matrix width\n");
00813 
00814   m = imat_new (ivec_length (v) / width, width);
00815   for (i = 0; i < imat_height (m); i++)
00816     for (j = 0; j < imat_width (m); j++)
00817       m[i][j] = v[k++];
00818   return m;
00819 }
00820 
00821 bmat bvec_to_bmat (bvec v, idx_t width)
00822 {
00823   bmat m;
00824   idx_t i, j, k = 0;
00825   it_assert (bvec_length (v) % width == 0,
00826        "Vector dimension does match the required matrix width\n");
00827 
00828   m = bmat_new (bvec_length (v) / width, width);
00829   for (i = 0; i < bmat_height (m); i++)
00830     for (j = 0; j < bmat_width (m); j++)
00831       m[i][j] = v[k++];
00832   return m;
00833 }
00834 
00835 cmat cvec_to_cmat (cvec v, idx_t width)
00836 {
00837   cmat m;
00838   idx_t i, j, k = 0;
00839   it_assert (cvec_length (v) % width == 0,
00840        "Vector dimension does match the required matrix width\n");
00841 
00842   m = cmat_new (cvec_length (v) / width, width);
00843   for (i = 0; i < cmat_height (m); i++)
00844     for (j = 0; j < cmat_width (m); j++)
00845       m[i][j] = v[k++];
00846   return m;
00847 }
00848 
00849 /*----------------------------------------------------------------------------*/
00850 mat imat_to_mat (imat m)
00851 {
00852   idx_t i, j;
00853   mat  cl;
00854 
00855   assert (m);
00856   cl = mat_new (imat_height (m), imat_width (m));
00857 
00858   for (i = 0; i < imat_height (m); i++)
00859     for (j = 0; j < imat_width (m); j++)
00860       cl[i][j] = m[i][j];
00861 
00862   return cl;
00863 }
00864 
00865 
00866 
00867 mat bmat_to_mat (bmat m)
00868 {
00869   idx_t i, j;
00870   mat  cl;
00871 
00872   assert (m);
00873   cl = mat_new (bmat_height (m), bmat_width (m));
00874 
00875   for (i = 0; i < bmat_height (m); i++)
00876     for (j = 0; j < bmat_width (m); j++)
00877       cl[i][j] = m[i][j];
00878 
00879   return cl;
00880 }
00881 
00882 
00883 imat bmat_to_imat (bmat m)
00884 {
00885   idx_t i, j;
00886   imat cl;
00887 
00888   assert (m);
00889   cl = imat_new (bmat_height (m), bmat_width (m));
00890 
00891   for (i = 0; i < bmat_height (m); i++)
00892     for (j = 0; j < bmat_width (m); j++)
00893       cl[i][j] = m[i][j];
00894 
00895   return cl;
00896 }
00897 
00898 
00899 imat mat_to_imat (mat m)
00900 {
00901   idx_t i, j;
00902   imat cl;
00903 
00904   assert (m);
00905   cl = imat_new (mat_height (m), mat_width (m));
00906 
00907   for (i = 0; i < mat_height (m); i++)
00908     for (j = 0; j < mat_width (m); j++)
00909       cl[i][j] = (int) m[i][j];
00910 
00911   return cl;
00912 }
00913 
00914 
00915 /*---------------------------------------------------------------------------*/
00916 /* Comparison functions                                                      */
00917 /*---------------------------------------------------------------------------*/
00918 
00919 int Mat_eq (Mat m1, Mat m2)
00920 {
00921   idx_t i;
00922   assert (m1);
00923   assert (m2);
00924 
00925   if (Mat_height (m1) != Mat_height (m2))
00926     return 0;
00927 
00928   for (i = 0; i < Mat_height (m1); i++)
00929     if (!Vec_eq (m1[i], m2[i]))
00930       return 0;
00931 
00932   return 1;
00933 }
00934 
00935 
00936 int mat_eq (mat m1, mat m2)
00937 {
00938   idx_t i;
00939   assert (m1);
00940   assert (m2);
00941 
00942   if (mat_height (m1) != mat_height (m2))
00943     return 0;
00944 
00945   for (i = 0; i < mat_height (m1); i++)
00946     if (!vec_eq (m1[i], m2[i]))
00947       return 0;
00948   return 1;
00949 }
00950 
00951 int imat_eq (imat m1, imat m2)
00952 {
00953   idx_t i;
00954   assert (m1);
00955   assert (m2);
00956 
00957   if (imat_height (m1) != imat_height (m2))
00958     return 0;
00959 
00960   for (i = 0; i < imat_height (m1); i++)
00961     if (!ivec_eq (m1[i], m2[i]))
00962       return 0;
00963   return 1;
00964 }
00965 
00966 int bmat_eq (bmat m1, bmat m2)
00967 {
00968   idx_t i;
00969   assert (m1);
00970   assert (m2);
00971 
00972   if (bmat_height (m1) != bmat_height (m2))
00973     return 0;
00974 
00975   for (i = 0; i < bmat_height (m1); i++)
00976     if (!bvec_eq (m1[i], m2[i]))
00977       return 0;
00978   return 1;
00979 }
00980 
00981 int cmat_eq (cmat m1, cmat m2)
00982 {
00983   idx_t i;
00984   assert (m1);
00985   assert (m2);
00986 
00987   if (cmat_height (m1) != cmat_height (m2))
00988     return 0;
00989 
00990   for (i = 0; i < cmat_height (m1); i++)
00991     if (!cvec_eq (m1[i], m2[i]))
00992       return 0;
00993   return 1;
00994 }
00995 
00996 
00997 int mat_is_void (mat m)
00998 {
00999   return mat_width (m) == 0 || mat_height (m) == 0;
01000 }
01001 
01002 
01003 int imat_is_void (imat m)
01004 {
01005   return imat_width (m) == 0 || imat_height (m) == 0;
01006 }
01007 
01008 
01009 int bmat_is_void (bmat m)
01010 {
01011   return bmat_width (m) == 0 || bmat_height (m) == 0;
01012 }
01013 
01014 
01015 int cmat_is_void (cmat m)
01016 {
01017   return cmat_width (m) == 0 || cmat_height (m) == 0;
01018 }
01019 
01020 
01021 /*---------------------------------------------------------------------------*/
01022 /** @name Row/column manipulation                                            */
01023 /*---------------------------------------------------------------------------*/
01024 
01025 mat __mat_del_row (mat m, idx_t pos) {
01026   Mat_del_row (m, pos);
01027   return m;
01028 }
01029 imat __imat_del_row (imat m, idx_t pos) {
01030   Mat_del_row (m, pos);
01031   return m;
01032 }
01033 bmat __bmat_del_row (bmat m, idx_t pos) {
01034   Mat_del_row (m, pos);
01035   return m;
01036 }
01037 cmat __cmat_del_row (cmat m, idx_t pos) {
01038   Mat_del_row (m, pos);
01039   return m;
01040 }
01041 
01042 mat __mat_ins_row (mat m, idx_t pos, vec v) {
01043   Mat_ins_row (m, pos, v);
01044   return m;
01045 }
01046 imat __imat_ins_row (imat m, idx_t pos, ivec v) {
01047   Mat_ins_row (m, pos, v);
01048   return m;
01049 }
01050 bmat __bmat_ins_row (bmat m, idx_t pos, bvec v) {
01051   Mat_ins_row (m, pos, v);
01052   return m;
01053 }
01054 cmat __cmat_ins_row (cmat m, idx_t pos, cvec v) {
01055   Mat_ins_row (m, pos, v);
01056   return m;
01057 }
01058 
01059 /* Add a vector at the end row of the matrix (Use matrix as a vector stack)  */
01060 mat __mat_push_row (mat m, vec v) {
01061   mat_ins_row (m, mat_height (m), v);
01062   return m;
01063 }
01064 imat __imat_push_row (imat m, ivec v) {
01065   imat_ins_row (m, imat_height (m), v);
01066   return m;
01067 }
01068 bmat __bmat_push_row (bmat m, bvec v) {
01069   bmat_ins_row (m, bmat_height (m), v);
01070   return m;
01071 }
01072 cmat __cmat_push_row (cmat m, cvec v) {
01073   cmat_ins_row (m, cmat_height (m), v);
01074   return m;
01075 }
01076 
01077 /* Retrieve the last element at the end of the vector (Use vector as a stack)*/
01078 mat __mat_pop_row (mat m) {
01079   Mat_pop_row (m);
01080   return m;
01081 }
01082 imat __imat_pop_row (imat m) {
01083   Mat_pop_row (m);
01084   return m;
01085 }
01086 bmat __bmat_pop_row (bmat m) {
01087   Mat_pop_row (m);
01088   return m;
01089 }
01090 cmat __cmat_pop_row (cmat m) {
01091   Mat_pop_row (m);
01092   return m;
01093 }
01094 
01095 
01096 /*----------------------------------------------------------------------------*/
01097 
01098 void mat_swap_rows (mat m, idx_t i, idx_t j)
01099 {
01100 
01101   vec r;
01102 
01103   it_assert (m, "Please use an existing matrix");
01104   it_assert (0 <= i && i <= mat_height (m) &&
01105        0 <= j && j <= mat_height (m), "Please specify existing rows");
01106 
01107   r = m[i];
01108 
01109   m[i] = m[j];
01110   m[j] = r;
01111 
01112   return;
01113 
01114 }
01115 
01116 
01117 void mat_swap_cols (mat m, idx_t i, idx_t j)
01118 {
01119 
01120   idx_t r;
01121   double t;
01122 
01123   it_assert (m, "Please use an existing matrix");
01124   it_assert (0 <= i && i <= mat_width (m) &&
01125        0 <= j && j <= mat_width (m), "Please specify existing columns");
01126 
01127   for (r = 0; r < mat_height (m); r++) {
01128     t = m[r][i];
01129     m[r][i] = m[r][j];
01130     m[r][j] = t;
01131   }
01132 
01133   return;
01134 
01135 }
01136 
01137 
01138 void imat_swap_rows (imat m, idx_t i, idx_t j)
01139 {
01140   ivec r;
01141 
01142   it_assert (m, "Please use an existing matrix");
01143   it_assert (0 <= i && i <= imat_height (m) &&
01144        0 <= j && j <= imat_height (m), "Please specify existing rows");
01145 
01146   r = m[i];
01147 
01148   m[i] = m[j];
01149   m[j] = r;
01150 }
01151 
01152 
01153 void imat_swap_cols (imat m, idx_t i, idx_t j)
01154 {
01155   idx_t r;
01156   int  t;
01157 
01158   it_assert (m, "Please use an existing matrix");
01159   it_assert (0 <= i && i <= imat_width (m) &&
01160        0 <= j && j <= imat_width (m), "Please specify existing columns");
01161 
01162   for (r = 0; r < imat_height (m); r++) {
01163     t = m[r][i];
01164     m[r][i] = m[r][j];
01165     m[r][j] = t;
01166   }
01167 }
01168 
01169 
01170 void bmat_swap_rows (bmat m, idx_t i, idx_t j)
01171 {
01172   bvec r;
01173 
01174   it_assert (m, "Please use an existing matrix");
01175   it_assert (0 <= i && i <= bmat_height (m) &&
01176        0 <= j && j <= bmat_height (m), "Please specify existing rows");
01177 
01178   r = m[i];
01179 
01180   m[i] = m[j];
01181   m[j] = r;
01182 }
01183 
01184 
01185 void bmat_swap_cols (bmat m, idx_t i, idx_t j)
01186 {
01187   idx_t r;
01188   byte t;
01189 
01190   it_assert (m, "Please use an existing matrix");
01191   it_assert (0 <= i && i <= bmat_width (m) &&
01192        0 <= j && j <= bmat_width (m), "Please specify existing columns");
01193 
01194   for (r = 0; r < bmat_height (m); r++) {
01195     t = m[r][i];
01196     m[r][i] = m[r][j];
01197     m[r][j] = t;
01198   }
01199 }
01200 
01201 
01202 void cmat_swap_rows (cmat m, idx_t i, idx_t j)
01203 {
01204   cvec r;
01205 
01206   it_assert (m, "Please use an existing matrix");
01207   it_assert (0 <= i && i <= cmat_height (m) &&
01208        0 <= j && j <= cmat_height (m), "Please specify existing rows");
01209 
01210   r = m[i];
01211 
01212   m[i] = m[j];
01213   m[j] = r;
01214 }
01215 
01216 
01217 void cmat_swap_cols (cmat m, idx_t i, idx_t j)
01218 {
01219   idx_t r;
01220   cplx t;
01221 
01222   it_assert (m, "Please use an existing matrix");
01223   it_assert (0 <= i && i <= cmat_width (m) &&
01224        0 <= j && j <= cmat_width (m), "Please specify existing columns");
01225 
01226   for (r = 0; r < cmat_height (m); r++) {
01227     t = m[r][i];
01228     m[r][i] = m[r][j];
01229     m[r][j] = t;
01230   }
01231 }
01232 
01233 
01234 mat _mat_transpose (mat m)
01235 {
01236   idx_t i, j;
01237   double val;
01238 
01239   it_assert (mat_height (m) == mat_width (m),
01240        "This function work with symmetric matrices only");
01241 
01242   for (i = 0; i < mat_width (m); i++)
01243     for (j = 0; j < mat_width (m); j++) {
01244       val = m[i][j];
01245       m[i][j] = m[j][i];
01246       m[j][i] = val;
01247     }
01248 
01249   return m;
01250 }
01251 
01252 
01253 imat _imat_transpose (imat m)
01254 {
01255   idx_t i, j;
01256   int  val;
01257 
01258   it_assert (imat_height (m) == imat_width (m),
01259        "This function work with symmetric matrices only");
01260 
01261   for (i = 0; i < imat_width (m); i++)
01262     for (j = 0; j < imat_width (m); j++) {
01263       val = m[i][j];
01264       m[i][j] = m[j][i];
01265       m[j][i] = val;
01266     }
01267 
01268   return m;
01269 }
01270 
01271 
01272 bmat _bmat_transpose (bmat m)
01273 {
01274   idx_t i, j;
01275   byte val;
01276 
01277   it_assert (bmat_height (m) == bmat_width (m),
01278        "This function work with symmetric matrices only");
01279 
01280   for (i = 0; i < bmat_width (m); i++)
01281     for (j = 0; j < bmat_width (m); j++) {
01282       val = m[i][j];
01283       m[i][j] = m[j][i];
01284       m[j][i] = val;
01285     }
01286 
01287   return m;
01288 }
01289 
01290 
01291 /*----------------------------------------------------------------------------*/
01292 mat mat_new_transpose (mat m)
01293 {
01294   idx_t i, j;
01295   mat  t = mat_new (mat_width (m), mat_height (m));
01296 
01297   for (i = 0; i < mat_height (m); i++)
01298     for (j = 0; j < mat_width (m); j++)
01299       t[j][i] = m[i][j];
01300   return t;
01301 }
01302 
01303 
01304 imat imat_new_transpose (imat m)
01305 {
01306   idx_t i, j;
01307   imat t = imat_new (imat_width (m), imat_height (m));
01308 
01309   for (i = 0; i < imat_height (m); i++)
01310     for (j = 0; j < imat_width (m); j++)
01311       t[j][i] = m[i][j];
01312   return t;
01313 }
01314 
01315 
01316 bmat bmat_new_transpose (bmat m)
01317 {
01318   idx_t i, j;
01319   bmat t = bmat_new (bmat_width (m), bmat_height (m));
01320 
01321   for (i = 0; i < bmat_height (m); i++)
01322     for (j = 0; j < bmat_width (m); j++)
01323       t[j][i] = m[i][j];
01324   return t;
01325 }
01326 
01327 
01328 /*------------------------------------------------------------------------------*/
01329 /* Mean, median, min, max, sum and elementary statistic indicators              */
01330 /*------------------------------------------------------------------------------*/
01331 
01332 
01333 double mat_sum (mat m)
01334 {
01335   idx_t i, j;
01336   double s = 0;
01337   assert (m);
01338   for (i = 0; i < mat_height (m); i++)
01339     for (j = 0; j < mat_width (m); j++)
01340       s += m[i][j];
01341   return s;
01342 }
01343 
01344 
01345 int imat_sum (imat m)
01346 {
01347   idx_t i, j;
01348   int  s = 0;
01349   assert (m);
01350   for (i = 0; i < imat_height (m); i++)
01351     for (j = 0; j < imat_width (m); j++)
01352       s += m[i][j];
01353   return s;
01354 }
01355 
01356 
01357 cplx cmat_sum (cmat m)
01358 {
01359   idx_t i, j;
01360   cplx s = cplx_0;
01361   assert (m);
01362   for (i = 0; i < cmat_height (m); i++)
01363     for (j = 0; j < cmat_width (m); j++)
01364       s = cadd (s, m[i][j]);
01365   return s;
01366 }
01367 
01368 
01369 /*----------------------------------------------------------------------------*/
01370 double mat_row_sum (mat m, idx_t c)
01371 {
01372   MAT_END_ROW_PARAM (m, c);
01373   return vec_sum (m[c]);
01374 }
01375 
01376 
01377 double mat_col_sum (mat m, idx_t c)
01378 {
01379   idx_t i;
01380   double s = 0;
01381   MAT_END_COL_PARAM (m, c);
01382   assert (m);
01383   for (i = 0; i < mat_height (m); i++)
01384     s += m[i][c];
01385   return s;
01386 }
01387 
01388 
01389 vec mat_rows_sum (mat m)
01390 {
01391   vec  s = vec_new (mat_height (m));
01392   idx_t i;
01393   for (i = 0; i < vec_length (s); i++)
01394     s[i] = mat_row_sum (m, i);
01395   return s;
01396 }
01397 
01398 
01399 vec mat_cols_sum (mat m)
01400 {
01401   vec  s = vec_new (mat_width (m));
01402   idx_t i;
01403   for (i = 0; i < vec_length (s); i++)
01404     s[i] = mat_col_sum (m, i);
01405   return s;
01406 }
01407 
01408 
01409 int imat_row_sum (imat m, idx_t c)
01410 {
01411   MAT_END_ROW_PARAM (m, c);
01412   return ivec_sum (m[c]);
01413 }
01414 
01415 
01416 int imat_col_sum (imat m, idx_t c)
01417 {
01418   idx_t i;
01419   int  s = 0;
01420   MAT_END_COL_PARAM (m, c);
01421   assert (m);
01422   for (i = 0; i < imat_height (m); i++)
01423     s += m[i][c];
01424   return s;
01425 }
01426 
01427 
01428 ivec imat_rows_sum (imat m)
01429 {
01430   ivec s = ivec_new (imat_height (m));
01431   idx_t i;
01432   for (i = 0; i < ivec_length (s); i++)
01433     s[i] = imat_row_sum (m, i);
01434   return s;
01435 }
01436 
01437 
01438 ivec imat_cols_sum (imat m)
01439 {
01440   ivec s = ivec_new (imat_width (m));
01441   idx_t i;
01442   for (i = 0; i < ivec_length (s); i++)
01443     s[i] = imat_col_sum (m, i);
01444   return s;
01445 }
01446 
01447 
01448 cplx cmat_row_sum (cmat m, idx_t c)
01449 {
01450   MAT_END_ROW_PARAM (m, c);
01451   return cvec_sum (m[c]);
01452 }
01453 
01454 
01455 cplx cmat_col_sum (cmat m, idx_t c)
01456 {
01457   idx_t i;
01458   cplx s = cplx_0;
01459   MAT_END_COL_PARAM (m, c);
01460   assert (m);
01461   for (i = 0; i < cmat_height (m); i++)
01462     s = cadd (s, m[i][c]);
01463   return s;
01464 }
01465 
01466 
01467 cvec cmat_rows_sum (cmat m)
01468 {
01469   cvec s = cvec_new (cmat_height (m));
01470   idx_t i;
01471   for (i = 0; i < cvec_length (s); i++)
01472     s[i] = cmat_row_sum (m, i);
01473   return s;
01474 }
01475 
01476 
01477 cvec cmat_cols_sum (cmat m)
01478 {
01479   cvec s = cvec_new (cmat_width (m));
01480   idx_t i;
01481   for (i = 0; i < cvec_length (s); i++)
01482     s[i] = cmat_col_sum (m, i);
01483   return s;
01484 }
01485 
01486 
01487 double mat_diag_sum (mat m)
01488 {
01489   double res = 0;
01490   int i, n = __mat_c_my_min (mat_height (m), mat_width (m));
01491 
01492   for (i = 0 ; i < n ; i++)
01493     res += m[i][i];
01494 
01495   return res;
01496 }
01497 
01498 
01499 int imat_diag_sum (imat m)
01500 {
01501   int res = 0;
01502   int i, n = __mat_c_my_min (imat_height (m), imat_width (m));
01503 
01504   for (i = 0 ; i < n ; i++)
01505     res += m[i][i];
01506 
01507   return res;
01508 }
01509 
01510 
01511 int bmat_diag_sum (bmat m)
01512 {
01513   int res = 0;
01514   int i, n = __mat_c_my_min (bmat_height (m), bmat_width (m));
01515 
01516   for (i = 0 ; i < n ; i++)
01517     res += m[i][i];
01518 
01519   return res;
01520 }
01521 
01522 
01523 cplx cmat_diag_sum (cmat m)
01524 {
01525   cplx res = cplx_0;
01526   int i, n = __mat_c_my_min (cmat_height (m), cmat_width (m));
01527 
01528   for (i = 0 ; i < n ; i++)
01529     cadd (res, m[i][i]);
01530 
01531   return res;
01532 }
01533 
01534 
01535 
01536 
01537 /*----------------------------------------------------------------------------*/
01538 double mat_mean (mat m)
01539 {
01540   assert (m);
01541   return mat_sum (m) / (mat_width (m) * mat_height (m));
01542 }
01543 
01544 
01545 double imat_mean (imat m)
01546 {
01547   assert (m);
01548   return imat_sum (m) / (double) (imat_width (m) * imat_height (m));
01549 }
01550 
01551 
01552 cplx cmat_mean (cmat m)
01553 {
01554   cplx s;
01555   assert (m);
01556   s = cmat_sum (m);
01557   creal (s) /= (cmat_width (m) * cmat_height (m));
01558   cimag (s) /= (cmat_width (m) * cmat_height (m));
01559   return s;
01560 }
01561 
01562 
01563 /*----------------------------------------------------------------------------*/
01564 double mat_max_index_submatrix (mat m, idx_t rmin, idx_t rmax, idx_t cmin,
01565         idx_t cmax, idx_t * r, idx_t * c)
01566 {
01567 
01568   double max = -HUGE_VAL;
01569   idx_t i = 0;
01570   idx_t j = 0;
01571 
01572   it_assert (m, "Please use an existing matrix");
01573   it_assert (rmin >= 0 && rmin <= rmax
01574        && rmax <= mat_height (m), "Wrong row indexes");
01575   it_assert (cmin >= 0 && cmin <= cmax
01576        && cmax <= mat_width (m), "Wrong column indexes");
01577 
01578   for (j = cmin; j < cmax; j++)
01579     for (i = rmin; i < rmax; i++)
01580       if (max < m[i][j]) {
01581   *r = i;
01582   *c = j;
01583   max = m[i][j];
01584       }
01585 
01586   return max;
01587 
01588 }
01589 
01590 double mat_min_index_submatrix (mat m, idx_t rmin, idx_t rmax, idx_t cmin,
01591         idx_t cmax, idx_t * r, idx_t * c)
01592 {
01593 
01594   double min = HUGE_VAL;
01595   idx_t i = 0;
01596   idx_t j = 0;
01597 
01598   it_assert (m, "Please use an existing matrix");
01599   it_assert (rmin >= 0 && rmin <= rmax
01600        && rmax <= mat_height (m), "Wrong row indexes");
01601   it_assert (cmin >= 0 && cmin <= cmax
01602        && cmax <= mat_width (m), "Wrong column indexes");
01603 
01604   for (j = cmin; j < cmax; j++)
01605     for (i = rmin; i < rmax; i++)
01606       if (min > m[i][j]) {
01607   *r = i;
01608   *c = j;
01609   min = m[i][j];
01610       }
01611 
01612   return min;
01613 
01614 }
01615 
01616 int imat_max_index_submatrix (imat m, idx_t rmin, idx_t rmax, idx_t cmin,
01617             idx_t cmax, idx_t * r, idx_t * c)
01618 {
01619 
01620   int  max = INT_MIN;
01621   idx_t i = 0;
01622   idx_t j = 0;
01623 
01624   it_assert (m, "Please use an existing matrix");
01625   it_assert (rmin >= 0 && rmin <= rmax
01626        && rmax <= imat_height (m), "Wrong row indexes");
01627   it_assert (cmin >= 0 && cmin <= cmax
01628        && cmax <= imat_width (m), "Wrong column indexes");
01629 
01630   for (j = cmin; j < cmax; j++)
01631     for (i = rmin; i < rmax; i++)
01632       if (max < m[i][j]) {
01633   *r = i;
01634   *c = j;
01635   max = m[i][j];
01636       }
01637 
01638   return max;
01639 
01640 }
01641 
01642 int imat_min_index_submatrix (imat m, idx_t rmin, idx_t rmax, idx_t cmin,
01643             idx_t cmax, idx_t * r, idx_t * c)
01644 {
01645 
01646   int  min = INT_MAX;
01647   idx_t i = 0;
01648   idx_t j = 0;
01649 
01650   it_assert (m, "Please use an existing matrix");
01651   it_assert (rmin >= 0 && rmin <= rmax
01652        && rmax <= imat_height (m), "Wrong row indexes");
01653   it_assert (cmin >= 0 && cmin <= cmax
01654        && cmax <= imat_width (m), "Wrong column indexes");
01655 
01656   for (j = cmin; j < cmax; j++)
01657     for (i = rmin; i < rmax; i++)
01658       if (min > m[i][j]) {
01659   *r = i;
01660   *c = j;
01661   min = m[i][j];
01662       }
01663 
01664   return min;
01665 
01666 }
01667 
01668 double mat_max (mat m)
01669 {
01670   idx_t r, c;
01671 
01672   return mat_max_index_submatrix (m, 0, mat_height (m), 0, mat_width (m),
01673           &r, &c);
01674 
01675 }
01676 
01677 
01678 int imat_max (imat m)
01679 {
01680   idx_t r, c;
01681 
01682   return imat_max_index_submatrix (m, 0, imat_height (m), 0,
01683            imat_width (m), &r, &c);
01684 
01685 }
01686 
01687 
01688 double mat_min (mat m)
01689 {
01690   idx_t r, c;
01691 
01692   return mat_min_index_submatrix (m, 0, mat_height (m), 0, mat_width (m),
01693           &r, &c);
01694 
01695 }
01696 
01697 
01698 int imat_min (imat m)
01699 {
01700   idx_t r, c;
01701 
01702   return imat_min_index_submatrix (m, 0, imat_height (m), 0,
01703            imat_width (m), &r, &c);
01704 
01705 }
01706 
01707 double mat_max_index (mat m, idx_t * r, idx_t * c)
01708 {
01709 
01710   return mat_max_index_submatrix (m, 0, mat_height (m), 0, mat_width (m),
01711           r, c);
01712 
01713 }
01714 
01715 double mat_max_col_index (mat m, idx_t c, idx_t * r)
01716 {
01717 
01718   idx_t i;
01719 
01720   return mat_max_index_submatrix (m, 0, mat_height (m), c, c, r, &i);
01721 
01722 }
01723 
01724 double mat_max_row_index (mat m, idx_t r, idx_t * c)
01725 {
01726 
01727   idx_t i;
01728 
01729   return mat_max_index_submatrix (m, r, r, 0, mat_width (m), &i, c);
01730 
01731 }
01732 
01733 double mat_min_index (mat m, idx_t * r, idx_t * c)
01734 {
01735 
01736   return mat_min_index_submatrix (m, 0, mat_height (m), 0, mat_width (m),
01737           r, c);
01738 
01739 }
01740 
01741 double mat_min_col_index (mat m, idx_t c, idx_t * r)
01742 {
01743 
01744   idx_t i;
01745 
01746   return mat_min_index_submatrix (m, 0, mat_height (m), c, c, r, &i);
01747 
01748 }
01749 
01750 double mat_min_row_index (mat m, idx_t r, idx_t * c)
01751 {
01752 
01753   idx_t i;
01754 
01755   return mat_min_index_submatrix (m, r, r, 0, mat_width (m), &i, c);
01756 
01757 }
01758 
01759 int imat_max_index (imat m, idx_t * r, idx_t * c)
01760 {
01761 
01762   return imat_max_index_submatrix (m, 0, imat_height (m), 0,
01763            imat_width (m), r, c);
01764 
01765 }
01766 
01767 int imat_max_col_index (imat m, idx_t c, idx_t * r)
01768 {
01769 
01770   idx_t i;
01771 
01772   return imat_max_index_submatrix (m, 0, imat_height (m), c, c, r, &i);
01773 
01774 }
01775 
01776 int imat_max_row_index (imat m, idx_t r, idx_t * c)
01777 {
01778 
01779   idx_t i;
01780 
01781   return imat_max_index_submatrix (m, r, r, 0, imat_width (m), &i, c);
01782 
01783 }
01784 
01785 int imat_min_index (imat m, idx_t * r, idx_t * c)
01786 {
01787 
01788   return imat_min_index_submatrix (m, 0, imat_height (m), 0,
01789            imat_width (m), r, c);
01790 
01791 }
01792 
01793 int imat_min_col_index (imat m, idx_t c, idx_t * r)
01794 {
01795 
01796   idx_t i;
01797 
01798   return imat_min_index_submatrix (m, 0, imat_height (m), c, c, r, &i);
01799 
01800 }
01801 
01802 int imat_min_row_index (imat m, idx_t r, idx_t * c)
01803 {
01804 
01805   idx_t i;
01806 
01807   return imat_min_index_submatrix (m, r, r, 0, imat_width (m), &i, c);
01808 
01809 }
01810 
01811 /*----------------------------------------------------------------------------*/
01812 double mat_norm_1 (mat m)
01813 {
01814   idx_t i, j;
01815   double r = -1, s;
01816 
01817   for (i = 0; i < mat_height (m); i++) {
01818     s = 0;
01819     for (j = 0; j < mat_width (m); j++)
01820       s += fabs (m[i][j]);
01821 
01822     if (s > r)
01823       r = s;
01824   }
01825   return r;
01826 }
01827 
01828 
01829 double mat_norm_inf (mat m)
01830 {
01831   idx_t i, j;
01832   double r = -1, s;
01833 
01834   for (j = 0; j < mat_width (m); j++) {
01835     s = 0;
01836     for (i = 0; i < mat_height (m); i++)
01837       s += fabs (m[i][j]);
01838 
01839     if (s > r)
01840       r = s;
01841   }
01842   return r;
01843 }
01844 
01845 
01846 /*----------------------------------------------------------------------------*/
01847 double mat_variance (mat m)
01848 {
01849   idx_t i, j;
01850   idx_t w, h;
01851   double sum = 0;
01852   double var = 0;
01853   assert (m);
01854   h = Mat_height (m);
01855   w = Mat_width (m);
01856   assert (w * h > 1);   /* otherwise the unbiased variance is not defined */
01857   for (i = 0; i < h; i++)
01858     for (j = 0; j < w; j++) {
01859       sum += m[i][j];
01860       var += m[i][j] * m[i][j];
01861     }
01862 
01863   return (var - sum * sum / (w * h)) / (w * h - 1);
01864 }
01865 
01866 
01867 /*----------------------------------------------------------------------------*/
01868 void mat_normalize (mat m)
01869 {
01870   idx_t i, j;
01871   double s = mat_sum (m);
01872   assert (m);
01873   for (j = 0; j < Mat_height (m); j++)
01874     for (i = 0; i < Mat_width (m); i++)
01875       m[j][i] /= s;
01876 }
01877 
01878 
01879 /*----------------------------------------------------------------------------*/
01880 /* Column Normalization */
01881 void mat_cols_normalize (mat m, double nr)
01882 {
01883   idx_t i, j;
01884   vec  sums = mat_cols_sum (m);
01885   double vecnorm;
01886 
01887   assert (m);
01888   for (i = 0; i < Mat_width (m); i++) {
01889 
01890     /* compute the norm */
01891     vecnorm = 0;
01892     for (j = 0; j < mat_height (m); j++)
01893       vecnorm += pow (fabs (m[j][i]), nr);
01894 
01895     vecnorm = pow (vecnorm, 1.0 / nr);
01896 
01897     /* Normalize the corresponding vector */
01898     for (j = 0; j < mat_height (m); j++)
01899       m[j][i] /= vecnorm;
01900   }
01901 
01902   vec_delete (sums);
01903 }
01904 
01905 
01906 /* Column Normalization */
01907 void mat_rows_normalize (mat m, double nr)
01908 {
01909   idx_t i;
01910   assert (m);
01911 
01912   for (i = 0; i < Mat_height (m); i++) 
01913     vec_normalize (m[i], nr);
01914 }
01915 
01916 
01917 
01918 /*------------------------------------------------------------------------------*/
01919 /** @name Basic arithmetic operations                                           */
01920 /*------------------------------------------------------------------------------*/
01921 
01922 
01923 /* Operations with a scalar value                                             */
01924 void mat_incr (mat m, double a)
01925 {
01926   idx_t i, j;
01927   assert (m);
01928   for (i = 0; i < mat_height (m); i++)
01929     for (j = 0; j < mat_width (m); j++)
01930       m[i][j] += a;
01931 }
01932 
01933 
01934 void mat_decr (mat m, double a)
01935 {
01936   idx_t i, j;
01937   assert (m);
01938   for (i = 0; i < mat_height (m); i++)
01939     for (j = 0; j < mat_width (m); j++)
01940       m[i][j] -= a;
01941 }
01942 
01943 
01944 void mat_mul_by (mat m, double a)
01945 {
01946   idx_t i, j;
01947   assert (m);
01948   for (i = 0; i < mat_height (m); i++)
01949     for (j = 0; j < mat_width (m); j++)
01950       m[i][j] *= a;
01951 }
01952 
01953 
01954 void mat_div_by (mat m, double a)
01955 {
01956   idx_t i, j;
01957   assert (m);
01958   for (i = 0; i < mat_height (m); i++)
01959     for (j = 0; j < mat_width (m); j++)
01960       m[i][j] /= a;
01961 }
01962 
01963 
01964 void imat_incr (imat m, int a)
01965 {
01966   idx_t i, j;
01967   assert (m);
01968   for (i = 0; i < imat_height (m); i++)
01969     for (j = 0; j < imat_width (m); j++)
01970       m[i][j] += a;
01971 }
01972 
01973 
01974 void imat_decr (imat m, int a)
01975 {
01976   idx_t i, j;
01977   assert (m);
01978   for (i = 0; i < imat_height (m); i++)
01979     for (j = 0; j < imat_width (m); j++)
01980       m[i][j] -= a;
01981 }
01982 
01983 
01984 void imat_mul_by (imat m, int a)
01985 {
01986   idx_t i, j;
01987   assert (m);
01988   for (i = 0; i < imat_height (m); i++)
01989     for (j = 0; j < imat_width (m); j++)
01990       m[i][j] *= a;
01991 }
01992 
01993 
01994 void imat_div_by (imat m, int a)
01995 {
01996   idx_t i, j;
01997   assert (m);
01998   for (i = 0; i < imat_height (m); i++)
01999     for (j = 0; j < imat_width (m); j++)
02000       m[i][j] /= a;
02001 }
02002 
02003 
02004 void cmat_incr (cmat m, cplx a)
02005 {
02006   idx_t i, j;
02007   assert (m);
02008   for (i = 0; i < cmat_height (m); i++)
02009     for (j = 0; j < cmat_width (m); j++)
02010       m[i][j] = cadd (m[i][j], a);
02011 }
02012 
02013 
02014 void cmat_decr (cmat m, cplx a)
02015 {
02016   idx_t i, j;
02017   assert (m);
02018   for (i = 0; i < cmat_height (m); i++)
02019     for (j = 0; j < cmat_width (m); j++)
02020       m[i][j] = csub (m[i][j], a);
02021 }
02022 
02023 
02024 void cmat_mul_by (cmat m, cplx a)
02025 {
02026   idx_t i, j;
02027   assert (m);
02028   for (i = 0; i < cmat_height (m); i++)
02029     for (j = 0; j < cmat_width (m); j++)
02030       m[i][j] = cmul (m[i][j], a);
02031 }
02032 
02033 
02034 void cmat_div_by (cmat m, cplx a)
02035 {
02036   idx_t i, j;
02037   assert (m);
02038   for (i = 0; i < cmat_height (m); i++)
02039     for (j = 0; j < cmat_width (m); j++)
02040       m[i][j] = cdiv (m[i][j], a);
02041 }
02042 
02043 
02044 /*------------------------------------------------------------------------------*/
02045 /** @name Basic arithmetic operations on rows/columns                           */
02046 /*------------------------------------------------------------------------------*/
02047 
02048 void mat_col_set (mat m, idx_t col, double a)
02049 {
02050   idx_t i;
02051   assert (m);
02052   MAT_END_COL_PARAM (m, col);
02053   assert (col >= 0 && col < mat_width (m));
02054   for (i = 0; i < mat_height (m); i++)
02055     m[i][col] = a;
02056 }
02057 
02058 
02059 void mat_col_incr (mat m, idx_t col, double a)
02060 {
02061   idx_t i;
02062   assert (m);
02063   MAT_END_COL_PARAM (m, col);
02064   assert (col >= 0 && col < mat_width (m));
02065   for (i = 0; i < mat_height (m); i++)
02066     m[i][col] += a;
02067 }
02068 
02069 
02070 void mat_col_decr (mat m, idx_t col, double a)
02071 {
02072   idx_t i;
02073   assert (m);
02074   MAT_END_COL_PARAM (m, col);
02075   assert (col >= 0 && col < mat_width (m));
02076   for (i = 0; i < mat_height (m); i++)
02077     m[i][col] -= a;
02078 }
02079 
02080 
02081 void mat_col_mul_by (mat m, idx_t col, double a)
02082 {
02083   idx_t i;
02084   assert (m);
02085   MAT_END_COL_PARAM (m, col);
02086   assert (col >= 0 && col < mat_width (m));
02087   for (i = 0; i < mat_height (m); i++)
02088     m[i][col] *= a;
02089 }
02090 
02091 
02092 void mat_col_div_by (mat m, idx_t col, double a)
02093 {
02094   idx_t i;
02095   assert (m);
02096   MAT_END_COL_PARAM (m, col);
02097   assert (col >= 0 && col < mat_width (m));
02098   for (i = 0; i < mat_height (m); i++)
02099     m[i][col] /= a;
02100 }
02101 
02102 
02103 void imat_col_set (imat m, idx_t col, int a)
02104 {
02105   idx_t i;
02106   assert (m);
02107   MAT_END_COL_PARAM (m, col);
02108   assert (col >= 0 && col < imat_width (m));
02109   for (i = 0; i < imat_height (m); i++)
02110     m[i][col] = a;
02111 }
02112 
02113 
02114 void imat_col_incr (imat m, idx_t col, int a)
02115 {
02116   idx_t i;
02117   assert (m);
02118   MAT_END_COL_PARAM (m, col);
02119   assert (col >= 0 && col < imat_width (m));
02120   for (i = 0; i < imat_height (m); i++)
02121     m[i][col] += a;
02122 }
02123 
02124 
02125 void imat_col_decr (imat m, idx_t col, int a)
02126 {
02127   idx_t i;
02128   assert (m);
02129   MAT_END_COL_PARAM (m, col);
02130   assert (col >= 0 && col < imat_width (m));
02131   for (i = 0; i < imat_height (m); i++)
02132     m[i][col] -= a;
02133 }
02134 
02135 
02136 void imat_col_mul_by (imat m, idx_t col, int a)
02137 {
02138   idx_t i;
02139   assert (m);
02140   MAT_END_COL_PARAM (m, col);
02141   assert (col >= 0 && col < imat_width (m));
02142   for (i = 0; i < imat_height (m); i++)
02143     m[i][col] *= a;
02144 }
02145 
02146 
02147 void imat_col_div_by (imat m, idx_t col, int a)
02148 {
02149   idx_t i;
02150   assert (m);
02151   MAT_END_COL_PARAM (m, col);
02152   assert (col >= 0 && col < imat_width (m));
02153   for (i = 0; i < imat_height (m); i++)
02154     m[i][col] /= a;
02155 }
02156 
02157 
02158 void mat_row_incr (mat m, idx_t row, double a)
02159 {
02160   assert (m);
02161   MAT_END_ROW_PARAM (m, row);
02162   vec_incr (m[row], a);
02163 }
02164 
02165 
02166 void mat_row_decr (mat m, idx_t row, double a)
02167 {
02168   assert (m);
02169   MAT_END_ROW_PARAM (m, row);
02170   vec_decr (m[row], a);
02171 }
02172 
02173 
02174 void mat_row_mul_by (mat m, idx_t row, double a)
02175 {
02176   assert (m);
02177   MAT_END_ROW_PARAM (m, row);
02178   vec_mul_by (m[row], a);
02179 }
02180 
02181 
02182 void mat_row_div_by (mat m, idx_t row, double a)
02183 {
02184   assert (m);
02185   MAT_END_ROW_PARAM (m, row);
02186   vec_div_by (m[row], a);
02187 }
02188 
02189 
02190 void imat_row_incr (imat m, idx_t row, int a)
02191 {
02192   assert (m);
02193   MAT_END_ROW_PARAM (m, row);
02194   ivec_incr (m[row], a);
02195 }
02196 
02197 
02198 void imat_row_decr (imat m, idx_t row, int a)
02199 {
02200   assert (m);
02201   MAT_END_ROW_PARAM (m, row);
02202   ivec_decr (m[row], a);
02203 }
02204 
02205 
02206 void imat_row_mul_by (imat m, idx_t row, int a)
02207 {
02208   assert (m);
02209   MAT_END_ROW_PARAM (m, row);
02210   ivec_mul_by (m[row], a);
02211 }
02212 
02213 
02214 void imat_row_div_by (imat m, idx_t row, int a)
02215 {
02216   assert (m);
02217   MAT_END_ROW_PARAM (m, row);
02218   ivec_div_by (m[row], a);
02219 }
02220 
02221 
02222 
02223 /*------------------------------------------------------------------------------*/
02224 /** @name Component per component operations                                    */
02225 /*------------------------------------------------------------------------------*/
02226 
02227 void mat_elem_add (mat m1, mat m2)
02228 {
02229   idx_t i, j;
02230   assert (m1 && m2);
02231   assert (mat_height (m1) == mat_height (m2));
02232   for (i = 0; i < mat_height (m1); i++)
02233     for (j = 0; j < mat_width (m1); j++)
02234       m1[i][j] += m2[i][j];
02235 }
02236 
02237 
02238 void mat_elem_sub (mat m1, mat m2)
02239 {
02240   idx_t i, j;
02241   assert (m1 && m2);
02242   assert (mat_height (m1) == mat_height (m2));
02243   for (i = 0; i < mat_height (m1); i++)
02244     for (j = 0; j < mat_width (m1); j++)
02245       m1[i][j] -= m2[i][j];
02246 }
02247 
02248 
02249 void mat_elem_mul (mat m1, mat m2)
02250 {
02251   idx_t i, j;
02252   assert (m1 && m2);
02253   assert (mat_height (m1) == mat_height (m2));
02254   for (i = 0; i < mat_height (m1); i++)
02255     for (j = 0; j < mat_width (m1); j++)
02256       m1[i][j] *= m2[i][j];
02257 }
02258 
02259 
02260 void mat_elem_div (mat m1, mat m2)
02261 {
02262   idx_t i, j;
02263   assert (m1 && m2);
02264   assert (mat_height (m1) == mat_height (m2));
02265   for (i = 0; i < mat_height (m1); i++)
02266     for (j = 0; j < mat_width (m1); j++)
02267       m1[i][j] /= m2[i][j];
02268 }
02269 
02270 void mat_elem_abs (mat m)
02271 {
02272   int i, j;
02273   assert(m); 
02274   for (i = 0; i < mat_height (m); i++)
02275     for (j = 0; j < mat_width (m); j++)
02276       m[i][j] = fabs (m[i][j]);
02277 }
02278 
02279 void mat_elem_exp (mat m)
02280 {
02281   int i, j;
02282   assert(m); 
02283   for (i = 0; i < mat_height (m); i++)
02284     for (j = 0; j < mat_width (m); j++)
02285       m[i][j] = exp (m[i][j]);
02286 }
02287 
02288 void mat_elem_sqrt (mat m)
02289 {
02290   int i, j;
02291   assert(m); 
02292   for (i = 0; i < mat_height (m); i++)
02293     for (j = 0; j < mat_width (m); j++)
02294       m[i][j] = sqrt (m[i][j]);
02295 }
02296 
02297 void mat_elem_sqr (mat m)
02298 {
02299   int i, j;
02300   assert(m); 
02301   for (i = 0; i < mat_height (m); i++)
02302     for (j = 0; j < mat_width (m); j++)
02303       m[i][j] = m[i][j] * m[i][j];
02304 }
02305 
02306 void mat_elem_pow (mat m, double p)
02307 {
02308   int i, j;
02309   assert(m);
02310   for (i = 0; i < mat_height (m); i++)
02311     for (j = 0; j < mat_width (m); j++)
02312       m[i][j] = pow (m[i][j], p);
02313 }
02314 
02315 void imat_elem_add (imat m1, imat m2)
02316 {
02317   idx_t i, j;
02318   assert (m1 && m2);
02319   assert (imat_height (m1) == imat_height (m2));
02320   for (i = 0; i < imat_height (m1); i++)
02321     for (j = 0; j < imat_width (m1); j++)
02322       m1[i][j] += m2[i][j];
02323 }
02324 
02325 
02326 void imat_elem_sub (imat m1, imat m2)
02327 {
02328   idx_t i, j;
02329   assert (m1 && m2);
02330   assert (imat_height (m1) == imat_height (m2));
02331   for (i = 0; i < imat_height (m1); i++)
02332     for (j = 0; j < imat_width (m1); j++)
02333       m1[i][j] -= m2[i][j];
02334 }
02335 
02336 
02337 void imat_elem_mul (imat m1, imat m2)
02338 {
02339   idx_t i, j;
02340   assert (m1 && m2);
02341   assert (imat_height (m1) == imat_height (m2));
02342   for (i = 0; i < imat_height (m1); i++)
02343     for (j = 0; j < imat_width (m1); j++)
02344       m1[i][j] *= m2[i][j];
02345 }
02346 
02347 
02348 void imat_elem_div (imat m1, imat m2)
02349 {
02350   idx_t i, j;
02351   assert (m1 && m2);
02352   assert (imat_height (m1) == imat_height (m2));
02353   for (i = 0; i < imat_height (m1); i++)
02354     for (j = 0; j < imat_width (m1); j++)
02355       m1[i][j] /= m2[i][j];
02356 }
02357 
02358 
02359 void imat_elem_sqr (imat m)
02360 {
02361   int i, j;
02362   assert(m); 
02363   for (i = 0; i < imat_height (m); i++)
02364     for (j = 0; j < imat_width (m); j++)
02365       m[i][j] = m[i][j] * m[i][j];
02366 }
02367 
02368 void cmat_elem_add (cmat m1, cmat m2)
02369 {
02370   idx_t i, j;
02371   assert (m1 && m2);
02372   assert (cmat_height (m1) == cmat_height (m2));
02373   for (i = 0; i < cmat_height (m1); i++)
02374     for (j = 0; j < cmat_width (m1); j++)
02375       m1[i][j] = cadd (m1[i][j], m2[i][j]);
02376 }
02377 
02378 
02379 void cmat_elem_sub (cmat m1, cmat m2)
02380 {
02381   idx_t i, j;
02382   assert (m1 && m2);
02383   assert (cmat_height (m1) == cmat_height (m2));
02384   for (i = 0; i < cmat_height (m1); i++)
02385     for (j = 0; j < cmat_width (m1); j++)
02386       m1[i][j] = csub (m1[i][j], m2[i][j]);
02387 }
02388 
02389 
02390 void cmat_elem_mul (cmat m1, cmat m2)
02391 {
02392   idx_t i, j;
02393   assert (m1 && m2);
02394   assert (cmat_height (m1) == cmat_height (m2));
02395   for (i = 0; i < cmat_height (m1); i++)
02396     for (j = 0; j < cmat_width (m1); j++)
02397       m1[i][j] = cmul (m1[i][j], m2[i][j]);
02398 }
02399 
02400 
02401 void cmat_elem_div (cmat m1, cmat m2)
02402 {
02403   idx_t i, j;
02404   assert (m1 && m2);
02405   assert (cmat_height (m1) == cmat_height (m2));
02406   for (i = 0; i < cmat_height (m1); i++)
02407     for (j = 0; j < cmat_width (m1); j++)
02408       m1[i][j] = cdiv (m1[i][j], m2[i][j]);
02409 }
02410 
02411 
02412 /*------------------------------------------------------------------------------*/
02413 /** @name Matrix arithmetic                                                     */
02414 /*------------------------------------------------------------------------------*/
02415 
02416 void mat_add (mat m1, mat m2)
02417 {
02418   mat_elem_add (m1, m2);
02419 }
02420 
02421 
02422 void mat_sub (mat m1, mat m2)
02423 {
02424   mat_elem_sub (m1, m2);
02425 }
02426 
02427 
02428 void imat_add (imat m1, imat m2)
02429 {
02430   imat_elem_add (m1, m2);
02431 }
02432 
02433 
02434 void imat_sub (imat m1, imat m2)
02435 {
02436   imat_elem_sub (m1, m2);
02437 }
02438 
02439 
02440 void cmat_add (cmat m1, cmat m2)
02441 {
02442   cmat_elem_add (m1, m2);
02443 }
02444 
02445 
02446 void cmat_sub (cmat m1, cmat m2)
02447 {
02448   cmat_elem_sub (m1, m2);
02449 }
02450 
02451 
02452 void mat_mul (mat out, mat m1, mat m2)
02453 {
02454   int i, j, k;
02455   assert( m1 && m2 );
02456   it_assert (mat_width(m1)==mat_height(m2), "Size mismatch in mat_mul inputs");
02457   it_assert (mat_height(m1)==mat_height(out), "Size mismatch between input and output");
02458   it_assert (mat_width(m2)==mat_width(out), "Size mismatch between input and output");
02459   
02460   mat_zeros (out);
02461 
02462   for ( i = 0 ; i< mat_height (m1) ; i++ )
02463     for ( j = 0 ; j< mat_width (m2) ; j++ )
02464       for ( k = 0 ; k< mat_width (m1) ; k++ )
02465   out[i][j] += m1[i][k]*m2[k][j];
02466 }
02467 
02468 
02469 void imat_mul (imat out, imat m1, imat m2)
02470 {
02471   int i, j, k;
02472   assert( m1 && m2 );
02473   it_assert (imat_width(m1)==imat_height(m2), "Size misimatch in imat_mul inputs");
02474   it_assert (imat_height(m1)==imat_height(out), "Size mismatch between input and output");
02475   it_assert (imat_width(m2)==imat_width(out), "Size mismatch between input and output");
02476   
02477   imat_zeros (out);
02478 
02479   for ( i = 0 ; i< imat_height (m1) ; i++ )
02480     for ( j = 0 ; j< imat_width (m2) ; j++ )
02481       for ( k = 0 ; k< imat_width (m1) ; k++ )
02482   out[i][j] += m1[i][k]*m2[k][j];
02483 }
02484 
02485 
02486 void mat_mul_transpose_left (mat out, mat m1, mat m2)
02487 {
02488   int i, j, k;
02489   assert( m1 && m2 );
02490   it_assert (mat_height(m1)==mat_height(m2), "Size mismatch in mat_mul inputs");
02491   it_assert (mat_width(m1)==mat_height(out), "Size mismatch between input and output");
02492   it_assert (mat_width(m2)==mat_width(out), "Size mismatch between input and output");
02493   
02494   mat_zeros (out);
02495   
02496   for ( i= 0; i< mat_width(m1); i++ )
02497     for ( j= 0; j< mat_width(m2); j++ )
02498       for ( k= 0; k< mat_height(m1); k++ )
02499   out[i][j] += m1[k][i]*m2[k][j];
02500 }
02501 
02502 
02503 void mat_mul_transpose_right (mat out, mat m1, mat m2)
02504 {
02505   int i, j, k;
02506   assert( m1 && m2 );
02507   it_assert (mat_height(m1)==mat_width(m2), "Size mismatch in mat_mul inputs");
02508   it_assert (mat_width(m1)==mat_height(out), "Size mismatch between input and output");
02509   it_assert (mat_height(m2)==mat_width(out), "Size mismatch between input and output");
02510   
02511   mat_zeros (out);
02512   
02513   for ( i= 0; i< mat_height(m1); i++ )
02514     for ( j= 0; j< mat_height(m2); j++ )
02515       for ( k= 0; k< mat_width(m1); k++ )
02516   out[i][j] += m1[i][k]*m2[j][k];
02517 }
02518 
02519 
02520 void mat_mul_transpose_leftright (mat out, mat m1, mat m2)
02521 {
02522   int i, j, k;
02523   assert( m1 && m2 );
02524   it_assert (mat_width(m1)==mat_width(m2), "Size mismatch in mat_mul inputs");
02525   it_assert (mat_height(m1)==mat_height(out), "Size mismatch between input and output");
02526   it_assert (mat_height(m2)==mat_width(out), "Size mismatch between input and output");
02527   
02528   mat_zeros (out);
02529 
02530   for ( i= 0; i< mat_width(m1); i++ )
02531     for ( j= 0; j< mat_height(m2); j++ )
02532       for ( k= 0; k< mat_height(m1); k++ )
02533   out[i][j] += m1[k][i]*m2[j][k];
02534 }
02535 
02536 
02537 /*******************************/
02538 
02539 mat mat_new_mul (mat m1, mat m2)
02540 {
02541   idx_t i, j, k;
02542   mat  m;
02543   assert (m1 && m2);
02544   assert (mat_width (m1) == mat_height (m2));
02545 
02546   m = mat_new_zeros (mat_height (m1), mat_width (m2));
02547 
02548   for (i = 0; i < mat_height (m1); i++)
02549     for (j = 0; j < mat_width (m2); j++)
02550       for (k = 0; k < mat_width (m1); k++)
02551   m[i][j] += m1[i][k] * m2[k][j];
02552   return m;
02553 }
02554 
02555 
02556 
02557 
02558 mat mat_new_add (mat m1, mat m2)
02559 {
02560   mat  m = mat_clone (m1);
02561   mat_add (m, m2);
02562   return m;
02563 }
02564 
02565 
02566 mat mat_new_sub (mat m1, mat m2)
02567 {
02568   mat  m = mat_clone (m1);
02569   mat_add (m, m2);
02570   return m;
02571 }
02572 
02573 
02574 imat imat_new_add (imat m1, imat m2)
02575 {
02576   imat m = imat_clone (m1);
02577   imat_add (m, m2);
02578   return m;
02579 }
02580 
02581 
02582 imat imat_new_sub (imat m1, imat m2)
02583 {
02584   imat m = imat_clone (m1);
02585   imat_add (m, m2);
02586   return m;
02587 }
02588 
02589 
02590 imat imat_new_mul (imat m1, imat m2)
02591 {
02592   idx_t i, j, k;
02593   imat m;
02594   assert (m1 && m2);
02595   assert (imat_width (m1) == imat_height (m2));
02596 
02597   m = imat_new_zeros (imat_height (m1), imat_width (m2));
02598 
02599   for (i = 0; i < imat_height (m1); i++)
02600     for (j = 0; j < imat_width (m2); j++)
02601       for (k = 0; k < imat_width (m1); k++)
02602   m[i][j] += m1[i][k] * m2[k][j];
02603   return m;
02604 }
02605 
02606 
02607 cmat cmat_new_add (cmat m1, cmat m2)
02608 {
02609   cmat m = cmat_clone (m1);
02610   cmat_add (m, m2);
02611   return m;
02612 }
02613 
02614 
02615 cmat cmat_new_sub (cmat m1, cmat m2)
02616 {
02617   cmat m = cmat_clone (m1);
02618   cmat_add (m, m2);
02619   return m;
02620 }
02621 
02622 
02623 cmat cmat_new_mul (cmat m1, cmat m2)
02624 {
02625   idx_t i, j, k;
02626   cmat m;
02627   assert (m1 && m2);
02628   assert (cmat_width (m1) == cmat_height (m2));
02629 
02630   m = cmat_new_zeros (cmat_height (m1), cmat_width (m2));
02631 
02632   for (i = 0; i < cmat_height (m1); i++)
02633     for (j = 0; j < cmat_width (m2); j++)
02634       for (k = 0; k < cmat_width (m1); k++)
02635   m[i][j] = cadd (m[i][j], cmul (m1[i][k], m2[k][j]));
02636   return m;
02637 }
02638 
02639 
02640 vec mat_vec_mul (mat m, vec v)
02641 {
02642   idx_t i, j;
02643   vec  r;
02644   assert (m && v);
02645   assert (mat_width (m) == vec_length (v));
02646 
02647   r = vec_new_zeros (mat_height (m));
02648 
02649   for (i = 0; i < mat_height (m); i++)
02650     for (j = 0; j < mat_width (m); j++)
02651       r[i] += m[i][j] * v[j];
02652   return r;
02653 }
02654 
02655 
02656 vec imat_vec_mul (imat m, vec v)
02657 {
02658   idx_t i, j;
02659   vec  r;
02660   assert (m && v);
02661   assert (imat_width (m) == vec_length (v));
02662 
02663   r = vec_new_zeros (imat_height (m));
02664 
02665   for (i = 0; i < imat_height (m); i++)
02666     for (j = 0; j < imat_width (m); j++)
02667       r[i] += m[i][j] * v[j];
02668   return r;
02669 }
02670 
02671 
02672 ivec imat_bvec_mul (imat m, bvec v)
02673 {
02674   idx_t i, j;
02675   ivec r;
02676   assert (m && v);
02677   assert (imat_width (m) == bvec_length (v));
02678 
02679   r = ivec_new_zeros (imat_height (m));
02680 
02681   for (i = 0; i < imat_height (m); i++)
02682     for (j = 0; j < imat_width (m); j++)
02683       r[i] += m[i][j] * v[j];
02684   return r;
02685 }
02686 
02687 
02688 vec mat_ivec_mul (mat m, ivec v)
02689 {
02690   idx_t i, j;
02691   vec  r;
02692   assert (m && v);
02693   assert (mat_width (m) == ivec_length (v));
02694 
02695   r = vec_new_zeros (mat_height (m));
02696 
02697   for (i = 0; i < mat_height (m); i++)
02698     for (j = 0; j < mat_width (m); j++)
02699       r[i] += m[i][j] * v[j];
02700   return r;
02701 }
02702 
02703 
02704 cvec cmat_vec_mul (cmat m, vec v)
02705 {
02706   idx_t i, j;
02707   cvec r;
02708   assert (m && v);
02709   assert (cmat_width (m) == vec_length (v));
02710 
02711   r = cvec_new_zeros (cmat_height (m));
02712 
02713   for (i = 0; i < cmat_height (m); i++)
02714     for (j = 0; j < cmat_width (m); j++)
02715       r[i] = cadd (r[i], cscale (m[i][j], v[j]));
02716   return r;
02717 }
02718 
02719 
02720 cvec cmat_cvec_mul (cmat m, cvec v)
02721 {
02722   idx_t i, j;
02723   cvec r;
02724   assert (m && v);
02725   assert (cmat_width (m) == cvec_length (v));
02726 
02727   r = cvec_new_zeros (cmat_height (m));
02728 
02729   for (i = 0; i < cmat_height (m); i++)
02730     for (j = 0; j < cmat_width (m); j++)
02731       r[i] = cadd (r[i], cmul (m[i][j], v[j]));
02732   return r;
02733 }
02734 
02735 
02736 vec vec_mat_mul (vec v, mat m)
02737 {
02738   idx_t i, j;
02739   vec  r;
02740   assert (m && v);
02741   assert (mat_height (m) == vec_length (v));
02742 
02743   r = vec_new_zeros (mat_width (m));
02744 
02745   for (i = 0; i < mat_height (m); i++)
02746     for (j = 0; j < mat_width (m); j++)
02747       r[j] += m[i][j] * v[i];
02748   return r;
02749 }
02750 
02751 
02752 ivec imat_ivec_mul (imat m, ivec v)
02753 {
02754   idx_t i, j;
02755   ivec r;
02756   assert (m && v);
02757   assert (imat_width (m) == ivec_length (v));
02758 
02759   r = ivec_new_zeros (imat_height (m));
02760 
02761   for (i = 0; i < imat_height (m); i++)
02762     for (j = 0; j < imat_width (m); j++)
02763       r[i] += m[i][j] * v[j];
02764   return r;
02765 }
02766 
02767 
02768 ivec ivec_imat_mul (ivec v, imat m)
02769 {
02770   idx_t i, j;
02771   ivec r;
02772   assert (m && v);
02773   assert (imat_height (m) == ivec_length (v));
02774 
02775   r = ivec_new_zeros (imat_width (m));
02776 
02777   for (i = 0; i < imat_height (m); i++)
02778     for (j = 0; j < imat_width (m); j++)
02779       r[j] += m[i][j] * v[i];
02780   return r;
02781 }
02782 
02783 
02784 /*----------------------------------------------------------------------------*/
02785 /* Retrieve part or assemble matrices                                         */
02786 mat mat_get_submatrix (mat m, idx_t r1, idx_t c1, idx_t r2, idx_t c2)
02787 {
02788   mat  s;
02789   idx_t r;
02790 
02791   if (r2 < r1) {
02792     it_warning
02793       ("Upper row number %d is greater than bottom row %d. Returning an empty matrix.",
02794        r1, r2);
02795     return mat_new_zeros (0, 0);
02796   };
02797 
02798   if (c2 < c1) {
02799     it_warning
02800       ("Left column %d greater than right column %d. Returning an empty matrix.",
02801        c1, c2);
02802     return mat_new_zeros (0, 0);
02803   };
02804 
02805   MAT_END_ROW_PARAM (m, r1);
02806   MAT_END_ROW_PARAM (m, r2);
02807   MAT_END_COL_PARAM (m, c1);
02808   MAT_END_COL_PARAM (m, c2);
02809 
02810   it_assert (r1 >= 0 && c1 >= 0 && r2 >= 0 && c2 >= 0
02811        && r1 < mat_height (m) && r2 < mat_height (m)
02812        && c1 < mat_width (m) && c2 < mat_width (m),
02813        "Invalid col or row number");
02814 
02815   s = mat_new (r2 - r1 + 1, c2 - c1 + 1);
02816 
02817   for (r = r1; r <= r2; r++)
02818     vec_init (s[r - r1], m[r] + c1, c2 - c1 + 1);
02819 
02820   return s;
02821 }
02822 
02823 
02824 imat imat_get_submatrix (imat m, idx_t r1, idx_t c1, idx_t r2, idx_t c2)
02825 {
02826   imat s;
02827   idx_t r;
02828 
02829   if (r2 < r1) {
02830     it_warning
02831       ("Upper row number %d is greater than bottom row %d . Return void matrix",
02832        r1, r2);
02833     return imat_new_zeros (0, 0);
02834   };
02835 
02836   if (c2 < c1) {
02837     it_warning
02838       ("Left column %d greater than right row %d . Return void matrix", c1,
02839        c2);
02840     return imat_new_zeros (0, 0);
02841   };
02842 
02843   MAT_END_ROW_PARAM (m, r1);
02844   MAT_END_ROW_PARAM (m, r2);
02845   MAT_END_COL_PARAM (m, c1);
02846   MAT_END_COL_PARAM (m, c2);
02847 
02848   it_assert (r1 >= 0 && c1 >= 0 && r2 >= 0 && c2 >= 0
02849        && r1 < imat_height (m) && r2 < imat_height (m)
02850        && c1 < imat_width (m) && c2 < imat_width (m),
02851        "Invalid col or row number");
02852 
02853   s = imat_new (r2 - r1 + 1, c2 - c1 + 1);
02854 
02855   for (r = r1; r <= r2; r++)
02856     ivec_init (s[r - r1], m[r] + c1, c2 - c1 + 1);
02857 
02858   return s;
02859 }
02860 
02861 
02862 bmat bmat_get_submatrix (bmat m, idx_t r1, idx_t c1, idx_t r2, idx_t c2)
02863 {
02864   bmat s;
02865   idx_t r;
02866 
02867   if (r2 < r1) {
02868     it_warning
02869       ("Upper row number %d is greater than bottom row %d . Return void matrix",
02870        r1, r2);
02871     return bmat_new_zeros (0, 0);
02872   };
02873 
02874   if (c2 < c1) {
02875     it_warning
02876       ("Left column %d greater than right row %d . Return void matrix", c1,
02877        c2);
02878     return bmat_new_zeros (0, 0);
02879   };
02880 
02881   MAT_END_ROW_PARAM (m, r1);
02882   MAT_END_ROW_PARAM (m, r2);
02883   MAT_END_COL_PARAM (m, c1);
02884   MAT_END_COL_PARAM (m, c2);
02885 
02886   it_assert (r1 >= 0 && c1 >= 0 && r2 >= 0 && c2 >= 0
02887        && r1 < bmat_height (m) && r2 < bmat_height (m)
02888        && c1 < bmat_width (m) && c2 < bmat_width (m),
02889        "Invalid col or row number");
02890 
02891   s = bmat_new (r2 - r1 + 1, c2 - c1 + 1);
02892 
02893   for (r = r1; r <= r2; r++)
02894     bvec_init (s[r - r1], m[r] + c1, c2 - c1 + 1);
02895 
02896   return s;
02897 }
02898 
02899 
02900 /*----------------------------------------------------------------------------*/
02901 mat mat_set_submatrix (mat m, mat s, idx_t r, idx_t c)
02902 {
02903   idx_t i, j;
02904 
02905   MAT_END_ROW_PARAM (m, r);
02906   MAT_END_COL_PARAM (m, c);
02907 
02908   it_assert (r >= 0 && c >= 0 && r < mat_height (m) && c < mat_width (m),
02909        "Invalid col or row number");
02910 
02911   it_assert (r + mat_height (s) <= mat_height (m)
02912        && c + mat_width (s) <= mat_width (m), "Submatrix is too big");
02913 
02914 
02915   for (i = 0; i < mat_height (s); i++)
02916     for (j = 0; j < mat_width (s); j++)
02917       m[r + i][c + j] = s[i][j];
02918 
02919   return m;
02920 }
02921 
02922 
02923 imat imat_set_submatrix (imat m, imat s, idx_t r, idx_t c)
02924 {
02925   idx_t i, j;
02926 
02927   MAT_END_ROW_PARAM (m, r);
02928   MAT_END_COL_PARAM (m, c);
02929 
02930   it_assert (r >= 0 && c >= 0 && r < imat_height (m)
02931        && c < imat_width (m), "Invalid col or row number");
02932 
02933   it_assert (r + imat_height (s) <= imat_height (m)
02934        && c + imat_width (s) <= imat_width (m), "Submatrix is too big");
02935 
02936 
02937   for (i = 0; i < imat_height (s); i++)
02938     for (j = 0; j < imat_width (s); j++)
02939       m[r + i][c + j] = s[i][j];
02940 
02941   return m;
02942 }
02943 
02944 
02945 bmat bmat_set_submatrix (bmat m, bmat s, idx_t r, idx_t c)
02946 {
02947   idx_t i, j;
02948 
02949   MAT_END_ROW_PARAM (m, r);
02950   MAT_END_COL_PARAM (m, c);
02951 
02952   it_assert (r >= 0 && c >= 0 && r < bmat_height (m)
02953        && c < bmat_width (m), "Invalid col or row number");
02954 
02955   it_assert (r + bmat_height (s) <= bmat_height (m)
02956        && c + bmat_width (s) <= bmat_width (m), "Submatrix is too big");
02957 
02958 
02959   for (i = 0; i < bmat_height (s); i++)
02960     for (j = 0; j < bmat_width (s); j++)
02961       m[r + i][c + j] = s[i][j];
02962 
02963   return m;
02964 }
02965 
02966 
02967 void mat_copy_row (vec v, mat m, idx_t r) 
02968 {
02969   assert (m);
02970   MAT_END_ROW_PARAM (m, r);
02971   assert (r < mat_height (m));
02972   assert (vec_length (v) == mat_width (m));
02973   Vec_copy (v, m[r]);
02974 }
02975 
02976 
02977 void imat_copy_row (ivec v, imat m, idx_t r) {
02978   assert (m);
02979   MAT_END_ROW_PARAM (m, r);
02980   assert (r < imat_height (m));
02981   assert (ivec_length (v) == imat_width (m));
02982   Vec_copy (v, m[r]);
02983 }
02984 
02985 
02986 void bmat_copy_row (bvec v, bmat m, idx_t r) {
02987   assert (m);
02988   MAT_END_ROW_PARAM (m, r);
02989   assert (r < bmat_height (m));
02990   assert (bvec_length (v) == bmat_width (m));
02991   Vec_copy (v, m[r]);
02992 }
02993 
02994 
02995 void cmat_copy_row (cvec v, cmat m, idx_t r) {
02996   assert (m);
02997   MAT_END_ROW_PARAM (m, r);
02998   assert (r < cmat_height (m));
02999   assert (cvec_length (v) == cmat_width (m));
03000   Vec_copy (v, m[r]);
03001 }
03002 
03003 
03004 /*----------------------------------------------------------------------------*/
03005 void mat_copy_col (vec v, mat m, idx_t c)
03006 {
03007   idx_t i;
03008 
03009   assert (m);
03010   assert (v);
03011   MAT_END_COL_PARAM (m, c);
03012   assert (vec_length (v) == mat_height (m));
03013   assert (c < mat_width (m));
03014 
03015   for (i = 0; i < mat_height (m); i++)
03016     v[i] = m[i][c];
03017 }
03018 
03019 
03020 void imat_copy_col (ivec v, imat m, idx_t c)
03021 {
03022   idx_t i;
03023 
03024   assert (m);
03025   assert (v);
03026   MAT_END_COL_PARAM (m, c);
03027   assert (ivec_length (v) == imat_height (m));
03028   assert (c < imat_width (m));
03029 
03030   for (i = 0; i < imat_height (m); i++)
03031     v[i] = m[i][c];
03032 }
03033 
03034 
03035 void bmat_copy_col (bvec v, bmat m, idx_t c)
03036 {
03037   idx_t i;
03038 
03039   assert (m);
03040   assert (v);
03041   MAT_END_COL_PARAM (m, c);
03042   assert (bvec_length (v) == bmat_height (m));
03043   assert (c < bmat_width (m));
03044 
03045   for (i = 0; i < bmat_height (m); i++)
03046     v[i] = m[i][c];
03047 }
03048 
03049 
03050 void cmat_copy_col (cvec v, cmat m, idx_t c)
03051 {
03052   idx_t i;
03053 
03054   assert (m);
03055   assert (v);
03056   MAT_END_COL_PARAM (m, c);
03057   assert (cvec_length (v) == cmat_height (m));
03058   assert (c < cmat_width (m));
03059 
03060 
03061   for (i = 0; i < cmat_height (m); i++)
03062     v[i] = m[i][c];
03063 }
03064 
03065 
03066 vec mat_get_row (mat m, idx_t r) {
03067   vec  v;
03068   assert (m);
03069   v = vec_new (mat_width (m));
03070   mat_copy_row (v, m, r);
03071   return v;
03072 }
03073 
03074 
03075 ivec imat_get_row (imat m, idx_t r) {
03076   ivec v;
03077   assert (m);
03078   v = ivec_new (imat_width (m));
03079   imat_copy_row (v, m, r);
03080   return v;
03081 }
03082 
03083 
03084 bvec bmat_get_row (bmat m, idx_t r) {
03085   bvec v;
03086   assert (m);
03087   v = bvec_new (bmat_width (m));
03088   bmat_copy_row (v, m, r);
03089   return v;
03090 }
03091 
03092 
03093 cvec cmat_get_row (cmat m, idx_t r) {
03094   cvec v;
03095   assert (m);
03096   v = cvec_new (cmat_width (m));
03097   cmat_copy_row (v, m, r);
03098   return v;
03099 }
03100 
03101 vec mat_get_col (mat m, idx_t c) {
03102   vec  v;
03103   assert (m);
03104   v = vec_new (mat_height (m));
03105   mat_copy_col (v, m, c);
03106   return v;
03107 }
03108 
03109 
03110 ivec imat_get_col (imat m, idx_t c) {
03111   ivec v;
03112   assert (m);
03113   v = ivec_new (imat_height (m));
03114   imat_copy_col (v, m, c);
03115   return v;
03116 }
03117 
03118 
03119 bvec bmat_get_col (bmat m, idx_t c) {
03120   bvec v;
03121   assert (m);
03122   v = bvec_new (bmat_height (m));
03123   bmat_copy_col (v, m, c);
03124   return v;
03125 }
03126 
03127 
03128 cvec cmat_get_col (cmat m, idx_t c) {
03129   cvec v;
03130   assert (m);
03131   v = cvec_new (cmat_height (m));
03132   cmat_copy_col (v, m, c);
03133   return v;
03134 }
03135 
03136 void Mat_set_col (Mat m, idx_t c, Vec v)
03137 {
03138   idx_t i;
03139   size_t s;
03140 
03141   assert (m);
03142   assert (m[0]);
03143   assert (v);
03144   assert (Mat_height (m) == Vec_length (v));
03145   MAT_END_COL_PARAM (m, c);
03146   assert (c < Mat_width (m));
03147   s = Vec_element_size (m[0]);
03148   assert (s == Vec_element_size (v));
03149 
03150   for (i = 0; i < Mat_height (m); i++)
03151     memcpy ((char *) m[i] + c * s, (char *) v + s * i, s);
03152 }
03153 
03154 
03155 void mat_set_col (mat m, idx_t c, vec v)
03156 {
03157   idx_t i;
03158 
03159   assert (m);
03160   assert (v);
03161   assert (mat_height (m) == vec_length (v));
03162   MAT_END_COL_PARAM (m, c);
03163   assert (c < mat_width (m));
03164 
03165   for (i = 0; i < mat_height (m); i++)
03166     m[i][c] = v[i];
03167 }
03168 
03169 
03170 void imat_set_col (imat m, idx_t c, ivec v)
03171 {
03172   idx_t i;
03173 
03174   assert (m);
03175   assert (v);
03176   assert (imat_height (m) == ivec_length (v));
03177   MAT_END_COL_PARAM (m, c);
03178   assert (c < imat_width (m));
03179 
03180   for (i = 0; i < imat_height (m); i++)
03181     m[i][c] = v[i];
03182 }
03183 
03184 
03185 void bmat_set_col (bmat m, idx_t c, bvec v)
03186 {
03187   idx_t i;
03188 
03189   assert (m);
03190   assert (v);
03191   assert (bmat_height (m) == bvec_length (v));
03192   MAT_END_COL_PARAM (m, c);
03193   assert (c < bmat_width (m));
03194 
03195   for (i = 0; i < bmat_height (m); i++)
03196     m[i][c] = v[i];
03197 }
03198 
03199 
03200 void cmat_set_col (cmat m, idx_t c, cvec v)
03201 {
03202   idx_t i;
03203 
03204   assert (m);
03205   assert (v);
03206   assert (cmat_height (m) == cvec_length (v));
03207   MAT_END_COL_PARAM (m, c);
03208   assert (c < cmat_width (m));
03209 
03210   for (i = 0; i < cmat_height (m); i++)
03211     m[i][c] = v[i];
03212 }
03213 
03214 
03215 /*----------------------------------------------------------------------------*/
03216 
03217 vec mat_get_diag (mat m)
03218 {
03219   int i;  
03220   int n = __mat_c_my_min (mat_height (m), mat_width (m));
03221   vec diag = vec_new (n); 
03222   for (i = 0; i < n; i++)
03223     diag[i] = m[i][i];
03224 
03225   return diag;
03226 }
03227 
03228 
03229 ivec imat_get_diag (imat m)
03230 {
03231   int i;  
03232   int n = __mat_c_my_min (imat_height (m), imat_width (m));
03233   ivec diag = ivec_new (n); 
03234   for (i = 0; i < n; i++)
03235     diag[i] = m[i][i];
03236 
03237   return diag;
03238 }
03239 
03240 
03241 bvec bmat_get_diag (bmat m)
03242 {
03243   int i;  
03244 
03245   int n = __mat_c_my_min (bmat_height (m), bmat_width (m));
03246   bvec diag = bvec_new (n); 
03247   for (i = 0; i < n; i++)
03248     diag[i] = m[i][i];
03249 
03250   return diag;
03251 }
03252 
03253 
03254 cvec cmat_get_diag (cmat m)
03255 {
03256   int i;  
03257 
03258   int n = __mat_c_my_min (cmat_height (m), cmat_width (m));
03259   cvec diag = cvec_new (n); 
03260   for (i = 0; i < n; i++) {
03261     diag[i] = m[i][i];
03262     diag[i] = m[i][i];
03263   }
03264 
03265   return diag;
03266 }
03267 
03268 
03269 void mat_diag (mat m, vec v)
03270 {
03271   idx_t i, mi;
03272   mi = __mat_c_my_min (mat_height (m), mat_width (m));
03273   it_assert (mi == vec_length (v), "Incompatible Matrix and vector sizes");
03274 
03275   mat_zeros (m);
03276   for (i = 0; i < mi; i++)
03277     m[i][i] = v[i];
03278 }
03279 
03280 
03281 void imat_diag (imat m, ivec v)
03282 {
03283   idx_t i, mi;
03284   mi = __mat_c_my_min (imat_height (m), imat_width (m));
03285   it_assert (mi == ivec_length (v), "Incompatible Matrix and vector sizes");
03286 
03287   imat_zeros (m);
03288   for (i = 0; i < mi; i++)
03289     m[i][i] = v[i];
03290 }
03291 
03292 
03293 void bmat_diag (bmat m, bvec v)
03294 {
03295   idx_t i, mi;
03296   mi = __mat_c_my_min (bmat_height (m), bmat_width (m));
03297   it_assert (mi == bvec_length (v), "Incompatible Matrix and vector sizes");
03298 
03299   bmat_zeros (m);
03300   for (i = 0; i < mi; i++)
03301     m[i][i] = v[i];
03302 }
03303 
03304 
03305 void cmat_diag (cmat m, cvec v)
03306 {
03307   idx_t i, mi;
03308   mi = __mat_c_my_min (cmat_height (m), cmat_width (m));
03309   it_assert (mi == cvec_length (v), "Incompatible Matrix and vector sizes");
03310 
03311   cmat_zeros (m);
03312   for (i = 0; i < mi; i++)
03313     m[i][i] = v[i];
03314 }
03315 
03316 
03317 void mat_set_diag (mat m, vec v)
03318 {
03319   idx_t i, mi;
03320   mi = __mat_c_my_min (mat_height (m), mat_width (m));
03321   it_assert (mi == vec_length (v), "Incompatible Matrix and vector sizes");
03322 
03323   for (i = 0; i < mi; i++)
03324     m[i][i] = v[i];
03325 }
03326 
03327 
03328 void imat_set_diag (imat m, ivec v)
03329 {
03330   idx_t i, mi;
03331   mi = __mat_c_my_min (imat_height (m), imat_width (m));
03332   it_assert (mi == ivec_length (v), "Incompatible Matrix and vector sizes");
03333 
03334   for (i = 0; i < mi; i++)
03335     m[i][i] = v[i];
03336 }
03337 
03338 
03339 void bmat_set_diag (bmat m, bvec v)
03340 {
03341   idx_t i, mi;
03342   mi = __mat_c_my_min (bmat_height (m), bmat_width (m));
03343   it_assert (mi == bvec_length (v), "Incompatible Matrix and vector sizes");
03344 
03345   for (i = 0; i < mi; i++)
03346     m[i][i] = v[i];
03347 }
03348 
03349 
03350 void cmat_set_diag (cmat m, cvec v)
03351 {
03352   idx_t i, mi;
03353   mi = __mat_c_my_min (cmat_height (m), cmat_width (m));
03354   it_assert (mi == cvec_length (v), "Incompatible Matrix and vector sizes");
03355 
03356   for (i = 0; i < mi; i++)
03357     m[i][i] = v[i];
03358 }
03359 
03360 
03361 /*----------------------------------------------------------------------------*/
03362 /** @name Component per component arbitrar function                           */
03363 /*----------------------------------------------------------------------------*/
03364 
03365 void mat_apply_function (mat m, it_function_t function, it_args_t args)
03366 {
03367   idx_t i;
03368   idx_t l;
03369   assert (m);
03370   l = mat_height (m);
03371   for (i = 0; i < l; i++)
03372     vec_apply_function (m[i], function, args);
03373 }
03374 
03375 
03376 mat mat_new_apply_function (mat m, it_function_t function, it_args_t args)
03377 {
03378   mat  r;
03379   idx_t i;
03380   idx_t l;
03381   assert (m);
03382   l = mat_height (m);
03383   r = mat_clone (m);
03384   for (i = 0; i < l; i++)
03385     vec_apply_function (r[i], function, args);
03386 
03387   return (r);
03388 }
03389 
03390 
03391 void imat_apply_function (imat m, it_ifunction_t function, it_args_t args)
03392 {
03393   idx_t i;
03394   idx_t l;
03395   assert (m);
03396   l = imat_height (m);
03397   for (i = 0; i < l; i++)
03398     ivec_apply_function (m[i], function, args);
03399 }
03400 
03401 
03402 imat imat_new_apply_function (imat m, it_ifunction_t function, it_args_t args)
03403 {
03404   imat r;
03405   idx_t i;
03406   idx_t l;
03407   assert (m);
03408   l = imat_height (m);
03409   r = imat_clone (m);
03410   for (i = 0; i < l; i++)
03411     ivec_apply_function (r[i], function, args);
03412 
03413   return (r);
03414 }
03415 
03416 
03417 
03418 /*----------------------------------------------------------------------------*/
03419 /*                Special Matrices                                            */
03420 /*----------------------------------------------------------------------------*/
03421 
03422 /*---------------------------------------------------------------------------*/
03423 void mat_rand (mat m)
03424 {
03425   int  i, j;
03426   for (i = 0; i < mat_height (m); i++)
03427     for (j = 0; j < mat_width (m); j++)
03428       m[i][j] = it_rand ();
03429 }
03430 
03431 
03432 void mat_randn (mat m)
03433 {
03434   int  i, j;
03435   for (i = 0; i < mat_height (m); i++)
03436     for (j = 0; j < mat_width (m); j++)
03437       m[i][j] = it_randn ();
03438 }
03439 
03440 /*---------------------------------------------------------------------------*/
03441 mat mat_new_rand (idx_t h, idx_t w)
03442 {
03443   int  i, j;
03444   mat  m = mat_new (h, w);
03445 
03446   for (i = 0; i < h; i++)
03447     for (j = 0; j < w; j++)
03448       m[i][j] = it_rand ();
03449 
03450   return m;
03451 }
03452 
03453 
03454 mat mat_new_randn (idx_t h, idx_t w)
03455 {
03456   int  i, j;
03457   mat  m = mat_new (h, w);
03458 
03459   for (i = 0; i < h; i++)
03460     for (j = 0; j < w; j++)
03461       m[i][j] = it_randn ();
03462 
03463   return m;
03464 }
03465 
03466 
03467 mat mat_cov (mat m)
03468 {
03469   int i, j;
03470   int n; 
03471   vec vec_temp_1, vec_temp_2;
03472   mat m_cov; 
03473 
03474   assert(m); 
03475   assert(mat_height(m)==mat_width(m)); 
03476 
03477   n = mat_height (m);
03478   m_cov = mat_new(n, n);
03479 
03480   for (i = 0; i < n; i++)
03481     for (j = 0; j < n; j++)
03482       {
03483   vec_temp_1 = mat_get_row (m, i);
03484   vec_temp_2 = mat_get_row (m, j);
03485   m_cov[i][j] = vec_cov (vec_temp_1, vec_temp_2);
03486   
03487   vec_delete (vec_temp_1);
03488   vec_delete (vec_temp_2);
03489       }
03490 
03491   return m_cov;
03492 }
03493 
03494 

Hosted by
Copyright (C) 2005-2006 Hervé Jégou
Vivien Chappelier
Francois Cayre
libit logo courtesy of Jonathan Delhumeau