NEURON
zgivens.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  Givens operations file. Contains routines for calculating and
30  applying givens rotations for/to vectors and also to matrices by
31  row and by column.
32 
33  Complex version.
34 */
35 
36 static char rcsid[] = "$Id: ";
37 
38 #include <stdio.h>
39 #include "zmatrix.h"
40 #include "zmatrix2.h"
41 #include <math.h>
42 
43 /*
44  (Complex) Givens rotation matrix:
45  [ c -s ]
46  [ s* c ]
47  Note that c is real and s is complex
48 */
49 
50 /* zgivens -- returns c,s parameters for Givens rotation to
51  eliminate y in the **column** vector [ x y ] */
52 void zgivens(x,y,c,s)
53 complex x,y,*s;
54 Real *c;
55 {
56  Real inv_norm, norm;
57  complex tmp;
58 
59  /* this is a safe way of computing sqrt(|x|^2+|y|^2) */
60  tmp.re = zabs(x); tmp.im = zabs(y);
61  norm = zabs(tmp);
62 
63  if ( norm == 0.0 )
64  { *c = 1.0; s->re = s->im = 0.0; } /* identity */
65  else
66  {
67  inv_norm = 1.0 / tmp.re; /* inv_norm = 1/|x| */
68  x.re *= inv_norm;
69  x.im *= inv_norm; /* normalise x */
70  inv_norm = 1.0/norm; /* inv_norm = 1/||[x,y]||2 */
71  *c = tmp.re * inv_norm;
72  /* now compute - conj(normalised x).y/||[x,y]||2 */
73  s->re = - inv_norm*(x.re*y.re + x.im*y.im);
74  s->im = inv_norm*(x.re*y.im - x.im*y.re);
75  }
76 }
77 
78 /* rot_zvec -- apply Givens rotation to x's i & k components */
79 ZVEC *rot_zvec(x,i,k,c,s,out)
80 ZVEC *x,*out;
81 int i,k;
82 double c;
83 complex s;
84 {
85 
86  complex temp1, temp2;
87 
88  if ( x==ZVNULL )
89  error(E_NULL,"rot_zvec");
90  if ( i < 0 || i >= x->dim || k < 0 || k >= x->dim )
91  error(E_RANGE,"rot_zvec");
92  if ( x != out )
93  out = zv_copy(x,out);
94 
95  /* temp1 = c*out->ve[i] - s*out->ve[k]; */
96  temp1.re = c*out->ve[i].re
97  - s.re*out->ve[k].re + s.im*out->ve[k].im;
98  temp1.im = c*out->ve[i].im
99  - s.re*out->ve[k].im - s.im*out->ve[k].re;
100 
101  /* temp2 = c*out->ve[k] + zconj(s)*out->ve[i]; */
102  temp2.re = c*out->ve[k].re
103  + s.re*out->ve[i].re + s.im*out->ve[i].im;
104  temp2.im = c*out->ve[k].im
105  + s.re*out->ve[i].im - s.im*out->ve[i].re;
106 
107  out->ve[i] = temp1;
108  out->ve[k] = temp2;
109 
110  return (out);
111 }
112 
113 /* zrot_rows -- premultiply mat by givens rotation described by c,s */
114 ZMAT *zrot_rows(mat,i,k,c,s,out)
115 ZMAT *mat,*out;
116 int i,k;
117 double c;
118 complex s;
119 {
120  u_int j;
121  complex temp1, temp2;
122 
123  if ( mat==ZMNULL )
124  error(E_NULL,"zrot_rows");
125  if ( i < 0 || i >= mat->m || k < 0 || k >= mat->m )
126  error(E_RANGE,"zrot_rows");
127 
128  if ( mat != out )
129  out = zm_copy(mat,zm_resize(out,mat->m,mat->n));
130 
131  /* temp1 = c*out->me[i][j] - s*out->me[k][j]; */
132  for ( j=0; j<mat->n; j++ )
133  {
134  /* temp1 = c*out->me[i][j] - s*out->me[k][j]; */
135  temp1.re = c*out->me[i][j].re
136  - s.re*out->me[k][j].re + s.im*out->me[k][j].im;
137  temp1.im = c*out->me[i][j].im
138  - s.re*out->me[k][j].im - s.im*out->me[k][j].re;
139 
140  /* temp2 = c*out->me[k][j] + conj(s)*out->me[i][j]; */
141  temp2.re = c*out->me[k][j].re
142  + s.re*out->me[i][j].re + s.im*out->me[i][j].im;
143  temp2.im = c*out->me[k][j].im
144  + s.re*out->me[i][j].im - s.im*out->me[i][j].re;
145 
146  out->me[i][j] = temp1;
147  out->me[k][j] = temp2;
148  }
149 
150  return (out);
151 }
152 
153 /* zrot_cols -- postmultiply mat by adjoint Givens rotation described by c,s */
154 ZMAT *zrot_cols(mat,i,k,c,s,out)
155 ZMAT *mat,*out;
156 int i,k;
157 double c;
158 complex s;
159 {
160  u_int j;
161  complex x, y;
162 
163  if ( mat==ZMNULL )
164  error(E_NULL,"zrot_cols");
165  if ( i < 0 || i >= mat->n || k < 0 || k >= mat->n )
166  error(E_RANGE,"zrot_cols");
167 
168  if ( mat != out )
169  out = zm_copy(mat,zm_resize(out,mat->m,mat->n));
170 
171  for ( j=0; j<mat->m; j++ )
172  {
173  x = out->me[j][i]; y = out->me[j][k];
174  /* out->me[j][i] = c*x - conj(s)*y; */
175  out->me[j][i].re = c*x.re - s.re*y.re - s.im*y.im;
176  out->me[j][i].im = c*x.im - s.re*y.im + s.im*y.re;
177 
178  /* out->me[j][k] = c*y + s*x; */
179  out->me[j][k].re = c*y.re + s.re*x.re - s.im*x.im;
180  out->me[j][k].im = c*y.im + s.re*x.im + s.im*x.re;
181  }
182 
183  return (out);
184 }
185 
#define c
#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 Real
Definition: machine.h:189
uint32_t u_int
Definition: machine.h:38
#define i
Definition: md1redef.h:12
size_t j
static philox4x32_key_t k
Definition: nrnran123.cpp:11
Definition: zmatrix.h:50
Definition: zmatrix.h:44
Real re
Definition: zmatrix.h:40
Real im
Definition: zmatrix.h:40
double zabs(complex z)
Definition: zfunc.c:65
void zgivens(complex x, complex y, Real *c, complex *s)
Definition: zgivens.c:52
ZVEC * rot_zvec(ZVEC *x, int i, int k, double c, complex s, ZVEC *out)
Definition: zgivens.c:79
ZMAT * zrot_rows(ZMAT *mat, int i, int k, double c, complex s, ZMAT *out)
Definition: zgivens.c:114
static char rcsid[]
Definition: zgivens.c:36
ZMAT * zrot_cols(ZMAT *mat, int i, int k, double c, complex s, ZMAT *out)
Definition: zgivens.c:154
#define zm_copy(A, B)
Definition: zmatrix.h:264
#define zv_copy(x, y)
Definition: zmatrix.h:263
ZMAT * zm_resize(ZMAT *A, int new_m, int new_n)
Definition: zmemory.c:227
#define ZVNULL
Definition: zmatrix.h:57
#define ZMNULL
Definition: zmatrix.h:58