comparison liboctave/dbleQRP.cc @ 8597:c86718093c1b

improve & fix QR classes
author Jaroslav Hajek <highegg@gmail.com>
date Tue, 27 Jan 2009 12:40:06 +0100
parents e3c9102431a9
children 20dfb885f877
comparison
equal deleted inserted replaced
8596:8833c0b18eb2 8597:c86718093c1b
28 #include <cassert> 28 #include <cassert>
29 29
30 #include "dbleQRP.h" 30 #include "dbleQRP.h"
31 #include "f77-fcn.h" 31 #include "f77-fcn.h"
32 #include "lo-error.h" 32 #include "lo-error.h"
33 #include "oct-locbuf.h"
33 34
34 extern "C" 35 extern "C"
35 { 36 {
36 F77_RET_T 37 F77_RET_T
37 F77_FUNC (dgeqp3, DGEQP3) (const octave_idx_type&, const octave_idx_type&, double*, 38 F77_FUNC (dgeqp3, DGEQP3) (const octave_idx_type&, const octave_idx_type&, double*,
38 const octave_idx_type&, octave_idx_type*, double*, double*, 39 const octave_idx_type&, octave_idx_type*, double*, double*,
39 const octave_idx_type&, octave_idx_type&); 40 const octave_idx_type&, octave_idx_type&);
40
41 F77_RET_T
42 F77_FUNC (dorgqr, DORGQR) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&,
43 double*, const octave_idx_type&, double*, double*,
44 const octave_idx_type&, octave_idx_type&);
45 } 41 }
46 42
47 // It would be best to share some of this code with QR class... 43 // It would be best to share some of this code with QR class...
48 44
49 QRP::QRP (const Matrix& a, QR::type qr_type) 45 QRP::QRP (const Matrix& a, QR::type qr_type)
58 assert (qr_type != QR::raw); 54 assert (qr_type != QR::raw);
59 55
60 octave_idx_type m = a.rows (); 56 octave_idx_type m = a.rows ();
61 octave_idx_type n = a.cols (); 57 octave_idx_type n = a.cols ();
62 58
63 if (m == 0 || n == 0)
64 {
65 (*current_liboctave_error_handler) ("QR must have non-empty matrix");
66 return;
67 }
68
69 octave_idx_type min_mn = m < n ? m : n; 59 octave_idx_type min_mn = m < n ? m : n;
70 Array<double> tau (min_mn); 60 OCTAVE_LOCAL_BUFFER (double, tau, min_mn);
71 double *ptau = tau.fortran_vec ();
72 61
73 octave_idx_type info = 0; 62 octave_idx_type info = 0;
74 63
75 Matrix A_fact = a; 64 Matrix afact = a;
76 if (m > n && qr_type != QR::economy) 65 if (m > n && qr_type == QR::std)
77 A_fact.resize (m, m, 0.0); 66 afact.resize (m, m);
78
79 double *tmp_data = A_fact.fortran_vec ();
80 67
81 MArray<octave_idx_type> jpvt (n, 0); 68 MArray<octave_idx_type> jpvt (n, 0);
82 octave_idx_type *pjpvt = jpvt.fortran_vec ();
83 69
84 double rlwork = 0; 70 if (m > 0)
85 // Workspace query... 71 {
86 F77_XFCN (dgeqp3, DGEQP3, (m, n, tmp_data, m, pjpvt, ptau, &rlwork, -1, info)); 72 // workspace query.
73 double rlwork;
74 F77_XFCN (dgeqp3, DGEQP3, (m, n, afact.fortran_vec (), m, jpvt.fortran_vec (),
75 tau, &rlwork, -1, info));
87 76
88 octave_idx_type lwork = rlwork; 77 // allocate buffer and do the job.
89 Array<double> work (lwork); 78 octave_idx_type lwork = rlwork; lwork = std::max (lwork, 1);
90 double *pwork = work.fortran_vec (); 79 OCTAVE_LOCAL_BUFFER (double, work, lwork);
91 80 F77_XFCN (dgeqp3, DGEQP3, (m, n, afact.fortran_vec (), m, jpvt.fortran_vec (),
92 // Code to enforce a certain permutation could go here... 81 tau, work, lwork, info));
93 82 }
94 F77_XFCN (dgeqp3, DGEQP3, (m, n, tmp_data, m, pjpvt, ptau, pwork, lwork, info)); 83 else
84 for (octave_idx_type i = 0; i < n; i++) jpvt(i) = i+1;
95 85
96 // Form Permutation matrix (if economy is requested, return the 86 // Form Permutation matrix (if economy is requested, return the
97 // indices only!) 87 // indices only!)
98 88
99 jpvt -= 1; 89 jpvt -= 1;
100 p = PermMatrix (jpvt, true); 90 p = PermMatrix (jpvt, true);
101 91
102 octave_idx_type n2 = (qr_type == QR::economy) ? min_mn : m;
103 92
104 if (qr_type == QR::economy && m > n) 93 form (n, afact, tau, qr_type);
105 r.resize (n, n, 0.0);
106 else
107 r.resize (m, n, 0.0);
108
109 for (octave_idx_type j = 0; j < n; j++)
110 {
111 octave_idx_type limit = j < min_mn-1 ? j : min_mn-1;
112 for (octave_idx_type i = 0; i <= limit; i++)
113 r.elem (i, j) = A_fact.elem (i, j);
114 }
115
116 F77_XFCN (dorgqr, DORGQR, (m, n2, min_mn, tmp_data, m, ptau,
117 pwork, lwork, info));
118
119 q = A_fact;
120 q.resize (m, n2);
121 } 94 }
122 95
123 ColumnVector 96 ColumnVector
124 QRP::Pvec (void) const 97 QRP::Pvec (void) const
125 { 98 {