// -*-C++-*-
// Copyright (C) 2004
// Christian Stimming <stimming@tuhh.de>
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation; either version 2, or
// (at your option) any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
// You should have received a copy of the GNU Lesser General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// constructor/destructor functions
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "lafnames.h"
#include LA_GEN_QR_FACT_COMPLEX_H
#include LA_EXCEPTION_H
#include "lapackc.h"
LaGenQRFactComplex::LaGenQRFactComplex()
: _matA()
, _tau()
, _work()
{
}
LaGenQRFactComplex::LaGenQRFactComplex(LaGenMatComplex& A)
: _matA()
, _tau()
, _work()
{
decomposeQR_IP(A);
}
LaGenQRFactComplex::LaGenQRFactComplex(LaGenQRFactComplex& q)
: _matA()
, _tau()
, _work()
{
_matA.ref(q._matA);
_tau.ref(q._tau);
}
LaGenQRFactComplex::~LaGenQRFactComplex()
{
}
void LaGenQRFactComplex::decomposeQR_IP(LaGenMatComplex& A)
{
integer m = A.size(0);
integer n = A.size(1);
integer lda = A.gdim(0);
integer info = 0;
_matA.ref(A);
_tau.resize(std::min(m,n), 1);
integer lwork;
if (_work.size() >= n)
lwork = _work.size();
else
{
// Calculate the optimal temporary workspace
lwork = -1;
_work.resize(1, 1);
F77NAME(zgeqrf)(&m, &n, &_matA(0,0), &lda, &_tau(0),
&_work(0), &lwork, &info);
lwork = int(la::abs(LaComplex(_work(0))));
_work.resize(lwork, 1);
}
F77NAME(zgeqrf)(&m, &n, &_matA(0,0), &lda, &_tau(0),
&_work(0), &lwork, &info);
// this shouldn't really happen.
if (info < 0)
throw(LaException("", "Internal error in LAPACK: SGELS()"));
}
LaGenMatComplex& LaGenQRFactComplex::generateQ_IP()
{
generateQ_internal(_matA);
return _matA.shallow_assign();
}
void LaGenQRFactComplex::generateQ(LaGenMatComplex& A) const
{
A.copy(_matA);
generateQ_internal(A);
}
void LaGenQRFactComplex::generateQ_internal(LaGenMatComplex& A) const
{
integer m = A.size(0);
integer n = A.size(1);
integer k = std::max(m, n); // FIXME: correct?
integer lda = A.gdim(0);
integer info = 0;
integer lwork;
if (_work.size() >= n)
lwork = _work.size();
else
{
// Calculate the optimal temporary workspace
lwork = -1;
_work.resize(1, 1);
F77NAME(zungqr)(&m, &n, &k, &A(0,0), &lda, &_tau(0),
&_work(0), &lwork, &info);
lwork = int(la::abs(LaComplex(_work(0))));
_work.resize(lwork, 1);
}
F77NAME(zungqr)(&m, &n, &k, &A(0,0), &lda, &_tau(0),
&_work(0), &lwork, &info);
// this shouldn't really happen.
if (info < 0)
throw(LaException("", "Internal error in LAPACK: SGELS()"));
}
void LaGenQRFactComplex::Mat_Mult(LaGenMatComplex& C, bool hermitian,
bool from_left) const
{
char side = from_left ? 'L' : 'R';
char trans = hermitian ? 'C' : 'N';
integer m = C.size(0);
integer n = C.size(1);
integer k = std::max(m, n); // FIXME: correct?
integer ldc = C.gdim(0);
integer lda = _matA.gdim(0);
integer info = 0;
integer lwork;
if (_work.size() >= std::max(m,n))
lwork = _work.size();
else
{
// Calculate the optimal temporary workspace
lwork = -1;
_work.resize(1, 1);
F77NAME(zunmqr)(&side, &trans, &m, &n, &k, &_matA(0,0), &lda, &_tau(0),
&C(0,0), &ldc, &_work(0), &lwork, &info);
lwork = int(la::abs(LaComplex(_work(0))));
_work.resize(lwork, 1);
}
F77NAME(zunmqr)(&side, &trans, &m, &n, &k, &_matA(0,0), &lda, &_tau(0),
&C(0,0), &ldc, &_work(0), &lwork, &info);
// this shouldn't really happen.
if (info < 0)
throw(LaException("", "Internal error in LAPACK: SGELS()"));
}
syntax highlighted by Code2HTML, v. 0.9.1