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