Accessing a subslice of a boost matrix in a helper class - c++

I'm trying to build a class that eases the use of the boost boost::numeric::ublas::matrix. Thus I've got:
using namespace boost::numeric::ublas;
typedef matrix<double> matrix_t;
class Tensor : public matrix_t {
public:
Tensor (const int M, const int N) : matrix_t(M, N) { }
virtual ~Tensor() { }
Tensor SubMatrix (const int start1, const int size1, const int start2, const int size2) const;
void Print() const;
}; // tensor
And I further define the SubMatrix() as follows:
Tensor Tensor::SubMatrix (const int start1, const int size1, const int start2, const int size2) const {
matrix_slice<matrix_t> s (this, slice(start1, 1, size1), slice(start2, 1, size2));
Tensor t (matrix_expression<matrix_t> (s));
return t;
}
I'd like to be able to easily create new Tensors by grabbing sub-matrices from within a Tensor. The compiler is complaining with the following:
g++ -ftemplate-depth-100 -Drestrict= -Wall -Wno-deprecated -g3 -ggdb -Wall -D_GLIBCXX_DEBUG -I/home/eshamay/md/src -I/home/eshamay/share/include -I/usr/include -I/usr/local/include -I/home/eshamay/src/boost-1_43_0 -L/home/eshamay/share/lib -L/home/eshamay/src/lapack-3.2.1 -lconfig++ -c -o morita2002.o morita2002.cpp
morita2002.cpp: In member function ‘morita::math::Tensor morita::math::Tensor::SubMatrix(int, int, int, int) const’:
morita2002.cpp:109: error: no matching function for call to ‘boost::numeric::ublas::matrix_slice<boost::numeric::ublas::matrix<double, boost::numeric::ublas:: basic_row_major<long unsigned int, long int>, boost::numeric::ublas::unbounded_array<double, std::allocator<double> > > >::matrix_slice(const morita::math::Tensor* const, boost::numeric::ublas::slice, boost::numeric::ublas::slice)’
/usr/include/boost/numeric/ublas/matrix_proxy.hpp:3192: note: candidates are: boost::numeric::ublas::matrix_slice<E>::matrix_slice(const typename boost::mpl:: if_<boost::is_const<T>, typename M::const_closure_type, typename M::closure_type>::type&, const boost::numeric::ublas::basic_slice<typename A::size_type, typename A:: difference_type>&, const boost::numeric::ublas::basic_slice<typename A::size_type, typename A::difference_type>&, int) [with M = boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<long unsigned int, long int>, boost::numeric::ublas::unbounded_array<double, std::allocator<double> > >]
/usr/include/boost/numeric/ublas/matrix_proxy.hpp:3183: note: boost::numeric::ublas::matrix_slice<E>::matrix_slice(M&, const boost::numeric::ublas:: basic_slice<typename A::size_type, typename A::difference_type>&, const boost::numeric::ublas::basic_slice<typename A::size_type, typename A::difference_type>&) [with M = boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<long unsigned int, long int>, boost::numeric::ublas::unbounded_array<double, std:: allocator<double> > >]
/usr/include/boost/numeric/ublas/matrix_proxy.hpp:3155: note: boost::numeric::ublas::matrix_slice<boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<long unsigned int, long int>, boost::numeric::ublas::unbounded_array<double, std::allocator<double> > > >::matrix_slice(const boost::numeric::ublas::matrix_slice<boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<long unsigned int, long int>, boost::numeric::ublas::unbounded_array<double, std::allocator<double> > > >&)
morita2002.cpp:112: error: conversion from ‘morita::math::Tensor (*)(boost::numeric::ublas::matrix_expression<boost::numeric::ublas::matrix<double, boost::numeric:: ublas::basic_row_major<long unsigned int, long int>, boost::numeric::ublas::unbounded_array<double, std::allocator<double> > > >)’ to non-scalar type ‘morita::math:: Tensor’ requested
After attempting a number of variations to appease the compiler, I'm stumped. What's the issue, and why can't I just create the matrix_slice the way it's written?

matrix_slice requires a reference as its first argument, while you're giving it a pointer (this). Try using *this, instead.
Furthermore, since you're SubMatrix method has a const qualifier, the type of *this would be matrix_t const&, so you should use matrix_slice<matrix_t const>.

Related

Use vectors as key in unordered_map

