GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
qrp.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1994-2018 John W. Eatonn
4 Copyright (C) 2009 VZLU Prague
5 
6 This file is part of Octave.
7 
8 Octave is free software: you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, see
20 <https://www.gnu.org/licenses/>.
21 
22 */
23 
24 #if defined (HAVE_CONFIG_H)
25 # include "config.h"
26 #endif
27 
28 #include <cassert>
29 
30 #include <algorithm>
31 
32 #include "Array.h"
33 #include "CMatrix.h"
34 #include "MArray.h"
35 #include "dMatrix.h"
36 #include "dRowVector.h"
37 #include "fCMatrix.h"
38 #include "fMatrix.h"
39 #include "fRowVector.h"
40 #include "lo-lapack-proto.h"
41 #include "oct-locbuf.h"
42 #include "qrp.h"
43 
44 namespace octave
45 {
46  namespace math
47  {
48  // Specialization.
49 
50  template <>
51  void
53  {
54  assert (qr_type != qr<Matrix>::raw);
55 
56  F77_INT m = to_f77_int (a.rows ());
57  F77_INT n = to_f77_int (a.cols ());
58 
59  F77_INT min_mn = (m < n ? m : n);
60  OCTAVE_LOCAL_BUFFER (double, tau, min_mn);
61 
62  F77_INT info = 0;
63 
64  Matrix afact = a;
65  if (m > n && qr_type == qr<Matrix>::std)
66  afact.resize (m, m);
67 
68  MArray<F77_INT> jpvt (dim_vector (n, 1), 0);
69 
70  if (m > 0)
71  {
72  // workspace query.
73  double rlwork;
74  F77_XFCN (dgeqp3, DGEQP3, (m, n, afact.fortran_vec (),
75  m, jpvt.fortran_vec (), tau,
76  &rlwork, -1, info));
77 
78  // allocate buffer and do the job.
79  F77_INT lwork = static_cast<F77_INT> (rlwork);
80  lwork = std::max (lwork, static_cast<F77_INT> (1));
81  OCTAVE_LOCAL_BUFFER (double, work, lwork);
82 
83  F77_XFCN (dgeqp3, DGEQP3, (m, n, afact.fortran_vec (),
84  m, jpvt.fortran_vec (), tau,
85  work, lwork, info));
86  }
87  else
88  {
89  for (F77_INT i = 0; i < n; i++)
90  jpvt(i) = i+1;
91  }
92 
93  // Form Permutation matrix (if economy is requested, return the
94  // indices only!)
95 
96  jpvt -= static_cast<F77_INT> (1);
97  p = PermMatrix (jpvt, true);
98 
99  form (n, afact, tau, qr_type);
100  }
101 
102  template <>
104  : qr<Matrix> (), p ()
105  {
106  init (a, qr_type);
107  }
108 
109  template <>
110  RowVector
111  qrp<Matrix>::Pvec (void) const
112  {
113  Array<double> pa (p.col_perm_vec ());
114  RowVector pv (MArray<double> (pa) + 1.0);
115  return pv;
116  }
117 
118  template <>
119  void
121  {
122  assert (qr_type != qr<FloatMatrix>::raw);
123 
124  F77_INT m = to_f77_int (a.rows ());
125  F77_INT n = to_f77_int (a.cols ());
126 
127  F77_INT min_mn = (m < n ? m : n);
128  OCTAVE_LOCAL_BUFFER (float, tau, min_mn);
129 
130  F77_INT info = 0;
131 
132  FloatMatrix afact = a;
133  if (m > n && qr_type == qr<FloatMatrix>::std)
134  afact.resize (m, m);
135 
136  MArray<F77_INT> jpvt (dim_vector (n, 1), 0);
137 
138  if (m > 0)
139  {
140  // workspace query.
141  float rlwork;
142  F77_XFCN (sgeqp3, SGEQP3, (m, n, afact.fortran_vec (),
143  m, jpvt.fortran_vec (), tau,
144  &rlwork, -1, info));
145 
146  // allocate buffer and do the job.
147  F77_INT lwork = static_cast<F77_INT> (rlwork);
148  lwork = std::max (lwork, static_cast<F77_INT> (1));
149  OCTAVE_LOCAL_BUFFER (float, work, lwork);
150 
151  F77_XFCN (sgeqp3, SGEQP3, (m, n, afact.fortran_vec (),
152  m, jpvt.fortran_vec (), tau,
153  work, lwork, info));
154  }
155  else
156  {
157  for (F77_INT i = 0; i < n; i++)
158  jpvt(i) = i+1;
159  }
160 
161  // Form Permutation matrix (if economy is requested, return the
162  // indices only!)
163 
164  jpvt -= static_cast<F77_INT> (1);
165  p = PermMatrix (jpvt, true);
166 
167  form (n, afact, tau, qr_type);
168  }
169 
170  template <>
172  : qr<FloatMatrix> (), p ()
173  {
174  init (a, qr_type);
175  }
176 
177  template <>
180  {
181  Array<float> pa (p.col_perm_vec ());
182  FloatRowVector pv (MArray<float> (pa) + 1.0f);
183  return pv;
184  }
185 
186  template <>
187  void
189  {
190  assert (qr_type != qr<ComplexMatrix>::raw);
191 
192  F77_INT m = to_f77_int (a.rows ());
193  F77_INT n = to_f77_int (a.cols ());
194 
195  F77_INT min_mn = (m < n ? m : n);
196  OCTAVE_LOCAL_BUFFER (Complex, tau, min_mn);
197 
198  F77_INT info = 0;
199 
200  ComplexMatrix afact = a;
201  if (m > n && qr_type == qr<ComplexMatrix>::std)
202  afact.resize (m, m);
203 
204  MArray<F77_INT> jpvt (dim_vector (n, 1), 0);
205 
206  if (m > 0)
207  {
208  OCTAVE_LOCAL_BUFFER (double, rwork, 2*n);
209 
210  // workspace query.
211  Complex clwork;
212  F77_XFCN (zgeqp3, ZGEQP3, (m, n,
213  F77_DBLE_CMPLX_ARG (afact.fortran_vec ()),
214  m, jpvt.fortran_vec (),
215  F77_DBLE_CMPLX_ARG (tau),
216  F77_DBLE_CMPLX_ARG (&clwork),
217  -1, rwork, info));
218 
219  // allocate buffer and do the job.
220  F77_INT lwork = static_cast<F77_INT> (clwork.real ());
221  lwork = std::max (lwork, static_cast<F77_INT> (1));
222  OCTAVE_LOCAL_BUFFER (Complex, work, lwork);
223 
224  F77_XFCN (zgeqp3, ZGEQP3, (m, n,
225  F77_DBLE_CMPLX_ARG (afact.fortran_vec ()),
226  m, jpvt.fortran_vec (),
227  F77_DBLE_CMPLX_ARG (tau),
228  F77_DBLE_CMPLX_ARG (work),
229  lwork, rwork, info));
230  }
231  else
232  {
233  for (F77_INT i = 0; i < n; i++)
234  jpvt(i) = i+1;
235  }
236 
237  // Form Permutation matrix (if economy is requested, return the
238  // indices only!)
239 
240  jpvt -= static_cast<F77_INT> (1);
241  p = PermMatrix (jpvt, true);
242 
243  form (n, afact, tau, qr_type);
244  }
245 
246  template <>
248  : qr<ComplexMatrix> (), p ()
249  {
250  init (a, qr_type);
251  }
252 
253  template <>
254  RowVector
256  {
257  Array<double> pa (p.col_perm_vec ());
258  RowVector pv (MArray<double> (pa) + 1.0);
259  return pv;
260  }
261 
262  template <>
263  void
265  {
267 
268  F77_INT m = to_f77_int (a.rows ());
269  F77_INT n = to_f77_int (a.cols ());
270 
271  F77_INT min_mn = (m < n ? m : n);
272  OCTAVE_LOCAL_BUFFER (FloatComplex, tau, min_mn);
273 
274  F77_INT info = 0;
275 
276  FloatComplexMatrix afact = a;
277  if (m > n && qr_type == qr<FloatComplexMatrix>::std)
278  afact.resize (m, m);
279 
280  MArray<F77_INT> jpvt (dim_vector (n, 1), 0);
281 
282  if (m > 0)
283  {
284  OCTAVE_LOCAL_BUFFER (float, rwork, 2*n);
285 
286  // workspace query.
287  FloatComplex clwork;
288  F77_XFCN (cgeqp3, CGEQP3, (m, n,
289  F77_CMPLX_ARG (afact.fortran_vec ()),
290  m, jpvt.fortran_vec (),
291  F77_CMPLX_ARG (tau),
292  F77_CMPLX_ARG (&clwork),
293  -1, rwork, info));
294 
295  // allocate buffer and do the job.
296  F77_INT lwork = static_cast<F77_INT> (clwork.real ());
297  lwork = std::max (lwork, static_cast<F77_INT> (1));
298  OCTAVE_LOCAL_BUFFER (FloatComplex, work, lwork);
299 
300  F77_XFCN (cgeqp3, CGEQP3, (m, n,
301  F77_CMPLX_ARG (afact.fortran_vec ()),
302  m, jpvt.fortran_vec (),
303  F77_CMPLX_ARG (tau),
304  F77_CMPLX_ARG (work),
305  lwork, rwork, info));
306  }
307  else
308  {
309  for (F77_INT i = 0; i < n; i++)
310  jpvt(i) = i+1;
311  }
312 
313  // Form Permutation matrix (if economy is requested, return the
314  // indices only!)
315 
316  jpvt -= static_cast<F77_INT> (1);
317  p = PermMatrix (jpvt, true);
318 
319  form (n, afact, tau, qr_type);
320  }
321 
322  template <>
324  : qr<FloatComplexMatrix> (), p ()
325  {
326  init (a, qr_type);
327  }
328 
329  template <>
332  {
333  Array<float> pa (p.col_perm_vec ());
334  FloatRowVector pv (MArray<float> (pa) + 1.0f);
335  return pv;
336  }
337  }
338 }
void resize(octave_idx_type nr, octave_idx_type nc, const FloatComplex &rfv=FloatComplex(0))
Definition: fCMatrix.h:192
void resize(octave_idx_type nr, octave_idx_type nc, float rfv=0)
Definition: fMatrix.h:152
Template for N-dimensional array classes with like-type math operators.
Definition: MArray.h:32
qrp(void)
Definition: qrp.h:46
void resize(octave_idx_type nr, octave_idx_type nc, double rfv=0)
Definition: dMatrix.h:148
qrp(const Matrix &a, type qr_type)
Definition: qrp.cc:103
F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE * f
OCTAVE_EXPORT octave_value_list while another program execution is suspended until the graphics object the function returns immediately In the second form
Definition: graphics.cc:12177
#define F77_DBLE_CMPLX_ARG(x)
Definition: f77-fcn.h:315
const T * fortran_vec(void) const
Definition: Array.h:584
RowVector Pvec(void) const
Definition: qrp.cc:111
#define F77_XFCN(f, F, args)
Definition: f77-fcn.h:41
void init(const T &, type=qr< T >::std)
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
Definition: cellfun.cc:400
Definition: mx-defs.h:79
static octave::math::qr< T >::type qr_type(int nargout, bool economy)
Definition: qr.cc:56
idx type
Definition: ov.cc:3114
Definition: dMatrix.h:36
void init(const Matrix &a, type qr_type)
Definition: qrp.cc:52
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:227
#define F77_CMPLX_ARG(x)
Definition: f77-fcn.h:309
void resize(octave_idx_type nr, octave_idx_type nc, const Complex &rfv=Complex(0))
Definition: CMatrix.h:187
octave_f77_int_type F77_INT
Definition: f77-fcn.h:305
p
Definition: lu.cc:138
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition: oct-locbuf.h:41
for i
Definition: data.cc:5264
std::complex< float > FloatComplex
Definition: oct-cmplx.h:32
std::complex< double > Complex
Definition: oct-cmplx.h:31
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87