wrapping boost::ublas with swig - c++

I am trying to pass data around the numpy and boost::ublas layers. I
have written an ultra thin wrapper because swig cannot parse ublas'
header correctly. The code is shown below
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/lexical_cast.hpp>
#include <algorithm>
#include <sstream>
#include <string>
using std::copy;
using namespace boost;
typedef boost::numeric::ublas::matrix<double> dm;
typedef boost::numeric::ublas::vector<double> dv;
class dvector : public dv{
public:
dvector(const int rhs):dv(rhs){;};
dvector();
dvector(const int size, double* ptr):dv(size){
copy(ptr, ptr+sizeof(double)*size, &(dv::data()[0]));
}
~dvector(){}
};
with the SWIG interface that looks something like
%apply(int DIM1, double* INPLACE_ARRAY1) {(const int size, double* ptr)}
class dvector{
public:
dvector(const int rhs);
dvector();
dvector(const int size, double* ptr);
%newobject toString;
char* toString();
~dvector();
};
I have compiled them successfully via gcc 4.3 and vc++9.0. However
when I simply run
a = dvector(array([1.,2.,3.]))
it gives me a segfault. This is the first time I use swigh with numpy
and not have fully understanding between the data conversion and
memory buffer passing. Does anyone see something obvious I have
missed? I have tried to trace through with a debugger but it crashed within the assmeblys of python.exe. I have no clue if this is a swig problem or of my simple wrapper. Anything is appreciated.

You may be interested in looking at the pyublas module. It does the conversion between numpy arrays and ublas data types seamlessly and without copying.

You may want to replace
copy(ptr, ptr+sizeof(double)*size, &(dv::data()[0]));
by
copy(ptr, ptr+size, &(dv::data()[0]));
Remember that in C/C++ adding or subtracting from a pointer moves it by a multiple of the size of the datatype it points to.
Best,

Related

How to initialize SparseMatrix of Eigen in a class