So I want to use vectors as keys in my unordered_map. I have followed this answer and I have the following
#include <iostream>
#include <cstdlib>
#include <tuple>
#include <unordered_map>
#include <vector>
#include <boost/functional/hash.hpp> /* hash_combine */
template <typename T>
struct vectorHasher{
std::size_t operator()(std::vector<T> &in) const
{
using boost::hash_value;
using boost::hash_combine;
// Start with a hash value of 0
std::size_t seed = 0;
T value;
for (int i=0; i< in.size(); i++)
{
value = static_cast<T>(in[i]);
hash_combine(seed, hash_value(value));
}
return seed;
}
};
int main()
{
typedef std::unordered_map< std::vector<std::size_t>, int, vectorHasher<std::vector<std::size_t> > > map_type;
map_type mymap;
std::vector<size_t> vec (3,100);
mymap[vec] = 1;
return 0;
}
, but I get the following error compiling the code.
In file included from mytest_vectorhasher.cpp:6:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/unordered_map:404:17: error:
no matching function for call to object of type 'const
vectorHasher<std::__1::vector<unsigned long, std::__1::allocator<unsigned long> >
>'
{return static_cast<const _Hash&>(*this)(__x);}
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__hash_table:1976:21: note:
in instantiation of member function
'std::__1::__unordered_map_hasher<std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >,
std::__1::__hash_value_type<std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >, int>, vectorHasher<std::__1::vector<unsigned
long, std::__1::allocator<unsigned long> > >, true>::operator()' requested here
size_t __hash = hash_function()(__k);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/unordered_map:1443:21: note:
in instantiation of function template specialization
'std::__1::__hash_table<std::__1::__hash_value_type<std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >, int>,
std::__1::__unordered_map_hasher<std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >,
std::__1::__hash_value_type<std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >, int>, vectorHasher<std::__1::vector<unsigned
long, std::__1::allocator<unsigned long> > >, true>,
std::__1::__unordered_map_equal<std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >,
std::__1::__hash_value_type<std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >, int>,
std::__1::equal_to<std::__1::vector<unsigned long, std::__1::allocator<unsigned
long> > >, true>,
std::__1::allocator<std::__1::__hash_value_type<std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >, int> >
>::__emplace_unique_key_args<std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >, const std::__1::piecewise_construct_t &,
std::__1::tuple<const std::__1::vector<unsigned long, std::__1::allocator<unsigned
long> > &>, std::__1::tuple<> >' requested here
return __table_.__emplace_unique_key_args(__k,
^
mytest_vectorhasher.cpp:41:10: note: in instantiation of member function
'std::__1::unordered_map<std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >, int, vectorHasher<std::__1::vector<unsigned
long, std::__1::allocator<unsigned long> > >,
std::__1::equal_to<std::__1::vector<unsigned long, std::__1::allocator<unsigned
long> > >, std::__1::allocator<std::__1::pair<const std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >, int> > >::operator[]' requested here
mymap[vec] = 1;
^
mytest_vectorhasher.cpp:13:17: note: candidate function not viable: no known conversion
from 'const std::__1::vector<unsigned long, std::__1::allocator<unsigned long> >'
to 'std::vector<vector<unsigned long, allocator<unsigned long> > > &' for 1st
argument
std::size_t operator()(std::vector<T> &in) const
^
1 error generated.
Is it something easy that I am messing up? What am I doing wrong?
There are two errors in this example. First, your hasher's operator() parameter should be const.
std::size_t operator()(const std::vector<T> &in) const
// Add const here ^^^^^
Second is you are defining your hashing type as vectorHasher<std::vector<std::size_t> > which would imply that T = std::vector<std::size_t>, meaning that you are trying to instantiate a hasher with std::size_t operator()(const std::vector<std::vector<std::size_t>> &in) const which is too many vectors. Remove the std::vector from your map type declaration like this :
typedef std::unordered_map< std::vector<std::size_t>, int, vectorHasher< std::size_t > > map_type;
// Remove std::vector from this template argument ^^^^^^^^^^^
The problem is you have the wrong parameter for operator(). When you construct the vectorHasher you use
vectorHasher<std::vector<std::size_t>>
Which means T is a
std::vector<std::size_t>
That means your operator() looks like
std::size_t operator()(std::vector<std::vector<std::size_t>> &in) const
Which is not what you want. What you can do is to use T directly like
std::size_t operator()(const T& in) const
Or change the vectorHasher to be
vectorHasher<std::size_t>
There are 2 errors in your code.
1) Since you defined your vectorHasher as
template <typename T>
struct vectorHasher{
std::size_t operator()(std::vector<T> &in) const
{
// ...
}
};
The following template instantiation vectorHasher<std::vector<std::size_t>> expands to:
struct vectorHasher{
std::size_t operator()(std::vector<std::vector<std::size_t>> &in) const
{
// ...
}
};
And, sure enough, std::vector<std::size_t> can't be passed to this function.
Change the instantiation of the template to vectorHasher<std::size_t>.
2) operator() of the struct used for hashing needs to take const value/reference, so you should change the signature of it to:
std::size_t operator()(std::vector<T> const &in) const
Live demo.

