home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / mesch12a.zip / hsehldr.c < prev    next >
C/C++ Source or Header  |  1994-01-13  |  5KB  |  179 lines

  1.  
  2. /**************************************************************************
  3. **
  4. ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved.
  5. **
  6. **                 Meschach Library
  7. ** 
  8. ** This Meschach Library is provided "as is" without any express 
  9. ** or implied warranty of any kind with respect to this software. 
  10. ** In particular the authors shall not be liable for any direct, 
  11. ** indirect, special, incidental or consequential damages arising 
  12. ** in any way from use of the software.
  13. ** 
  14. ** Everyone is granted permission to copy, modify and redistribute this
  15. ** Meschach Library, provided:
  16. **  1.  All copies contain this copyright notice.
  17. **  2.  All modified copies shall carry a notice stating who
  18. **      made the last modification and the date of such modification.
  19. **  3.  No charge is made for this software or works derived from it.  
  20. **      This clause shall not be construed as constraining other software
  21. **      distributed on the same medium as this software, nor is a
  22. **      distribution fee considered a charge.
  23. **
  24. ***************************************************************************/
  25.  
  26.  
  27. /*
  28.         Files for matrix computations
  29.  
  30.     Householder transformation file. Contains routines for calculating
  31.     householder transformations, applying them to vectors and matrices
  32.     by both row & column.
  33. */
  34.  
  35. /* hsehldr.c 1.3 10/8/87 */
  36. static    char    rcsid[] = "$Id: hsehldr.c,v 1.2 1994/01/13 05:36:29 des Exp $";
  37.  
  38. #include    <stdio.h>
  39. #include    <math.h>
  40. #include    "matrix.h"
  41. #include        "matrix2.h"
  42.  
  43.  
  44. /* hhvec -- calulates Householder vector to eliminate all entries after the
  45.     i0 entry of the vector vec. It is returned as out. May be in-situ */
  46. VEC    *hhvec(vec,i0,beta,out,newval)
  47. VEC    *vec,*out;
  48. u_int    i0;
  49. Real    *beta,*newval;
  50. {
  51.     Real    norm;
  52.  
  53.     out = _v_copy(vec,out,i0);
  54.     norm = sqrt(_in_prod(out,out,i0));
  55.     if ( norm <= 0.0 )
  56.     {
  57.         *beta = 0.0;
  58.         return (out);
  59.     }
  60.     *beta = 1.0/(norm * (norm+fabs(out->ve[i0])));
  61.     if ( out->ve[i0] > 0.0 )
  62.         *newval = -norm;
  63.     else
  64.         *newval = norm;
  65.     out->ve[i0] -= *newval;
  66.  
  67.     return (out);
  68. }
  69.  
  70. /* hhtrvec -- apply Householder transformation to vector -- may be in-situ */
  71. VEC    *hhtrvec(hh,beta,i0,in,out)
  72. VEC    *hh,*in,*out;    /* hh = Householder vector */
  73. u_int    i0;
  74. double    beta;
  75. {
  76.     Real    scale;
  77.     /* u_int    i; */
  78.  
  79.     if ( hh==(VEC *)NULL || in==(VEC *)NULL )
  80.         error(E_NULL,"hhtrvec");
  81.     if ( in->dim != hh->dim )
  82.         error(E_SIZES,"hhtrvec");
  83.     if ( i0 > in->dim )
  84.         error(E_BOUNDS,"hhtrvec");
  85.  
  86.     scale = beta*_in_prod(hh,in,i0);
  87.     out = v_copy(in,out);
  88.     __mltadd__(&(out->ve[i0]),&(hh->ve[i0]),-scale,(int)(in->dim-i0));
  89.     /************************************************************
  90.     for ( i=i0; i<in->dim; i++ )
  91.         out->ve[i] = in->ve[i] - scale*hh->ve[i];
  92.     ************************************************************/
  93.  
  94.     return (out);
  95. }
  96.  
  97. /* hhtrrows -- transform a matrix by a Householder vector by rows
  98.     starting at row i0 from column j0 -- in-situ */
  99. MAT    *hhtrrows(M,i0,j0,hh,beta)
  100. MAT    *M;
  101. u_int    i0, j0;
  102. VEC    *hh;
  103. double    beta;
  104. {
  105.     Real    ip, scale;
  106.     int    i /*, j */;
  107.  
  108.     if ( M==(MAT *)NULL || hh==(VEC *)NULL )
  109.         error(E_NULL,"hhtrrows");
  110.     if ( M->n != hh->dim )
  111.         error(E_RANGE,"hhtrrows");
  112.     if ( i0 > M->m || j0 > M->n )
  113.         error(E_BOUNDS,"hhtrrows");
  114.  
  115.     if ( beta == 0.0 )    return (M);
  116.  
  117.     /* for each row ... */
  118.     for ( i = i0; i < M->m; i++ )
  119.     {    /* compute inner product */
  120.         ip = __ip__(&(M->me[i][j0]),&(hh->ve[j0]),(int)(M->n-j0));
  121.         /**************************************************
  122.         ip = 0.0;
  123.         for ( j = j0; j < M->n; j++ )
  124.             ip += M->me[i][j]*hh->ve[j];
  125.         **************************************************/
  126.         scale = beta*ip;
  127.         if ( scale == 0.0 )
  128.             continue;
  129.  
  130.         /* do operation */
  131.         __mltadd__(&(M->me[i][j0]),&(hh->ve[j0]),-scale,
  132.                             (int)(M->n-j0));
  133.         /**************************************************
  134.         for ( j = j0; j < M->n; j++ )
  135.             M->me[i][j] -= scale*hh->ve[j];
  136.         **************************************************/
  137.     }
  138.  
  139.     return (M);
  140. }
  141.  
  142.  
  143. /* hhtrcols -- transform a matrix by a Householder vector by columns
  144.     starting at row i0 from column j0 -- in-situ */
  145. MAT    *hhtrcols(M,i0,j0,hh,beta)
  146. MAT    *M;
  147. u_int    i0, j0;
  148. VEC    *hh;
  149. double    beta;
  150. {
  151.     /* Real    ip, scale; */
  152.     int    i /*, k */;
  153.     static    VEC    *w = VNULL;
  154.  
  155.     if ( M==(MAT *)NULL || hh==(VEC *)NULL )
  156.         error(E_NULL,"hhtrcols");
  157.     if ( M->m != hh->dim )
  158.         error(E_SIZES,"hhtrcols");
  159.     if ( i0 > M->m || j0 > M->n )
  160.         error(E_BOUNDS,"hhtrcols");
  161.  
  162.     if ( beta == 0.0 )    return (M);
  163.  
  164.     w = v_resize(w,M->n);
  165.     MEM_STAT_REG(w,TYPE_VEC);
  166.     v_zero(w);
  167.  
  168.     for ( i = i0; i < M->m; i++ )
  169.         if ( hh->ve[i] != 0.0 )
  170.         __mltadd__(&(w->ve[j0]),&(M->me[i][j0]),hh->ve[i],
  171.                             (int)(M->n-j0));
  172.     for ( i = i0; i < M->m; i++ )
  173.         if ( hh->ve[i] != 0.0 )
  174.         __mltadd__(&(M->me[i][j0]),&(w->ve[j0]),-beta*hh->ve[i],
  175.                             (int)(M->n-j0));
  176.     return (M);
  177. }
  178.  
  179.