NEURON
zqrfctr.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  This file contains the routines needed to perform QR factorisation
29  of matrices, as well as Householder transformations.
30  The internal "factored form" of a matrix A is not quite standard.
31  The diagonal of A is replaced by the diagonal of R -- not by the 1st non-zero
32  entries of the Householder vectors. The 1st non-zero entries are held in
33  the diag parameter of QRfactor(). The reason for this non-standard
34  representation is that it enables direct use of the Usolve() function
35  rather than requiring that a seperate function be written just for this case.
36  See, e.g., QRsolve() below for more details.
37 
38  Complex version
39 
40 */
41 
42 static char rcsid[] = "zqrfctr.c,v 1.1 1997/12/04 17:56:15 hines Exp";
43 
44 #include <stdio.h>
45 #include "zmatrix.h"
46 #include "zmatrix2.h"
47 #include <math.h>
48 
49 
50 #define is_zero(z) ((z).re == 0.0 && (z).im == 0.0)
51 
52 
53 #define sign(x) ((x) > 0.0 ? 1 : ((x) < 0.0 ? -1 : 0 ))
54 
55 /* Note: The usual representation of a Householder transformation is taken
56  to be:
57  P = I - beta.u.u*
58  where beta = 2/(u*.u) and u is called the Householder vector
59  (u* is the conjugate transposed vector of u
60 */
61 
62 /* zQRfactor -- forms the QR factorisation of A
63  -- factorisation stored in compact form as described above
64  (not quite standard format) */
66 ZMAT *A;
67 ZVEC *diag;
68 {
69  u_int k,limit;
70  Real beta;
71  static ZVEC *tmp1=ZVNULL;
72 
73  if ( ! A || ! diag )
74  error(E_NULL,"zQRfactor");
75  limit = min(A->m,A->n);
76  if ( diag->dim < limit )
77  error(E_SIZES,"zQRfactor");
78 
79  tmp1 = zv_resize(tmp1,A->m);
80  MEM_STAT_REG(tmp1,TYPE_ZVEC);
81 
82  for ( k=0; k<limit; k++ )
83  {
84  /* get H/holder vector for the k-th column */
85  zget_col(A,k,tmp1);
86  /* hhvec(tmp1,k,&beta->ve[k],tmp1,&A->me[k][k]); */
87  zhhvec(tmp1,k,&beta,tmp1,&A->me[k][k]);
88  diag->ve[k] = tmp1->ve[k];
89 
90  /* apply H/holder vector to remaining columns */
91  /* hhtrcols(A,k,k+1,tmp1,beta->ve[k]); */
92  tracecatch(zhhtrcols(A,k,k+1,tmp1,beta),"zQRfactor");
93  }
94 
95  return (A);
96 }
97 
98 /* zQRCPfactor -- forms the QR factorisation of A with column pivoting
99  -- factorisation stored in compact form as described above
100  ( not quite standard format ) */
102 ZMAT *A;
103 ZVEC *diag;
104 PERM *px;
105 {
106  u_int i, i_max, j, k, limit;
107  static ZVEC *tmp1=ZVNULL, *tmp2=ZVNULL;
108  static VEC *gamma=VNULL;
109  Real beta;
110  Real maxgamma, sum, tmp;
111  complex ztmp;
112 
113  if ( ! A || ! diag || ! px )
114  error(E_NULL,"QRCPfactor");
115  limit = min(A->m,A->n);
116  if ( diag->dim < limit || px->size != A->n )
117  error(E_SIZES,"QRCPfactor");
118 
119  tmp1 = zv_resize(tmp1,A->m);
120  tmp2 = zv_resize(tmp2,A->m);
121  gamma = v_resize(gamma,A->n);
122  MEM_STAT_REG(tmp1,TYPE_ZVEC);
123  MEM_STAT_REG(tmp2,TYPE_ZVEC);
124  MEM_STAT_REG(gamma,TYPE_VEC);
125 
126  /* initialise gamma and px */
127  for ( j=0; j<A->n; j++ )
128  {
129  px->pe[j] = j;
130  sum = 0.0;
131  for ( i=0; i<A->m; i++ )
132  sum += square(A->me[i][j].re) + square(A->me[i][j].im);
133  gamma->ve[j] = sum;
134  }
135 
136  for ( k=0; k<limit; k++ )
137  {
138  /* find "best" column to use */
139  i_max = k; maxgamma = gamma->ve[k];
140  for ( i=k+1; i<A->n; i++ )
141  /* Loop invariant:maxgamma=gamma[i_max]
142  >=gamma[l];l=k,...,i-1 */
143  if ( gamma->ve[i] > maxgamma )
144  { maxgamma = gamma->ve[i]; i_max = i; }
145 
146  /* swap columns if necessary */
147  if ( i_max != k )
148  {
149  /* swap gamma values */
150  tmp = gamma->ve[k];
151  gamma->ve[k] = gamma->ve[i_max];
152  gamma->ve[i_max] = tmp;
153 
154  /* update column permutation */
155  px_transp(px,k,i_max);
156 
157  /* swap columns of A */
158  for ( i=0; i<A->m; i++ )
159  {
160  ztmp = A->me[i][k];
161  A->me[i][k] = A->me[i][i_max];
162  A->me[i][i_max] = ztmp;
163  }
164  }
165 
166  /* get H/holder vector for the k-th column */
167  zget_col(A,k,tmp1);
168  /* hhvec(tmp1,k,&beta->ve[k],tmp1,&A->me[k][k]); */
169  zhhvec(tmp1,k,&beta,tmp1,&A->me[k][k]);
170  diag->ve[k] = tmp1->ve[k];
171 
172  /* apply H/holder vector to remaining columns */
173  /* hhtrcols(A,k,k+1,tmp1,beta->ve[k]); */
174  zhhtrcols(A,k,k+1,tmp1,beta);
175 
176  /* update gamma values */
177  for ( j=k+1; j<A->n; j++ )
178  gamma->ve[j] -= square(A->me[k][j].re)+square(A->me[k][j].im);
179  }
180 
181  return (A);
182 }
183 
184 /* zQsolve -- solves Qx = b, Q is an orthogonal matrix stored in compact
185  form a la QRfactor()
186  -- may be in-situ */
187 ZVEC *_zQsolve(QR,diag,b,x,tmp)
188 ZMAT *QR;
189 ZVEC *diag, *b, *x, *tmp;
190 {
191  u_int dynamic;
192  int k, limit;
193  Real beta, r_ii, tmp_val;
194 
195  limit = min(QR->m,QR->n);
196  dynamic = FALSE;
197  if ( ! QR || ! diag || ! b )
198  error(E_NULL,"_zQsolve");
199  if ( diag->dim < limit || b->dim != QR->m )
200  error(E_SIZES,"_zQsolve");
201  x = zv_resize(x,QR->m);
202  if ( tmp == ZVNULL )
203  dynamic = TRUE;
204  tmp = zv_resize(tmp,QR->m);
205 
206  /* apply H/holder transforms in normal order */
207  x = zv_copy(b,x);
208  for ( k = 0 ; k < limit ; k++ )
209  {
210  zget_col(QR,k,tmp);
211  r_ii = zabs(tmp->ve[k]);
212  tmp->ve[k] = diag->ve[k];
213  tmp_val = (r_ii*zabs(diag->ve[k]));
214  beta = ( tmp_val == 0.0 ) ? 0.0 : 1.0/tmp_val;
215  /* hhtrvec(tmp,beta->ve[k],k,x,x); */
216  zhhtrvec(tmp,beta,k,x,x);
217  }
218 
219  if ( dynamic )
220  ZV_FREE(tmp);
221 
222  return (x);
223 }
224 
225 /* zmakeQ -- constructs orthogonal matrix from Householder vectors stored in
226  compact QR form */
227 ZMAT *zmakeQ(QR,diag,Qout)
228 ZMAT *QR,*Qout;
229 ZVEC *diag;
230 {
231  static ZVEC *tmp1=ZVNULL,*tmp2=ZVNULL;
232  u_int i, limit;
233  Real beta, r_ii, tmp_val;
234  int j;
235 
236  limit = min(QR->m,QR->n);
237  if ( ! QR || ! diag )
238  error(E_NULL,"zmakeQ");
239  if ( diag->dim < limit )
240  error(E_SIZES,"zmakeQ");
241  Qout = zm_resize(Qout,QR->m,QR->m);
242 
243  tmp1 = zv_resize(tmp1,QR->m); /* contains basis vec & columns of Q */
244  tmp2 = zv_resize(tmp2,QR->m); /* contains H/holder vectors */
245  MEM_STAT_REG(tmp1,TYPE_ZVEC);
246  MEM_STAT_REG(tmp2,TYPE_ZVEC);
247 
248  for ( i=0; i<QR->m ; i++ )
249  { /* get i-th column of Q */
250  /* set up tmp1 as i-th basis vector */
251  for ( j=0; j<QR->m ; j++ )
252  tmp1->ve[j].re = tmp1->ve[j].im = 0.0;
253  tmp1->ve[i].re = 1.0;
254 
255  /* apply H/h transforms in reverse order */
256  for ( j=limit-1; j>=0; j-- )
257  {
258  zget_col(QR,j,tmp2);
259  r_ii = zabs(tmp2->ve[j]);
260  tmp2->ve[j] = diag->ve[j];
261  tmp_val = (r_ii*zabs(diag->ve[j]));
262  beta = ( tmp_val == 0.0 ) ? 0.0 : 1.0/tmp_val;
263  /* hhtrvec(tmp2,beta->ve[j],j,tmp1,tmp1); */
264  zhhtrvec(tmp2,beta,j,tmp1,tmp1);
265  }
266 
267  /* insert into Q */
268  zset_col(Qout,i,tmp1);
269  }
270 
271  return (Qout);
272 }
273 
274 /* zmakeR -- constructs upper triangular matrix from QR (compact form)
275  -- may be in-situ (all it does is zero the lower 1/2) */
276 ZMAT *zmakeR(QR,Rout)
277 ZMAT *QR,*Rout;
278 {
279  u_int i,j;
280 
281  if ( QR==ZMNULL )
282  error(E_NULL,"zmakeR");
283  Rout = zm_copy(QR,Rout);
284 
285  for ( i=1; i<QR->m; i++ )
286  for ( j=0; j<QR->n && j<i; j++ )
287  Rout->me[i][j].re = Rout->me[i][j].im = 0.0;
288 
289  return (Rout);
290 }
291 
292 /* zQRsolve -- solves the system Q.R.x=b where Q & R are stored in compact form
293  -- returns x, which is created if necessary */
295 ZMAT *QR;
296 ZVEC *diag, *b, *x;
297 {
298  int limit;
299  static ZVEC *tmp = ZVNULL;
300 
301  if ( ! QR || ! diag || ! b )
302  error(E_NULL,"zQRsolve");
303  limit = min(QR->m,QR->n);
304  if ( diag->dim < limit || b->dim != QR->m )
305  error(E_SIZES,"zQRsolve");
306  tmp = zv_resize(tmp,limit);
307  MEM_STAT_REG(tmp,TYPE_ZVEC);
308 
309  x = zv_resize(x,QR->n);
310  _zQsolve(QR,diag,b,x,tmp);
311  x = zUsolve(QR,x,x,0.0);
312  x = zv_resize(x,QR->n);
313 
314  return x;
315 }
316 
317 /* zQRAsolve -- solves the system (Q.R)*.x = b
318  -- Q & R are stored in compact form
319  -- returns x, which is created if necessary */
321 ZMAT *QR;
322 ZVEC *diag, *b, *x;
323 {
324  int j, limit;
325  Real beta, r_ii, tmp_val;
326  static ZVEC *tmp = ZVNULL;
327 
328  if ( ! QR || ! diag || ! b )
329  error(E_NULL,"zQRAsolve");
330  limit = min(QR->m,QR->n);
331  if ( diag->dim < limit || b->dim != QR->n )
332  error(E_SIZES,"zQRAsolve");
333 
334  x = zv_resize(x,QR->m);
335  x = zUAsolve(QR,b,x,0.0);
336  x = zv_resize(x,QR->m);
337 
338  tmp = zv_resize(tmp,x->dim);
339  MEM_STAT_REG(tmp,TYPE_ZVEC);
340  printf("zQRAsolve: tmp->dim = %d, x->dim = %d\n", tmp->dim, x->dim);
341 
342  /* apply H/h transforms in reverse order */
343  for ( j=limit-1; j>=0; j-- )
344  {
345  zget_col(QR,j,tmp);
346  tmp = zv_resize(tmp,QR->m);
347  r_ii = zabs(tmp->ve[j]);
348  tmp->ve[j] = diag->ve[j];
349  tmp_val = (r_ii*zabs(diag->ve[j]));
350  beta = ( tmp_val == 0.0 ) ? 0.0 : 1.0/tmp_val;
351  zhhtrvec(tmp,beta,j,x,x);
352  }
353 
354 
355  return x;
356 }
357 
358 /* zQRCPsolve -- solves A.x = b where A is factored by QRCPfactor()
359  -- assumes that A is in the compact factored form */
360 ZVEC *zQRCPsolve(QR,diag,pivot,b,x)
361 ZMAT *QR;
362 ZVEC *diag;
363 PERM *pivot;
364 ZVEC *b, *x;
365 {
366  if ( ! QR || ! diag || ! pivot || ! b )
367  error(E_NULL,"zQRCPsolve");
368  if ( (QR->m > diag->dim && QR->n > diag->dim) || QR->n != pivot->size )
369  error(E_SIZES,"zQRCPsolve");
370 
371  x = zQRsolve(QR,diag,b,x);
372  x = pxinv_zvec(pivot,x,x);
373 
374  return x;
375 }
376 
377 /* zUmlt -- compute out = upper_triang(U).x
378  -- may be in situ */
379 ZVEC *zUmlt(U,x,out)
380 ZMAT *U;
381 ZVEC *x, *out;
382 {
383  int i, limit;
384 
385  if ( U == ZMNULL || x == ZVNULL )
386  error(E_NULL,"zUmlt");
387  limit = min(U->m,U->n);
388  if ( limit != x->dim )
389  error(E_SIZES,"zUmlt");
390  if ( out == ZVNULL || out->dim < limit )
391  out = zv_resize(out,limit);
392 
393  for ( i = 0; i < limit; i++ )
394  out->ve[i] = __zip__(&(x->ve[i]),&(U->me[i][i]),limit - i,Z_NOCONJ);
395  return out;
396 }
397 
398 /* zUAmlt -- returns out = upper_triang(U)^T.x */
399 ZVEC *zUAmlt(U,x,out)
400 ZMAT *U;
401 ZVEC *x, *out;
402 {
403  /* complex sum; */
404  complex tmp;
405  int i, limit;
406 
407  if ( U == ZMNULL || x == ZVNULL )
408  error(E_NULL,"zUAmlt");
409  limit = min(U->m,U->n);
410  if ( out == ZVNULL || out->dim < limit )
411  out = zv_resize(out,limit);
412 
413  for ( i = limit-1; i >= 0; i-- )
414  {
415  tmp = x->ve[i];
416  out->ve[i].re = out->ve[i].im = 0.0;
417  __zmltadd__(&(out->ve[i]),&(U->me[i][i]),tmp,limit-i-1,Z_CONJ);
418  }
419 
420  return out;
421 }
422 
423 
424 /* zQRcondest -- returns an estimate of the 2-norm condition number of the
425  matrix factorised by QRfactor() or QRCPfactor()
426  -- note that as Q does not affect the 2-norm condition number,
427  it is not necessary to pass the diag, beta (or pivot) vectors
428  -- generates a lower bound on the true condition number
429  -- if the matrix is exactly singular, HUGE is returned
430  -- note that QRcondest() is likely to be more reliable for
431  matrices factored using QRCPfactor() */
432 double zQRcondest(QR)
433 ZMAT *QR;
434 {
435  static ZVEC *y=ZVNULL;
436  Real norm, norm1, norm2, tmp1, tmp2;
437  complex sum, tmp;
438  int i, j, limit;
439 
440  if ( QR == ZMNULL )
441  error(E_NULL,"zQRcondest");
442 
443  limit = min(QR->m,QR->n);
444  for ( i = 0; i < limit; i++ )
445  /* if ( QR->me[i][i] == 0.0 ) */
446  if ( is_zero(QR->me[i][i]) )
447  return HUGE;
448 
449  y = zv_resize(y,limit);
450  MEM_STAT_REG(y,TYPE_ZVEC);
451  /* use the trick for getting a unit vector y with ||R.y||_inf small
452  from the LU condition estimator */
453  for ( i = 0; i < limit; i++ )
454  {
455  sum.re = sum.im = 0.0;
456  for ( j = 0; j < i; j++ )
457  /* sum -= QR->me[j][i]*y->ve[j]; */
458  sum = zsub(sum,zmlt(QR->me[j][i],y->ve[j]));
459  /* sum -= (sum < 0.0) ? 1.0 : -1.0; */
460  norm1 = zabs(sum);
461  if ( norm1 == 0.0 )
462  sum.re = 1.0;
463  else
464  {
465  sum.re += sum.re / norm1;
466  sum.im += sum.im / norm1;
467  }
468  /* y->ve[i] = sum / QR->me[i][i]; */
469  y->ve[i] = zdiv(sum,QR->me[i][i]);
470  }
471  zUAmlt(QR,y,y);
472 
473  /* now apply inverse power method to R*.R */
474  for ( i = 0; i < 3; i++ )
475  {
476  tmp1 = zv_norm2(y);
477  zv_mlt(zmake(1.0/tmp1,0.0),y,y);
478  zUAsolve(QR,y,y,0.0);
479  tmp2 = zv_norm2(y);
480  zv_mlt(zmake(1.0/tmp2,0.0),y,y);
481  zUsolve(QR,y,y,0.0);
482  }
483  /* now compute approximation for ||R^{-1}||_2 */
484  norm1 = sqrt(tmp1)*sqrt(tmp2);
485 
486  /* now use complementary approach to compute approximation to ||R||_2 */
487  for ( i = limit-1; i >= 0; i-- )
488  {
489  sum.re = sum.im = 0.0;
490  for ( j = i+1; j < limit; j++ )
491  sum = zadd(sum,zmlt(QR->me[i][j],y->ve[j]));
492  if ( is_zero(QR->me[i][i]) )
493  return HUGE;
494  tmp = zdiv(sum,QR->me[i][i]);
495  if ( is_zero(tmp) )
496  {
497  y->ve[i].re = 1.0;
498  y->ve[i].im = 0.0;
499  }
500  else
501  {
502  norm = zabs(tmp);
503  y->ve[i].re = sum.re / norm;
504  y->ve[i].im = sum.im / norm;
505  }
506  /* y->ve[i] = (sum >= 0.0) ? 1.0 : -1.0; */
507  /* y->ve[i] = (QR->me[i][i] >= 0.0) ? y->ve[i] : - y->ve[i]; */
508  }
509 
510  /* now apply power method to R*.R */
511  for ( i = 0; i < 3; i++ )
512  {
513  tmp1 = zv_norm2(y);
514  zv_mlt(zmake(1.0/tmp1,0.0),y,y);
515  zUmlt(QR,y,y);
516  tmp2 = zv_norm2(y);
517  zv_mlt(zmake(1.0/tmp2,0.0),y,y);
518  zUAmlt(QR,y,y);
519  }
520  norm2 = sqrt(tmp1)*sqrt(tmp2);
521 
522  /* printf("QRcondest: norm1 = %g, norm2 = %g\n",norm1,norm2); */
523 
524  return norm1*norm2;
525 }
526 
#define TRUE
Definition: err.c:57
#define FALSE
Definition: err.c:56
#define error(err_num, fn_name)
Definition: err.h:73
#define tracecatch(ok_part, function)
Definition: err.h:166
#define E_NULL
Definition: err.h:102
#define E_SIZES
Definition: err.h:95
#define diag(s)
Definition: fmenu.cpp:192
static Object ** v_resize(void *v)
Definition: ivocvect.cpp:1383
#define Real
Definition: machine.h:189
uint32_t u_int
Definition: machine.h:38
PERM * px_transp(PERM *px, u_int i, u_int j)
Definition: pxop.c:208
#define VNULL
Definition: matrix.h:631
#define min(a, b)
Definition: matrix.h:157
#define i
Definition: md1redef.h:12
#define TYPE_VEC
Definition: meminfo.h:52
#define MEM_STAT_REG(var, type)
Definition: meminfo.h:133
sqrt
Definition: extdef.h:3
#define A(i)
Definition: multisplit.cpp:63
#define printf
Definition: mwprefix.h:26
for(i=0;i< n;i++)
size_t j
static philox4x32_key_t k
Definition: nrnran123.cpp:11
Definition: matrix.h:87
u_int * pe
Definition: matrix.h:88
u_int size
Definition: matrix.h:88
Definition: matrix.h:67
Real * ve
Definition: matrix.h:69
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
complex zmake(double real, double imag)
Definition: zfunc.c:41
complex zdiv(complex z1, complex z2)
Definition: zfunc.c:166
complex zmlt(complex z1, complex z2)
Definition: zfunc.c:121
complex zsub(complex z1, complex z2)
Definition: zfunc.c:107
complex zadd(complex z1, complex z2)
Definition: zfunc.c:93
double zabs(complex z)
Definition: zfunc.c:65
ZVEC * zhhvec(ZVEC *vec, int i0, Real *beta, ZVEC *out, complex *newval)
Definition: zhsehldr.c:49
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
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
ZMAT * zset_col(ZMAT *mat, int col, ZVEC *vec)
Definition: zmatop.c:565
ZVEC * zget_col(ZMAT *mat, int col, ZVEC *vec)
Definition: zmatop.c:520
ZVEC * zUAsolve(ZMAT *U, ZVEC *b, ZVEC *out, double diag)
Definition: zsolve.c:157
ZVEC * zUsolve(ZMAT *matrix, ZVEC *b, ZVEC *out, double diag)
Definition: zsolve.c:46
ZVEC * zv_mlt(complex scalar, ZVEC *vector, ZVEC *out)
Definition: zvecop.c:54
#define Z_CONJ
Definition: zmatrix.h:60
#define zv_norm2(x)
Definition: zmatrix.h:279
#define ZV_FREE(x)
Definition: zmatrix.h:273
#define zm_copy(A, B)
Definition: zmatrix.h:264
ZVEC * zv_resize(ZVEC *x, int new_dim)
Definition: zmemory.c:362
#define zv_copy(x, y)
Definition: zmatrix.h:263
ZVEC * pxinv_zvec(PERM *pi, ZVEC *in, ZVEC *out)
Definition: zvecop.c:466
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
#define Z_NOCONJ
Definition: zmatrix.h:61
#define square(x)
Definition: znorm.c:75
ZVEC * zUmlt(ZMAT *U, ZVEC *x, ZVEC *out)
Definition: zqrfctr.c:379
ZMAT * zQRCPfactor(ZMAT *A, ZVEC *diag, PERM *px)
Definition: zqrfctr.c:101
ZVEC * zUAmlt(ZMAT *U, ZVEC *x, ZVEC *out)
Definition: zqrfctr.c:399
ZVEC * _zQsolve(ZMAT *QR, ZVEC *diag, ZVEC *b, ZVEC *x, ZVEC *tmp)
Definition: zqrfctr.c:187
ZMAT * zmakeR(ZMAT *QR, ZMAT *Rout)
Definition: zqrfctr.c:276
ZMAT * zmakeQ(ZMAT *QR, ZVEC *diag, ZMAT *Qout)
Definition: zqrfctr.c:227
#define is_zero(z)
Definition: zqrfctr.c:50
ZVEC * zQRAsolve(ZMAT *QR, ZVEC *diag, ZVEC *b, ZVEC *x)
Definition: zqrfctr.c:320
ZMAT * zQRfactor(ZMAT *A, ZVEC *diag)
Definition: zqrfctr.c:65
double zQRcondest(ZMAT *QR)
Definition: zqrfctr.c:432
ZVEC * zQRsolve(ZMAT *QR, ZVEC *diag, ZVEC *b, ZVEC *x)
Definition: zqrfctr.c:294
ZVEC * zQRCPsolve(ZMAT *QR, ZVEC *diag, PERM *pivot, ZVEC *b, ZVEC *x)
Definition: zqrfctr.c:360
static char rcsid[]
Definition: zqrfctr.c:42