NEURON
update.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  Matrix factorisation routines to work with the other matrix files.
30 */
31 
32 /* update.c 1.3 11/25/87 */
33 static char rcsid[] = "update.c,v 1.1 1997/12/04 17:56:01 hines Exp";
34 
35 #include <stdio.h>
36 #include "matrix.h"
37 #include "matrix2.h"
38 #include <math.h>
39 
40 
41 
42 
43 /* Most matrix factorisation routines are in-situ unless otherwise specified */
44 
45 /* LDLupdate -- updates a CHolesky factorisation, replacing LDL' by
46  MD~M' = LDL' + alpha.w.w' Note: w is overwritten
47  Ref: Gill et al Math Comp 28, p516 Algorithm C1 */
48 MAT *LDLupdate(CHmat,w,alpha)
49 MAT *CHmat;
50 VEC *w;
51 double alpha;
52 {
53  u_int i,j;
54  Real diag,new_diag,beta,p;
55 
56  if ( CHmat==(MAT *)NULL || w==(VEC *)NULL )
57  error(E_NULL,"LDLupdate");
58  if ( CHmat->m != CHmat->n || w->dim != CHmat->m )
59  error(E_SIZES,"LDLupdate");
60 
61  for ( j=0; j < w->dim; j++ )
62  {
63  p = w->ve[j];
64  diag = CHmat->me[j][j];
65  new_diag = CHmat->me[j][j] = diag + alpha*p*p;
66  if ( new_diag <= 0.0 )
67  error(E_POSDEF,"LDLupdate");
68  beta = p*alpha/new_diag;
69  alpha *= diag/new_diag;
70 
71  for ( i=j+1; i < w->dim; i++ )
72  {
73  w->ve[i] -= p*CHmat->me[i][j];
74  CHmat->me[i][j] += beta*w->ve[i];
75  CHmat->me[j][i] = CHmat->me[i][j];
76  }
77  }
78 
79  return (CHmat);
80 }
81 
82 
83 /* QRupdate -- updates QR factorisation in expanded form (seperate matrices)
84  Finds Q+, R+ s.t. Q+.R+ = Q.(R+u.v') and Q+ orthogonal, R+ upper triang
85  Ref: Golub & van Loan Matrix Computations pp437-443
86  -- does not update Q if it is NULL */
87 MAT *QRupdate(Q,R,u,v)
88 MAT *Q,*R;
89 VEC *u,*v;
90 {
91  int i,j,k;
92  Real c,s,temp;
93 
94  if ( ! R || ! u || ! v )
95  error(E_NULL,"QRupdate");
96  if ( ( Q && ( Q->m != Q->n || R->m != Q->n ) ) ||
97  u->dim != R->m || v->dim != R->n )
98  error(E_SIZES,"QRupdate");
99 
100  /* find largest k s.t. u[k] != 0 */
101  for ( k=R->m-1; k>=0; k-- )
102  if ( u->ve[k] != 0.0 )
103  break;
104 
105  /* transform R+u.v' to Hessenberg form */
106  for ( i=k-1; i>=0; i-- )
107  {
108  /* get Givens rotation */
109  givens(u->ve[i],u->ve[i+1],&c,&s);
110  rot_rows(R,i,i+1,c,s,R);
111  if ( Q )
112  rot_cols(Q,i,i+1,c,s,Q);
113  rot_vec(u,i,i+1,c,s,u);
114  }
115 
116  /* add into R */
117  temp = u->ve[0];
118  for ( j=0; j<R->n; j++ )
119  R->me[0][j] += temp*v->ve[j];
120 
121  /* transform Hessenberg to upper triangular */
122  for ( i=0; i<k; i++ )
123  {
124  givens(R->me[i][i],R->me[i+1][i],&c,&s);
125  rot_rows(R,i,i+1,c,s,R);
126  if ( Q )
127  rot_cols(Q,i,i+1,c,s,Q);
128  }
129 
130  return R;
131 }
132 
#define alpha
Definition: bkpfacto.c:43
#define c
#define error(err_num, fn_name)
Definition: err.h:73
#define E_NULL
Definition: err.h:102
#define E_SIZES
Definition: err.h:95
#define E_POSDEF
Definition: err.h:99
#define diag(s)
Definition: fmenu.cpp:192
void givens(double x, double y, Real *c, Real *s)
Definition: givens.c:47
VEC * rot_vec(VEC *x, u_int i, u_int k, double c, double s, VEC *out)
Definition: givens.c:61
MAT * rot_cols(MAT *mat, u_int i, u_int k, double c, double s, MAT *out)
Definition: givens.c:114
MAT * rot_rows(MAT *mat, u_int i, u_int k, double c, double s, MAT *out)
Definition: givens.c:85
#define Real
Definition: machine.h:189
uint32_t u_int
Definition: machine.h:38
#define v
Definition: md1redef.h:4
#define i
Definition: md1redef.h:12
for(i=0;i< n;i++)
size_t p
size_t j
static philox4x32_key_t k
Definition: nrnran123.cpp:11
#define NULL
Definition: sptree.h:16
Definition: matrix.h:73
Definition: matrix.h:67
u_int dim
Definition: matrix.h:68
Real * ve
Definition: matrix.h:69
MAT * LDLupdate(MAT *CHmat, VEC *w, double alpha)
Definition: update.c:48
MAT * QRupdate(MAT *Q, MAT *R, VEC *u, VEC *v)
Definition: update.c:87
static char rcsid[]
Definition: update.c:33