NoseKnowsAll
NoseKnowsAll

Reputation: 4624

Errors using boost numeric bindings and lapack call to gesvd

I've done my best recently to set up boost's numeric bindings to allow me to use LAPACK from C++, but I've run into some roadblocks. First off, I have confirmed that boost is working fine, so it's something to do with my LAPACK libraries or the boost numeric bindings.

Here's a bit of code to test what I'm trying to do:

#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/bindings/lapack/gesvd.hpp>
#include <boost/numeric/bindings/traits/ublas_matrix.hpp>
//#include <boost/numeric/bindings/traits/ublas_vector2.hpp>
//#include <boost/numeric/bindings/traits/matrix_traits.hpp>

typedef boost::numeric::ublas::matrix<int> iMatrix;
typedef boost::numeric::ublas::matrix<double> dMatrix;
typedef boost::numeric::ublas::vector<int> iVector;
typedef boost::numeric::ublas::vector<double> dVector;
namespace ublas = boost::numeric::ublas;
namespace lapack = boost::numeric::bindings::lapack;

void function() {
    int n = 10;
    dMatrix jacobi(n,n); // then actually initialize it
    dVector eigenvals(n);
    dMatrix eigenvects(n);
    dVector work(n);

    int error = lapack::gesvd('N', 'A', jacobi, eigenvals, eigenvects, work);

    std::cout << eigenvals << std::endl;
}

Now while I'm not 100% correct that this code should compile when everything is set up correctly, the errors I've been getting when building don't seem to make much sense to me.

Again, I have tested that boost and ublas by itself is working fine. When I comment out the lapack::gesvd line of code, everything compiles and runs fine. As far as I can tell, these errors means that I have correctly linked LAPACK to the program (there are no unresolved symbols), and my program is able to find the correct binding files (calling lapack::gesvd returns a different error when you give it incorrect input). So I'm at a loss.

I'm on Windows 64 bit, using Eclipse, C++, boost, ublas, and LAPACK. Information about the boost numeric bindings to LAPACK can be found here: http://git.tiker.net/boost-numeric-bindings.git/blob_plain/be4a548307f3e95786acb3487e571bdffe738e4a:/libs/numeric/bindings/lapack/doc/index.html

Any advice about the overall linking/compiling process using boost numeric bindings+LAPACK would be appreciated. I honestly haven't been able to find any good examples online.

Upvotes: 0

Views: 1439

Answers (1)

NoseKnowsAll
NoseKnowsAll

Reputation: 4624

So I figured out my problem(s) -- there were several,-- and I thought I should answer my own question so that others might benefit.

First off, my LAPACK installation was incorrect. I had downloaded the 64-bit version instead of the 32-bit version. Even though it's 2015, somehow I'm stuck using a 32-bit version of the lapack dll...

Secondly, linking in Eclipse works a little differently than I thought. Going to the project properties, C/C++ Build -> Settings -> Tool Settings -> MinGW C++ Linker -> Libraries allows you to link libraries. Under the top libraries option (-l), I added lapack and blas. Under the bottom Library search path (-L), I added the location of the .dll files.

At this point, I could run sample LAPACK code, just not use the boost numeric bindings. Thirdly, I figured out what the numeric bindings traits includes were. From the traits overview page, I was able to figure out that in order to use particular vector or matrix class in bindings to LAPACK, I had to include proper traits specialization. For instance, using the boost::numeric::ublas::matrix object and sending it to LAPACK required including the trait header file <boost/numeric/bindings/traits/ublas_matrix.hpp>.

This solved my error that you see from the original post, and I could use the boost numeric bindings. Finally, I had messed up my example code because I didn't actually understand what gesvd was doing. It was just a test program, so it's no big deal, but I'll attach the working code below to show the singular value decomposition that I had initially attempted.

#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>

#include <boost/numeric/bindings/lapack/gesvd.hpp>

#include <boost/numeric/bindings/traits/ublas_matrix.hpp>
#include <boost/numeric/bindings/traits/ublas_vector.hpp>
#include <boost/numeric/bindings/traits/ublas_vector2.hpp>

typedef boost::numeric::ublas::matrix<int> iMatrix;
typedef boost::numeric::ublas::matrix<double> dMatrix;
typedef boost::numeric::ublas::vector<int> iVector;
typedef boost::numeric::ublas::vector<double> dVector;
namespace ublas = boost::numeric::ublas;
namespace lapack = boost::numeric::bindings::lapack;

void function() {
    int n = 10;
    dMatrix jacobi(n,n); // then actually initialize it
    dVector eigenvals(n);

    //int error = lapack::gesvd('S','S', jacobi, eigenvals, eigenvects1, eigenvects2);
    int error = lapack::syevd('V','L', jacobi, eigenvals, lapack::optimal_workspace() );

    std::cout << eigenvals << std::endl;
    std::cout << jacobi << std::endl;
}

Upvotes: 1

Related Questions