This forum has been archived. All content is frozen. Please use KDE Discuss instead.

cwise min/max with a scalar

Tags: None
(comma "," separated)
abachrac
Registered Member
Posts
8
Karma
0
OS

cwise min/max with a scalar

Fri Dec 30, 2011 12:08 am
I was surprised to find that the max function in the array class does not allow you to pass in a scalar.

Is there a reason for this/is this going to be implemented?

Array4d x;
x<<1,-2,3,4;
x.max(0); //doesn't work
x.max(Array4d::Zero()); // works but seems inefficient for large arrays

the submitter of this post was extending eigen to do this, but it seems like it should be built in!
viewtopic.php?f=74&t=23287&p=30316&hilit=max+scalar#p30316


thanks!
-=Abe
abachrac
Registered Member
Posts
8
Karma
0
OS

Re: cwise min/max with a scalar

Fri Dec 30, 2011 4:40 pm
also, on a semi-related note... is there any way to obtain the coefficients of the indices for a rowwise call to maxCoeff?

ie:

Code: Select all
 
  ArrayXXd test= ArrayXXd::Random(5,5);
  ArrayXi inds;
  ArrayXd mtest = test.rowwise().maxCoeff(inds);
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS

Re: cwise min/max with a scalar

Mon Jan 02, 2012 1:41 pm
sounds reasonable, feel free to add one for both requests there: http://eigen.tuxfamily.org/bz/ so that we don't forget about them. You might even try to submit patches! For the former, I'd rather make array.max(scalar) a shortcut for array.max(ArrayType::Constant(array.rows(), array.cols(), scalar)). I don't see any reason why this would be slower than adding a specialized functor and this would provide vectorization automatically.
abachrac
Registered Member
Posts
8
Karma
0
OS

Re: cwise min/max with a scalar

Fri Jan 06, 2012 4:30 am
glad to hear you think the suggestions are reasonable... I created the feature requests.

I also read through some of the documentation, and tried to tackle implementing the max with a scalar function, however I'm stuck and not sure what to try next...

Following instructions in:
http://eigen.tuxfamily.org/dox/TopicCus ... Eigen.html

I created an extension header with the following function definition:

Code: Select all
EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, const Derived>
max(const Scalar &other) const
{
  return max(Derived::PlainObject::Constant(rows(), rows(), other));
}

which doesn't compile.


I tried a bunch of other permutations, such as:

Code: Select all
EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, const Derived>
max(const Scalar &other) const
{
  return CwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, const Derived>
       (derived(), Derived::PlainObject::Constant(rows(), rows(), other));
}

which does compile but throws a runtime exection.

It's probably something stupid, but not sure what else to try...

I also wasn't 100% sure where the function would belong in the codebase. My best guess is:
Eigen/src/Plugins/ArrayCwiseBinaryOps.h
is that correct? or would somewhere else be more appropriate.

thanks!
-=Abe
jitseniesen
Registered Member
Posts
204
Karma
2

Re: cwise min/max with a scalar

Fri Jan 06, 2012 10:56 am
abachrac wrote:I created an extension header with the following function definition:

Code: Select all
EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, const Derived>
max(const Scalar &other) const
{
  return max(Derived::PlainObject::Constant(rows(), rows(), other));
}

which doesn't compile.


The error message from the compiler should give you a hint on what is going on. Without your test code and the error message, we cannot be sure what the issue is.

However, I can guess. Perhaps the problem is that the type of "Derived::PlainObject::Constant(rows(), rows(), other)" does not correspond with the third template argument of the CwiseBinaryOp. The static member function Constant() returns an object of the type CwiseNullaryOp. I think the correct version for your function is
Code: Select all
EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, const CwiseNullaryOp<internal::scalar_constant_op<float>, PlainObject> >
max(const Scalar &other) const
{
  return max(PlainObject::Constant(rows(), rows(), other));
  /*                                       ^^^^
                        should probably be cols()  */
}


The reason that your second attempt compiles may be that in that case, the return value of Constant() is converted to a temporary object of the type PlainObject = Array. However, there are two problems with this. Firstly, it is inefficient. Secondly, the temporary object may be deleted before the evaluation of the CwiseBinaryOp, leaving a dangling reference; this may be the cause of your runtime error.
abachrac
Registered Member
Posts
8
Karma
0
OS

Re: cwise min/max with a scalar

Fri Jan 06, 2012 1:24 pm
Thanks you very much for your help. You are correct. The issue was the third template argument.

The correct function is:
Code: Select all
EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, const ConstantReturnType>
max(const Scalar &other) const
{
  return max(Derived::PlainObject::Constant(rows(), cols(), other));
}


ConstantReturnType is a typedef for the CwiseNullaryOp<> exorpression that you suggested.



I had meant to summarize the error message, however, however it was HUGE, and I didn't think it would be all that interpretable/useful.

thanks again!


Bookmarks



Who is online

Registered users: Bing [Bot], Google [Bot], Yahoo [Bot]