GNU Octave  4.0.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
dbleQR.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1994-2015 John W. Eaton
4 Copyright (C) 2008-2009 Jaroslav Hajek
5 Copyright (C) 2009 VZLU Prague
6 
7 This file is part of Octave.
8 
9 Octave is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13 
14 Octave is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Octave; see the file COPYING. If not, see
21 <http://www.gnu.org/licenses/>.
22 
23 */
24 
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28 
29 #include "dbleQR.h"
30 #include "f77-fcn.h"
31 #include "lo-error.h"
32 #include "Range.h"
33 #include "idx-vector.h"
34 #include "oct-locbuf.h"
35 
36 #include "base-qr.cc"
37 
38 template class base_qr<Matrix>;
39 
40 extern "C"
41 {
42  F77_RET_T
43  F77_FUNC (dgeqrf, DGEQRF) (const octave_idx_type&, const octave_idx_type&,
44  double*, const octave_idx_type&, double*,
45  double*, const octave_idx_type&,
46  octave_idx_type&);
47 
48  F77_RET_T
49  F77_FUNC (dorgqr, DORGQR) (const octave_idx_type&, const octave_idx_type&,
50  const octave_idx_type&, double*,
51  const octave_idx_type&, double*, double*,
52  const octave_idx_type&, octave_idx_type&);
53 
54 #ifdef HAVE_QRUPDATE
55 
56  F77_RET_T
57  F77_FUNC (dqr1up, DQR1UP) (const octave_idx_type&, const octave_idx_type&,
58  const octave_idx_type&, double*,
59  const octave_idx_type&, double*,
60  const octave_idx_type&, double*, double*, double*);
61 
62  F77_RET_T
63  F77_FUNC (dqrinc, DQRINC) (const octave_idx_type&, const octave_idx_type&,
64  const octave_idx_type&, double*,
65  const octave_idx_type&, double*,
66  const octave_idx_type&, const octave_idx_type&,
67  const double*, double*);
68 
69  F77_RET_T
70  F77_FUNC (dqrdec, DQRDEC) (const octave_idx_type&, const octave_idx_type&,
71  const octave_idx_type&, double*,
72  const octave_idx_type&, double*,
73  const octave_idx_type&, const octave_idx_type&,
74  double*);
75 
76  F77_RET_T
77  F77_FUNC (dqrinr, DQRINR) (const octave_idx_type&, const octave_idx_type&,
78  double*, const octave_idx_type&, double*,
79  const octave_idx_type&, const octave_idx_type&,
80  const double*, double*);
81 
82  F77_RET_T
83  F77_FUNC (dqrder, DQRDER) (const octave_idx_type&, const octave_idx_type&,
84  double*, const octave_idx_type&, double*,
85  const octave_idx_type&, const octave_idx_type&,
86  double*);
87 
88  F77_RET_T
89  F77_FUNC (dqrshc, DQRSHC) (const octave_idx_type&, const octave_idx_type&,
90  const octave_idx_type&, double*,
91  const octave_idx_type&, double*,
92  const octave_idx_type&, const octave_idx_type&,
93  const octave_idx_type&, double*);
94 
95 #endif
96 }
97 
99 
100 QR::QR (const Matrix& a, qr_type_t qr_type)
101 {
102  init (a, qr_type);
103 }
104 
105 void
106 QR::init (const Matrix& a, qr_type_t qr_type)
107 {
108  octave_idx_type m = a.rows ();
109  octave_idx_type n = a.cols ();
110 
111  octave_idx_type min_mn = m < n ? m : n;
112  OCTAVE_LOCAL_BUFFER (double, tau, min_mn);
113 
114  octave_idx_type info = 0;
115 
116  Matrix afact = a;
117  if (m > n && qr_type == qr_type_std)
118  afact.resize (m, m);
119 
120  if (m > 0)
121  {
122  // workspace query.
123  double rlwork;
124  F77_XFCN (dgeqrf, DGEQRF, (m, n, afact.fortran_vec (), m, tau,
125  &rlwork, -1, info));
126 
127  // allocate buffer and do the job.
128  octave_idx_type lwork = rlwork;
129  lwork = std::max (lwork, static_cast<octave_idx_type> (1));
130  OCTAVE_LOCAL_BUFFER (double, work, lwork);
131  F77_XFCN (dgeqrf, DGEQRF, (m, n, afact.fortran_vec (), m, tau,
132  work, lwork, info));
133  }
134 
135  form (n, afact, tau, qr_type);
136 }
137 
139  double *tau, qr_type_t qr_type)
140 {
141  octave_idx_type m = afact.rows ();
142  octave_idx_type min_mn = std::min (m, n);
143  octave_idx_type info;
144 
145  if (qr_type == qr_type_raw)
146  {
147  for (octave_idx_type j = 0; j < min_mn; j++)
148  {
149  octave_idx_type limit = j < min_mn - 1 ? j : min_mn - 1;
150  for (octave_idx_type i = limit + 1; i < m; i++)
151  afact.elem (i, j) *= tau[j];
152  }
153 
154  r = afact;
155  }
156  else
157  {
158  // Attempt to minimize copying.
159  if (m >= n)
160  {
161  // afact will become q.
162  q = afact;
163  octave_idx_type k = qr_type == qr_type_economy ? n : m;
164  r = Matrix (k, n);
165  for (octave_idx_type j = 0; j < n; j++)
166  {
167  octave_idx_type i = 0;
168  for (; i <= j; i++)
169  r.xelem (i, j) = afact.xelem (i, j);
170  for (; i < k; i++)
171  r.xelem (i, j) = 0;
172  }
173  afact = Matrix (); // optimize memory
174  }
175  else
176  {
177  // afact will become r.
178  q = Matrix (m, m);
179  for (octave_idx_type j = 0; j < m; j++)
180  for (octave_idx_type i = j + 1; i < m; i++)
181  {
182  q.xelem (i, j) = afact.xelem (i, j);
183  afact.xelem (i, j) = 0;
184  }
185  r = afact;
186  }
187 
188 
189  if (m > 0)
190  {
191  octave_idx_type k = q.columns ();
192  // workspace query.
193  double rlwork;
194  F77_XFCN (dorgqr, DORGQR, (m, k, min_mn, q.fortran_vec (), m, tau,
195  &rlwork, -1, info));
196 
197  // allocate buffer and do the job.
198  octave_idx_type lwork = rlwork;
199  lwork = std::max (lwork, static_cast<octave_idx_type> (1));
200  OCTAVE_LOCAL_BUFFER (double, work, lwork);
201  F77_XFCN (dorgqr, DORGQR, (m, k, min_mn, q.fortran_vec (), m, tau,
202  work, lwork, info));
203  }
204  }
205 }
206 
207 #ifdef HAVE_QRUPDATE
208 
209 void
211 {
212  octave_idx_type m = q.rows ();
213  octave_idx_type n = r.columns ();
214  octave_idx_type k = q.columns ();
215 
216  if (u.length () == m && v.length () == n)
217  {
218  ColumnVector utmp = u;
219  ColumnVector vtmp = v;
220  OCTAVE_LOCAL_BUFFER (double, w, 2*k);
221  F77_XFCN (dqr1up, DQR1UP, (m, n, k, q.fortran_vec (),
222  m, r.fortran_vec (), k,
223  utmp.fortran_vec (), vtmp.fortran_vec (), w));
224  }
225  else
226  (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
227 }
228 
229 void
230 QR::update (const Matrix& u, const Matrix& v)
231 {
232  octave_idx_type m = q.rows ();
233  octave_idx_type n = r.columns ();
234  octave_idx_type k = q.columns ();
235 
236  if (u.rows () == m && v.rows () == n && u.cols () == v.cols ())
237  {
238  OCTAVE_LOCAL_BUFFER (double, w, 2*k);
239  for (volatile octave_idx_type i = 0; i < u.cols (); i++)
240  {
241  ColumnVector utmp = u.column (i);
242  ColumnVector vtmp = v.column (i);
243  F77_XFCN (dqr1up, DQR1UP, (m, n, k, q.fortran_vec (),
244  m, r.fortran_vec (), k,
245  utmp.fortran_vec (), vtmp.fortran_vec (),
246  w));
247  }
248  }
249  else
250  (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
251 }
252 
253 void
255 {
256  octave_idx_type m = q.rows ();
257  octave_idx_type n = r.columns ();
258  octave_idx_type k = q.columns ();
259 
260  if (u.length () != m)
261  (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
262  else if (j < 0 || j > n)
263  (*current_liboctave_error_handler) ("qrinsert: index out of range");
264  else
265  {
266  if (k < m)
267  {
268  q.resize (m, k+1);
269  r.resize (k+1, n+1);
270  }
271  else
272  {
273  r.resize (k, n+1);
274  }
275 
276  ColumnVector utmp = u;
277  OCTAVE_LOCAL_BUFFER (double, w, k);
278  F77_XFCN (dqrinc, DQRINC, (m, n, k, q.fortran_vec (), q.rows (),
279  r.fortran_vec (), r.rows (), j + 1,
280  utmp.data (), w));
281  }
282 }
283 
284 void
286 {
287  octave_idx_type m = q.rows ();
288  octave_idx_type n = r.columns ();
289  octave_idx_type k = q.columns ();
290 
292  Array<octave_idx_type> js = j.sort (jsi, 0, ASCENDING);
293  octave_idx_type nj = js.length ();
294  bool dups = false;
295  for (octave_idx_type i = 0; i < nj - 1; i++)
296  dups = dups && js(i) == js(i+1);
297 
298  if (dups)
299  (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
300  else if (u.length () != m || u.columns () != nj)
301  (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
302  else if (nj > 0 && (js(0) < 0 || js(nj-1) > n))
303  (*current_liboctave_error_handler) ("qrinsert: index out of range");
304  else if (nj > 0)
305  {
306  octave_idx_type kmax = std::min (k + nj, m);
307  if (k < m)
308  {
309  q.resize (m, kmax);
310  r.resize (kmax, n + nj);
311  }
312  else
313  {
314  r.resize (k, n + nj);
315  }
316 
317  OCTAVE_LOCAL_BUFFER (double, w, kmax);
318  for (volatile octave_idx_type i = 0; i < js.length (); i++)
319  {
320  octave_idx_type ii = i;
321  ColumnVector utmp = u.column (jsi(i));
322  F77_XFCN (dqrinc, DQRINC, (m, n + ii, std::min (kmax, k + ii),
323  q.fortran_vec (), q.rows (),
324  r.fortran_vec (), r.rows (), js(ii) + 1,
325  utmp.data (), w));
326  }
327  }
328 }
329 
330 void
332 {
333  octave_idx_type m = q.rows ();
334  octave_idx_type k = r.rows ();
335  octave_idx_type n = r.columns ();
336 
337  if (j < 0 || j > n-1)
338  (*current_liboctave_error_handler) ("qrdelete: index out of range");
339  else
340  {
341  OCTAVE_LOCAL_BUFFER (double, w, k);
342  F77_XFCN (dqrdec, DQRDEC, (m, n, k, q.fortran_vec (), q.rows (),
343  r.fortran_vec (), r.rows (), j + 1, w));
344 
345  if (k < m)
346  {
347  q.resize (m, k-1);
348  r.resize (k-1, n-1);
349  }
350  else
351  {
352  r.resize (k, n-1);
353  }
354  }
355 }
356 
357 void
359 {
360  octave_idx_type m = q.rows ();
361  octave_idx_type n = r.columns ();
362  octave_idx_type k = q.columns ();
363 
365  Array<octave_idx_type> js = j.sort (jsi, 0, DESCENDING);
366  octave_idx_type nj = js.length ();
367  bool dups = false;
368  for (octave_idx_type i = 0; i < nj - 1; i++)
369  dups = dups && js(i) == js(i+1);
370 
371  if (dups)
372  (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
373  else if (nj > 0 && (js(0) > n-1 || js(nj-1) < 0))
374  (*current_liboctave_error_handler) ("qrinsert: index out of range");
375  else if (nj > 0)
376  {
377  OCTAVE_LOCAL_BUFFER (double, w, k);
378  for (volatile octave_idx_type i = 0; i < js.length (); i++)
379  {
380  octave_idx_type ii = i;
381  F77_XFCN (dqrdec, DQRDEC, (m, n - ii, k == m ? k : k - ii,
382  q.fortran_vec (), q.rows (),
383  r.fortran_vec (), r.rows (),
384  js(ii) + 1, w));
385  }
386  if (k < m)
387  {
388  q.resize (m, k - nj);
389  r.resize (k - nj, n - nj);
390  }
391  else
392  {
393  r.resize (k, n - nj);
394  }
395 
396  }
397 }
398 
399 void
401 {
402  octave_idx_type m = r.rows ();
403  octave_idx_type n = r.columns ();
404  octave_idx_type k = std::min (m, n);
405 
406  if (! q.is_square () || u.length () != n)
407  (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
408  else if (j < 0 || j > m)
409  (*current_liboctave_error_handler) ("qrinsert: index out of range");
410  else
411  {
412  q.resize (m + 1, m + 1);
413  r.resize (m + 1, n);
414  RowVector utmp = u;
415  OCTAVE_LOCAL_BUFFER (double, w, k);
416  F77_XFCN (dqrinr, DQRINR, (m, n, q.fortran_vec (), q.rows (),
417  r.fortran_vec (), r.rows (),
418  j + 1, utmp.fortran_vec (), w));
419 
420  }
421 }
422 
423 void
425 {
426  octave_idx_type m = r.rows ();
427  octave_idx_type n = r.columns ();
428 
429  if (! q.is_square ())
430  (*current_liboctave_error_handler) ("qrdelete: dimensions mismatch");
431  else if (j < 0 || j > m-1)
432  (*current_liboctave_error_handler) ("qrdelete: index out of range");
433  else
434  {
435  OCTAVE_LOCAL_BUFFER (double, w, 2*m);
436  F77_XFCN (dqrder, DQRDER, (m, n, q.fortran_vec (), q.rows (),
437  r.fortran_vec (), r.rows (), j + 1,
438  w));
439 
440  q.resize (m - 1, m - 1);
441  r.resize (m - 1, n);
442  }
443 }
444 
445 void
447 {
448  octave_idx_type m = q.rows ();
449  octave_idx_type k = r.rows ();
450  octave_idx_type n = r.columns ();
451 
452  if (i < 0 || i > n-1 || j < 0 || j > n-1)
453  (*current_liboctave_error_handler) ("qrshift: index out of range");
454  else
455  {
456  OCTAVE_LOCAL_BUFFER (double, w, 2*k);
457  F77_XFCN (dqrshc, DQRSHC, (m, n, k,
458  q.fortran_vec (), q.rows (),
459  r.fortran_vec (), r.rows (),
460  i + 1, j + 1, w));
461  }
462 }
463 
464 #else
465 
466 // Replacement update methods.
467 
468 void
469 QR::update (const ColumnVector& u, const ColumnVector& v)
470 {
471  warn_qrupdate_once ();
472 
473  octave_idx_type m = q.rows ();
474  octave_idx_type n = r.columns ();
475 
476  if (u.length () == m && v.length () == n)
477  {
478  init (q*r + Matrix (u) * Matrix (v).transpose (), get_type ());
479  }
480  else
481  (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
482 }
483 
484 void
485 QR::update (const Matrix& u, const Matrix& v)
486 {
487  warn_qrupdate_once ();
488 
489  octave_idx_type m = q.rows ();
490  octave_idx_type n = r.columns ();
491 
492  if (u.rows () == m && v.rows () == n && u.cols () == v.cols ())
493  {
494  init (q*r + u * v.transpose (), get_type ());
495  }
496  else
497  (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
498 }
499 
500 static
501 Matrix insert_col (const Matrix& a, octave_idx_type i,
502  const ColumnVector& x)
503 {
504  Matrix retval (a.rows (), a.columns () + 1);
505  retval.assign (idx_vector::colon, idx_vector (0, i),
506  a.index (idx_vector::colon, idx_vector (0, i)));
507  retval.assign (idx_vector::colon, idx_vector (i), x);
508  retval.assign (idx_vector::colon, idx_vector (i+1, retval.columns ()),
509  a.index (idx_vector::colon, idx_vector (i, a.columns ())));
510  return retval;
511 }
512 
513 static
514 Matrix insert_row (const Matrix& a, octave_idx_type i,
515  const RowVector& x)
516 {
517  Matrix retval (a.rows () + 1, a.columns ());
518  retval.assign (idx_vector (0, i), idx_vector::colon,
519  a.index (idx_vector (0, i), idx_vector::colon));
520  retval.assign (idx_vector (i), idx_vector::colon, x);
521  retval.assign (idx_vector (i+1, retval.rows ()), idx_vector::colon,
522  a.index (idx_vector (i, a.rows ()), idx_vector::colon));
523  return retval;
524 }
525 
526 static
527 Matrix delete_col (const Matrix& a, octave_idx_type i)
528 {
529  Matrix retval = a;
530  retval.delete_elements (1, idx_vector (i));
531  return retval;
532 }
533 
534 static
535 Matrix delete_row (const Matrix& a, octave_idx_type i)
536 {
537  Matrix retval = a;
538  retval.delete_elements (0, idx_vector (i));
539  return retval;
540 }
541 
542 static
543 Matrix shift_cols (const Matrix& a,
545 {
546  octave_idx_type n = a.columns ();
548  for (octave_idx_type k = 0; k < n; k++) p(k) = k;
549  if (i < j)
550  {
551  for (octave_idx_type k = i; k < j; k++) p(k) = k+1;
552  p(j) = i;
553  }
554  else if (j < i)
555  {
556  p(j) = i;
557  for (octave_idx_type k = j+1; k < i+1; k++) p(k) = k-1;
558  }
559 
560  return a.index (idx_vector::colon, idx_vector (p));
561 }
562 
563 void
565 {
566  warn_qrupdate_once ();
567 
568  octave_idx_type m = q.rows ();
569  octave_idx_type n = r.columns ();
570 
571  if (u.length () != m)
572  (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
573  else if (j < 0 || j > n)
574  (*current_liboctave_error_handler) ("qrinsert: index out of range");
575  else
576  {
577  init (::insert_col (q*r, j, u), get_type ());
578  }
579 }
580 
581 void
582 QR::insert_col (const Matrix& u, const Array<octave_idx_type>& j)
583 {
584  warn_qrupdate_once ();
585 
586  octave_idx_type m = q.rows ();
587  octave_idx_type n = r.columns ();
588 
590  Array<octave_idx_type> js = j.sort (jsi, 0, ASCENDING);
591  octave_idx_type nj = js.length ();
592  bool dups = false;
593  for (octave_idx_type i = 0; i < nj - 1; i++)
594  dups = dups && js(i) == js(i+1);
595 
596  if (dups)
597  (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
598  else if (u.length () != m || u.columns () != nj)
599  (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
600  else if (nj > 0 && (js(0) < 0 || js(nj-1) > n))
601  (*current_liboctave_error_handler) ("qrinsert: index out of range");
602  else if (nj > 0)
603  {
604  Matrix a = q*r;
605  for (octave_idx_type i = 0; i < js.length (); i++)
606  a = ::insert_col (a, js(i), u.column (i));
607  init (a, get_type ());
608  }
609 }
610 
611 void
613 {
614  warn_qrupdate_once ();
615 
616  octave_idx_type n = r.columns ();
617 
618  if (j < 0 || j > n-1)
619  (*current_liboctave_error_handler) ("qrdelete: index out of range");
620  else
621  {
622  init (::delete_col (q*r, j), get_type ());
623  }
624 }
625 
626 void
628 {
629  warn_qrupdate_once ();
630 
631  octave_idx_type n = r.columns ();
632 
634  Array<octave_idx_type> js = j.sort (jsi, 0, DESCENDING);
635  octave_idx_type nj = js.length ();
636  bool dups = false;
637  for (octave_idx_type i = 0; i < nj - 1; i++)
638  dups = dups && js(i) == js(i+1);
639 
640  if (dups)
641  (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
642  else if (nj > 0 && (js(0) > n-1 || js(nj-1) < 0))
643  (*current_liboctave_error_handler) ("qrinsert: index out of range");
644  else if (nj > 0)
645  {
646  Matrix a = q*r;
647  for (octave_idx_type i = 0; i < js.length (); i++)
648  a = ::delete_col (a, js(i));
649  init (a, get_type ());
650  }
651 }
652 
653 void
655 {
656  warn_qrupdate_once ();
657 
658  octave_idx_type m = r.rows ();
659  octave_idx_type n = r.columns ();
660 
661  if (! q.is_square () || u.length () != n)
662  (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
663  else if (j < 0 || j > m)
664  (*current_liboctave_error_handler) ("qrinsert: index out of range");
665  else
666  {
667  init (::insert_row (q*r, j, u), get_type ());
668  }
669 }
670 
671 void
673 {
674  octave_idx_type m = r.rows ();
675 
676  if (! q.is_square ())
677  (*current_liboctave_error_handler) ("qrdelete: dimensions mismatch");
678  else if (j < 0 || j > m-1)
679  (*current_liboctave_error_handler) ("qrdelete: index out of range");
680  else
681  {
682  init (::delete_row (q*r, j), get_type ());
683  }
684 }
685 
686 void
688 {
689  warn_qrupdate_once ();
690 
691  octave_idx_type n = r.columns ();
692 
693  if (i < 0 || i > n-1 || j < 0 || j > n-1)
694  (*current_liboctave_error_handler) ("qrshift: index out of range");
695  else
696  {
697  init (::shift_cols (q*r, i, j), get_type ());
698  }
699 }
700 
701 void warn_qrupdate_once (void)
702 {
703  static bool warned = false;
704  if (! warned)
705  {
706  (*current_liboctave_warning_with_id_handler)
707  ("Octave:missing-dependency",
708  "In this version of Octave, QR & Cholesky updating routines "
709  "simply update the matrix and recalculate factorizations. "
710  "To use fast algorithms, link Octave with the qrupdate library. "
711  "See <http://sourceforge.net/projects/qrupdate>.");
712 
713  warned = true;
714  }
715 }
716 
717 #endif
void insert_col(const ColumnVector &u, octave_idx_type j)
Definition: dbleQR.cc:254
void delete_row(octave_idx_type j)
Definition: dbleQR.cc:424
static const type std
Definition: dbleQR.h:43
void resize(octave_idx_type nr, octave_idx_type nc, double rfv=0)
Definition: dMatrix.h:130
static const idx_vector colon
Definition: idx-vector.h:492
F77_RET_T F77_FUNC(dgeqrf, DGEQRF)(const octave_idx_type &
void delete_elements(const idx_vector &i)
Deleting elements.
Definition: Array.cc:1393
QR(void)
Definition: dbleQR.h:47
static void transpose(octave_idx_type N, const octave_idx_type *ridx, const octave_idx_type *cidx, octave_idx_type *ridx2, octave_idx_type *cidx2)
Definition: symrcm.cc:382
static const type raw
Definition: dbleQR.h:44
T & elem(octave_idx_type n)
Definition: Array.h:380
void shift_cols(octave_idx_type i, octave_idx_type j)
Definition: dbleQR.cc:446
qr_type_t get_type(void) const
#define F77_XFCN(f, F, args)
Definition: f77-fcn.h:51
void insert_row(const RowVector &u, octave_idx_type j)
Definition: dbleQR.cc:400
octave_idx_type rows(void) const
Definition: Array.h:313
liboctave_error_handler current_liboctave_error_handler
Definition: lo-error.c:38
static const type economy
Definition: dbleQR.h:45
Array< T > sort(int dim=0, sortmode mode=ASCENDING) const
Definition: Array.cc:1766
std::complex< double > w(std::complex< double > z, double relerr=0)
const T * data(void) const
Definition: Array.h:479
Matrix transpose(void) const
Definition: dMatrix.h:114
qr_type_t
Definition: base-qr.h:30
bool is_square(void) const
Definition: Array.h:470
void init(const Matrix &, qr_type_t)
Definition: dbleQR.cc:106
#define F77_RET_T
Definition: f77-fcn.h:264
Definition: dMatrix.h:35
T & xelem(octave_idx_type n)
Definition: Array.h:353
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:233
octave_idx_type length(void) const
Number of elements in the array.
Definition: Array.h:267
ColumnVector column(octave_idx_type i) const
Definition: dMatrix.cc:645
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition: oct-locbuf.h:197
void assign(const idx_vector &i, const Array< T > &rhs, const T &rfv)
Indexed assignment (always with resize & fill).
Definition: Array.cc:1140
const T * fortran_vec(void) const
Definition: Array.h:481
octave_idx_type cols(void) const
Definition: Array.h:321
void delete_col(octave_idx_type j)
Definition: dbleQR.cc:331
void update(const ColumnVector &u, const ColumnVector &v)
Definition: dbleQR.cc:210
octave_idx_type columns(void) const
Definition: Array.h:322
void form(octave_idx_type n, Matrix &afact, double *tau, qr_type_t qr_type)
Definition: dbleQR.cc:138
Array< T > index(const idx_vector &i) const
Indexing without resizing.
Definition: Array.cc:716
F77_RET_T const double * x
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:210