fake iterator operations for enumerating all the node values in a graph

I'm trying to have a fake iterator for enumerating all the node values in a graph. The graph can be abstracted in any sequence, as long as the sequence consists of all and only the nodes in the graph. There should be a mutable qualifier, and the 4 operations' implementations are short and supposed to be only 1 line per function.
The test case for the 4 fake iterator operations is as follow, it is supposed to print out a string of values of the graph nodes through the fake iterator operations:
gdwg::Graph<std::string,int>> g
for (g.begin(); !g.end(); g.next())
std::cout << g.value() << std::end;
I declared the graph as the following:
template <typename N, typename E> class Graph {
private:
struct Node;
struct Edge;
struct Node {
N val_;
int numEdges_;
int numIncomingEdges_;
std::set<std::shared_ptr<Edge>> edges_;
std::set<std::shared_ptr<Edge>> incomingEdges_;
Node() {}
Node(const N x) : val_{x} { numEdges_=0; numIncomingEdges_=0; }
void printNode(N n);
~Node();
void update();
};
struct Edge {
std::weak_ptr<Node> orig;
std::weak_ptr<Node> dest;
E val_;
Edge(std::shared_ptr<Node> o, std::shared_ptr<Node> d, E x);
Edge() {};
void printEdge();
~Edge();
};
// fake iterator operations
void begin() const;
bool end() const;
void next() const;
const N& value() const;
public:
friend class Node_Iterator<N, E>;
friend class Edge_Iterator<N, E>;
private:
std::map< N, std::shared_ptr<Node> > nodes_;
// fake iterator to be used for the four operations begin(), end(), next() and value()
mutable typename std::map< N, std::shared_ptr<Node> >::iterator fakeIter_;
};
The implementation of the 4 operations are as follows:
// void begin() const: Sets an internal iterator, i.e., ``pointer'' to the first element of a sequence.
template <typename N, typename E>
void Graph<N,E>::begin() const {
// gets iterator to the first key/value pair in map sequence
fakeIter_ = nodes_.begin();
}
// bool end() const: Returns true if the iterator goes past the last element of the sequence and false otherwise.
template <typename N, typename E>
bool Graph<N,E>::end() const {
// return true if iterator goes past last element, otherwise return false
return ((fakeIter_ == nodes_.end()) ? true : false);
}
// void next() const: Moves the iterator to the next element of the sequence.
template <typename N, typename E>
void Graph<N,E>::next() const {
fakeIter_ = std::next(fakeIter_, 1);
}
// const N& value() const: Returns the value of the node pointed to by the iterator.
template <typename N, typename E>
const N& Graph<N,E>::value() const {
return fakeIter_->second->val_;
}
When I try to compile, there is a bunch of errors popping up. I'm just wondering whether I'm implementing the fake iterator operations correctly and if there is any way to improve it if need be?
tests/Graph.tem: In instantiation of ‘void gdwg::Graph<N, E>::begin() const [with N = unsigned int; E = int]’:
tests/test13.cpp:23:15: required from here
tests/Graph.tem:713:12: error: no match for ‘operator=’ (operand types are ‘std::map<unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node>, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > > >::iterator {aka std::_Rb_tree_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >}’ and ‘std::map<unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node>, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > > >::const_iterator {aka std::_Rb_tree_const_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >}’)
fakeIter_ = nodes_.begin();
In file included from /usr/local/include/c++/6.1.0/map:60:0,
from tests/Graph.h:19,
from tests/test13.cpp:3:
/usr/local/include/c++/6.1.0/bits/stl_tree.h:174:12: note: candidate: constexpr std::_Rb_tree_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >& std::_Rb_tree_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >::operator=(const std::_Rb_tree_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >&)
struct _Rb_tree_iterator
^~~~~~~~~~~~~~~~~
/usr/local/include/c++/6.1.0/bits/stl_tree.h:174:12: note: no known conversion for argument 1 from ‘std::map<unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node>, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > > >::const_iterator {aka std::_Rb_tree_const_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >}’ to ‘const std::_Rb_tree_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >&’
/usr/local/include/c++/6.1.0/bits/stl_tree.h:174:12: note: candidate: constexpr std::_Rb_tree_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >& std::_Rb_tree_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >::operator=(std::_Rb_tree_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >&&)
/usr/local/include/c++/6.1.0/bits/stl_tree.h:174:12: note: no known conversion for argument 1 from ‘std::map<unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node>, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > > >::const_iterator {aka std::_Rb_tree_const_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >}’ to ‘std::_Rb_tree_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >&&’
What that first error is saying is that, as your begin function is const, nodes_.begin() will return a const_iterator. This cannot be assigned to an iterator, the type of fakeIter_.
You'll need to remove the const from begin, change the type of fakeIter_, or change your implementation (begin should return an iterator, not void).

