home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / clib / progs / meschach / !Meschach / c / zmemory < prev    next >
Encoding:
Text File  |  1994-04-04  |  14.9 KB  |  645 lines

  1.   va_end(ap);
  2.    return i;
  3. }
  4.  
  5.  
  6.  
  7. #elif VARARGS
  8.  
  9. #include <varargs.h>
  10.  
  11. /* To allocate memory to many arguments. 
  12.    The function should be called:
  13.    v_get_vars(dim,&x,&y,&z,...,NULL);
  14.    where 
  15.      int dim;
  16.      ZVEC *x, *y, *z,...;
  17.      The last argument should be NULL ! 
  18.      dim is the length of vectors x,y,z,...
  19.      returned value is equal to the number of allocated variables
  20.      Other gec_... functions are similar.
  21. */
  22.  
  23. int zv_get_vars(va_alist) va_dcl
  24. {
  25.    va_list ap;
  26.    int dim,i=0;
  27.    ZVEC **par;
  28.    
  29.    va_start(ap);
  30.    dim = va_arg(ap,int);
  31.    while (par = va_arg(ap,ZVEC **)) {   /* NULL ends the list*/
  32.       *par = zv_get(dim);
  33.       i++;
  34.    } 
  35.  
  36.    va_end(ap);
  37.    return i;
  38. }
  39.  
  40.  
  41.  
  42. int zm_get_vars(va_alist) va_dcl
  43. {
  44.    va_list ap;
  45.    int i=0, n, m;
  46.    ZMAT **par;
  47.    
  48.    va_start(ap);
  49.    m = va_arg(ap,int);
  50.    n = va_arg(ap,int);
  51.    while (par = va_arg(ap,ZMAT **)) {   /* NULL ends the list*/
  52.       *par = zm_get(m,n);
  53.       i++;
  54.    } 
  55.  
  56.    va_end(ap);
  57.    return i;
  58. }
  59.  
  60.  
  61.  
  62. /* To resize memory for many arguments. 
  63.    The function should be called:
  64.    v_resize_vars(new_dim,&x,&y,&z,...,NULL);
  65.    where 
  66.      int new_dim;
  67.      ZVEC *x, *y, *z,...;
  68.      The last argument should be NULL ! 
  69.      rdim is the resized length of vectors x,y,z,...
  70.      returned value is equal to the number of allocated variables.
  71.      If one of x,y,z,.. arguments is NULL then memory is allocated to this 
  72.      argument. 
  73.      Other *_resize_list() functions are similar.
  74. */
  75.  
  76. int zv_resize_vars(va_alist) va_dcl
  77. {
  78.    va_list ap;
  79.    int i=0, new_dim;
  80.    ZVEC **par;
  81.    
  82.    va_start(ap);
  83.    new_dim = va_arg(ap,int);
  84.    while (par = va_arg(ap,ZVEC **)) {   /* NULL ends the list*/
  85.       *par = zv_resize(*par,new_dim);
  86.       i++;
  87.    } 
  88.  
  89.    va_end(ap);
  90.    return i;
  91. }
  92.  
  93.  
  94. int zm_resize_vars(va_alist) va_dcl
  95. {
  96.    va_list ap;
  97.    int i=0, m, n;
  98.    ZMAT **par;
  99.    
  100.    va_start(ap);
  101.    m = va_arg(ap,int);
  102.    n = va_arg(ap,int);
  103.    while (par = va_arg(ap,ZMAT **)) {   /* NULL ends the list*/
  104.       *par = zm_resize(*par,m,n);
  105.       i++;
  106.    } 
  107.  
  108.    va_end(ap);
  109.    return i;
  110. }
  111.  
  112.  
  113.  
  114. /* To deallocate memory for many arguments. 
  115.    The function should be called:
  116.    v_free_vars(&x,&y,&z,...,NULL);
  117.    where 
  118.      ZVEC *x, *y, *z,...;
  119.      The last argument should be NULL ! 
  120.      There must be at least one not NULL argument.
  121.      returned value is equal to the number of allocated variables.
  122.      Returned value of x,y,z,.. is VNULL.
  123.      Other *_free_list() functions are similar.
  124. */
  125.  
  126. int zv_free_vars(va_alist) va_dcl
  127. {
  128.    va_list ap;
  129.    int i=0;
  130.    ZVEC **par;
  131.    
  132.    va_start(ap);
  133.    while (par = va_arg(ap,ZVEC **)) {   /* NULL ends the list*/
  134.       zv_free(*par); 
  135.       *par = ZVNULL;
  136.       i++;
  137.    } 
  138.  
  139.    va_end(ap);
  140.    return i;
  141. }
  142.  
  143.  
  144.  
  145. int zm_free_vars(va_alist) va_dcl
  146. {
  147.    va_list ap;
  148.    int i=0;
  149.    ZMAT **par;
  150.    
  151.    va_start(ap);
  152.    while (par = va_arg(ap,ZMAT **)) {   /* NULL ends the list*/
  153.       zm_free(*par); 
  154.       *par = ZMNULL;
  155.       i++;
  156.    } 
  157.  
  158.    va_end(ap);
  159.    return i;
  160. }
  161.  
  162.  
  163. #endif
  164.  
  165. FileDataŵznormEÿÿÿ¬@9{
  166. /**************************************************************************
  167. **
  168. ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved.
  169. **
  170. **                 Meschach Library
  171. ** 
  172. ** This Meschach Library is provided "as is" without any express 
  173. ** or implied warranty of any kind with respect to this software. 
  174. ** In particular the authors shall not be liable for any direct, 
  175. ** indirect, special, incidental or consequential damages arising 
  176. ** in any way from use of the software.
  177. ** 
  178. ** Everyone is granted permission to copy, modify and redistribute this
  179. ** Meschach Library, provided:
  180. **  1.  All copies contain this copyright notice.
  181. **  2.  All modified copies shall carry a notice stating who
  182. **      made the last modification and the date of such modification.
  183. **  3.  No charge is made for this software or works derived from it.  
  184. **      This clause shall not be construed as constraining other software
  185. **      distributed on the same medium as this software, nor is a
  186. **      distribution fee considered a charge.
  187. **
  188. ***************************************************************************/
  189.  
  190.  
  191. /*
  192.     A collection of functions for computing norms: scaled and unscaled
  193.     Complex version
  194. */
  195. static    char    rcsid[] = "$Id: znorm.c,v 1.1 1994/01/13 04:21:31 des Exp $";
  196.  
  197. #include    <stdio.h>
  198. #include    <math.h>
  199. #include    "zmatrix.h"
  200.  
  201.  
  202.  
  203. /* _zv_norm1 -- computes (scaled) 1-norms of vectors */
  204. double    _zv_norm1(x,scale)
  205. ZVEC    *x;
  206. VEC    *scale;
  207. {
  208.     int    i, dim;
  209.     Real    s, sum;
  210.     
  211.     if ( x == ZVNULL )
  212.     error(E_NULL,"_zv_norm1");
  213.     dim = x->dim;
  214.     
  215.     sum = 0.0;
  216.     if ( scale == VNULL )
  217.     for ( i = 0; i < dim; i++ )
  218.         sum += zabs(x->ve[i]);
  219.     else if ( scale->dim < dim )
  220.     error(E_SIZES,"_zv_norm1");
  221.     else
  222.     for ( i = 0; i < dim; i++ )
  223.     {
  224.         s = scale->ve[i];
  225.         sum += ( s== 0.0 ) ? zabs(x->ve[i]) : zabs(x->ve[i])/fabs(s);
  226.     }
  227.     
  228.     return sum;
  229. }
  230.  
  231. /* square -- returns x^2 */
  232. /******************************
  233. double    square(x)
  234. double    x;
  235. {    return x*x;    }
  236. ******************************/
  237.  
  238. #define    square(x)    ((x)*(x))
  239.  
  240. /* _zv_norm2 -- computes (scaled) 2-norm (Euclidean norm) of vectors */
  241. double    _zv_norm2(x,scale)
  242. ZVEC    *x;
  243. VEC    *scale;
  244. {
  245.     int    i, dim;
  246.     Real    s, sum;
  247.     
  248.     if ( x == ZVNULL )
  249.     error(E_NULL,"_zv_norm2");
  250.     dim = x->dim;
  251.     
  252.     sum = 0.0;
  253.     if ( scale == VNULL )
  254.     for ( i = 0; i < dim; i++ )
  255.         sum += square(x->ve[i].re) + square(x->ve[i].im);
  256.     else if ( scale->dim < dim )
  257.     error(E_SIZES,"_v_norm2");
  258.     else
  259.     for ( i = 0; i < dim; i++ )
  260.     {
  261.         s = scale->ve[i];
  262.         sum += ( s== 0.0 ) ? square(x->ve[i].re) + square(x->ve[i].im) :
  263.         (square(x->ve[i].re) + square(x->ve[i].im))/square(s);
  264.     }
  265.     
  266.     return sqrt(sum);
  267. }
  268.  
  269. #define    max(a,b)    ((a) > (b) ? (a) : (b))
  270.  
  271. /* _zv_norm_inf -- computes (scaled) infinity-norm (supremum norm) of vectors */
  272. double    _zv_norm_inf(x,scale)
  273. ZVEC    *x;
  274. VEC    *scale;
  275. {
  276.     int    i, dim;
  277.     Real    s, maxval, tmp;
  278.     
  279.     if ( x == ZVNULL )
  280.     error(E_NULL,"_zv_norm_inf");
  281.     dim = x->dim;
  282.     
  283.     maxval = 0.0;
  284.     if ( scale == VNULL )
  285.     for ( i = 0; i < dim; i++ )
  286.     {
  287.         tmp = zabs(x->ve[i]);
  288.         maxval = max(maxval,tmp);
  289.     }
  290.     else if ( scale->dim < dim )
  291.     error(E_SIZES,"_zv_norm_inf");
  292.     else
  293.     for ( i = 0; i < dim; i++ )
  294.     {
  295.         s = scale->ve[i];
  296.         tmp = ( s == 0.0 ) ? zabs(x->ve[i]) : zabs(x->ve[i])/fabs(s);
  297.         maxval = max(maxval,tmp);
  298.     }
  299.     
  300.     return maxval;
  301. }
  302.  
  303. /* zm_norm1 -- compute matrix 1-norm -- unscaled
  304.     -- complex version */
  305. double    zm_norm1(A)
  306. ZMAT    *A;
  307. {
  308.     int    i, j, m, n;
  309.     Real    maxval, sum;
  310.     
  311.     if ( A == ZMNULL )
  312.     error(E_NULL,"zm_norm1");
  313.  
  314.     m = A->m;    n = A->n;
  315.     maxval = 0.0;
  316.     
  317.     for ( j = 0; j < n; j++ )
  318.     {
  319.     sum = 0.0;
  320.     for ( i = 0; i < m; i ++ )
  321.         sum += zabs(A->me[i][j]);
  322.     maxval = max(maxval,sum);
  323.     }
  324.     
  325.     return maxval;
  326. }
  327.  
  328. /* zm_norm_inf -- compute matrix infinity-norm -- unscaled
  329.     -- complex version */
  330. double    zm_norm_inf(A)
  331. ZMAT    *A;
  332. {
  333.     int    i, j, m, n;
  334.     Real    maxval, sum;
  335.     
  336.     if ( A == ZMNULL )
  337.     error(E_NULL,"zm_norm_inf");
  338.     
  339.     m = A->m;    n = A->n;
  340.     maxval = 0.0;
  341.     
  342.     for ( i = 0; i < m; i++ )
  343.     {
  344.     sum = 0.0;
  345.     for ( j = 0; j < n; j ++ )
  346.         sum += zabs(A->me[i][j]);
  347.     maxval = max(maxval,sum);
  348.     }
  349.     
  350.     return maxval;
  351. }
  352.  
  353. /* zm_norm_frob -- compute matrix frobenius-norm -- unscaled */
  354. double    zm_norm_frob(A)
  355. ZMAT    *A;
  356. {
  357.     int    i, j, m, n;
  358.     Real    sum;
  359.     
  360.     if ( A == ZMNULL )
  361.     error(E_NULL,"zm_norm_frob");
  362.     
  363.     m = A->m;    n = A->n;
  364.     sum = 0.0;
  365.     
  366.     for ( i = 0; i < m; i++ )
  367.     for ( j = 0; j < n; j ++ )
  368.         sum += square(A->me[i][j].re) + square(A->me[i][j].im);
  369.     
  370.     return sqrt(sum);
  371. }
  372.  
  373. FileDataŵzqrfctrÜ5Eÿÿÿ¬Þøÿ=
  374. /**************************************************************************
  375. **
  376. ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved.
  377. **
  378. **                 Meschach Library
  379. ** 
  380. ** This Meschach Library is provided "as is" without any express 
  381. ** or implied warranty of any kind with respect to this software. 
  382. ** In particular the authors shall not be liable for any direct, 
  383. ** indirect, special, incidental or consequential damages arising 
  384. ** in any way from use of the software.
  385. ** 
  386. ** Everyone is granted permission to copy, modify and redistribute this
  387. ** Meschach Library, provided:
  388. **  1.  All copies contain this copyright notice.
  389. **  2.  All modified copies shall carry a notice stating who
  390. **      made the last modification and the date of such modification.
  391. **  3.  No charge is made for this software or works derived from it.  
  392. **      This clause shall not be construed as constraining other software
  393. **      distributed on the same medium as this software, nor is a
  394. **      distribution fee considered a charge.
  395. **
  396. ***************************************************************************/
  397.  
  398. /*
  399.   This file contains the routines needed to perform QR factorisation
  400.   of matrices, as well as Householder transformations.
  401.   The internal "factored form" of a matrix A is not quite standard.
  402.   The diagonal of A is replaced by the diagonal of R -- not by the 1st non-zero
  403.   entries of the Householder vectors. The 1st non-zero entries are held in
  404.   the diag parameter of QRfactor(). The reason for this non-standard
  405.   representation is that it enables direct use of the Usolve() function
  406.   rather than requiring that  a seperate function be written just for this case.
  407.   See, e.g., QRsolve() below for more details.
  408.  
  409.   Complex version
  410.   
  411. */
  412.  
  413. static    char    rcsid[] = "$Id: zqrfctr.c,v 1.1 1994/01/13 04:21:22 des Exp $";
  414.  
  415. #include    <stdio.h>
  416. #include    <math.h>
  417. #include    "zmatrix.h"
  418. #include    "zmatrix2.h" 
  419.  
  420.  
  421. #define    is_zero(z)    ((z).re == 0.0 && (z).im == 0.0)
  422.  
  423.  
  424. #define        sign(x)    ((x) > 0.0 ? 1 : ((x) < 0.0 ? -1 : 0 ))
  425.  
  426. /* Note: The usual representation of a Householder transformation is taken
  427.    to be:
  428.    P = I - beta.u.u*
  429.    where beta = 2/(u*.u) and u is called the Householder vector
  430.    (u* is the conjugate transposed vector of u
  431. */
  432.  
  433. /* zQRfactor -- forms the QR factorisation of A
  434.     -- factorisation stored in compact form as described above
  435.     (not quite standard format) */
  436. ZMAT    *zQRfactor(A,diag)
  437. ZMAT    *A;
  438. ZVEC    *diag;
  439. {
  440.     u_int    k,limit;
  441.     Real    beta;
  442.     static    ZVEC    *tmp1=ZVNULL;
  443.     
  444.     if ( ! A || ! diag )
  445.     error(E_NULL,"zQRfactor");
  446.     limit = min(A->m,A->n);
  447.     if ( diag->dim < limit )
  448.     error(E_SIZES,"zQRfactor");
  449.     
  450.     tmp1 = zv_resize(tmp1,A->m);
  451.     MEM_STAT_REG(tmp1,TYPE_ZVEC);
  452.     
  453.     for ( k=0; k<limit; k++ )
  454.     {
  455.     /* get H/holder vector for the k-th column */
  456.     zget_col(A,k,tmp1);
  457.     /* hhvec(tmp1,k,&beta->ve[k],tmp1,&A->me[k][k]); */
  458.     zhhvec(tmp1,k,&beta,tmp1,&A->me[k][k]);
  459.     diag->ve[k] = tmp1->ve[k];
  460.     
  461.     /* apply H/holder vector to remaining columns */
  462.     /* hhtrcols(A,k,k+1,tmp1,beta->ve[k]); */
  463.     tracecatch(zhhtrcols(A,k,k+1,tmp1,beta),"zQRfactor");
  464.     }
  465.  
  466.     return (A);
  467. }
  468.  
  469. /* zQRCPfactor -- forms the QR factorisation of A with column pivoting
  470.    -- factorisation stored in compact form as described above
  471.    ( not quite standard format )                */
  472. ZMAT    *zQRCPfactor(A,diag,px)
  473. ZMAT    *A;
  474. ZVEC    *diag;
  475. PERM    *px;
  476. {
  477.     u_int    i, i_max, j, k, limit;
  478.     static    ZVEC    *tmp1=ZVNULL, *tmp2=ZVNULL;
  479.     static    VEC    *gamma=VNULL;
  480.     Real     beta;
  481.     Real    maxgamma, sum, tmp;
  482.     complex    ztmp;
  483.     
  484.     if ( ! A || ! diag || ! px )
  485.     error(E_NULL,"QRCPfactor");
  486.     limit = min(A->m,A->n);
  487.     if ( diag->dim < limit || px->size != A->n )
  488.     error(E_SIZES,"QRCPfactor");
  489.     
  490.     tmp1 = zv_resize(tmp1,A->m);
  491.     tmp2 = zv_resize(tmp2,A->m);
  492.     gamma = v_resize(gamma,A->n);
  493.     MEM_STAT_REG(tmp1,TYPE_ZVEC);
  494.     MEM_STAT_REG(tmp2,TYPE_ZVEC);
  495.     MEM_STAT_REG(gamma,TYPE_VEC);
  496.     
  497.     /* initialise gamma and px */
  498.     for ( j=0; j<A->n; j++ )
  499.     {
  500.     px->pe[j] = j;
  501.     sum = 0.0;
  502.     for ( i=0; i<A->m; i++ )
  503.         sum += square(A->me[i][j].re) + square(A->me[i][j].im);
  504.     gamma->ve[j] = sum;
  505.     }
  506.     
  507.     for ( k=0; k<limit; k++ )
  508.     {
  509.     /* find "best" column to use */
  510.     i_max = k;    maxgamma = gamma->ve[k];
  511.     for ( i=k+1; i<A->n; i++ )
  512.         /* Loop invariant:maxgamma=gamma[i_max]
  513.            >=gamma[l];l=k,...,i-1 */
  514.         if ( gamma->ve[i] > maxgamma )
  515.         {    maxgamma = gamma->ve[i]; i_max = i;    }
  516.     
  517.     /* swap columns if necessary */
  518.     if ( i_max != k )
  519.     {
  520.         /* swap gamma values */
  521.         tmp = gamma->ve[k];
  522.         gamma->ve[k] = gamma->ve[i_max];
  523.         gamma->ve[i_max] = tmp;
  524.         
  525.         /* update column permutation */
  526.         px_transp(px,k,i_max);
  527.         
  528.         /* swap columns of A */
  529.         for ( i=0; i<A->m; i++ )
  530.         {
  531.         ztmp = A->me[i][k];
  532.         A->me[i][k] = A->me[i][i_max];
  533.         A->me[i][i_max] = ztmp;
  534.         }
  535.     }
  536.     
  537.     /* get H/holder vector for the k-th column */
  538.     zget_col(A,k,tmp1);
  539.     /* hhvec(tmp1,k,&beta->ve[k],tmp1,&A->me[k][k]); */
  540.     zhhvec(tmp1,k,&beta,tmp1,&A->me[k][k]);
  541.     diag->ve[k] = tmp1->ve[k];
  542.     
  543.     /* apply H/holder vector to remaining columns */
  544.     /* hhtrcols(A,k,k+1,tmp1,beta->ve[k]); */
  545.     zhhtrcols(A,k,k+1,tmp1,beta);
  546.     
  547.     /* update gamma values */
  548.     for ( j=k+1; j<A->n; j++ )
  549.         gamma->ve[j] -= square(A->me[k][j].re)+square(A->me[k][j].im);
  550.     }
  551.  
  552.     return (A);
  553. }
  554.  
  555. /* zQsolve -- solves Qx = b, Q is an orthogonal matrix stored in compact
  556.     form a la QRfactor()
  557.     -- may be in-situ */
  558. ZVEC    *_zQsolve(QR,diag,b,x,tmp)
  559. ZMAT    *QR;
  560. ZVEC    *diag, *b, *x, *tmp;
  561. {
  562.     u_int    dynamic;
  563.     int        k, limit;
  564.     Real    beta, r_ii, tmp_val;
  565.     
  566.     limit = min(QR->m,QR->n);
  567.     dynamic = FALSE;
  568.     if ( ! QR || ! diag || ! b )
  569.     error(E_NULL,"_zQsolve");
  570.     if ( diag->dim < limit || b->dim != QR->m )
  571.     error(E_SIZES,"_zQsolve");
  572.     x = zv_resize(x,QR->m);
  573.     if ( tmp == ZVNULL )
  574.     dynamic = TRUE;
  575.     tmp = zv_resize(tmp,QR->m);
  576.     
  577.     /* apply H/holder transforms in normal order */
  578.     x = zv_copy(b,x);
  579.     for ( k = 0 ; k < limit ; k++ )
  580.     {
  581.     zget_col(QR,k,tmp);
  582.     r_ii = zabs(tmp->ve[k]);
  583.     tmp->ve[k] = diag->ve[k];
  584.     tmp_val = (r_ii*zabs(diag->ve[k]));
  585.     beta = ( tmp_val == 0.0 ) ? 0.0 : 1.0/tmp_val;
  586.     /* hhtrvec(tmp,beta->ve[k],k,x,x); */
  587.     zhhtrvec(tmp,beta,k,x,x);
  588.     }
  589.     
  590.     if ( dynamic )
  591.     ZV_FREE(tmp);
  592.     
  593.     return (x);
  594. }
  595.  
  596. /* zmakeQ -- constructs orthogonal matrix from Householder vectors stored in
  597.    compact QR form */
  598. ZMAT    *zmakeQ(QR,diag,Qout)
  599. ZMAT    *QR,*Qout;
  600. ZVEC    *diag;
  601. {
  602.     static    ZVEC    *tmp1=ZVNULL,*tmp2=ZVNULL;
  603.     u_int    i, limit;
  604.     Real    beta, r_ii, tmp_val;
  605.     int    j;
  606.  
  607.     limit = min(QR->m,QR->n);
  608.     if ( ! QR || ! diag )
  609.     error(E_NULL,"zmakeQ");
  610.     if ( diag->dim < limit )
  611.     error(E_SIZES,"zmakeQ");
  612.     Qout = zm_resize(Qout,QR->m,QR->m);
  613.  
  614.     tmp1 = zv_resize(tmp1,QR->m);    /* contains basis vec & columns of Q */
  615.     tmp2 = zv_resize(tmp2,QR->m);    /* contains H/holder vectors */
  616.     MEM_STAT_REG(tmp1,TYPE_ZVEC);
  617.     MEM_STAT_REG(tmp2,TYPE_ZVEC);
  618.  
  619.     for ( i=0; i<QR->m ; i++ )
  620.     {    /* get i-th column of Q */
  621.     /* set up tmp1 as i-th basis vector */
  622.     for ( j=0; j<QR->m ; j++ )
  623.         tmp1->ve[j].re = tmp1->ve[j].im = 0.0;
  624.     tmp1->ve[i].re = 1.0;
  625.     
  626.     /* apply H/h transforms in reverse order */
  627.     for ( j=limit-1; j>=0; j-- )
  628.     {
  629.         zget_col(QR,j,tmp2);
  630.         r_ii = zabs(tmp2->ve[j]);
  631.         tmp2->ve[j] = diag->ve[j];
  632.         tmp_val = (r_ii*zabs(diag->ve[j]));
  633.         beta = ( tmp_val == 0.0 ) ? 0.0 : 1.0/tmp_val;
  634.         /* hhtrvec(tmp2,beta->ve[j],j,tmp1,tmp1); */
  635.         zhhtrvec(tmp2,beta,j,tmp1,tmp1);
  636.     }
  637.     
  638.     /* insert into Q */
  639.     zset_col(Qout,i,tmp1);
  640.     }
  641.  
  642.     return (Qout);
  643. }
  644.  
  645. /* zmakeR -- constructs upper triangu