I am trying initializing sparseMatrix of Eigen, but it does not work when the initialization is in a class description. In the case of initialization in a function, not in a class, it works.
I am writting codes by C++ and using Visual Studio 2017.
I added
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW , but the problem remains.
#include <iostream>
#include <vector>
#include <Eigen/SparseCore>
#include <Eigen/Sparse>
#include "pch.h"
using namespace Eigen;
namespace A {
class A
{
std::size_t max_doc_id = 4;
std::size_t max_term_id = 4;
SparseMatrix<float, Eigen::RowMajor, int64_t> smat(max_term_id, max_doc_id);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
I want to decide the size of smat matrix (col=4, row=4) , but the error message is like this (actually it is written in Japanese so it may not correct)
"the member A::A::max_term_id is not the name of the type."
I appreciate if you can help me.
The compiler thinks that you are declaring a member function not a member variable (see here for more info on initialization). The following compiles. I am using Index instead of size_t to get rid of some warnings (narrowing conversion). You can play around with the code here: https://godbolt.org/z/yV1NUL
#include <iostream>
#include <vector>
#include <Eigen/SparseCore>
#include <Eigen/Sparse>
using namespace Eigen;
namespace A {
class A
{
Index max_doc_id = 4;
Index max_term_id = 4;
SparseMatrix<float, Eigen::RowMajor, int64_t> smat{max_term_id, max_doc_id};
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
Note: you should not use using namespace in header files, see "using namespace" in c++ headers
Edit: please also consider what user #ggael says in the comments, most likely you do not need EIGEN_MAKE_ALIGNED_OPERATOR_NEW because the SparseMatrix is not fixed-size vectorizable

How to add some headers file in VS2015

I've read visual studio 2012 adding new header file, but my problem has not been solved! Anyway, I want to add foo.h to my project:
#pragma once
void MyLDA(vector<int>, Mat_<float>, Mat&, Mat&);
Now, foo.cpp:
#include "stdafx.h"
#include "foo.h"
using namespace std;
auto getIndices = [](const std::vector<int>& vec, const int value)
{
//some code
}
void MyLDA(vector<int> gnd, Mat_<float> _data, Mat &eigvector, Mat &eigvalue)
{
//some code
}
when i build my project, i get this error:
'vector': undeclared identifier
type 'int' unexpected
'my_project': identifier not found
You need to #include <vector> to use std::vector. Also, best practice is to avoid using namespace std; and instead write std::vector. Some also recommend that for OpenCV classes such as Mat. (For what it’s worth, my own coding style is to write std:: in front of STL classes, since there’s a lot of legacy code out there with a custom string or array class, but to write cout and memcpy() rather than things like std::cout, for stuff that was around long before the STL.)
There’s also a missing semicolon after the assignment of a lambda expression, which happens to look a lot like a function definition at a glance. (#BarmakShemirani caught it, not me.)

Yet Another: Passing Vector of Structs to Function - C++, MinGW

I am aware there are numerous similar queries on here, however I haven't been able to resolve this, not has a colleague, so:
I am using MinGW (4.8.x) with Eclipse CDT Kepler.
1) I have my own code and to clean it up I changed it to use a vector of structs - all is fine, except that the function that receives it complains about Invalid Argument'.
2) I reduced my code down to a minimum working example, if I place it all in a single file it works, however if I move out my definitions to the header (which I need to do in my main code) it suddenly cannot resolve the fields in the struct...
The code below is for a three file configuration, header/function/main.
(In my main code I use namespace std - but that doesn't seem to be the problem. Also, there are extraneous headers for a minimum working example in this, however they are needed in my main code.)
myheaders.h
/*************************/
/****** myheaders.h ******/
/*************************/
/**-- Header Files --**/
// File Streams and IO
#include <stdio.h>
#include <sstream>
#include <iostream>
#include <fstream>
// For strtod -> string to double
#include <stdlib.h>
// Math Operations
//#include <math.h>
#include <cmath>
// To get the CPU time
#include <time.h>
// For Vectors
#include <vector>
// For strings, C strings right now...
#include <cstring>
// Needed globally for the function definitions
// using namespace std;
#ifndef MY_HEADERS
#define MY_HEADERS
struct SpeciesLoss {
int ReactionID;
int SpeciesID;
double coefficient;
};
std::vector< double > SpeciesLossRate(std::vector<SpeciesLoss> , int, const std::vector< double > & );
#endif
function.cpp
/*************************/
/****** function.cpp *****/
/*************************/
#include "myheaders.h"
std::vector< double > SpeciesLossRate(
std::vector< SpeciesLoss > SpeciesLossList,
int Number_Species,
const std::vector< double >& Combined_Rates
)
{
std::vector< double > temp_species_loss;
temp_species_loss.resize(1);
temp_species_loss[0]=SpeciesLossList[0].ReactionID;
return temp_species_loss;
}
main.cpp
/*************************/
/******** main.cpp *******/
/*************************/
#include "myheaders.h"
std::vector< SpeciesLoss > SpeciesLossAll; // New vector for recording species loss, uses a vector of structs
int main(int argc, char* argv[])
{
std::vector< double > Rates;
Rates.push_back(1);
SpeciesLossAll.push_back(SpeciesLoss());
SpeciesLossAll[0].ReactionID = 0;
SpeciesLossAll[0].SpeciesID = 0;
SpeciesLossAll[0].coefficient = 0;
std::vector< double > SpeciesConcentrationChange = SpeciesLossRate(SpeciesLossAll,1, Rates);
return 0;
}
Edit:
Screenshot
Edit 2:
And interesting update - it compiles fine on Linux with GCC. Better than nothing, but I still want to know what is going wrong, plus I'd like my code to be cross platform...
Edit 3:
This is more and more bizarre - I just tested my code (the full project that compiles on Linux) on my home PC which runs Windows 7 where it builds fine while my laptop runs Windows 8 and the problem occurs.
The Settings for the C++ build are absolutely identical.
Both run MinGW 4.8.1...
Both run the latest Eclipse Kepler...
And yes, I am aware that I need to test some suggestions still.
#ifndef MY_HEADERS
#define MY_HEADERS
Should be at the beginning of your file. Since you have no idea in what order the compiler is going to include headers this might be causing a problem... Especially if you are including your personal header in multiple files, wich will definitely make it behave like so. Also, keep in mind that since you are not providing a default constructor but rather using the one the compiler provides for you, those variables inside the struct will most likely not be initialized to zero as you expect them.
EDIT#1
Are you compiling everything NOT just main... I just copied your code into VS and it works!
EDIT#2
Try defining the function inline instead of a separate implementation file.
static std::vector< double > SpeciesLossRate(
std::vector< SpeciesLoss > SpeciesLossList,
int Number_Species,
const std::vector< double >& Combined_Rates
)
{
std::vector< double > temp_species_loss;
temp_species_loss.resize(1);
temp_species_loss[0]=SpeciesLossList[0].ReactionID;
return temp_species_loss;
}
EDIT#3
Ok, from the screen-shot this is definitely valid code. For sake of trying everything; implement your own constructor and copy constructor of the struct. I know this might sound silly but maybe Eclipse doesn't think so.
OK - I have found the answer - I think - and it boils down to Eclipse.
-> Project -> C/C++ Index -> Rebuild
This resolves the issue.
In fact, this problem is known on earlier Eclipse CDT versions: https://bugs.eclipse.org/bugs/show_bug.cgi?id=348170

Change all the int type to another type using #define for large program

I want to change all my int type in my program to support arbitrary position integer. I chose to use GMP.
I am thinking about is it possible to do a #define to replace all int to mpz_class.
I start by a small program
#include <iostream>
#define int long long int
using namespace std;
int main(){
// .... code
}
The compiler is already complaining about main have to return an int type.
Is it possible to add exception to #define? or this is a really bad idea to do so?
Redefining a keyword is prohibited iff you include any standard headers. Here, you included <iostream> so your program is ill-formed.
Otherwise, knock yourself out! Wait, no, don't, because this would still be really silly.
Instead, refactor your code to use some new type called, say, my_integer (but with a much better name):
typedef int my_integer;
Then, when you want to change from int to mpz_class, you just change the definition of my_integer:
typedef mpz_class my_integer;
use main without int like this:
#include <iostream>
#define int long long int
using namespace std;
main(){
// .... code
}
The simple answer: although technically possible you are not allowed to #define any of the reserved identifiers.

using CString with boost string algorithms - reduce to one typedef?

I need to write some code for a MFC project, but I don't know how to get required code to work when using MFC.
I prototyped my function first just using the STL types, and boost.
STL Prototype
#include <string>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/find.hpp>
void ProtoTest()
{
std::string sText("123Hello4");
boost::iterator_range<std::string::iterator> nc_result = find_token(sText, boost::algorithm::is_alpha(), boost::algorithm ::token_compress_on);
}
Result = "Hello"
I eventually managed to get it working with MFC, however I had to supply two typedefs. I would like to do it in one, however there isn't much documentation on using the MFC port provided in boost.
#include "stdafx.h"
#include <boost\range\atl.hpp>
void Test()
{
typedef boost::range_iterator<CString>::type CString_it;
typedef boost::iterator_range<CString_it> CString_range;
CString strText("123Hello4");
CString_range r;
r = find_token(text, boost::algorithm::is_alpha(), boost::algorithm ::token_compress_on);
}
Again Result = "Hello"
Is there a single typedef I can use to hold the result of find_token, rather than needing two typdefs to achieve it.
You could just combine them
typedef boost::iterator_range<boost::range_iterator<CString>::type> CString_range;
But I don't know if that is an advantage.