Partition a boost::range::transformed range adaptor

I am trying to partition a boost::range::transformed adaptor:
#include <boost/range.hpp>
#include <boost/range/algorithm/partition.hpp>
#include <boost/range/algorithm/transform.hpp>
#include <boost/range/any_range.hpp>
#include <boost/range/adaptor/transformed.hpp>
using boost::adaptors::transformed;
void foo()
{
boost::any_range<int,
boost::forward_traversal_tag,
int&,
std::ptrdiff_t> r;
auto t = r | transformed( [](int) {return 0;} );
auto p = boost::range::partition(t, [](int) {return true;} );
std::vector<int> v;
auto t2 = r | transformed( [](int) {return 0;} );
auto p2 = boost::range::partition(t2, [](int) {return true;} );
}
The compiler complains for p1 and p2 that it cannot find a function __partition which accepts a boost::iterators__transform_iterator. The complete error message is
In file included from /opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/algorithm:62:0,
from /tmp/boost_1_59_0/boost/iterator/iterator_concepts.hpp:29,
from /tmp/boost_1_59_0/boost/range/concepts.hpp:20,
from /tmp/boost_1_59_0/boost/range/size_type.hpp:20,
from /tmp/boost_1_59_0/boost/range/size.hpp:21,
from /tmp/boost_1_59_0/boost/range/functions.hpp:20,
from /tmp/boost_1_59_0/boost/range.hpp:18,
from range_partition.cpp:1:
/opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/bits/stl_algo.h: In instantiation of ‘_BIter std::partition(_BIter, _BIter, _Predicate) [with _BIter = boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default>; _Predicate = foo()::<lambda(int)>]’:
/tmp/boost_1_59_0/boost/range/algorithm/partition.hpp:34:65: required from ‘typename boost::range_iterator<C>::type boost::range::partition(ForwardRange&, UnaryPredicate) [with ForwardRange = boost::range_detail::transformed_range<foo()::<lambda(int)>, boost::range_detail::any_range<int, boost::iterators::forward_traversal_tag, int&, long int> >; UnaryPredicate = foo()::<lambda(int)>; typename boost::range_iterator<C>::type = boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default>]’
range_partition.cpp:22:66: required from here
/opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/bits/stl_algo.h:4509:43: error: no matching function for call to ‘__partition(boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default>&, boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default>&, foo()::<lambda(int)>&, std::__iterator_traits<boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default>, true>::iterator_category)’
std::__iterator_category(__first));
^
/opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/bits/stl_algo.h:4509:43: note: candidates are:
/opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/bits/stl_algo.h:1462:5: note: template<class _ForwardIterator, class _Predicate> _ForwardIterator std::__partition(_ForwardIterator, _ForwardIterator, _Predicate, std::forward_iterator_tag)
__partition(_ForwardIterator __first, _ForwardIterator __last,
^
/opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/bits/stl_algo.h:1462:5: note: template argument deduction/substitution failed:
/opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/bits/stl_algo.h:4509:43: note: cannot convert ‘std::__iterator_category<boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default> >((*(const boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default>*)(& __first)))’ (type ‘std::__iterator_traits<boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default>, true>::iterator_category {aka boost::iterators::detail::iterator_category_with_traversal<std::input_iterator_tag, boost::iterators::forward_traversal_tag>}’) to type ‘std::forward_iterator_tag’
std::__iterator_category(__first));
^
/opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/bits/stl_algo.h:1487:5: note: template<class _BidirectionalIterator, class _Predicate> _BidirectionalIterator std::__partition(_BidirectionalIterator, _BidirectionalIterator, _Predicate, std::bidirectional_iterator_tag)
__partition(_BidirectionalIterator __first, _BidirectionalIterator __last,
^
/opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/bits/stl_algo.h:1487:5: note: template argument deduction/substitution failed:
/opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/bits/stl_algo.h:4509:43: note: cannot convert ‘std::__iterator_category<boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default> >((*(const boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default>*)(& __first)))’ (type ‘std::__iterator_traits<boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default>, true>::iterator_category {aka boost::iterators::detail::iterator_category_with_traversal<std::input_iterator_tag, boost::iterators::forward_traversal_tag>}’) to type ‘std::bidirectional_iterator_tag’
std::__iterator_category(__first));
I am quite lost and don't see a solution for this. Any help would be greatly appreciated.
The transformed range is not a mutable sequence.
You cannot partition such a range (because you can't swap elements).
You can look at partition_copy, in which case you should have a destination iterator to receive the partitioned range.
With a bit of work, it seems like you should be able to craft a Boost Range style Adaptor out of this too (see docs on extending: http://www.boost.org/doc/libs/1_59_0/libs/range/doc/html/range/reference/extending/method_3.html) in case you really insist on having partitioned like in the first example.
Sample
Here's what I'd suggest as a 'halfway' solution: convenient without too much effort (c++11)
Live On Coliru
#include <boost/range.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/algorithm_ext.hpp>
#include <boost/range/any_range.hpp>
#include <boost/range/adaptors.hpp>
using boost::adaptors::transformed;
namespace {
// convenience wrapper
template <typename Range, typename Predicate, typename OutIt1, typename OutIt2>
std::pair<OutIt1, OutIt2> partition_copy(Range const& range, OutIt1 out1, OutIt2 out2, Predicate&& predicate) {
return std::partition_copy(
boost::begin(range), boost::end(range),
out1, out2,
std::forward<Predicate>(predicate));
}
}
#include <iostream>
int main()
{
std::vector<int> demo { 1,2,7,3,-9,42 };
std::vector<int> even, odd;
partition_copy(
demo | transformed( [](int i) {return i+1;} ),
back_inserter(even), back_inserter(odd),
[] (int i) { return 0 == i%2; }
);
// output
boost::copy(even, std::ostream_iterator<int>(std::cout << "even : ", " "));
boost::copy(odd, std::ostream_iterator<int>(std::cout << "\nodd : ", " "));
}
Prints
even : 2 8 4 -8
odd : 3 43

How to compile thrust and c++ project?

I got big problems about the compile when I want to use thrust and c++ meanwhile.
Here is the project structure(just a test project):
sortbase.h
#include<iostream>
#include <thrust/device_vector.h>
using namespace std;
template<class T>
class SortBase
{
public:
void Init()
{
}
void resize(const int &x)
{
CV.resize(x);
cout<<"resize succeed!"<<endl;
}
private:
thrust::device_vector<T> CV;
};
sorter.h
#ifndef __SORTER_H__
#define __SORTER_H__
#include <iostream>
#include <thrust/device_vector.h>
#include "sortbase.h"
using namespace std;
template<class T>
void ttest()
{cout<<"tttttttttttttttt";cout<<endl;}
template<class KEY>
class Sorter
{
public:
Sorter():CV(NULL)
{
CV=new SortBase<KEY>();
}
~Sorter()
{
if (CV!=NULL)
{
delete CV;
CV=NULL;
}
}
__host__ __device__
virtual bool operator()(const KEY& x,const KEY& y)const
{
return (x<y);
}
void test()
{
//ttest<KEY>();
resize(5);
}
private:
void resize(const int &x)
{
CV->resize(x);
cout<<"resize: "<<x<<endl;
}
private:
SortBase<KEY> *CV;
};
#endif
main.cpp
#include <iostream>
#include "include/sorter.cu"
using namespace std;
int main(int argc,char **argv)
{
Sorter<int> *sorter=new Sorter<int>();
sorter->test();
return 0;
}
What I do like this:
nvcc -c sorter.cu
g++ -c main.cpp -I/usr/local/cuda/include
g++ sorter.o main.o -o sorter
but the second step gives the error message, a lot of warning and error message.
who can help me?
some warning and error message like these:
/usr/local/cuda/include/thrust/detail/device/cuda/for_each.inl: In function \u2018RandomAccessIterator thrust::detail::device::cuda::for_each_n(RandomAccessIterator, Size, UnaryFunction) [with RandomAccessIterator = thrust::detail::normal_iterator<thrust::device_ptr<int> >, Size = long unsigned int, UnaryFunction = thrust::detail::generate_functor<thrust::detail::fill_functor<int> >]\u2019:
/usr/local/cuda/include/thrust/detail/device/dispatch/for_each.h:56: instantiated from \u2018RandomAccessIterator thrust::detail::device::dispatch::for_each_n(RandomAccessIterator, Size, UnaryFunction, thrust::detail::cuda_device_space_tag) [with RandomAccessIterator = thrust::detail::normal_iterator<thrust::device_ptr<int> >, Size = long unsigned int, UnaryFunction = thrust::detail::generate_functor<thrust::detail::fill_functor<int> >]\u2019
/usr/local/cuda/include/thrust/detail/device/for_each.inl:43: instantiated from \u2018OutputIterator thrust::detail::device::for_each_n(OutputIterator, Size, UnaryFunction) [with OutputIterator = thrust::detail::normal_iterator<thrust::device_ptr<int> >, Size = long unsigned int, UnaryFunction = thrust::detail::generate_functor<thrust::detail::fill_functor<int> >]\u2019
/usr/local/cuda/include/thrust/detail/dispatch/for_each.h:84: instantiated from \u2018OutputIterator thrust::detail::dispatch::for_each_n(OutputIterator, Size, UnaryFunction, thrust::device_space_tag) [with OutputIterator = thrust::detail::normal_iterator<thrust::device_ptr<int> >, Size = long unsigned int, UnaryFunction = thrust::detail::generate_functor<thrust::detail::fill_functor<int> >]\u2019
/usr/local/cuda/include/thrust/detail/for_each.inl:41: instantiated from \u2018OutputIterator thrust::detail::for_each_n(OutputIterator, Size, UnaryFunction) [with OutputIterator = thrust::detail::normal_iterator<thrust::device_ptr<int> >, Size = long unsigned int, UnaryFunction = thrust::detail::generate_functor<thrust::detail::fill_functor<int> >]\u2019
/usr/local/cuda/include/thrust/detail/generate.inl:47: instantiated from \u2018OutputIterator thrust::generate_n(OutputIterator, Size, Generator) [with OutputIterator = thrust::detail::normal_iterator<thrust::device_ptr<int> >, Size = long unsigned int, Generator = thrust::detail::fill_functor<int>]\u2019
/usr/local/cuda/include/thrust/detail/device/cuda/fill.inl:87: instantiated from \u2018OutputIterator thrust::detail::device::cuda::detail::fill_n(OutputIterator, Size, const T&, thrust::detail::false_type) [with OutputIterator = thrust::detail::normal_iterator<thrust::device_ptr<int> >, Size = long unsigned int, T = int]\u2019
/usr/local/cuda/include/thrust/detail/device/cuda/fill.inl:117: instantiated from \u2018OutputIterator thrust::detail::device::cuda::detail::fill_n(OutputIterator, Size, const T&, thrust::detail::true_type) [with OutputIterator = thrust::detail::normal_iterator<thrust::device_ptr<int> >, Size = long unsigned int, T = int]\u2019
/usr/local/cuda/include/thrust/detail/device/cuda/fill.inl:138: instantiated from \u2018OutputIterator thrust::detail::device::cuda::fill_n(OutputIterator, Size, const T&) [with OutputIterator = thrust::detail::normal_iterator<thrust::device_ptr<int> >, Size = long unsigned int, T = int]\u2019
/usr/local/cuda/include/thrust/detail/device/dispatch/fill.h:57: instantiated from \u2018OutputIterator thrust::detail::device::dispatch::fill_n(OutputIterator, Size, const T&, thrust::detail::cuda_device_space_tag) [with OutputIterator = thrust::detail::normal_iterator<thrust::device_ptr<int> >, Size = long unsigned int, T = int]\u2019
/usr/local/cuda/include/thrust/detail/device/fill.inl:47: instantiated from \u2018OutputIterator thrust::detail::device::fill_n(OutputIterator, Size, const T&) [with OutputIterator = thrust::detail::normal_iterator<thrust::device_ptr<int> >, Size = long unsigned int, T = int]\u2019
/usr/local/cuda/include/thrust/detail/dispatch/fill.h:76: instantiated from \u2018OutputIterator thrust::detail::dispatch::fill_n(OutputIterator, Size, const T&, thrust::device_space_tag) [with OutputIterator = thrust::detail::normal_iterator<thrust::device_ptr<int> >, Size = long unsigned int, T = int]\u2019
/usr/local/cuda/include/thrust/detail/fill.inl:46: instantiated from \u2018OutputIterator thrust::fill_n(OutputIterator, Size, const T&) [with OutputIterator = thrust::detail::normal_iterator<thrust::device_ptr<int> >, Size = long unsigned int, T = int]\u2019
/usr/local/cuda/include/thrust/detail/vector_base.inl:757: instantiated from \u2018void thrust::detail::vector_base<T, Alloc>::fill_insert(typename thrust::detail::contiguous_storage<T, Alloc>::iterator, typename thrust::detail::contiguous_storage<T, Alloc>::size_type, const T&) [with T = int, Alloc = thrust::device_malloc_allocator<int>]\u2019
/usr/local/cuda/include/thrust/detail/vector_base.inl:561: instantiated from \u2018void thrust::detail::vector_base<T, Alloc>::insert(typename thrust::detail::contiguous_storage<T, Alloc>::iterator, typename thrust::detail::contiguous_storage<T, Alloc>::size_type, const T&) [with T = int, Alloc = thrust::device_malloc_allocator<int>]\u2019
/usr/local/cuda/include/thrust/detail/vector_base.inl:223: instantiated from \u2018void thrust::detail::vector_base<T, Alloc>::resize(typename thrust::detail::contiguous_storage<T, Alloc>::size_type, typename thrust::detail::contiguous_storage<T, Alloc>::value_type) [with T = int, Alloc = thrust::device_malloc_allocator<int>]\u2019
include/sortbase.h:14: instantiated from void SortBase<T>::resize(const int&) [with T = int]
include/sorter.cu:40: instantiated from void Sorter<KEY>::resize(const int&) [with KEY = int]
include/sorter.cu:35: instantiated from void Sorter<KEY>::test() [with KEY = int]
main.cpp:9: instantiated from here
/usr/local/cuda/include/thrust/detail/device/cuda/for_each.inl:93: error: invalid application of sizeof to incomplete type thrust::detail::STATIC_ASSERTION_FAILURE<false>
/usr/local/cuda/include/thrust/detail/device/cuda/arch.h: At global scope:
/usr/local/cuda/include/thrust/detail/device/cuda/arch.h:59: warning: inline function size_t thrust::detail::device::cuda::arch::compute_capability() used but never defined
I think that the problem is you are including your .cu file from a .cpp file. Thrust code can only be used from .cu files, which must be compiled by NVCC, not by the host compiler g++. So you need to move all of your Thrust and CUDA device code inside .cu files in functions that can be called from your .cpp files.
Harrism is right. If you are going to compile a file using gpu, you must use .cu for the file and nvcc like:
nvcc -o test test.cu

C++: Help Creating unordered_map with User-Defined Hash/Equality

I'm trying to create a std::unordered_map, using a user-defined hash function and equality predicate, for matrix rows of integral built-in types. I use std::bind, since I need the hashing and equality functors to work for variable ranges. How would I get the following code to compile and work as intended? I'm guessing that my mistake is towards the bottom of the listing, where I use std::bind and instantiate the std::unordered_map.
Some clarifications:
I can't use boost::hash_combine because I care about individual bits in the integers stored in the matrix row, so unless I create my own iterator, boost::hash_combine would combine whole integers, leading to erroneous results. Also, I need the hash and equality functors to work on ranges from 1 to ~200,000, so specifying the range in template parameters would not be a reasonable option.
template <class T,class F,class A>
struct row_hash_right : std::function<size_t(
ublas::matrix_row<ublas::matrix<T,F,A>>,
unsigned, unsigned)>
{
typedef ublas::matrix_row<ublas::matrix<T,F,A>> row_type;
// I want to use std::bind to bind the last two arguments.
size_t operator()(row_type& a, unsigned s, unsigned e)
{
// Implementation of hash function.
}
};
template <class T,class F,class A>
struct row_equal_right : std::function<bool(
ublas::matrix_row<ublas::matrix<T,F,A>>,
ublas::matrix_row<ublas::matrix<T,F,A>>,
unsigned, unsigned)>
{
typedef ublas::matrix_row<ublas::matrix<T,F,A>> row_type;
bool operator()(row_type& a, row_type& b, unsigned s, unsigned e)
{
// Implementation of equality predicate.
}
};
// Inside a function.
for (unsigned i = 0; i < len; ++i) {
for (unsigned j = i + 1; j < len; ++j) {
auto x = std::bind(r_hash, _1, i, j);
auto y = std::bind(r_equal, _1, _2, i, j);
// ERROR:
std::unordered_map<row_type, unsigned,
decltype(x), decltype(y)> m(256, x, y);
}
}
The error:
Here is (what I think) the most important part of the error produced upon attempted compilation:
/usr/include/c++/4.6/bits/stl_pair.h:92:11: error: ‘std::pair<_T1,
_T2>::first’ has incomplete type
/usr/include/boost/numeric/ublas/fwd.hpp:73:11: error: declaration of ‘const struct
boost::numeric::ublas::matrix_row,
boost::numeric::ublas::unbounded_array > > >’
If you want the see the whole thing, I've dumped it all here:
In file included from /usr/include/c++/4.6/bits/stl_algobase.h:65:0,
from /usr/include/c++/4.6/bits/char_traits.h:41,
from /usr/include/c++/4.6/ios:41,
from /usr/include/c++/4.6/ostream:40,
from /usr/include/c++/4.6/iostream:40,
from src/test/read_test.cpp:1:
/usr/include/c++/4.6/bits/stl_pair.h: In instantiation of ‘std::pair, boost::numeric::ublas::unbounded_array > > >, unsigned int>’:
/usr/include/c++/4.6/bits/stl_function.h:486:12: instantiated from ‘std::_Select1st, boost::numeric::ublas::unbounded_array > > >, unsigned int> >’
/usr/include/c++/4.6/bits/hashtable_policy.h:789:20: instantiated from ‘std::__detail::_Hash_code_base, boost::numeric::ublas::unbounded_array > > >, std::pair, boost::numeric::ublas::unbounded_array > > >, unsigned int>, std::_Select1st, boost::numeric::ublas::unbounded_array > > >, unsigned int> >, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, std::_Placeholder, unsigned int, unsigned int)>, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, unsigned int, unsigned int)>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>’
/usr/include/c++/4.6/bits/hashtable.h:105:11: instantiated from ‘std::_Hashtable, boost::numeric::ublas::unbounded_array > > >, std::pair, boost::numeric::ublas::unbounded_array > > >, unsigned int>, std::allocator, boost::numeric::ublas::unbounded_array > > >, unsigned int> >, std::_Select1st, boost::numeric::ublas::unbounded_array > > >, unsigned int> >, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, std::_Placeholder, unsigned int, unsigned int)>, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, unsigned int, unsigned int)>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, false, false, true>’
/usr/include/c++/4.6/bits/unordered_map.h:44:11: instantiated from ‘std::__unordered_map, boost::numeric::ublas::unbounded_array > > >, unsigned int, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, unsigned int, unsigned int)>, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, std::_Placeholder, unsigned int, unsigned int)>, std::allocator, boost::numeric::ublas::unbounded_array > > >, unsigned int> >, false>’
/usr/include/c++/4.6/bits/unordered_map.h:256:11: instantiated from ‘std::unordered_map, boost::numeric::ublas::unbounded_array > > >, unsigned int, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, unsigned int, unsigned int)>, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, std::_Placeholder, unsigned int, unsigned int)>, std::allocator, boost::numeric::ublas::unbounded_array > > >, unsigned int> > >’
./sal/alg/ehh.hpp:144:31: instantiated from ‘sal::ehh_results sal::compute_ehh(boost::numeric::ublas::matrix&, unsigned int) [with FloatType = double, T = unsigned int, F = boost::numeric::ublas::basic_row_major, A = boost::numeric::ublas::unbounded_array >]’
src/test/read_test.cpp:11:51: instantiated from here
/usr/include/c++/4.6/bits/stl_pair.h:92:11: error: ‘std::pair::first’ has incomplete type
/usr/include/boost/numeric/ublas/fwd.hpp:73:11: error: declaration of ‘const struct boost::numeric::ublas::matrix_row, boost::numeric::ublas::unbounded_array > > >’
If you want to hash a range of things, you need something like hash_combine(). I usually lift this function from Boost (surprisingly, it wasn't included in the standard!). Here's how I'd use it on std::arrays, and I trust you can manipulate this into something to work on matrix rows:
#include <array>
template <class T>
inline void hash_combine(std::size_t & seed, const T & v)
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
namespace std
{
template<typename T, size_t N> struct hash<array<T, N>>
{
inline size_t operator()(const array<T, N> & a) const
{
size_t seed = 0;
for (size_t i = 0; i != N; ++i)
{
::hash_combine(seed, a[i]);
}
return seed;
}
};
}
(The above specialisation allows you to use std::unordered_set<std::array<int, 10>> etc.)
If the matrix rows don't come with an equality predicate, you could also add a specialization of std::equal_to for matrix rows.