NEURON
zhsehldr.c
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 
3 /**************************************************************************
4 **
5 ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved.
6 **
7 ** Meschach Library
8 **
9 ** This Meschach Library is provided "as is" without any express
10 ** or implied warranty of any kind with respect to this software.
11 ** In particular the authors shall not be liable for any direct,
12 ** indirect, special, incidental or consequential damages arising
13 ** in any way from use of the software.
14 **
15 ** Everyone is granted permission to copy, modify and redistribute this
16 ** Meschach Library, provided:
17 ** 1. All copies contain this copyright notice.
18 ** 2. All modified copies shall carry a notice stating who
19 ** made the last modification and the date of such modification.
20 ** 3. No charge is made for this software or works derived from it.
21 ** This clause shall not be construed as constraining other software
22 ** distributed on the same medium as this software, nor is a
23 ** distribution fee considered a charge.
24 **
25 ***************************************************************************/
26 
27 
28 /*
29  Files for matrix computations
30 
31  Householder transformation file. Contains routines for calculating
32  householder transformations, applying them to vectors and matrices
33  by both row & column.
34 
35  Complex version
36 */
37 
38 static char rcsid[] = "zhsehldr.c,v 1.1 1997/12/04 17:56:08 hines Exp";
39 
40 #include <stdio.h>
41 #include "zmatrix.h"
42 #include "zmatrix2.h"
43 #include <math.h>
44 
45 #define is_zero(z) ((z).re == 0.0 && (z).im == 0.0)
46 
47 /* zhhvec -- calulates Householder vector to eliminate all entries after the
48  i0 entry of the vector vec. It is returned as out. May be in-situ */
49 ZVEC *zhhvec(vec,i0,beta,out,newval)
50 ZVEC *vec,*out;
51 int i0;
52 Real *beta;
53 complex *newval;
54 {
55  complex tmp;
56  Real norm, abs_val;
57 
58  if ( i0 < 0 || i0 >= vec->dim )
59  error(E_BOUNDS,"zhhvec");
60  out = _zv_copy(vec,out,i0);
61  tmp = _zin_prod(out,out,i0,Z_CONJ);
62  if ( tmp.re <= 0.0 )
63  {
64  *beta = 0.0;
65  *newval = out->ve[i0];
66  return (out);
67  }
68  norm = sqrt(tmp.re);
69  abs_val = zabs(out->ve[i0]);
70  *beta = 1.0/(norm * (norm+abs_val));
71  if ( abs_val == 0.0 )
72  {
73  newval->re = norm;
74  newval->im = 0.0;
75  }
76  else
77  {
78  abs_val = -norm / abs_val;
79  newval->re = abs_val*out->ve[i0].re;
80  newval->im = abs_val*out->ve[i0].im;
81  } abs_val = -norm / abs_val;
82  out->ve[i0].re -= newval->re;
83  out->ve[i0].im -= newval->im;
84 
85  return (out);
86 }
87 
88 /* zhhtrvec -- apply Householder transformation to vector -- may be in-situ */
89 ZVEC *zhhtrvec(hh,beta,i0,in,out)
90 ZVEC *hh,*in,*out; /* hh = Householder vector */
91 int i0;
92 double beta;
93 {
94  complex scale, tmp;
95  /* u_int i; */
96 
97  if ( hh==ZVNULL || in==ZVNULL )
98  error(E_NULL,"zhhtrvec");
99  if ( in->dim != hh->dim )
100  error(E_SIZES,"zhhtrvec");
101  if ( i0 < 0 || i0 > in->dim )
102  error(E_BOUNDS,"zhhvec");
103 
104  tmp = _zin_prod(hh,in,i0,Z_CONJ);
105  scale.re = -beta*tmp.re;
106  scale.im = -beta*tmp.im;
107  out = zv_copy(in,out);
108  __zmltadd__(&(out->ve[i0]),&(hh->ve[i0]),scale,
109  (int)(in->dim-i0),Z_NOCONJ);
110  /************************************************************
111  for ( i=i0; i<in->dim; i++ )
112  out->ve[i] = in->ve[i] - scale*hh->ve[i];
113  ************************************************************/
114 
115  return (out);
116 }
117 
118 /* zhhtrrows -- transform a matrix by a Householder vector by rows
119  starting at row i0 from column j0 -- in-situ */
120 ZMAT *zhhtrrows(M,i0,j0,hh,beta)
121 ZMAT *M;
122 int i0, j0;
123 ZVEC *hh;
124 double beta;
125 {
126  complex ip, scale;
127  int i /*, j */;
128 
129  if ( M==ZMNULL || hh==ZVNULL )
130  error(E_NULL,"zhhtrrows");
131  if ( M->n != hh->dim )
132  error(E_RANGE,"zhhtrrows");
133  if ( i0 < 0 || i0 > M->m || j0 < 0 || j0 > M->n )
134  error(E_BOUNDS,"zhhtrrows");
135 
136  if ( beta == 0.0 ) return (M);
137 
138  /* for each row ... */
139  for ( i = i0; i < M->m; i++ )
140  { /* compute inner product */
141  ip = __zip__(&(M->me[i][j0]),&(hh->ve[j0]),
142  (int)(M->n-j0),Z_NOCONJ);
143  /**************************************************
144  ip = 0.0;
145  for ( j = j0; j < M->n; j++ )
146  ip += M->me[i][j]*hh->ve[j];
147  **************************************************/
148  scale.re = -beta*ip.re;
149  scale.im = -beta*ip.im;
150  /* if ( scale == 0.0 ) */
151  if ( is_zero(scale) )
152  continue;
153 
154  /* do operation */
155  __zmltadd__(&(M->me[i][j0]),&(hh->ve[j0]),scale,
156  (int)(M->n-j0),Z_CONJ);
157  /**************************************************
158  for ( j = j0; j < M->n; j++ )
159  M->me[i][j] -= scale*hh->ve[j];
160  **************************************************/
161  }
162 
163  return (M);
164 }
165 
166 
167 /* zhhtrcols -- transform a matrix by a Householder vector by columns
168  starting at row i0 from column j0 -- in-situ */
169 ZMAT *zhhtrcols(M,i0,j0,hh,beta)
170 ZMAT *M;
171 int i0, j0;
172 ZVEC *hh;
173 double beta;
174 {
175  /* Real ip, scale; */
176  complex scale;
177  int i /*, k */;
178  static ZVEC *w = ZVNULL;
179 
180  if ( M==ZMNULL || hh==ZVNULL )
181  error(E_NULL,"zhhtrcols");
182  if ( M->m != hh->dim )
183  error(E_SIZES,"zhhtrcols");
184  if ( i0 < 0 || i0 > M->m || j0 < 0 || j0 > M->n )
185  error(E_BOUNDS,"zhhtrcols");
186 
187  if ( beta == 0.0 ) return (M);
188 
189  w = zv_resize(w,M->n);
190  MEM_STAT_REG(w,TYPE_ZVEC);
191  zv_zero(w);
192 
193  for ( i = i0; i < M->m; i++ )
194  /* if ( hh->ve[i] != 0.0 ) */
195  if ( ! is_zero(hh->ve[i]) )
196  __zmltadd__(&(w->ve[j0]),&(M->me[i][j0]),hh->ve[i],
197  (int)(M->n-j0),Z_CONJ);
198  for ( i = i0; i < M->m; i++ )
199  /* if ( hh->ve[i] != 0.0 ) */
200  if ( ! is_zero(hh->ve[i]) )
201  {
202  scale.re = -beta*hh->ve[i].re;
203  scale.im = -beta*hh->ve[i].im;
204  __zmltadd__(&(M->me[i][j0]),&(w->ve[j0]),scale,
205  (int)(M->n-j0),Z_CONJ);
206  }
207  return (M);
208 }
209 
#define error(err_num, fn_name)
Definition: err.h:73
#define E_RANGE
Definition: err.h:104
#define E_NULL
Definition: err.h:102
#define E_BOUNDS
Definition: err.h:96
#define E_SIZES
Definition: err.h:95
#define Real
Definition: machine.h:189
#define i
Definition: md1redef.h:12
#define MEM_STAT_REG(var, type)
Definition: meminfo.h:133
sqrt
Definition: extdef.h:3
Definition: zmatrix.h:50
Definition: zmatrix.h:44
complex * ve
Definition: zmatrix.h:46
u_int dim
Definition: zmatrix.h:45
Real re
Definition: zmatrix.h:40
Real im
Definition: zmatrix.h:40
ZVEC * _zv_copy(ZVEC *in, ZVEC *out, u_int i0)
Definition: zcopy.c:58
double zabs(complex z)
Definition: zfunc.c:65
#define is_zero(z)
Definition: zhsehldr.c:45
ZVEC * zhhvec(ZVEC *vec, int i0, Real *beta, ZVEC *out, complex *newval)
Definition: zhsehldr.c:49
ZMAT * zhhtrrows(ZMAT *M, int i0, int j0, ZVEC *hh, double beta)
Definition: zhsehldr.c:120
ZMAT * zhhtrcols(ZMAT *M, int i0, int j0, ZVEC *hh, double beta)
Definition: zhsehldr.c:169
ZVEC * zhhtrvec(ZVEC *hh, double beta, int i0, ZVEC *in, ZVEC *out)
Definition: zhsehldr.c:89
static char rcsid[]
Definition: zhsehldr.c:38
complex __zip__(complex *zp1, complex *zp2, int len, int flag)
Definition: zmachine.c:56
void __zmltadd__(complex *zp1, complex *zp2, complex s, int len, int flag)
Definition: zmachine.c:87
ZVEC * zv_zero(ZVEC *x)
Definition: zmemory.c:39
#define Z_CONJ
Definition: zmatrix.h:60
ZVEC * zv_resize(ZVEC *x, int new_dim)
Definition: zmemory.c:362
complex _zin_prod(ZVEC *x, ZVEC *y, u_int i0, u_int flag)
Definition: zvecop.c:38
#define zv_copy(x, y)
Definition: zmatrix.h:263
#define ZVNULL
Definition: zmatrix.h:57
#define ZMNULL
Definition: zmatrix.h:58
#define Z_NOCONJ
Definition: zmatrix.h:61