Errors using boost numeric bindings and lapack call to gesvd - c++

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.
In file included from C:\MinGW\boost\boost_1_57_0/boost/serialization/tracking.hpp:20:0,
In file included from C:\MinGW\boost\boost_1_57_0/boost/serialization/tracking.hpp:20:0,
.............
from ..\Solver.cpp:6:
C:\MinGW\boost\boost_1_57_0/boost/numeric/bindings/traits/ublas_matrix.hpp: In instantiation of 'struct boost::numeric::bindings::traits::matrix_detail_traits, boost::numeric::ublas::matrix >':
C:\MinGW\boost\boost_1_57_0/boost/numeric/bindings/traits/matrix_traits.hpp:48:10: required from 'struct boost::numeric::bindings::traits::matrix_traits >'
C:\MinGW\boost\boost_1_57_0/boost/numeric/bindings/lapack/gesvd.hpp:167:7: required from 'int boost::numeric::bindings::lapack::gesvd(char, char, char, MatrA&, VecS&, MatrU&, MatrV&) '
C:\MinGW\boost\boost_1_57_0/boost/numeric/bindings/lapack/gesvd.hpp:477:50: required from 'int boost::numeric::bindings::lapack::gesvd(char, char, MatrA&, VecS&, MatrU&, MatrV&)'
..\Solver.cpp:85:77: required from here
C:\MinGW\boost\boost_1_57_0/boost/numeric/bindings/traits/ublas_matrix.hpp:46:5: error: invalid application of 'sizeof' to incomplete type 'boost::STATIC_ASSERTION_FAILURE'
BOOST_STATIC_ASSERT((boost::is_same<
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.

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;
}

Related

BGL: call to strong_components fails to compile when random_spanning_tree.hpp is included

This is a weird one, I was hoping to use boost::random_spanning_tree in an existing function which also calls boost::strong_components but simply including boost/graph/random_spanning_tree.hpp without otherwise modifying the code causes gcc to produce a compilation error.
The function looks something like this:
#include "boost/graph/adjacency_list.hpp"
#include "boost/graph/strong_components.hpp"
//#include "boost/graph/random_spanning_tree.hpp" // can't include this!
void foo() {
boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS> g;
// TODO: add some vertices
std::vector<unsigned> component(boost::num_vertices(g));
unsigned num = boost::strong_components(g, &component[0]);
}
and gcc complains:
error: no matching function for call to ‘get(unsigned int*&, boost::graph_traits<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS> >::vertex_descriptor&)’
if (get(comp, w) == (std::numeric_limits<comp_type>::max)())
Is the code itself flawed or is this an issue with Boost?
EDIT:
I must apologize, I have made a slight mistake in my minimal example, the code above only fails to compile on my system (Linus, g++ 8.2.1, Boost 1.67) if boost/graph/random_spanning_tree.hpp is included before boost/graph/strong_components.hpp. Using wandbox, I have found no combination of compiler / Boost version for which this does not happen.
I would file a ticket for this but Boost makes this needlessly difficult (I don't have TICKET_CREATE rights for Boost's Trac but how to obtain those is not specified anywhere).
It's no problem here: Live On Coliru
Also try
https://wandbox.org/permlink/jDIYB9oCjAP2wxHo wandbox which lets you switch compiler versions, flags and every possible boost version
Which leads me to believe it's a problem with the rest of your code/compiler config.
Are you on windows? I see max which is a MACRO in windows.h. Be sure to not include that (also check stdafx.h if you use it)
UPDATE
After your edit I was able to repro the error. That's a bug in boost, and I've created a ticket for it at the bug tracker

Unknown type name ‘vector’

I have a program written in C++, consisting of 6 classes. Somebody else, who has left, using a version of visual C++, wrote the program. However, the program has no GUIs and is supposed to run in batch mode, generating lots of data (we are talking 100,000+ ASCII files). So, we are thinking that in long term we’ll run it under UNIX.
I have a MacBook air running OS X 10.9.4 and I loaded Xcode 5.1.1
I have quickly examined the 13 files making up the source code and removed various #include "StdAfx.h" statements. Nothing else seems to be non-ANSI compliant. I tried to compile. I get 4 instances of the following error
Unknown type name ‘vector’
Indeed I have various declarations of the type
vector<VariableName*> VariableInstance
In my previous experience something like #include <vector.h> should work. However, it does not work here.
What may I be doing wrong?
normally you do
#include <vector>
then usually you'd do std::vector<blah>
however, you can put the following statement before you start using vector, but generally not recommended...
using namespace std;
and then you can do vector<blah>

Boost date/time microsec_clock not compiling correctly

I'm trying to use the date/time facilities of the C++ Boost library v1.41. (Note: this is Linux, not Windows; g++ v4.4.7)
Code:
#include <boost/date_time/posix_time/posix_time.hpp>
using boost::posix_time::ptime;
using boost::date_time::microsec_clock;
:
t1 = (boost::date_time::microsec_clock::local_time()); // line 208
The error:
tom.cpp:208: error: 'template<class time_type> class boost::date_time::microsec_clock' used without template parameters
Now, there's this in boost/date_time/posix_time/posix_time_types.hpp:
#ifdef BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
//! A time clock that has a resolution of one microsecond
/*! \ingroup time_basics
*/
typedef date_time::microsec_clock<ptime> microsec_clock;
#endif
What I'm concluding is that BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK is undefined, resulting in the typedef never happening, resulting in the reference to "microsec_clock" looking like it needed a template parameter.
As far as I can tell, I'm following the Boost date_time documentation to the letter. Any ideas?
I have the same problem right now.
Yesterday it worked without any problems but today I needed to delete all my compiled libraries and recompile them due to a svn corruption problem. Ever since this error occurred.
The way to fix it is rather simple.
Just use
t1 = (boost::posix_time::microsec_clock::local_time());
instead of
t1 = (boost::date_time::microsec_clock::local_time());
This will preset the time type to posix format however it will not fix the initial problem with BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK.
I hope this was of help to you.

Intersection_inserter was not declared in this scope

I am trying to calculate the overlap area between two ellipses. I am approximating the ellipses with polygons now and I have found an example that apparently used an old version of Boost.Geometry, as per this answer. From the second answer to this question, I can see that this is an old example as well, since some of the header files are not there in v1.53.
I have replaced those with:
#include <boost/geometry/geometries/adapted/c_array.hpp>
#include <boost/geometry/multi/multi.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
#include <boost/geometry/multi/geometries/multi_polygon.hpp>
and also added this code:
typedef boost::geometry::model::d2::point_xy<double,
boost::geometry::cs::cartesian> point_2d;
typedef boost::geometry::model::polygon<point_2d> polygon_2d;
and almost everything works. The only problem is with this:
polygon_2d poly, poly2;
typedef std::vector<polygon_2d > polygon_list;
polygon_list v;
intersection_inserter<polygon_2d >(poly2, poly, std::back_inserter(v));
I am getting an error:
intersection_inserter was not declared in this scope
expected primary expression before '>' token
The documentation of boost on the matter here is from 2009, so I guess it does not apply anymore... Their example is written the same as mine, as far as I can tell. I have found the place on the header file intersection.hpp where intersection_inserter is defined but I cannot make heads or tails of it...
I am getting the same error both in VS2012 in win7 and Qt 4.7.4 in Linux Mint 14. Any help would be greatly appreciated!
I cannot find any reference to intersection_inserter in the current boost documentation. Perhaps this functionality has been removed?
It seems that the "official" way to calculate intersections in boost::geometry is through the intersection function, as documented (with example) here

Passing an STL string to a C++ DLL from a C++/CLI app

I have a C++/CLI project using OpenCV. I compiled this version of OpenCV in VS 2010 myself and I can use it in unmanaged projects without an issue — the trouble started when I tried to use it in a managed one.
The function of interest is cv::imread(std::string&, int). Simply calling it from a managed module did not work at all, producing <invalid pointer> on the receiving end. I was sort of expecting it. After all, managed code has its own std::string implementation.
Things got a little more interesting when I created a separate C++ file, removed CLI support from its module, and placed my code in it. Now, imread was getting a valid pointer, but its contents were scrambled. Apparently, the string I was passing it contained the string pointer offset by 4 bytes, but it expected it to be at the 0 offset.
The unmanaged module is using the same CRT DLL as OpenCV and has all options set to the values appropriate for normal OpenCV use. Why would it have a different string layout? I am lost.
Sample code:
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <string>
using namespace cv;
using namespace std;
void Run()
{
string path("C:\\Users\\Don Reba\\Pictures\\Merlin 1D.jpg");
Mat image(imread(path, CV_LOAD_IMAGE_GRAYSCALE));
imwrite("image.jpg", image);
}
Answering the question in the title: no, you can't directly marshal std::string from managed to unmanaged code. See answers to another SO question on the reasons. Main reason is that std::string is a template and not a "real" type.
Basically, you need to write a small unmanaged module which provides simple wrappers for the openCV functions, getting rid of STL types. With your example function, it can be as simple as that:
declspec(__dllexport) imread(char* c, int i) {
string s = c;
cv::imread(s, i);
}
As for the problem with the string offset... Try creating a separate project, with "Unmanaged" type from the beginning. Switching the project to managed and back can produce a mess with project settings, having unpredictable consequences - at least, I've hit such pits twice...
You shouldn't (can't) pass a std::string& between different modules (DLLs) unless you are sure that all your modules were compiled the same way (release vs. debug etc).
For example: if you compile one DLL in release and another as debug - then the memory layout of std::string is likely to be different.
Other compiler settings may influence the memory layout as well.
Try this - compile the code below as release vs. debug and run it.
In debug you get 32 in relase 28.
#include <iostream>
#include <string>
int main()
{
std::cout << "sizeof(std::string) : " << sizeof(std::string) << std::endl;
return 0;
}
I suggest not to cross module boundaries using std::string.
Short answer: Yes, you can pass a STL string to a native C++ DLL from a C++/CLI app, if you use the same compiler settings for the DLL and the C++/CLI app.
Code:
#include <msclr/marshal_cppstd.h> // header for marshal utilities
...
String^ path = "C:\\Users\\Don Reba\\Pictures\\Merlin 1D.jpg"; // Managed string
std::string s = msclr::interop::marshal_as<std::string>(path); // To stl string
cv::imread(s, CV_LOAD_IMAGE_GRAYSCALE);
See this page for more details: http://msdn.microsoft.com/en-us/library/bb384865.aspx
The problem is that Visual Studio 2010 uses different toolsets for C++ and C++/CLI projects by default. This is why STL classes have different layouts despite identical settings. To fix the problem, make sure that Configuration Properties / General / Platform Toolset is set to v100 in the C++/CLI project.