DenseQR relaunched in gtsam now.
parent
7d4f1ad268
commit
e83950373e
|
@ -17,10 +17,6 @@ SUBDIRS = CppUnitLite base geometry inference linear nonlinear slam . tests wrap
|
||||||
SUBLIBS = base/libbase.la geometry/libgeometry.la inference/libinference.la \
|
SUBLIBS = base/libbase.la geometry/libgeometry.la inference/libinference.la \
|
||||||
linear/liblinear.la nonlinear/libnonlinear.la slam/libslam.la
|
linear/liblinear.la nonlinear/libnonlinear.la slam/libslam.la
|
||||||
|
|
||||||
if USE_LAPACK
|
|
||||||
SUBLIBS += -L$(DenseQRLib) -lDenseQR
|
|
||||||
endif
|
|
||||||
|
|
||||||
# TODO: UFconfig, CCOLAMD, and LDL automake magic without adding or touching any file
|
# TODO: UFconfig, CCOLAMD, and LDL automake magic without adding or touching any file
|
||||||
# in those directories as to not invalidate the LGPL license
|
# in those directories as to not invalidate the LGPL license
|
||||||
# See some possibilities in
|
# See some possibilities in
|
||||||
|
|
|
@ -0,0 +1,197 @@
|
||||||
|
/*
|
||||||
|
* DenseQR.cpp
|
||||||
|
*
|
||||||
|
* Created on: Oct 19, 2010
|
||||||
|
* Author: nikai
|
||||||
|
* Description: Dense QR, inspired by Tim Davis's dense solver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <math.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "DenseQR.h"
|
||||||
|
|
||||||
|
// all the lapack functions we need here
|
||||||
|
extern "C" {
|
||||||
|
void dlarft_ (char *direct, char *storev, int *n, int *k, double *V, int *ldv, double *Tau, double *T, int *ldt) ;
|
||||||
|
void dlarfb_ (char *side, char *trans, char *direct, char *storev, int *m, int *n, int *k, double *V, int *ldv, double *T, int *ldt, double *C, int *ldc, double *Work, int *ldwork) ;
|
||||||
|
void dlarfg_ (int *n, double *alpha, double *X, int *incx, double *tau) ;
|
||||||
|
void dlarf_ (char *side, int *m, int *n, double *V, int *incv, double *tau, double *C, int *ldc, double *Work) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace gtsam {
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
/**
|
||||||
|
* LARF applies a real elementary reflector H to a real m by n matrix
|
||||||
|
* C, from either the left or the right. H is represented in the form
|
||||||
|
*/
|
||||||
|
void dlarf_wrap(long m, long n, long ldc, double *V, double tau, double *C, double *W)
|
||||||
|
{
|
||||||
|
static char left = 'L' ;
|
||||||
|
double vsave ;
|
||||||
|
if (m <= 0 || n <= 0) return ;
|
||||||
|
vsave = V [0] ; // temporarily restore unit diagonal of V
|
||||||
|
V [0] = 1 ;
|
||||||
|
int m_ = m, n_ = n, ldc_ = ldc, one = 1 ;
|
||||||
|
dlarf_ (&left, &m_, &n_, V, &one, &tau, C, &ldc_, W) ;
|
||||||
|
V [0] = vsave ; // restore V [0]
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
void dlarftb_wrap(long m, long n, long k, long ldc, long ldv, double *V, double *Tau, double *C, double *W)
|
||||||
|
{
|
||||||
|
static char direct = 'F';
|
||||||
|
static char storev = 'C';
|
||||||
|
static char side = 'L';
|
||||||
|
static char trans = 'T';
|
||||||
|
if (m <= 0 || n <= 0 || k <= 0) return ;
|
||||||
|
|
||||||
|
double *T, *Work ;
|
||||||
|
T = W ; // triangular k-by-k matrix for block reflector
|
||||||
|
Work = W + k*k ; // workspace of size n*k or m*k for larfb
|
||||||
|
|
||||||
|
// construct and apply the k-by-k upper triangular matrix T
|
||||||
|
// larft and larfb are always used "Forward" and "Columnwise"
|
||||||
|
assert (m >= k) ;
|
||||||
|
int m_ = m, n_ = n, k_ = k, ldv_ = ldv, ldc_ = ldc;
|
||||||
|
dlarft_(&direct, &storev, &m_, &k_, V, &ldv_, Tau, T, &k_) ;
|
||||||
|
// Left, Transpose, Forward, Columwise:
|
||||||
|
dlarfb_(&side, &trans, &direct, &storev, &m_, &n_, &k_, V, &ldv_,
|
||||||
|
T, &k_, C, &ldc_, Work, &n_);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
long DenseQR(long m, long n, long npiv, double tol, long ntol, long fchunk,
|
||||||
|
double *F, long *Stair, char *Rdead, double *Tau, double *W, double *wscale, double *wssq) {
|
||||||
|
double tau, wk, *V;
|
||||||
|
long k, t, g, g1, nv, k1, k2, i, t0, vzeros, mleft, nleft, vsize, minchunk, rank ;
|
||||||
|
|
||||||
|
assert (F != NULL) ;
|
||||||
|
assert (Stair != NULL) ;
|
||||||
|
assert (Rdead != NULL) ;
|
||||||
|
assert (Tau != NULL) ;
|
||||||
|
assert (W != NULL) ;
|
||||||
|
assert (m >= 0 && n >= 0) ;
|
||||||
|
|
||||||
|
npiv = max (0l, npiv) ; // npiv must be between 0 and n
|
||||||
|
npiv = min (n, npiv) ;
|
||||||
|
g1 = 0 ; // row index of first queued-up Householder
|
||||||
|
k1 = 0 ; // pending Householders are in F (g1:t, k1:k2-1)
|
||||||
|
k2 = 0 ;
|
||||||
|
V = F ; // Householder vectors start here
|
||||||
|
g = 0 ; // number of good Householders found
|
||||||
|
nv = 0 ; // number of Householder reflections queued up
|
||||||
|
vzeros = 0 ; // number of explicit zeros in queued-up H's
|
||||||
|
t = 0 ; // staircase of current column
|
||||||
|
fchunk = max (fchunk, 1l) ;
|
||||||
|
minchunk = max (4l, fchunk/4l) ;
|
||||||
|
rank = min (m,npiv) ;
|
||||||
|
ntol = min (ntol, npiv) ;
|
||||||
|
|
||||||
|
for (k = 0; k < n; k++) {
|
||||||
|
t0 = t; // t0 = staircase of column k-1
|
||||||
|
t = Stair[k]; // t = staircase of this column k
|
||||||
|
|
||||||
|
if (g >= m) {
|
||||||
|
for (; k < npiv; k++) {
|
||||||
|
Rdead[k] = 1;
|
||||||
|
Stair[k] = 0;
|
||||||
|
Tau[k] = 0;
|
||||||
|
}
|
||||||
|
for (; k < n; k++) {
|
||||||
|
Stair[k] = m;
|
||||||
|
Tau[k] = 0;
|
||||||
|
}
|
||||||
|
assert (nv == 0);
|
||||||
|
return (rank);
|
||||||
|
}
|
||||||
|
|
||||||
|
t = max(g + 1, t);
|
||||||
|
Stair[k] = t;
|
||||||
|
|
||||||
|
vzeros += nv * (t - t0);
|
||||||
|
if (nv >= minchunk) {
|
||||||
|
vsize = (nv * (nv + 1)) / 2 + nv * (t - g1 - nv);
|
||||||
|
if (vzeros > max(16l, vsize / 2)) {
|
||||||
|
dlarftb_wrap(t0 - g1, n - k2, nv, m, m, V, // F (g1:t-1, k1:k1+nv-1)
|
||||||
|
&Tau[k1], &F[g1+k2*m], W);
|
||||||
|
nv = 0;
|
||||||
|
vzeros = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find a Householder reflection that reduces column k
|
||||||
|
int n_ = t - g, one = 1;
|
||||||
|
double *X = &F[g+k*m];
|
||||||
|
dlarfg_(&n_, X, X + 1, &one, &tau);
|
||||||
|
|
||||||
|
// check to see if the kth column is OK
|
||||||
|
if (k < ntol && (wk = fabs(F[g+k*m])) <= tol) {
|
||||||
|
if (wk != 0) {
|
||||||
|
if ((*wscale) == 0) {
|
||||||
|
(*wssq) = 1;
|
||||||
|
}
|
||||||
|
if ((*wscale) < wk) {
|
||||||
|
double rr = (*wscale) / wk;
|
||||||
|
(*wssq) = 1 + (*wssq) * rr * rr;
|
||||||
|
(*wscale) = wk;
|
||||||
|
} else {
|
||||||
|
double rr = wk / (*wscale);
|
||||||
|
(*wssq) += rr * rr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// zero out F (g:m-1,k) and flag it as dead
|
||||||
|
for (i = g; i < m; i++)
|
||||||
|
F[i+k*m] = 0;
|
||||||
|
Stair[k] = 0;
|
||||||
|
Tau[k] = 0;
|
||||||
|
Rdead[k] = 1;
|
||||||
|
|
||||||
|
// apply pending block of Householder reflections
|
||||||
|
if (nv > 0) {
|
||||||
|
dlarftb_wrap(t0 - g1, n - k2, nv, m, m, V, &Tau[k1], &F[g1+k2*m], W);
|
||||||
|
nv = 0; // clear queued-up Householder reflections
|
||||||
|
vzeros = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// one more good pivot column found
|
||||||
|
Tau[k] = tau;
|
||||||
|
if (nv == 0) {
|
||||||
|
g1 = g;
|
||||||
|
k1 = k;
|
||||||
|
k2 = min(n, k + fchunk);
|
||||||
|
V = &F[g1+k1*m];
|
||||||
|
|
||||||
|
// check for switch to unblocked code
|
||||||
|
mleft = m - g1; // number of rows left
|
||||||
|
nleft = n - k1; // number of columns left
|
||||||
|
if (mleft * (nleft - (fchunk + 4)) < 5000 || mleft <= fchunk / 2
|
||||||
|
|| fchunk <= 1)
|
||||||
|
k2 = n;
|
||||||
|
}
|
||||||
|
nv++; // one more pending update; V is F (g1:t-1, k1:k1+nv-1)
|
||||||
|
|
||||||
|
// apply the kth Householder reflection to the current panel
|
||||||
|
dlarf_wrap(t - g, k2 - k - 1, m, &F[g+k*m], tau, &F[g+(k+1)*m], W);
|
||||||
|
|
||||||
|
g++; // one more pivot found
|
||||||
|
|
||||||
|
if (k == k2 - 1 || g == m) {
|
||||||
|
dlarftb_wrap(t - g1, n - k2, nv, m, m, V, &Tau[k1], &F[g1+(k2*m)], W);
|
||||||
|
nv = 0; // clear queued-up Householder reflections
|
||||||
|
vzeros = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (k == npiv - 1) rank = g;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rank;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* DenseQR.h
|
||||||
|
*
|
||||||
|
* Created on: Oct 19, 2010
|
||||||
|
* Author: nikai
|
||||||
|
* Description: Dense QR, inspired by Tim Davis's dense solver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace gtsam {
|
||||||
|
long DenseQR(
|
||||||
|
long m, // F is m-by-n with leading dimension m
|
||||||
|
long n,
|
||||||
|
long npiv, // number of pivot columns
|
||||||
|
double tol, // a column is flagged as dead if its norm is <= tol
|
||||||
|
long ntol, // apply tol only to first ntol pivot columns
|
||||||
|
long fchunk, // block size for compact WY Householder reflections,
|
||||||
|
// treated as 1 if fchunk <= 1
|
||||||
|
|
||||||
|
// input/output
|
||||||
|
double *F, // frontal matrix F of size m-by-n
|
||||||
|
long *Stair, // size n, entries F (Stair[k]:m-1, k) are all zero,
|
||||||
|
// and remain zero on output.
|
||||||
|
char *Rdead, // size npiv; all zero on input. If k is dead,
|
||||||
|
// Rdead [k] is set to 1
|
||||||
|
|
||||||
|
// output, not defined on input
|
||||||
|
double *Tau, // size n, Householder coefficients
|
||||||
|
|
||||||
|
// workspace, undefined on input and output
|
||||||
|
double *W, // size b*(n+b), where b = min (fchunk,n,m)
|
||||||
|
|
||||||
|
// input/output
|
||||||
|
double *wscale,
|
||||||
|
double *wssq
|
||||||
|
);
|
||||||
|
}
|
|
@ -10,15 +10,15 @@
|
||||||
* -------------------------------------------------------------------------- */
|
* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SPQRUtil.cpp
|
* DenseQRUtil.cpp
|
||||||
*
|
*
|
||||||
* Created on: Jul 1, 2010
|
* Created on: Jul 1, 2010
|
||||||
* Author: nikai
|
* Author: nikai
|
||||||
* Description: the utility functions for SPQR
|
* Description: the utility functions for DenseQR
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gtsam/base/timing.h>
|
#include <gtsam/base/timing.h>
|
||||||
#include <gtsam/base/SPQRUtil.h>
|
#include <gtsam/base/DenseQRUtil.h>
|
||||||
#include <boost/numeric/ublas/matrix.hpp>
|
#include <boost/numeric/ublas/matrix.hpp>
|
||||||
#include <boost/numeric/ublas/matrix_proxy.hpp>
|
#include <boost/numeric/ublas/matrix_proxy.hpp>
|
||||||
#include <boost/numeric/ublas/triangular.hpp>
|
#include <boost/numeric/ublas/triangular.hpp>
|
||||||
|
@ -99,9 +99,9 @@ namespace gtsam {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
void householder_spqr(Matrix &A, long* Stair) {
|
void householder_denseqr(Matrix &A, long* Stair) {
|
||||||
|
|
||||||
tic("householder_spqr");
|
tic("householder_denseqr");
|
||||||
|
|
||||||
long m = A.size1();
|
long m = A.size1();
|
||||||
long n = A.size2();
|
long n = A.size2();
|
||||||
|
@ -114,13 +114,13 @@ namespace gtsam {
|
||||||
Stair[j] = m;
|
Stair[j] = m;
|
||||||
}
|
}
|
||||||
|
|
||||||
tic("householder_spqr: row->col");
|
tic("householder_denseqr: row->col");
|
||||||
// convert from row major to column major
|
// convert from row major to column major
|
||||||
ublas::matrix<double, ublas::column_major> Acolwise(A);
|
ublas::matrix<double, ublas::column_major> Acolwise(A);
|
||||||
double *a = Acolwise.data().begin();
|
double *a = Acolwise.data().begin();
|
||||||
toc("householder_spqr: row->col");
|
toc("householder_denseqr: row->col");
|
||||||
|
|
||||||
tic("householder_spqr: spqr_front");
|
tic("householder_denseqr: denseqr_front");
|
||||||
long npiv = min(m,n);
|
long npiv = min(m,n);
|
||||||
double tol = -1; long ntol = -1; // no tolerance is used
|
double tol = -1; long ntol = -1; // no tolerance is used
|
||||||
long fchunk = m < 32 ? m : 32;
|
long fchunk = m < 32 ? m : 32;
|
||||||
|
@ -131,18 +131,18 @@ namespace gtsam {
|
||||||
double wscale = 0;
|
double wscale = 0;
|
||||||
double wssq = 0;
|
double wssq = 0;
|
||||||
|
|
||||||
cholmod_common cc;
|
// cholmod_common cc;
|
||||||
cholmod_l_start(&cc);
|
// cholmod_l_start(&cc);
|
||||||
|
|
||||||
// todo: do something with the rank
|
// todo: do something with the rank
|
||||||
long rank = spqr_front<double>(m, n, npiv, tol, ntol, fchunk,
|
long rank = DenseQR(m, n, npiv, tol, ntol, fchunk,
|
||||||
a, Stair, Rdead, Tau, W, &wscale, &wssq, &cc);
|
a, Stair, Rdead, Tau, W, &wscale, &wssq);
|
||||||
toc("householder_spqr: spqr_front");
|
toc("householder_denseqr: denseqr_front");
|
||||||
|
|
||||||
//#ifndef NDEBUG
|
//#ifndef NDEBUG
|
||||||
for(long j=0; j<npiv; ++j)
|
for(long j=0; j<npiv; ++j)
|
||||||
if(Rdead[j]) {
|
if(Rdead[j]) {
|
||||||
cout << "In householder_spqr, aborting because some columns were found to be\n"
|
cout << "In householder_denseqr, aborting because some columns were found to be\n"
|
||||||
"numerically linearly-dependent and we cannot handle this case yet." << endl;
|
"numerically linearly-dependent and we cannot handle this case yet." << endl;
|
||||||
print(A, "The matrix being factored was\n");
|
print(A, "The matrix being factored was\n");
|
||||||
ublas::matrix_range<ublas::matrix<double,ublas::column_major> > Acolsub(
|
ublas::matrix_range<ublas::matrix<double,ublas::column_major> > Acolsub(
|
||||||
|
@ -156,7 +156,7 @@ namespace gtsam {
|
||||||
}
|
}
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
tic("householder_spqr: col->row");
|
tic("householder_denseqr: col->row");
|
||||||
long k0 = 0;
|
long k0 = 0;
|
||||||
long j0;
|
long j0;
|
||||||
int k;
|
int k;
|
||||||
|
@ -173,24 +173,24 @@ namespace gtsam {
|
||||||
// ublas::matrix_range<Matrix> Asub(ublas::project(A, ublas::range(0, min(m,n)), ublas::range(0,n)));
|
// ublas::matrix_range<Matrix> Asub(ublas::project(A, ublas::range(0, min(m,n)), ublas::range(0,n)));
|
||||||
// ublas::noalias(Asub) = ublas::triangular_adaptor<typeof(Acolsub), ublas::upper>(Acolsub);
|
// ublas::noalias(Asub) = ublas::triangular_adaptor<typeof(Acolsub), ublas::upper>(Acolsub);
|
||||||
|
|
||||||
toc("householder_spqr: col->row");
|
toc("householder_denseqr: col->row");
|
||||||
|
|
||||||
cholmod_l_finish(&cc);
|
// cholmod_l_finish(&cc);
|
||||||
|
|
||||||
if(allocedStair) delete[] Stair;
|
if(allocedStair) delete[] Stair;
|
||||||
|
|
||||||
toc("householder_spqr");
|
toc("householder_denseqr");
|
||||||
}
|
}
|
||||||
|
|
||||||
void householder_spqr_colmajor(ublas::matrix<double, ublas::column_major>& A, long *Stair) {
|
void householder_denseqr_colmajor(ublas::matrix<double, ublas::column_major>& A, long *Stair) {
|
||||||
tic("householder_spqr");
|
tic("householder_denseqr");
|
||||||
|
|
||||||
long m = A.size1();
|
long m = A.size1();
|
||||||
long n = A.size2();
|
long n = A.size2();
|
||||||
|
|
||||||
assert(Stair != NULL);
|
assert(Stair != NULL);
|
||||||
|
|
||||||
tic("householder_spqr: spqr_front");
|
tic("householder_denseqr: denseqr_front");
|
||||||
long npiv = min(m,n);
|
long npiv = min(m,n);
|
||||||
double tol = -1; long ntol = -1; // no tolerance is used
|
double tol = -1; long ntol = -1; // no tolerance is used
|
||||||
long fchunk = m < 32 ? m : 32;
|
long fchunk = m < 32 ? m : 32;
|
||||||
|
@ -201,18 +201,18 @@ namespace gtsam {
|
||||||
double wscale = 0;
|
double wscale = 0;
|
||||||
double wssq = 0;
|
double wssq = 0;
|
||||||
|
|
||||||
cholmod_common cc;
|
// cholmod_common cc;
|
||||||
cholmod_l_start(&cc);
|
// cholmod_l_start(&cc);
|
||||||
|
|
||||||
// todo: do something with the rank
|
// todo: do something with the rank
|
||||||
long rank = spqr_front<double>(m, n, npiv, tol, ntol, fchunk,
|
long rank = DenseQR(m, n, npiv, tol, ntol, fchunk,
|
||||||
A.data().begin(), Stair, Rdead, Tau, W, &wscale, &wssq, &cc);
|
A.data().begin(), Stair, Rdead, Tau, W, &wscale, &wssq);
|
||||||
toc("householder_spqr: spqr_front");
|
toc("householder_denseqr: denseqr_front");
|
||||||
|
|
||||||
//#ifndef NDEBUG
|
//#ifndef NDEBUG
|
||||||
for(long j=0; j<npiv; ++j)
|
for(long j=0; j<npiv; ++j)
|
||||||
if(Rdead[j]) {
|
if(Rdead[j]) {
|
||||||
cout << "In householder_spqr, aborting because some columns were found to be\n"
|
cout << "In householder_denseqr, aborting because some columns were found to be\n"
|
||||||
"numerically linearly-dependent and we cannot handle this case yet." << endl;
|
"numerically linearly-dependent and we cannot handle this case yet." << endl;
|
||||||
print(A, "The matrix being factored was\n");
|
print(A, "The matrix being factored was\n");
|
||||||
ublas::matrix_range<ublas::matrix<double,ublas::column_major> > Acolsub(
|
ublas::matrix_range<ublas::matrix<double,ublas::column_major> > Acolsub(
|
||||||
|
@ -226,9 +226,9 @@ namespace gtsam {
|
||||||
}
|
}
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
cholmod_l_finish(&cc);
|
// cholmod_l_finish(&cc);
|
||||||
|
|
||||||
toc("householder_spqr");
|
toc("householder_denseqr");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,11 @@
|
||||||
* -------------------------------------------------------------------------- */
|
* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SPQRUtil.h
|
* DenseQRUtil.h
|
||||||
*
|
*
|
||||||
* Created on: Jul 1, 2010
|
* Created on: Jul 1, 2010
|
||||||
* Author: nikai
|
* Author: nikai
|
||||||
* Description: the utility functions for SPQR
|
* Description: the utility functions for DenseQR
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@ -22,16 +22,16 @@
|
||||||
#include <gtsam/base/Matrix.h>
|
#include <gtsam/base/Matrix.h>
|
||||||
|
|
||||||
#ifdef GT_USE_LAPACK
|
#ifdef GT_USE_LAPACK
|
||||||
#include <spqr_subset.hpp>
|
#include <gtsam/base/DenseQR.h>
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
|
||||||
/** make stairs and speed up householder_spqr. Stair is defined as the row index of where zero entries start in each column */
|
/** make stairs and speed up householder_denseqr. Stair is defined as the row index of where zero entries start in each column */
|
||||||
long* MakeStairs(Matrix &A);
|
long* MakeStairs(Matrix &A);
|
||||||
|
|
||||||
/** Householder tranformation, zeros below diagonal */
|
/** Householder tranformation, zeros below diagonal */
|
||||||
void householder_spqr(Matrix &A, long* Stair = NULL);
|
void householder_denseqr(Matrix &A, long* Stair = NULL);
|
||||||
|
|
||||||
void householder_spqr_colmajor(boost::numeric::ublas::matrix<double, boost::numeric::ublas::column_major>& A, long *Stair);
|
void householder_denseqr_colmajor(boost::numeric::ublas::matrix<double, boost::numeric::ublas::column_major>& A, long *Stair);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
|
@ -18,8 +18,8 @@ sources += Vector.cpp svdcmp.cpp Matrix.cpp
|
||||||
check_PROGRAMS += tests/testFixedVector tests/testVector tests/testMatrix
|
check_PROGRAMS += tests/testFixedVector tests/testVector tests/testMatrix
|
||||||
|
|
||||||
if USE_LAPACK
|
if USE_LAPACK
|
||||||
sources += SPQRUtil.cpp
|
sources += DenseQR.cpp DenseQRUtil.cpp
|
||||||
check_PROGRAMS += tests/testSPQRUtil
|
check_PROGRAMS += tests/testDenseQRUtil
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Testing
|
# Testing
|
||||||
|
@ -50,7 +50,7 @@ base_HEADERS = $(headers)
|
||||||
noinst_LTLIBRARIES = libbase.la
|
noinst_LTLIBRARIES = libbase.la
|
||||||
libbase_la_SOURCES = $(sources)
|
libbase_la_SOURCES = $(sources)
|
||||||
|
|
||||||
AM_CPPFLAGS = $(BOOST_CPPFLAGS) -I$(CCOLAMDInc) -I$(DenseQRInc) -I$(top_srcdir)/..
|
AM_CPPFLAGS = $(BOOST_CPPFLAGS) -I$(CCOLAMDInc) -I$(top_srcdir)/..
|
||||||
AM_LDFLAGS = $(BOOST_LDFLAGS)
|
AM_LDFLAGS = $(BOOST_LDFLAGS)
|
||||||
|
|
||||||
if USE_BLAS
|
if USE_BLAS
|
||||||
|
@ -76,7 +76,6 @@ endif
|
||||||
|
|
||||||
if USE_LAPACK
|
if USE_LAPACK
|
||||||
AM_CPPFLAGS += -DGT_USE_LAPACK
|
AM_CPPFLAGS += -DGT_USE_LAPACK
|
||||||
AM_LDFLAGS += -L$(DenseQRLib) -lDenseQR
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if USE_LAPACK_LINUX
|
if USE_LAPACK_LINUX
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <gtsam/CppUnitLite/TestHarness.h>
|
#include <gtsam/CppUnitLite/TestHarness.h>
|
||||||
#include <gtsam/base/SPQRUtil.h>
|
#include <gtsam/base/DenseQRUtil.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace gtsam;
|
using namespace gtsam;
|
||||||
|
@ -77,7 +77,7 @@ TEST(SPQRUtil, MakeStair2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
TEST(SPQRUtil, houseHolder_spqr)
|
TEST(SPQRUtil, houseHolder_denseqr)
|
||||||
{
|
{
|
||||||
double data[] = { -5, 0, 5, 0, 0, 0, -1,
|
double data[] = { -5, 0, 5, 0, 0, 0, -1,
|
||||||
00,-5, 0, 5, 0, 0, 1.5,
|
00,-5, 0, 5, 0, 0, 1.5,
|
||||||
|
@ -91,12 +91,12 @@ TEST(SPQRUtil, houseHolder_spqr)
|
||||||
0, 0, 0, 4.4721, 0, -4.4721, 0.894 };
|
0, 0, 0, 4.4721, 0, -4.4721, 0.894 };
|
||||||
Matrix expected1 = Matrix_(4, 7, data1);
|
Matrix expected1 = Matrix_(4, 7, data1);
|
||||||
Matrix A1 = Matrix_(4, 7, data);
|
Matrix A1 = Matrix_(4, 7, data);
|
||||||
householder_spqr(A1);
|
householder_denseqr(A1);
|
||||||
CHECK(assert_equal(expected1, A1, 1e-3));
|
CHECK(assert_equal(expected1, A1, 1e-3));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
TEST(SPQRUtil, houseHolder_spqr2)
|
TEST(SPQRUtil, houseHolder_denseqr2)
|
||||||
{
|
{
|
||||||
double data[] = { -5, 0, 5, 0, 0, 0, -1,
|
double data[] = { -5, 0, 5, 0, 0, 0, -1,
|
||||||
00,-5, 0, 5, 0, 0, 1.5,
|
00,-5, 0, 5, 0, 0, 1.5,
|
||||||
|
@ -111,13 +111,13 @@ TEST(SPQRUtil, houseHolder_spqr2)
|
||||||
Matrix expected1 = Matrix_(4, 7, data1);
|
Matrix expected1 = Matrix_(4, 7, data1);
|
||||||
Matrix A1 = Matrix_(4, 7, data);
|
Matrix A1 = Matrix_(4, 7, data);
|
||||||
long* Stair = MakeStairs(A1);
|
long* Stair = MakeStairs(A1);
|
||||||
householder_spqr(A1, Stair);
|
householder_denseqr(A1, Stair);
|
||||||
delete[] Stair;
|
delete[] Stair;
|
||||||
CHECK(assert_equal(expected1, A1, 1e-3));
|
CHECK(assert_equal(expected1, A1, 1e-3));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
TEST(SPQRUtil, houseHolder_spqr3)
|
TEST(SPQRUtil, houseHolder_denseqr3)
|
||||||
{
|
{
|
||||||
double data[] = { 1, 1, 9,
|
double data[] = { 1, 1, 9,
|
||||||
1, 0, 5};
|
1, 0, 5};
|
||||||
|
@ -127,11 +127,11 @@ TEST(SPQRUtil, houseHolder_spqr3)
|
||||||
0, -1/sqrt(2), -4/sqrt(2)};
|
0, -1/sqrt(2), -4/sqrt(2)};
|
||||||
Matrix expected1 = Matrix_(2, 3, data1);
|
Matrix expected1 = Matrix_(2, 3, data1);
|
||||||
Matrix A1 = Matrix_(2, 3, data);
|
Matrix A1 = Matrix_(2, 3, data);
|
||||||
householder_spqr(A1);
|
householder_denseqr(A1);
|
||||||
CHECK(assert_equal(expected1, A1, 1e-3));
|
CHECK(assert_equal(expected1, A1, 1e-3));
|
||||||
}
|
}
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
TEST(SPQRUtil, houseHolder_spqr4)
|
TEST(SPQRUtil, houseHolder_denseqr4)
|
||||||
{
|
{
|
||||||
Matrix A = Matrix_(15, 34,
|
Matrix A = Matrix_(15, 34,
|
||||||
-5.48351, 23.2337, -45.2073, 6.33455,-0.342553,-0.897005, 7.91126, 3.20237, -2.49219, -2.44189,-0.977376, -1.61127, -3.68421,-1.28059, -2.83303, 2.45949, 0.218835, -0.71239,-0.169314,-0.131355, 2.04233, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,-0.0782689,
|
-5.48351, 23.2337, -45.2073, 6.33455,-0.342553,-0.897005, 7.91126, 3.20237, -2.49219, -2.44189,-0.977376, -1.61127, -3.68421,-1.28059, -2.83303, 2.45949, 0.218835, -0.71239,-0.169314,-0.131355, 2.04233, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,-0.0782689,
|
||||||
|
@ -185,13 +185,13 @@ TEST(SPQRUtil, houseHolder_spqr4)
|
||||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.86199, 8.53755, -19.6873, 20.8838, 6.09985, -12.3691, -28.4341, 7.05672, 3.02888, 0.594889,-0.214789);
|
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.86199, 8.53755, -19.6873, 20.8838, 6.09985, -12.3691, -28.4341, 7.05672, 3.02888, 0.594889,-0.214789);
|
||||||
|
|
||||||
Matrix actualR = A;
|
Matrix actualR = A;
|
||||||
householder_spqr(actualR);
|
householder_denseqr(actualR);
|
||||||
|
|
||||||
long* Stair = MakeStairs(A);
|
long* Stair = MakeStairs(A);
|
||||||
CHECK(assert_equal(expectedA, A));
|
CHECK(assert_equal(expectedA, A));
|
||||||
|
|
||||||
Matrix actualRstair = A;
|
Matrix actualRstair = A;
|
||||||
householder_spqr(actualRstair, Stair);
|
householder_denseqr(actualRstair, Stair);
|
||||||
delete[] Stair;
|
delete[] Stair;
|
||||||
|
|
||||||
CHECK(assert_equal(expectedR, actualR, 1e-3));
|
CHECK(assert_equal(expectedR, actualR, 1e-3));
|
17
configure.ac
17
configure.ac
|
@ -169,21 +169,4 @@ AC_ARG_WITH([ccolamd-lib],
|
||||||
[CCOLAMDLib=${HOME}/lib])
|
[CCOLAMDLib=${HOME}/lib])
|
||||||
AC_SUBST([CCOLAMDLib])
|
AC_SUBST([CCOLAMDLib])
|
||||||
|
|
||||||
# ask for DenseQR library include directory
|
|
||||||
AC_ARG_WITH([denseqr-inc],
|
|
||||||
[AS_HELP_STRING([--with-denseqr-inc],
|
|
||||||
[specify the DenseQR library include directory (defaults to /HOME/include/DenseQR)])],
|
|
||||||
[DenseQRInc=$withval],
|
|
||||||
[DenseQRInc=${HOME}/include/DenseQR])
|
|
||||||
AC_SUBST([DenseQRInc])
|
|
||||||
|
|
||||||
# ask for DenseQR library lib directory
|
|
||||||
AC_ARG_WITH([denseqr-lib],
|
|
||||||
[AS_HELP_STRING([--with-denseqr-lib],
|
|
||||||
[specify the DenseQR library lib directory (defaults to /HOME/lib)])],
|
|
||||||
[DenseQRLib=$withval],
|
|
||||||
[DenseQRLib=${HOME}/lib])
|
|
||||||
AC_SUBST([DenseQRLib])
|
|
||||||
|
|
||||||
|
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|
|
@ -51,7 +51,7 @@ lineardir = $(pkgincludedir)/linear
|
||||||
linear_HEADERS = $(headers)
|
linear_HEADERS = $(headers)
|
||||||
noinst_LTLIBRARIES = liblinear.la
|
noinst_LTLIBRARIES = liblinear.la
|
||||||
liblinear_la_SOURCES = $(sources)
|
liblinear_la_SOURCES = $(sources)
|
||||||
AM_CPPFLAGS = $(BOOST_CPPFLAGS) -I$(CCOLAMDInc) -I$(DenseQRInc) -I$(top_srcdir)/..
|
AM_CPPFLAGS = $(BOOST_CPPFLAGS) -I$(CCOLAMDInc) -I$(top_srcdir)/..
|
||||||
AM_LDFLAGS = $(BOOST_LDFLAGS)
|
AM_LDFLAGS = $(BOOST_LDFLAGS)
|
||||||
AM_CXXFLAGS =
|
AM_CXXFLAGS =
|
||||||
|
|
||||||
|
@ -78,6 +78,5 @@ endif
|
||||||
|
|
||||||
if USE_LAPACK
|
if USE_LAPACK
|
||||||
AM_CXXFLAGS += -DGT_USE_LAPACK
|
AM_CXXFLAGS += -DGT_USE_LAPACK
|
||||||
AM_LDFLAGS += -L$(DenseQRLib) -lDenseQR
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
#include <gtsam/linear/NoiseModel.h>
|
#include <gtsam/linear/NoiseModel.h>
|
||||||
#include <gtsam/linear/SharedDiagonal.h>
|
#include <gtsam/linear/SharedDiagonal.h>
|
||||||
#include <gtsam/base/SPQRUtil.h>
|
#include <gtsam/base/DenseQRUtil.h>
|
||||||
|
|
||||||
namespace ublas = boost::numeric::ublas;
|
namespace ublas = boost::numeric::ublas;
|
||||||
typedef ublas::matrix_column<Matrix> column;
|
typedef ublas::matrix_column<Matrix> column;
|
||||||
|
@ -133,9 +133,9 @@ SharedDiagonal Gaussian::QR(Matrix& Ab, boost::optional<vector<long>&> firstZero
|
||||||
// Perform in-place Householder
|
// Perform in-place Householder
|
||||||
#ifdef GT_USE_LAPACK
|
#ifdef GT_USE_LAPACK
|
||||||
if(firstZeroRows)
|
if(firstZeroRows)
|
||||||
householder_spqr(Ab, &(*firstZeroRows)[0]);
|
householder_denseqr(Ab, &(*firstZeroRows)[0]);
|
||||||
else
|
else
|
||||||
householder_spqr(Ab);
|
householder_denseqr(Ab);
|
||||||
#else
|
#else
|
||||||
householder(Ab, maxRank);
|
householder(Ab, maxRank);
|
||||||
#endif
|
#endif
|
||||||
|
@ -156,7 +156,7 @@ SharedDiagonal Gaussian::QRColumnWise(ublas::matrix<double, ublas::column_major>
|
||||||
|
|
||||||
// Perform in-place Householder
|
// Perform in-place Householder
|
||||||
#ifdef GT_USE_LAPACK
|
#ifdef GT_USE_LAPACK
|
||||||
householder_spqr_colmajor(Ab, &firstZeroRows[0]);
|
householder_denseqr_colmajor(Ab, &firstZeroRows[0]);
|
||||||
#else
|
#else
|
||||||
householder(Ab, maxRank);
|
householder(Ab, maxRank);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue