diff liboctave/dbleQR.cc @ 7553:56be6f31dd4e

implementation of QR factorization updating
author Jaroslav Hajek <highegg@gmail.com>
date Tue, 04 Mar 2008 21:47:11 -0500
parents 29980c6b8604
children 40574114c514
line wrap: on
line diff
--- a/liboctave/dbleQR.cc	Tue Mar 04 17:01:05 2008 -0500
+++ b/liboctave/dbleQR.cc	Tue Mar 04 21:47:11 2008 -0500
@@ -21,6 +21,8 @@
 
 */
 
+// updating/downdating by Jaroslav Hajek 2008
+
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
@@ -28,6 +30,8 @@
 #include "dbleQR.h"
 #include "f77-fcn.h"
 #include "lo-error.h"
+#include "Range.h"
+#include "idx-vector.h"
 
 extern "C"
 {
@@ -38,6 +42,30 @@
   F77_RET_T
   F77_FUNC (dorgqr, DORGQR) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, double*,
 			     const octave_idx_type&, double*, double*, const octave_idx_type&, octave_idx_type&);
+
+  // these come from qrupdate
+
+  F77_RET_T
+  F77_FUNC (dqr1up, DQR1UP) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, 
+                             double*, double*, const double*, const double*);
+
+  F77_RET_T
+  F77_FUNC (dqrinc, DQRINC) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, 
+                             double*, const double*, double*, const octave_idx_type&, const double*);
+
+  F77_RET_T
+  F77_FUNC (dqrdec, DQRDEC) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, 
+                             double*, const double*, double*, const octave_idx_type&);
+
+  F77_RET_T
+  F77_FUNC (dqrinr, DQRINR) (const octave_idx_type&, const octave_idx_type&, 
+                             const double*, double*, const double*, double*, 
+                             const octave_idx_type&, const double*);
+
+  F77_RET_T
+  F77_FUNC (dqrder, DQRDER) (const octave_idx_type&, const octave_idx_type&, 
+                             const double*, double*, const double*, double *, 
+                             const octave_idx_type&);
 }
 
 QR::QR (const Matrix& a, QR::type qr_type)
@@ -118,6 +146,140 @@
     }
 }
 
+QR::QR (const Matrix& q, const Matrix& r)
+{
+  if (q.columns () != r.rows ()) 
+    {
+      (*current_liboctave_error_handler) ("QR dimensions mismatch");
+      return;
+    }
+
+  this->q = q;
+  this->r = r;
+}
+
+void
+QR::update (const Matrix& u, const Matrix& v)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  if (u.length () == m && v.length () == n)
+    F77_XFCN (dqr1up, DQR1UP, (m, n, k, q.fortran_vec (), r.fortran_vec (), 
+			       u.data (), v.data ()));
+  else
+    (*current_liboctave_error_handler) ("QR update dimensions mismatch");
+}
+
+void
+QR::insert_col (const Matrix& u, octave_idx_type j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type n = r.columns ();
+  octave_idx_type k = q.columns ();
+
+  if (u.length () != m)
+    (*current_liboctave_error_handler) ("QR insert dimensions mismatch");
+  else if (j < 1 || j > n+1) 
+    (*current_liboctave_error_handler) ("QR insert index out of range");
+  else
+    {
+      Matrix r1 (m, n+1);
+
+      F77_XFCN (dqrinc, DQRINC, (m, n, k, q.fortran_vec (), r.data (),
+				 r1.fortran_vec (), j, u.data ()));
+
+      r = r1;
+    }
+}
+
+void
+QR::delete_col (octave_idx_type j)
+{
+  octave_idx_type m = q.rows ();
+  octave_idx_type k = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (k < m && k < n) 
+    (*current_liboctave_error_handler) ("QR delete dimensions mismatch");
+  else if (j < 1 || j > n) 
+    (*current_liboctave_error_handler) ("QR delete index out of range");
+  else
+    {
+      Matrix r1 (k, n-1);
+
+      F77_XFCN (dqrdec, DQRDEC, (m, n, k, q.fortran_vec (), r.data (),
+				 r1.fortran_vec (), j));
+
+      r = r1;
+    }
+}
+
+void
+QR::insert_row (const Matrix& u, octave_idx_type j)
+{
+  octave_idx_type m = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (! q.is_square () || u.length () != n)
+    (*current_liboctave_error_handler) ("QR insert dimensions mismatch");
+  else if (j < 1 || j > m+1) 
+    (*current_liboctave_error_handler) ("QR insert index out of range");
+  else
+    {
+      Matrix q1 (m+1, m+1);
+      Matrix r1 (m+1, n);
+
+      F77_XFCN (dqrinr, DQRINR, (m, n, q.data (), q1.fortran_vec (), 
+				 r.data (), r1.fortran_vec (), j, u.data ()));
+
+      q = q1;
+      r = r1;
+    }
+}
+
+void
+QR::delete_row (octave_idx_type j)
+{
+  octave_idx_type m = r.rows ();
+  octave_idx_type n = r.columns ();
+
+  if (! q.is_square ())
+    (*current_liboctave_error_handler) ("QR insert dimensions mismatch");
+  else if (j < 1 || j > n) 
+    (*current_liboctave_error_handler) ("QR delete index out of range");
+  else
+    {
+      Matrix q1 (m-1, m-1);
+      Matrix r1 (m-1, n);
+
+      F77_XFCN (dqrder, DQRDER, (m, n, q.data (), q1.fortran_vec (), 
+				 r.data (), r1.fortran_vec (), j ));
+
+      q = q1;
+      r = r1;
+    }
+}
+
+void
+QR::economize (void)
+{
+  idx_vector c (':'), i (Range (1, r.columns ()));
+  q = Matrix (q.index (c, i));
+  r = Matrix (r.index (i, c));
+#if 0
+  octave_idx_type r_nc = r.columns ();
+
+  if (r.rows () > r_nc)
+    {
+      q.resize (q.rows (), r_nc);
+      r.resize (r_nc, r_nc);
+    }
+#endif
+}
+
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***