get upper triangle of eigen::selfadjointView<Lower>() - c++

I have this which works fine:
MatrixXf Sig(p,p);
Sig.selfadjointView<Lower>().rankUpdate(xSub.adjoint());
Now, i need to also get the upper triangular
part of Sig. This answer seems to suggest
to do
Sig.triangularView<StrictUpper>()=Sig.adjoint().triangularView<StrictUpper>();
But doing that causes mayhem --or as the compiler calls it:
DetMCD_1.cpp: In function ‘float CStep(const MatrixXf&, Eigen::VectorXi&, const int&, const int&)’:
DetMCD_1.cpp:263:21: error: ‘StrictUpper’ was not declared in this scope
DetMCD_1.cpp:263:34: error: no matching function for call to ‘Eigen::Matrix<float, -0x00000000000000001, -0x00000000000000001>::triangularView()’
DetMCD_1.cpp:263:34: note: candidates are:
/home/kaveh/R/x86_64-pc-linux-gnu-library/2.15/RcppEigen/include/Eigen/src/Core/MatrixBase.h:248:79: note: template<unsigned int Mode> typename Eigen::MatrixBase<Derived>::TriangularViewReturnType<Mode>::Type Eigen::MatrixBase::triangularView() [with unsigned int Mode = Mode, Derived = Eigen::Matrix<float, -0x00000000000000001, -0x00000000000000001>, typename Eigen::MatrixBase<Derived>::TriangularViewReturnType<Mode>::Type = <type error>]
/home/kaveh/R/x86_64-pc-linux-gnu-library/2.15/RcppEigen/include/Eigen/src/Core/MatrixBase.h:249:84: note: template<unsigned int Mode> typename Eigen::MatrixBase<Derived>::ConstTriangularViewReturnType<Mode>::Type Eigen::MatrixBase::triangularView() const [with unsigned int Mode = Mode, Derived = Eigen::Matrix<float, -0x00000000000000001, -0x00000000000000001>, typename Eigen::MatrixBase<Derived>::ConstTriangularViewReturnType<Mode>::Type = <type error>]
DetMCD_1.cpp:263:78: error: no matching function for call to ‘Eigen::Transpose<const Eigen::Matrix<float, -0x00000000000000001, -0x00000000000000001> >::triangularView() const’
DetMCD_1.cpp:263:78: note: candidates are:
/home/kaveh/R/x86_64-pc-linux-gnu-library/2.15/RcppEigen/include/Eigen/src/Core/MatrixBase.h:248:79: note: template<unsigned int Mode> typename Eigen::MatrixBase<Derived>::TriangularViewReturnType<Mode>::Type Eigen::MatrixBase::triangularView() [with unsigned int Mode = Mode, Derived = Eigen::Transpose<const Eigen::Matrix<float, -0x00000000000000001, -0x00000000000000001> >, typename Eigen::MatrixBase<Derived>::TriangularViewReturnType<Mode>::Type = <type error>]
/home/kaveh/R/x86_64-pc-linux-gnu-library/2.15/RcppEigen/include/Eigen/src/Core/MatrixBase.h:249:84: note: template<unsigned int Mode> typename Eigen::MatrixBase<Derived>::ConstTriangularViewReturnType<Mode>::Type Eigen::MatrixBase::triangularView() const [with unsigned int Mode = Mode, Derived = Eigen::Transpose<const Eigen::Matrix<float, -0x00000000000000001, -0x00000000000000001> >, typename Eigen::MatrixBase<Derived>::ConstTriangularViewReturnType<Mode>::Type = <type error>]
make: *** [DetMCD_1.o] Error 1
My question is this: given that i have
the lower triangular part of Sig, how
to convince eigen to return me the full
matrix?

This is because there is typo, it's StrictlyUpper, and not StrictUpper. See the respective doc. The following two lines are equivalent:
Long version:
M.triangularView<StrictlyUpper>()=M.adjoint().triangularView<StrictlyUpper>();
Short version:
M.triangularView<StrictlyUpper>()=M.adjoint();
Please, also not that in most cases you do not need to explicitly compute the upper triangular part.

Related

When casting Eigen matrix type, error: expected primary-expression before ‘float’

template <typename T>
bool operator()(const T* parameters, T* residuals) const
{
Eigen::Matrix<T, 3, 1> pose(parameters[0],parameters[1],parameters[2]);
Eigen::Vector3f pose1 = pose.cast<float>();
Eigen::Affine2f transform = occ->getTransformForState(pose1); // transform: rotation->translation
Eigen::Vector3f tmp1 = occ->interpMapValueWithDerivatives( transform * currPoint);
Eigen::Matrix<T, 3, 1> transformedPointData(tmp1.cast<T>()); /// {M,dM/dx,dM/dy}
T funVal = T(1) - transformedPointData[0];
residuals[0] = funVal;
return true;
}
I have a template member function like above. During compilation, it reports
error: expected primary-expression before ‘float’
Eigen::Vector3f pose1 = pose.cast<float>();
I have to cast to type "float" to make it consistent with "getTransformForState" function's input and output.
I compared with other examples provided by Eigen Library but couldnt find anything wrong.
Any ideas are highly appreciated !
-------------------- update ------------------------
By changing as pose.template cast<float>()
The error is changed as:
/usr/include/eigen3/Eigen/src/Core/MathFunctions.h: In instantiation of ‘static NewType Eigen::internal::cast_impl<OldType, NewType>::run(const OldType&) [with OldType = ceres::Jet<double, 3>; NewType = float]’:
/usr/include/eigen3/Eigen/src/Core/MathFunctions.h:328:44: required from ‘NewType Eigen::internal::cast(const OldType&) [with OldType = ceres::Jet<double, 3>; NewType = float]’
/usr/include/eigen3/Eigen/src/Core/Functors.h:351:104: required from ‘const NewType Eigen::internal::scalar_cast_op<Scalar, NewType>::operator()(const Scalar&) const [with Scalar = ceres::Jet<double, 3>; NewType = float]’
/usr/include/eigen3/Eigen/src/Core/CwiseUnaryOp.h:114:75: required from ‘const Scalar Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::coeff(Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::Index) const [with UnaryOp = Eigen::internal::scalar_cast_op<ceres::Jet<double, 3>, float>; XprType = const Eigen::Matrix<ceres::Jet<double, 3>, 3, 1, 0, 3, 1>; Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::Scalar = float; Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::Index = long int]’
/usr/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h:495:33: required from ‘void Eigen::DenseCoeffsBase<Derived, 1>::copyCoeff(Eigen::DenseCoeffsBase<Derived, 1>::Index, const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<ceres::Jet<double, 3>, float>, const Eigen::Matrix<ceres::Jet<double, 3>, 3, 1, 0, 3, 1> >; Derived = Eigen::Matrix<float, 3, 1>; Eigen::DenseCoeffsBase<Derived, 1>::Index = long int]’
/usr/include/eigen3/Eigen/src/Core/Assign.h:180:5: required from ‘static void Eigen::internal::assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Index, Stop>::run(Derived1&, const Derived2&) [with Derived1 = Eigen::Matrix<float, 3, 1>; Derived2 = Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<ceres::Jet<double, 3>, float>, const Eigen::Matrix<ceres::Jet<double, 3>, 3, 1, 0, 3, 1> >; int Index = 0; int Stop = 3]’
/usr/include/eigen3/Eigen/src/Core/Assign.h:314:21: [ skipping 5 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/eigen3/Eigen/src/Core/Matrix.h:281:31: required from ‘Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::Matrix(const Eigen::MatrixBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<ceres::Jet<double, 3>, float>, const Eigen::Matrix<ceres::Jet<double, 3>, 3, 1, 0, 3, 1> >; _Scalar = float; int _Rows = 3; int _Cols = 1; int _Options = 0; int _MaxRows = 3; int _MaxCols = 1]’
The error message means the compiler doesn't know that pose.cast is a template. There are three basic options for what a class member .foo can be:
A value (e.g. a data member or an enum value)
A type name (e.g. something defined with typedef)
A template for one of the above.
In your case, pose is of type Eigen::Matrix<T, 3, 1>. The compiler doesn't yet know what Eigen::Matrix<T, 3, 1> looks like because it depends on what T is (someone could have specialized Eigen::Matrix differently for different types).
So when you access a member of an unknown class (as with pose.cast), the compiler assumes it's option #1 (a value). This leads to it parsing pose.cast < as the beginning of a less-than comparison. The next token (float) triggers an error because the compiler was expecting another value, not a type name.
The fix is to tell the compiler explicitly that .cast is a template:
Eigen::Vector3f pose1 = pose.template cast<float>();
(The fix for case #2 is to use the typename keyword to force interpretation as a type name.)

Error with constructor of private struct inside a class

I have this class:
template <typename C, typename R, typename D>
class Cache {
typedef std::shared_ptr<cc::Distance<C,D>> DistancePtr;
public:
Cache(const DistancePtr distance, const std::function<R(C)> &backEnd, const size_t size = 10000, const float treshold = 0);
...
private:
struct CacheElem{
CacheElem(const C code, const R result, std::list<size_t>::iterator listElem) : code(code), result(result), listElem(listElem) {}
C code;
R result;
std::list<size_t>::iterator listElem; //pointing to corresponding element in lru0
};
...
I instantiated this object with cc::Cache<int,int,int> cache(...) (I don't know if you need to know all passed arguments, let me know in that case), but I get this error that I don't understand at all:
In file included from /usr/include/c++/5/memory:64:0,
from ../main.cpp:9:
/usr/include/c++/5/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = cc::Cache<int, int, int>::CacheElem; _Args = {}]’:
/usr/include/c++/5/bits/stl_uninitialized.h:519:18: required from ‘static _ForwardIterator std::__uninitialized_default_n_1<_TrivialValueType>::__uninit_default_n(_ForwardIterator, _Size) [with _ForwardIterator = cc::Cache<int, int, int>::CacheElem*; _Size = long unsigned int; bool _TrivialValueType = false]’
/usr/include/c++/5/bits/stl_uninitialized.h:575:20: required from ‘_ForwardIterator std::__uninitialized_default_n(_ForwardIterator, _Size) [with _ForwardIterator = cc::Cache<int, int, int>::CacheElem*; _Size = long unsigned int]’
/usr/include/c++/5/bits/stl_uninitialized.h:637:44: required from ‘_ForwardIterator std::__uninitialized_default_n_a(_ForwardIterator, _Size, std::allocator<_Tp>&) [with _ForwardIterator = cc::Cache<int, int, int>::CacheElem*; _Size = long unsigned int; _Tp = cc::Cache<int, int, int>::CacheElem]’
/usr/include/c++/5/bits/stl_vector.h:1311:36: required from ‘void std::vector<_Tp, _Alloc>::_M_default_initialize(std::vector<_Tp, _Alloc>::size_type) [with _Tp = cc::Cache<int, int, int>::CacheElem; _Alloc = std::allocator<cc::Cache<int, int, int>::CacheElem>; std::vector<_Tp, _Alloc>::size_type = long unsigned int]’
/usr/include/c++/5/bits/stl_vector.h:279:30: required from ‘std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const allocator_type&) [with _Tp = cc::Cache<int, int, int>::CacheElem; _Alloc = std::allocator<cc::Cache<int, int, int>::CacheElem>; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<cc::Cache<int, int, int>::CacheElem>]’
/home/luca/Dropbox/HKUST/CloudCache/cloudcache/CloudCache/Core/Cache.hpp:59:85: required from ‘cc::Cache<C, R, D>::Cache(cc::Cache<C, R, D>::DistancePtr, const std::function<R(C)>&, size_t, float) [with C = int; R = int; D = int; cc::Cache<C, R, D>::DistancePtr = std::shared_ptr<cc::Distance<int, int> >; size_t = long unsigned int]’
../main.cpp:33:53: required from here
/usr/include/c++/5/bits/stl_construct.h:75:7: error: no matching function for call to ‘cc::Cache<int, int, int>::CacheElem::CacheElem()’
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^
In file included from ../Core/CCCore.hpp:19:0,
from ../main.cpp:15:
/home/luca/Dropbox/HKUST/CloudCache/cloudcache/CloudCache/Core/Cache.hpp:36:4: note: candidate: cc::Cache<C, R, D>::CacheElem::CacheElem(C, R, std::__cxx11::list<long unsigned int>::iterator) [with C = int; R = int; D = int; std::__cxx11::list<long unsigned int>::iterator = std::_List_iterator<long unsigned int>]
CacheElem(const C code, const R result, std::list<size_t>::iterator listElem) : code(code), result(result), listElem(listElem) {}
^
/home/luca/Dropbox/HKUST/CloudCache/cloudcache/CloudCache/Core/Cache.hpp:36:4: note: candidate expects 3 arguments, 0 provided
/home/luca/Dropbox/HKUST/CloudCache/cloudcache/CloudCache/Core/Cache.hpp:35:10: note: candidate: constexpr cc::Cache<int, int, int>::CacheElem::CacheElem(const cc::Cache<int, int, int>::CacheElem&)
struct CacheElem{
^
/home/luca/Dropbox/HKUST/CloudCache/cloudcache/CloudCache/Core/Cache.hpp:35:10: note: candidate expects 1 argument, 0 provided
/home/luca/Dropbox/HKUST/CloudCache/cloudcache/CloudCache/Core/Cache.hpp:35:10: note: candidate: constexpr cc::Cache<int, int, int>::CacheElem::CacheElem(cc::Cache<int, int, int>::CacheElem&&)
/home/luca/Dropbox/HKUST/CloudCache/cloudcache/CloudCache/Core/Cache.hpp:35:10: note: candidate expects 1 argument, 0 provided
<builtin>: recipe for target 'main.o' failed
make: *** [main.o] Error 1
Why this happen?
UPDATE TO COMMENT ONE ANSWER:
Ok I found out where the problem is, but not why it occours. The Cache constructor implementation is this one:
template <typename C, typename R, typename D>
Cache<C,R,D>::Cache(const DistancePtr distance, const std::function<R(C)> &backEnd, const size_t size, const float treshold)
: distance(distance), backEnd(backEnd), values(size), treshold(treshold), size(size) {}
Where values is declared as:
std::vector<CacheElem> values;
But if I delete values(size) from the constructor above, everything works fine and no compile error occurs. Why? And hot to solve it?
It looks like the problem is that you're missing a default constructor for CacheElem. Somewhere in your code, a CacheElem needs to be default constructed, either because you stored it in an STL container that requires elements to be default constructible, or because you simply tried to instantiate one somewhere without calling a constructor.
I found the error thanks to the tip from this answer.
Changing the Cache constructor implementation from this:
template <typename C, typename R, typename D>
Cache<C,R,D>::Cache(const DistancePtr distance, const std::function<R(C)> &backEnd, const size_t size, const float treshold)
: distance(distance), backEnd(backEnd), values(size), treshold(treshold), size(size) {}
To this:
template <typename C, typename R, typename D>
Cache<C,R,D>::Cache(const DistancePtr distance, const std::function<R(C)> &backEnd, const size_t size, const float treshold)
: distance(distance), backEnd(backEnd), treshold(treshold), size(size) {
values.reserve(size);
}
Solved the problem. I think because calling values(size) is implicitly calling resize() which is illegal without providing CacheElem constructor elements.

How can I use std::rotate to rotate an array of pairs whose first member is const?

I am implementing a map, and I would like to use std::rotate on an array of pairs, of which the first member is const (so that the key cannot be changed when inserted in the map). It is equivalent to the code below which doesn't compile:
#include <utility>
#include <array>
#include <algorithm>
int main()
{
typedef std::pair<const int, int> map_entry;
std::array<map_entry, 3> a{ { {2, 0}, {1, 0}, {3, 0} } };
std::rotate(&a[0], &a[1], &a[3]);
}
Unfortunately, I cannot control the type of the pair ("value_type") which needs to be defined as follows be compatible with std::unordered_map:
template <class K, class T, class H, class P, class A>
class unordered_map
{
public:
typedef K key_type;
typedef std::pair<const K, T> value_type;
typedef T mapped_type;
Is there way for me to use std::rotate on such an array, maybe by removing the const somehow?
Here is the compile error:
$ g++ -std=c++11 xx.cxx
In file included from /usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/utility:70:0,
from xx.cxx:1:
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_pair.h: In instantiation of ‘std::pair<_T1, _T2>& std::pair<_T1, _T2>::operator=(std::pair<_T1 , _T2>&&) [with _T1 = const int; _T2 = int]’:
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_algo.h:1610:22: required from ‘void std::__rotate(_RandomAccessIterator, _RandomAccessIterat or, _RandomAccessIterator, std::random_access_iterator_tag) [with _RandomAccessIterator = std::pair<const int, int>*]’
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_algo.h:1686:59: required from ‘void std::rotate(_FIter, _FIter, _FIter) [with _FIter = std:: pair<const int, int>*]’
xx.cxx:9:36: required from here
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_pair.h:170:8: error: assignment of read-only member ‘std::pair<const int, int>::first’
first = std::forward<first_type>(__p.first);
^
In file included from /usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_pair.h:59:0,
from /usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/utility:70,
from xx.cxx:1:
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/move.h: In instantiation of ‘void std::swap(_Tp&, _Tp&) [with _Tp = const int]’:
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_pair.h:199:23: required from ‘void std::pair<_T1, _T2>::swap(std::pair<_T1, _T2>&) [with _T1 = const int; _T2 = int]’
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_pair.h:256:7: required from ‘void std::swap(std::pair<_T1, _T2>&, std::pair<_T1, _T2>&) [wit h _T1 = const int; _T2 = int]’
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_algobase.h:147:22: required from ‘void std::iter_swap(_ForwardIterator1, _ForwardIterator2) [with _ForwardIterator1 = std::pair<const int, int>*; _ForwardIterator2 = std::pair<const int, int>*]’
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_algo.h:1616:28: required from ‘void std::__rotate(_RandomAccessIterator, _RandomAccessIterat or, _RandomAccessIterator, std::random_access_iterator_tag) [with _RandomAccessIterator = std::pair<const int, int>*]’
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_algo.h:1686:59: required from ‘void std::rotate(_FIter, _FIter, _FIter) [with _FIter = std:: pair<const int, int>*]’
xx.cxx:9:36: required from here
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/move.h:176:11: error: assignment of read-only reference ‘__a’
__a = _GLIBCXX_MOVE(__b);
^
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/move.h:177:11: error: assignment of read-only reference ‘__b’
__b = _GLIBCXX_MOVE(__tmp);
^
Simple: don't use std::pair. Design a class that has the semantics that you need and use that. In particular, don't make the data members const. Instead, make them private and write accessors to enforce const-ness. int first() const;, int second() const; and int& second(); are a good start. But they really should be named key() and value(), or something else that matches your design better.
I found my solution. Internally, I store the pair without the const (mutable_value_type), but I still define value_type with the const and this is what is returned when you dereference an iterator for example.
template <class K, class T, class H, class P, class A>
class unordered_map
{
public:
typedef K key_type;
typedef std::pair<const K, T> value_type;
typedef std::pair<K, T> mutable_value_type;

Why does boost require &vector[0]?

Take edmonds_maximum_cardinality_matching for example. I can do:
vector<uint32_t> mate_map(n_vertices);
edmonds_maximum_cardinality_matching(g, &mate_map[0]);
But not:
vector<uint32_t> mate_map(n_vertices);
edmonds_maximum_cardinality_matching(g, mate_map);
Why is that so? A vector has all operations an array has right? NB: Here is the error message (for the second snippet) which I could not really handle:
In file included from main.C:5:0:
/usr/include/boost/graph/max_cardinality_matching.hpp: In instantiation of ‘static void boost::extra_greedy_matching<Graph, MateMap>::find_matching(const Graph&, MateMap) [with Graph = boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS>; MateMap = std::vector<unsigned int>]’:
/usr/include/boost/graph/max_cardinality_matching.hpp:842:63: required from ‘bool boost::matching(const Graph&, MateMap, VertexIndexMap) [with Graph = boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS>; MateMap = std::vector<unsigned int>; VertexIndexMap = boost::vec_adj_list_vertex_id_map<boost::no_property, long unsigned int>; AugmentingPathFinder = boost::edmonds_augmenting_path_finder; InitialMatchingFinder = boost::extra_greedy_matching; MatchingVerifier = boost::no_matching_verifier]’
/usr/include/boost/graph/max_cardinality_matching.hpp:885:19: required from ‘void boost::edmonds_maximum_cardinality_matching(const Graph&, MateMap, VertexIndexMap) [with Graph = boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS>; MateMap = std::vector<unsigned int>; VertexIndexMap = boost::vec_adj_list_vertex_id_map<boost::no_property, long unsigned int>]’
/usr/include/boost/graph/max_cardinality_matching.hpp:894:70: required from ‘void boost::edmonds_maximum_cardinality_matching(const Graph&, MateMap) [with Graph = boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS>; MateMap = std::vector<unsigned int>]’
main.C:20:51: required from here
/usr/include/boost/graph/max_cardinality_matching.hpp:617:58: error: no matching function for call to ‘put(std::vector<unsigned int>&, boost::iterators::detail::iterator_facade_base<boost::range_detail::integer_iterator<long unsigned int>, long unsigned int, boost::iterators::random_access_traversal_tag, long unsigned int, long int, false, false>::reference, boost::graph_traits<boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS> >::vertex_descriptor)’
put(mate, *vi, graph_traits<Graph>::null_vertex());
^
/usr/include/boost/graph/max_cardinality_matching.hpp:617:58: note: candidates are:
In file included from /usr/include/boost/graph/adjacency_list.hpp:36:0,
from main.C:4:
/usr/include/boost/property_map/property_map.hpp:124:15: note: template<class T, class V> void put(T*, std::ptrdiff_t, const V&)
inline void put(T* pa, std::ptrdiff_t k, const V& val) { pa[k] = val; }
^
/usr/include/boost/property_map/property_map.hpp:124:15: note: template argument deduction/substitution failed:
In file included from main.C:5:0:
/usr/include/boost/graph/max_cardinality_matching.hpp:617:58: note: mismatched types ‘T*’ and ‘std::vector<unsigned int>’
put(mate, *vi, graph_traits<Graph>::null_vertex());
^
In file included from /usr/include/boost/graph/adjacency_list.hpp:36:0,
from main.C:4:
/usr/include/boost/property_map/property_map.hpp:193:8: note: template<class K, class V> void boost::put(const boost::writable_property_map_archetype<K, V>&, const typename boost::writable_property_map_archetype<K, V>::key_type&, const typename boost::writable_property_map_archetype<K, V>::value_type&)
void put(const writable_property_map_archetype<K,V>&,
^
/usr/include/boost/property_map/property_map.hpp:193:8: note: template argument deduction/substitution failed:
In file included from main.C:5:0:
/usr/include/boost/graph/max_cardinality_matching.hpp:617:58: note: ‘std::vector<unsigned int>’ is not derived from ‘const boost::writable_property_map_archetype<K, V>’
put(mate, *vi, graph_traits<Graph>::null_vertex());
^
In file included from /usr/include/boost/graph/adjacency_list.hpp:36:0,
from main.C:4:
/usr/include/boost/property_map/property_map.hpp:307:3: note: template<class PropertyMap, class Reference, class K, class V> void boost::put(const boost::put_get_helper<Reference, PropertyMap>&, K, const V&)
put(const put_get_helper<Reference, PropertyMap>& pa, K k, const V& v)
^
/usr/include/boost/property_map/property_map.hpp:307:3: note: template argument deduction/substitution failed:
In file included from main.C:5:0:
/usr/include/boost/graph/max_cardinality_matching.hpp:617:58: note: ‘std::vector<unsigned int>’ is not derived from ‘const boost::put_get_helper<Reference, PropertyMap>’
put(mate, *vi, graph_traits<Graph>::null_vertex());
^
In file included from /usr/include/boost/graph/properties.hpp:21:0,
from /usr/include/boost/graph/adjacency_list.hpp:44,
from main.C:4:
/usr/include/boost/graph/property_maps/null_property_map.hpp:32:10: note: template<class K, class V> void boost::put(boost::null_property_map<K, V>&, const K&, const V&)
void put(null_property_map<K,V>& /*pm*/, const K& /*key*/, const V& /*value*/)
^
/usr/include/boost/graph/property_maps/null_property_map.hpp:32:10: note: template argument deduction/substitution failed:
In file included from main.C:5:0:
/usr/include/boost/graph/max_cardinality_matching.hpp:617:58: note: ‘std::vector<unsigned int>’ is not derived from ‘boost::null_property_map<K, V>’
put(mate, *vi, graph_traits<Graph>::null_vertex());
^
In file included from /usr/include/boost/graph/adjacency_list.hpp:246:0,
from main.C:4:
/usr/include/boost/graph/detail/adjacency_list.hpp:1760:5: note: template<class Config, class Base, class Property, class Key, class Value> void boost::put(Property, boost::adj_list_helper<Config, Base>&, const Key&, const Value&)
put(Property p, adj_list_helper<Config, Base>& g,
^
/usr/include/boost/graph/detail/adjacency_list.hpp:1760:5: note: template argument deduction/substitution failed:
In file included from main.C:5:0:
/usr/include/boost/graph/max_cardinality_matching.hpp:617:58: note: mismatched types ‘boost::adj_list_helper<Config, Base>’ and ‘boost::iterators::detail::iterator_facade_base<boost::range_detail::integer_iterator<long unsigned int>, long unsigned int, boost::iterators::random_access_traversal_tag, long unsigned int, long int, false, false>::reference {aka long unsigned int}’
put(mate, *vi, graph_traits<Graph>::null_vertex());
^
In file included from /usr/include/boost/graph/max_cardinality_matching.hpp:22:0,
from main.C:5:
/usr/include/boost/graph/filtered_graph.hpp:472:3: note: template<class G, class EP, class VP, class Property, class Key, class Value> void boost::put(Property, const boost::filtered_graph<Graph, EdgePredicate, VertexPredicate>&, const Key&, const Value&)
put(Property p, const filtered_graph<G, EP, VP>& g, const Key& k,
^
/usr/include/boost/graph/filtered_graph.hpp:472:3: note: template argument deduction/substitution failed:
In file included from main.C:5:0:
/usr/include/boost/graph/max_cardinality_matching.hpp:617:58: note: mismatched types ‘const boost::filtered_graph<Graph, EdgePredicate, VertexPredicate>’ and ‘boost::iterators::detail::iterator_facade_base<boost::range_detail::integer_iterator<long unsigned int>, long unsigned int, boost::iterators::random_access_traversal_tag, long unsigned int, long int, false, false>::reference {aka long unsigned int}’
put(mate, *vi, graph_traits<Graph>::null_vertex());
^
Full output here: http://pastebin.com/fG2aLRiG (Outsourced because of SO's restrictions on post length)
"A vector has all operations an array has" No. Arrays implicitly decay to pointers, vector does not. So when boost tries to pass it to the put function it generates this error:
error: no matching function for call to ‘put(std::vector<unsigned int>&, [blah blah])
note: candidates are:
template<class T, class V> void put(T*, std::ptrdiff_t, const V&)
template argument deduction/substitution failed:
mismatched types ‘T*’ and ‘std::vector<unsigned int>’
[followed by details about the other potential put functions]
Apperently the put function would accept one of these, or something that implicitly converts to one of these.
T*
boost::writable_property_map_archetype<K, V>&
const boost::put_get_helper<Reference, PropertyMap>&
boost::null_property_map<K, V>&
Property
(edmonds_maximum_cardinality_matching may have other requirements that cause these other types to also be invalid, I'm just saying these five types pass this particular hurdle.)
No, a std::vector does not have all these operations and won't convert to an array implicitly. Ignoring the fact that a std::array won't change that, for your purposes, it would be better suited.

map eigen::MatrixXf to an existing eigen::matrixXf

Sometime ago user ggael gave an answer to the
problem of mapping a eigen::vectorXf to an eigen::matrixXf.
Now, i need to do something similar, but to an existing matrix,
e.g i know i can:
for(int i=0;i<p;++i){
VectorXf vec=q.col(i);
/*q is a p**2 by n matrix*/
Map<MatrixXf> qi(vec.data(),p,p);
/*run function that uses qi to produce a scalare and store that scalar*/
}
but (it seems to me) it would be more efficient to
create qi once and for all outside the loop and then
use the same qi over and over again (is that right?)
Also, i wonder whether the intermediate step where
i map q.col(i) to vec is really necessary...
A recent answer proposes to do:
qi=Map<MatrixXd>(vec.data(),p,p);
but doing that yields:
In function ‘Eigen::VectorXi DepType(const MatrixXf&, const MatrixXf&, const int&)’:
DeC.cpp:279:34: error: no matching function for call to ‘Eigen::Map<Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001> >::Map(Eigen::PlainObjectBase<Eigen::Matrix<float, -0x00000000000000001, 1> >::Scalar*, int&, int&)’
DeC.cpp:279:34: note: candidates are:
/eigen/Eigen/src/Core/Map.h:179:12: note: Eigen::Map<MatrixType, MapOptions, StrideType>::Map(Eigen::Map<MatrixType, MapOptions, StrideType>::PointerArgType, Eigen::Map<MatrixType, MapOptions, StrideType>::Index, Eigen::Map<MatrixType, MapOptions, StrideType>::Index, const StrideType&) [with PlainObjectType = Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001>, int MapOptions = 0, StrideType = Eigen::Stride<0, 0>, Eigen::Map<MatrixType, MapOptions, StrideType>::PointerArgType = double*, Eigen::Map<MatrixType, MapOptions, StrideType>::Index = long int]
/home/kaveh/Desktop/work/p1/geqw4/vi3/out/sp/ccode/eigen/Eigen/src/Core/Map.h:179:12: note: no known conversion for argument 1 from ‘Eigen::PlainObjectBase<Eigen::Matrix<float, -0x00000000000000001, 1> >::Scalar* {aka float*}’ to ‘double*’
/eigen/Eigen/src/Core/Map.h:166:12: note: Eigen::Map<MatrixType, MapOptions, StrideType>::Map(Eigen::Map<MatrixType, MapOptions, StrideType>::PointerArgType, Eigen::Map<MatrixType, MapOptions, StrideType>::Index, const StrideType&) [with PlainObjectType = Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001>, int MapOptions = 0, StrideType = Eigen::Stride<0, 0>, Eigen::Map<MatrixType, MapOptions, StrideType>::PointerArgType = double*, Eigen::Map<MatrixType, MapOptions, StrideType>::Index = long int]
/eigen/Eigen/src/Core/Map.h:166:12: note: no known conversion for argument 1 from ‘Eigen::PlainObjectBase<Eigen::Matrix<float, -0x00000000000000001, 1> >::Scalar* {aka float*}’ to ‘double*’
/eigen/Eigen/src/Core/Map.h:154:12: note: Eigen::Map<MatrixType, MapOptions, StrideType>::Map(Eigen::Map<MatrixType, MapOptions, StrideType>::PointerArgType, const StrideType&) [with PlainObjectType = Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001>, int MapOptions = 0, StrideType = Eigen::Stride<0, 0>, Eigen::Map<MatrixType, MapOptions, StrideType>::PointerArgType = double*]
/eigen/Eigen/src/Core/Map.h:154:12: note: candidate expects 2 arguments, 3 provided
/eigen/Eigen/src/Core/Map.h:119:79: note: Eigen::Map<Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001> >::Map(const Eigen::Map<Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001> >&)
/eigen/Eigen/src/Core/Map.h:119:79: note: candidate expects 1 argument, 3 provided
e.g. it seems Eigen thinks qi is a vector....:(
The following:
qi=Map<MatrixXd>(vec.data(),p,p);
means that you want to copy the coefficients of Map(vec.data(),p,p) into the matrix referenced by qi. However, what you actually want is to re-initialize the Map<> object. To do so you must call the constructor again using the construct new syntax of C++:
new (&qi) Map<MatrixXd>(vec.data(),p,p);
Moreover, I must say that a Map<> object is extremely lightweight: it is only one pointer and 2 integers that are statically allocated on the stack. So moving the declaration of Map<> qi outside the loop will have zero effect on the performance. On the other hand, note that you do not need to copy q.col(i) into a temporary buffer. If q is column major, you can directly do:
Map<MatrixXf> qi(q.col(i).data(),p,p);