floatQR.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1994-2012 John W. Eaton
00004 Copyright (C) 2008-2009 Jaroslav Hajek
00005 Copyright (C) 2009 VZLU Prague
00006 
00007 This file is part of Octave.
00008 
00009 Octave is free software; you can redistribute it and/or modify it
00010 under the terms of the GNU General Public License as published by the
00011 Free Software Foundation; either version 3 of the License, or (at your
00012 option) any later version.
00013 
00014 Octave is distributed in the hope that it will be useful, but WITHOUT
00015 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00016 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00017 for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with Octave; see the file COPYING.  If not, see
00021 <http://www.gnu.org/licenses/>.
00022 
00023 */
00024 
00025 #ifdef HAVE_CONFIG_H
00026 #include <config.h>
00027 #endif
00028 
00029 #include "floatQR.h"
00030 #include "f77-fcn.h"
00031 #include "lo-error.h"
00032 #include "Range.h"
00033 #include "idx-vector.h"
00034 #include "oct-locbuf.h"
00035 
00036 #include "base-qr.cc"
00037 
00038 template class base_qr<FloatMatrix>;
00039 
00040 extern "C"
00041 {
00042   F77_RET_T
00043   F77_FUNC (sgeqrf, SGEQRF) (const octave_idx_type&, const octave_idx_type&,
00044                              float*, const octave_idx_type&, float*, float*,
00045                              const octave_idx_type&, octave_idx_type&);
00046 
00047   F77_RET_T
00048   F77_FUNC (sorgqr, SORGQR) (const octave_idx_type&, const octave_idx_type&,
00049                              const octave_idx_type&, float*,
00050                              const octave_idx_type&, float*, float*,
00051                              const octave_idx_type&, octave_idx_type&);
00052 
00053 #ifdef HAVE_QRUPDATE
00054 
00055   F77_RET_T
00056   F77_FUNC (sqr1up, SQR1UP) (const octave_idx_type&, const octave_idx_type&,
00057                              const octave_idx_type&, float*,
00058                              const octave_idx_type&, float*,
00059                              const octave_idx_type&, float*, float*, float*);
00060 
00061   F77_RET_T
00062   F77_FUNC (sqrinc, SQRINC) (const octave_idx_type&, const octave_idx_type&,
00063                              const octave_idx_type&, float*,
00064                              const octave_idx_type&, float*,
00065                              const octave_idx_type&,
00066                              const octave_idx_type&, const float*, float*);
00067 
00068   F77_RET_T
00069   F77_FUNC (sqrdec, SQRDEC) (const octave_idx_type&, const octave_idx_type&,
00070                              const octave_idx_type&, float*,
00071                              const octave_idx_type&, float*,
00072                              const octave_idx_type&,
00073                              const octave_idx_type&, float*);
00074 
00075   F77_RET_T
00076   F77_FUNC (sqrinr, SQRINR) (const octave_idx_type&, const octave_idx_type&,
00077                              float*, const octave_idx_type&,
00078                              float*, const octave_idx_type&,
00079                              const octave_idx_type&, const float*, float*);
00080 
00081   F77_RET_T
00082   F77_FUNC (sqrder, SQRDER) (const octave_idx_type&, const octave_idx_type&,
00083                              float*, const octave_idx_type&,
00084                              float*, const octave_idx_type&,
00085                              const octave_idx_type&, float*);
00086 
00087   F77_RET_T
00088   F77_FUNC (sqrshc, SQRSHC) (const octave_idx_type&, const octave_idx_type&,
00089                              const octave_idx_type&, float*,
00090                              const octave_idx_type&, float*,
00091                              const octave_idx_type&,
00092                              const octave_idx_type&, const octave_idx_type&,
00093                              float*);
00094 
00095 #endif
00096 }
00097 
00098 FloatQR::FloatQR (const FloatMatrix& a, qr_type_t qr_type)
00099 {
00100   init (a, qr_type);
00101 }
00102 
00103 void
00104 FloatQR::init (const FloatMatrix& a, qr_type_t qr_type)
00105 {
00106   octave_idx_type m = a.rows ();
00107   octave_idx_type n = a.cols ();
00108 
00109   octave_idx_type min_mn = m < n ? m : n;
00110   OCTAVE_LOCAL_BUFFER (float, tau, min_mn);
00111 
00112   octave_idx_type info = 0;
00113 
00114   FloatMatrix afact = a;
00115   if (m > n && qr_type == qr_type_std)
00116     afact.resize (m, m);
00117 
00118   if (m > 0)
00119     {
00120       // workspace query.
00121       float rlwork;
00122       F77_XFCN (sgeqrf, SGEQRF, (m, n, afact.fortran_vec (), m, tau, &rlwork, -1, info));
00123 
00124       // allocate buffer and do the job.
00125       octave_idx_type lwork = rlwork;
00126       lwork = std::max (lwork, static_cast<octave_idx_type> (1));
00127       OCTAVE_LOCAL_BUFFER (float, work, lwork);
00128       F77_XFCN (sgeqrf, SGEQRF, (m, n, afact.fortran_vec (), m, tau, work, lwork, info));
00129     }
00130 
00131   form (n, afact, tau, qr_type);
00132 }
00133 
00134 void FloatQR::form (octave_idx_type n, FloatMatrix& afact,
00135                     float *tau, qr_type_t qr_type)
00136 {
00137   octave_idx_type m = afact.rows (), min_mn = std::min (m, n);
00138   octave_idx_type info;
00139 
00140   if (qr_type == qr_type_raw)
00141     {
00142       for (octave_idx_type j = 0; j < min_mn; j++)
00143         {
00144           octave_idx_type limit = j < min_mn - 1 ? j : min_mn - 1;
00145           for (octave_idx_type i = limit + 1; i < m; i++)
00146             afact.elem (i, j) *= tau[j];
00147         }
00148 
00149       r = afact;
00150     }
00151   else
00152     {
00153       // Attempt to minimize copying.
00154       if (m >= n)
00155         {
00156           // afact will become q.
00157           q = afact;
00158           octave_idx_type k = qr_type == qr_type_economy ? n : m;
00159           r = FloatMatrix (k, n);
00160           for (octave_idx_type j = 0; j < n; j++)
00161             {
00162               octave_idx_type i = 0;
00163               for (; i <= j; i++)
00164                 r.xelem (i, j) = afact.xelem (i, j);
00165               for (;i < k; i++)
00166                 r.xelem (i, j) = 0;
00167             }
00168           afact = FloatMatrix (); // optimize memory
00169         }
00170       else
00171         {
00172           // afact will become r.
00173           q = FloatMatrix (m, m);
00174           for (octave_idx_type j = 0; j < m; j++)
00175             for (octave_idx_type i = j + 1; i < m; i++)
00176               {
00177                 q.xelem (i, j) = afact.xelem (i, j);
00178                 afact.xelem (i, j) = 0;
00179               }
00180           r = afact;
00181         }
00182 
00183 
00184       if (m > 0)
00185         {
00186           octave_idx_type k = q.columns ();
00187           // workspace query.
00188           float rlwork;
00189           F77_XFCN (sorgqr, SORGQR, (m, k, min_mn, q.fortran_vec (), m, tau,
00190                                      &rlwork, -1, info));
00191 
00192           // allocate buffer and do the job.
00193           octave_idx_type lwork = rlwork;
00194           lwork = std::max (lwork, static_cast<octave_idx_type> (1));
00195           OCTAVE_LOCAL_BUFFER (float, work, lwork);
00196           F77_XFCN (sorgqr, SORGQR, (m, k, min_mn, q.fortran_vec (), m, tau,
00197                                      work, lwork, info));
00198         }
00199     }
00200 }
00201 
00202 #ifdef HAVE_QRUPDATE
00203 
00204 void
00205 FloatQR::update (const FloatColumnVector& u, const FloatColumnVector& v)
00206 {
00207   octave_idx_type m = q.rows ();
00208   octave_idx_type n = r.columns ();
00209   octave_idx_type k = q.columns ();
00210 
00211   if (u.length () == m && v.length () == n)
00212     {
00213       FloatColumnVector utmp = u, vtmp = v;
00214       OCTAVE_LOCAL_BUFFER (float, w, 2*k);
00215       F77_XFCN (sqr1up, SQR1UP, (m, n, k, q.fortran_vec (), m, r.fortran_vec (), k,
00216                                  utmp.fortran_vec (), vtmp.fortran_vec (), w));
00217     }
00218   else
00219     (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
00220 }
00221 
00222 void
00223 FloatQR::update (const FloatMatrix& u, const FloatMatrix& v)
00224 {
00225   octave_idx_type m = q.rows ();
00226   octave_idx_type n = r.columns ();
00227   octave_idx_type k = q.columns ();
00228 
00229   if (u.rows () == m && v.rows () == n && u.cols () == v.cols ())
00230     {
00231       OCTAVE_LOCAL_BUFFER (float, w, 2*k);
00232       for (volatile octave_idx_type i = 0; i < u.cols (); i++)
00233         {
00234           FloatColumnVector utmp = u.column (i), vtmp = v.column (i);
00235           F77_XFCN (sqr1up, SQR1UP, (m, n, k, q.fortran_vec (), m, r.fortran_vec (), k,
00236                                      utmp.fortran_vec (), vtmp.fortran_vec (), w));
00237         }
00238     }
00239   else
00240     (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
00241 }
00242 
00243 void
00244 FloatQR::insert_col (const FloatColumnVector& u, octave_idx_type j)
00245 {
00246   octave_idx_type m = q.rows ();
00247   octave_idx_type n = r.columns ();
00248   octave_idx_type k = q.columns ();
00249 
00250   if (u.length () != m)
00251     (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
00252   else if (j < 0 || j > n)
00253     (*current_liboctave_error_handler) ("qrinsert: index out of range");
00254   else
00255     {
00256       if (k < m)
00257         {
00258           q.resize (m, k+1);
00259           r.resize (k+1, n+1);
00260         }
00261       else
00262         {
00263           r.resize (k, n+1);
00264         }
00265 
00266       FloatColumnVector utmp = u;
00267       OCTAVE_LOCAL_BUFFER (float, w, k);
00268       F77_XFCN (sqrinc, SQRINC, (m, n, k, q.fortran_vec (), q.rows (),
00269                                  r.fortran_vec (), r.rows (), j + 1,
00270                                  utmp.data (), w));
00271     }
00272 }
00273 
00274 void
00275 FloatQR::insert_col (const FloatMatrix& u, const Array<octave_idx_type>& j)
00276 {
00277   octave_idx_type m = q.rows ();
00278   octave_idx_type n = r.columns ();
00279   octave_idx_type k = q.columns ();
00280 
00281   Array<octave_idx_type> jsi;
00282   Array<octave_idx_type> js = j.sort (jsi, 0, ASCENDING);
00283   octave_idx_type nj = js.length ();
00284   bool dups = false;
00285   for (octave_idx_type i = 0; i < nj - 1; i++)
00286     dups = dups && js(i) == js(i+1);
00287 
00288   if (dups)
00289     (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
00290   else if (u.length () != m || u.columns () != nj)
00291     (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
00292   else if (nj > 0 && (js(0) < 0 || js(nj-1) > n))
00293     (*current_liboctave_error_handler) ("qrinsert: index out of range");
00294   else if (nj > 0)
00295     {
00296       octave_idx_type kmax = std::min (k + nj, m);
00297       if (k < m)
00298         {
00299           q.resize (m, kmax);
00300           r.resize (kmax, n + nj);
00301         }
00302       else
00303         {
00304           r.resize (k, n + nj);
00305         }
00306 
00307       OCTAVE_LOCAL_BUFFER (float, w, kmax);
00308       for (volatile octave_idx_type i = 0; i < js.length (); i++)
00309         {
00310           octave_idx_type ii = i;
00311           FloatColumnVector utmp = u.column (jsi(i));
00312           F77_XFCN (sqrinc, SQRINC, (m, n + ii, std::min (kmax, k + ii),
00313                                      q.fortran_vec (), q.rows (),
00314                                      r.fortran_vec (), r.rows (), js(ii) + 1,
00315                                      utmp.data (), w));
00316         }
00317     }
00318 }
00319 
00320 void
00321 FloatQR::delete_col (octave_idx_type j)
00322 {
00323   octave_idx_type m = q.rows ();
00324   octave_idx_type k = r.rows ();
00325   octave_idx_type n = r.columns ();
00326 
00327   if (j < 0 || j > n-1)
00328     (*current_liboctave_error_handler) ("qrdelete: index out of range");
00329   else
00330     {
00331       OCTAVE_LOCAL_BUFFER (float, w, k);
00332       F77_XFCN (sqrdec, SQRDEC, (m, n, k, q.fortran_vec (), q.rows (),
00333                                  r.fortran_vec (), r.rows (), j + 1, w));
00334 
00335       if (k < m)
00336         {
00337           q.resize (m, k-1);
00338           r.resize (k-1, n-1);
00339         }
00340       else
00341         {
00342           r.resize (k, n-1);
00343         }
00344     }
00345 }
00346 
00347 void
00348 FloatQR::delete_col (const Array<octave_idx_type>& j)
00349 {
00350   octave_idx_type m = q.rows ();
00351   octave_idx_type n = r.columns ();
00352   octave_idx_type k = q.columns ();
00353 
00354   Array<octave_idx_type> jsi;
00355   Array<octave_idx_type> js = j.sort (jsi, 0, DESCENDING);
00356   octave_idx_type nj = js.length ();
00357   bool dups = false;
00358   for (octave_idx_type i = 0; i < nj - 1; i++)
00359     dups = dups && js(i) == js(i+1);
00360 
00361   if (dups)
00362     (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
00363   else if (nj > 0 && (js(0) > n-1 || js(nj-1) < 0))
00364     (*current_liboctave_error_handler) ("qrinsert: index out of range");
00365   else if (nj > 0)
00366     {
00367       OCTAVE_LOCAL_BUFFER (float, w, k);
00368       for (volatile octave_idx_type i = 0; i < js.length (); i++)
00369         {
00370           octave_idx_type ii = i;
00371           F77_XFCN (sqrdec, SQRDEC, (m, n - ii, k == m ? k : k - ii,
00372                                      q.fortran_vec (), q.rows (),
00373                                      r.fortran_vec (), r.rows (), js(ii) + 1, w));
00374         }
00375       if (k < m)
00376         {
00377           q.resize (m, k - nj);
00378           r.resize (k - nj, n - nj);
00379         }
00380       else
00381         {
00382           r.resize (k, n - nj);
00383         }
00384 
00385     }
00386 }
00387 
00388 void
00389 FloatQR::insert_row (const FloatRowVector& u, octave_idx_type j)
00390 {
00391   octave_idx_type m = r.rows ();
00392   octave_idx_type n = r.columns ();
00393   octave_idx_type k = std::min (m, n);
00394 
00395   if (! q.is_square () || u.length () != n)
00396     (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
00397   else if (j < 0 || j > m)
00398     (*current_liboctave_error_handler) ("qrinsert: index out of range");
00399   else
00400     {
00401       q.resize (m + 1, m + 1);
00402       r.resize (m + 1, n);
00403       FloatRowVector utmp = u;
00404       OCTAVE_LOCAL_BUFFER (float, w, k);
00405       F77_XFCN (sqrinr, SQRINR, (m, n, q.fortran_vec (), q.rows (),
00406                                  r.fortran_vec (), r.rows (),
00407                                  j + 1, utmp.fortran_vec (), w));
00408 
00409     }
00410 }
00411 
00412 void
00413 FloatQR::delete_row (octave_idx_type j)
00414 {
00415   octave_idx_type m = r.rows ();
00416   octave_idx_type n = r.columns ();
00417 
00418   if (! q.is_square ())
00419     (*current_liboctave_error_handler) ("qrdelete: dimensions mismatch");
00420   else if (j < 0 || j > m-1)
00421     (*current_liboctave_error_handler) ("qrdelete: index out of range");
00422   else
00423     {
00424       OCTAVE_LOCAL_BUFFER (float, w, 2*m);
00425       F77_XFCN (sqrder, SQRDER, (m, n, q.fortran_vec (), q.rows (),
00426                                  r.fortran_vec (), r.rows (), j + 1,
00427                                  w));
00428 
00429       q.resize (m - 1, m - 1);
00430       r.resize (m - 1, n);
00431     }
00432 }
00433 
00434 void
00435 FloatQR::shift_cols (octave_idx_type i, octave_idx_type j)
00436 {
00437   octave_idx_type m = q.rows ();
00438   octave_idx_type k = r.rows ();
00439   octave_idx_type n = r.columns ();
00440 
00441   if (i < 0 || i > n-1 || j < 0 || j > n-1)
00442     (*current_liboctave_error_handler) ("qrshift: index out of range");
00443   else
00444     {
00445       OCTAVE_LOCAL_BUFFER (float, w, 2*k);
00446       F77_XFCN (sqrshc, SQRSHC, (m, n, k,
00447                                  q.fortran_vec (), q.rows (),
00448                                  r.fortran_vec (), r.rows (),
00449                                  i + 1, j + 1, w));
00450     }
00451 }
00452 
00453 #else
00454 
00455 // Replacement update methods.
00456 
00457 void
00458 FloatQR::update (const FloatColumnVector& u, const FloatColumnVector& v)
00459 {
00460   warn_qrupdate_once ();
00461 
00462   octave_idx_type m = q.rows ();
00463   octave_idx_type n = r.columns ();
00464 
00465   if (u.length () == m && v.length () == n)
00466     {
00467       init(q*r + FloatMatrix (u) * FloatMatrix (v).transpose (), get_type ());
00468     }
00469   else
00470     (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
00471 }
00472 
00473 void
00474 FloatQR::update (const FloatMatrix& u, const FloatMatrix& v)
00475 {
00476   warn_qrupdate_once ();
00477 
00478   octave_idx_type m = q.rows ();
00479   octave_idx_type n = r.columns ();
00480 
00481   if (u.rows () == m && v.rows () == n && u.cols () == v.cols ())
00482     {
00483       init(q*r + u * v.transpose (), get_type ());
00484     }
00485   else
00486     (*current_liboctave_error_handler) ("qrupdate: dimensions mismatch");
00487 }
00488 
00489 static
00490 FloatMatrix insert_col (const FloatMatrix& a, octave_idx_type i,
00491                         const FloatColumnVector& x)
00492 {
00493   FloatMatrix retval (a.rows (), a.columns () + 1);
00494   retval.assign (idx_vector::colon, idx_vector (0, i),
00495                  a.index (idx_vector::colon, idx_vector (0, i)));
00496   retval.assign (idx_vector::colon, idx_vector (i), x);
00497   retval.assign (idx_vector::colon, idx_vector (i+1, retval.columns ()),
00498                  a.index (idx_vector::colon, idx_vector (i, a.columns ())));
00499   return retval;
00500 }
00501 
00502 static
00503 FloatMatrix insert_row (const FloatMatrix& a, octave_idx_type i,
00504                         const FloatRowVector& x)
00505 {
00506   FloatMatrix retval (a.rows () + 1, a.columns ());
00507   retval.assign (idx_vector (0, i), idx_vector::colon,
00508                  a.index (idx_vector (0, i), idx_vector::colon));
00509   retval.assign (idx_vector (i), idx_vector::colon, x);
00510   retval.assign (idx_vector (i+1, retval.rows ()), idx_vector::colon,
00511                  a.index (idx_vector (i, a.rows ()), idx_vector::colon));
00512   return retval;
00513 }
00514 
00515 static
00516 FloatMatrix delete_col (const FloatMatrix& a, octave_idx_type i)
00517 {
00518   FloatMatrix retval = a;
00519   retval.delete_elements (1, idx_vector (i));
00520   return retval;
00521 }
00522 
00523 static
00524 FloatMatrix delete_row (const FloatMatrix& a, octave_idx_type i)
00525 {
00526   FloatMatrix retval = a;
00527   retval.delete_elements (0, idx_vector (i));
00528   return retval;
00529 }
00530 
00531 static
00532 FloatMatrix shift_cols (const FloatMatrix& a,
00533                         octave_idx_type i, octave_idx_type j)
00534 {
00535   octave_idx_type n = a.columns ();
00536   Array<octave_idx_type> p (n);
00537   for (octave_idx_type k = 0; k < n; k++) p(k) = k;
00538   if (i < j)
00539     {
00540       for (octave_idx_type k = i; k < j; k++) p(k) = k+1;
00541       p(j) = i;
00542     }
00543   else if (j < i)
00544     {
00545       p(j) = i;
00546       for (octave_idx_type k = j+1; k < i+1; k++) p(k) = k-1;
00547     }
00548 
00549   return a.index (idx_vector::colon, idx_vector (p));
00550 }
00551 
00552 void
00553 FloatQR::insert_col (const FloatColumnVector& u, octave_idx_type j)
00554 {
00555   warn_qrupdate_once ();
00556 
00557   octave_idx_type m = q.rows ();
00558   octave_idx_type n = r.columns ();
00559 
00560   if (u.length () != m)
00561     (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
00562   else if (j < 0 || j > n)
00563     (*current_liboctave_error_handler) ("qrinsert: index out of range");
00564   else
00565     {
00566       init (::insert_col (q*r, j, u), get_type ());
00567     }
00568 }
00569 
00570 void
00571 FloatQR::insert_col (const FloatMatrix& u, const Array<octave_idx_type>& j)
00572 {
00573   warn_qrupdate_once ();
00574 
00575   octave_idx_type m = q.rows ();
00576   octave_idx_type n = r.columns ();
00577 
00578   Array<octave_idx_type> jsi;
00579   Array<octave_idx_type> js = j.sort (jsi, 0, ASCENDING);
00580   octave_idx_type nj = js.length ();
00581   bool dups = false;
00582   for (octave_idx_type i = 0; i < nj - 1; i++)
00583     dups = dups && js(i) == js(i+1);
00584 
00585   if (dups)
00586     (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
00587   else if (u.length () != m || u.columns () != nj)
00588     (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
00589   else if (nj > 0 && (js(0) < 0 || js(nj-1) > n))
00590     (*current_liboctave_error_handler) ("qrinsert: index out of range");
00591   else if (nj > 0)
00592     {
00593       FloatMatrix a = q*r;
00594       for (octave_idx_type i = 0; i < js.length (); i++)
00595         a = ::insert_col (a, js(i), u.column (i));
00596       init (a, get_type ());
00597     }
00598 }
00599 
00600 void
00601 FloatQR::delete_col (octave_idx_type j)
00602 {
00603   warn_qrupdate_once ();
00604 
00605   octave_idx_type m = q.rows ();
00606   octave_idx_type n = r.columns ();
00607 
00608   if (j < 0 || j > n-1)
00609     (*current_liboctave_error_handler) ("qrdelete: index out of range");
00610   else
00611     {
00612       init (::delete_col (q*r, j), get_type ());
00613     }
00614 }
00615 
00616 void
00617 FloatQR::delete_col (const Array<octave_idx_type>& j)
00618 {
00619   warn_qrupdate_once ();
00620 
00621   octave_idx_type m = q.rows ();
00622   octave_idx_type n = r.columns ();
00623 
00624   Array<octave_idx_type> jsi;
00625   Array<octave_idx_type> js = j.sort (jsi, 0, DESCENDING);
00626   octave_idx_type nj = js.length ();
00627   bool dups = false;
00628   for (octave_idx_type i = 0; i < nj - 1; i++)
00629     dups = dups && js(i) == js(i+1);
00630 
00631   if (dups)
00632     (*current_liboctave_error_handler) ("qrinsert: duplicate index detected");
00633   else if (nj > 0 && (js(0) > n-1 || js(nj-1) < 0))
00634     (*current_liboctave_error_handler) ("qrinsert: index out of range");
00635   else if (nj > 0)
00636     {
00637       FloatMatrix a = q*r;
00638       for (octave_idx_type i = 0; i < js.length (); i++)
00639         a = ::delete_col (a, js(i));
00640       init (a, get_type ());
00641     }
00642 }
00643 
00644 void
00645 FloatQR::insert_row (const FloatRowVector& u, octave_idx_type j)
00646 {
00647   warn_qrupdate_once ();
00648 
00649   octave_idx_type m = r.rows ();
00650   octave_idx_type n = r.columns ();
00651 
00652   if (! q.is_square () || u.length () != n)
00653     (*current_liboctave_error_handler) ("qrinsert: dimensions mismatch");
00654   else if (j < 0 || j > m)
00655     (*current_liboctave_error_handler) ("qrinsert: index out of range");
00656   else
00657     {
00658       init (::insert_row (q*r, j, u), get_type ());
00659     }
00660 }
00661 
00662 void
00663 FloatQR::delete_row (octave_idx_type j)
00664 {
00665   warn_qrupdate_once ();
00666 
00667   octave_idx_type m = r.rows ();
00668   octave_idx_type n = r.columns ();
00669 
00670   if (! q.is_square ())
00671     (*current_liboctave_error_handler) ("qrdelete: dimensions mismatch");
00672   else if (j < 0 || j > m-1)
00673     (*current_liboctave_error_handler) ("qrdelete: index out of range");
00674   else
00675     {
00676       init (::delete_row (q*r, j), get_type ());
00677     }
00678 }
00679 
00680 void
00681 FloatQR::shift_cols (octave_idx_type i, octave_idx_type j)
00682 {
00683   warn_qrupdate_once ();
00684 
00685   octave_idx_type m = q.rows ();
00686   octave_idx_type n = r.columns ();
00687 
00688   if (i < 0 || i > n-1 || j < 0 || j > n-1)
00689     (*current_liboctave_error_handler) ("qrshift: index out of range");
00690   else
00691     {
00692       init (::shift_cols (q*r, i, j), get_type ());
00693     }
00694 }
00695 
00696 #endif
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines