Re: [eigen] combine matrix blocks

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


sorry for the long delay.

On Mon, Jul 13, 2009 at 7:09 PM, Stefan Ulbrich<s.ulbrich@xxxxxxxxxxxxxx> wrote:
> I started on an operator that returns the 'proxy'. I'm not so sure but I
> think constructor copies the whole matrix. For the operator (or in general)
> I guess this is not necessary, is it?
>  template <typename RowType, typename ColType>
>   RowColProxy<Derived, RowType, ColType>
>   operator()(RowType rowProxy, ColType colProxy) {
>           Eigen::RowColProxy<Derived,RowType,ColType> proxy(*this, rowProxy,
> colProxy);
>           return proxy;
>   }

indeed, you should use const references:

template <typename RowType, typename ColType>
RowColProxy<Derived, RowType, ColType>
operator()(const RowType& rowProxy, const ColType& colProxy) {
 return RowColProxy<Derived,RowType,ColType> proxy(derived(),
rowProxy, colProxy);
}

with also a const version:

template <typename RowType, typename ColType>
const RowColProxy<Derived, RowType, ColType>
operator()(const RowType& rowProxy, const ColType& colProxy) const {
 return RowColProxy<Derived,RowType,ColType> proxy(derived(),
rowProxy, colProxy);
}

> For the Range I thought about three versions
> 1. the normal range
>        template<int Size>
>                   inline CwiseNullaryOp<ei_scalar_range_op<int>,
> Matrix<int,Size,1> >
>                   Range(int from, int to) {
>                           int size = (to-from);
>                           return CwiseNullaryOp<ei_scalar_range_op<int>,
> Matrix<int,Size,1> >(size, 1, ei_scalar_range_op<int>(from));
>                   };
> 2. slices
>           // typedef for return type (template parameter Size)
>           template<int Size>
>                   inline CwiseNullaryOp<ei_scalar_slice_op<int>,
> Matrix<int,Size,1> >
>                   Range(int from, int to, int stride) {
>                           int size = (int) ((to-from)/stride);
>                           return CwiseNullaryOp<ei_scalar_slice_op<int>,
> Matrix<int,Size,1> >(size, 1, ei_scalar_slice_op<int>(from,stride));
>                   };
>  3. the identity interval
>           template<int Size>
>                   inline CwiseNullaryOp<ei_scalar_id_range_op<int>,
> Matrix<int,Size,1> >
>                   Range() {
>                           return CwiseNullaryOp<ei_scalar_id_range_op<int>,
> Matrix<int,Size,1> >(Size, 1, ei_scalar_id_range_op<int>());
>                   };
> The question is if it's better to define it dynamically sized (there are no
> default template parameters for functions) or like I did?

you can have both, and the prototype of the functions have to be
adapted accordingly, e.g.:

// dynamic or fixed size:
template<int Size>
inline CwiseNullaryOp<ei_scalar_range_op<int>, Matrix<int,Size,1> >
Range(int from, int size=Size) { // we only need to specify the start
  return CwiseNullaryOp<ei_scalar_range_op<int>, Matrix<int,Size,1>
>(size, 1, ei_scalar_range_op<int>(from));
}

// dynamic size only:
inline CwiseNullaryOp<ei_scalar_range_op<int>, VectorXi >
Range(int start, int size) {
  return CwiseNullaryOp<ei_scalar_range_op<int>, VectorXi >(size, 1,
ei_scalar_range_op<int>(start));
}

This one can write:

// fixed size:
Range<3>(2);
// dynamic size
Range(2,3);

// in a templated code where v can be a fixed-size of dynamic-size vector:
template<typename VectorType> void foo(const VectorType& v)
{
  enum { Half = VectorType::SizeAtCompileTime==Dynamic ? Dynamic :
VectorType::SizeAtCompileTime/2 };
  Range<Half>(0,v.size()/2);
}

cheers,

Gael.



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/