mlpack / ensmallen

A header-only C++ library for numerical optimization --

Home Page:http://ensmallen.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

armadillo / bandicoot conv_to ambiguity

zoq opened this issue · comments

In some optimizers / functions we use conv_to<type>::from(X), now ADL doesn't work here since it matches arma::conv_to and coot::conv_to, so this will fail if I build against bandicoot. An easy solution is to introduce a type_trait for coot and arma types and implement a utility function that call's the right conv_to based on the type. But maybe there is a better solution? @conradsnicta @rcurtin

Dealing with ADL is always fun. Not sure what the best approach is without looking into this deeper. However, the suggested approach (essentially an abstraction layer) sounds pragmatic and doable.

(PS. Based on experience, ADL in its current state is a net negative in my view. In retrospect, its inclusion into the C++ standard was a mistake. A better solution would be to have an explicit using statement for every function/object that would be allowed to be pulled in during lookups and argument matching.)

I guess another solution would be to make conv_to a member function of X, instead of a standalone function. But maybe there is a reason why you opted out for this? So similar to X.max() I can also do X.conv_to<type>().

Armadillo aims to follow both the letter and spirit of Matlab syntax, where stand-alone functions take inputs and provide outputs, ie. Y = f(X). Member functions mainly aim to modify the underlying objects, eg. X.load().

There are targeted exceptions for pragmatic reasons, such as Y = X.t(), which aims to mimic the transpose operation in Matlab (ie. Y = X'). The X.max() member function is available so the maximum scalar value can be obtained regardless whether X is a vector or matrix, which is not possible in normal Matlab syntax without ugly workarounds that may have performance penalties (eg. val = max(max(X)), or val = max(vectorise(X))). It's of course possible to have dedicated internal code that ameliorates the performance penalties, but this adds to the maintenance burden and doesn't address the ugliness aspect.

For the conv_to family of functions, I'd rather not modify/extend the Armadillo API for a central function such as this. Adding the X.conv_to() member function would be inconsistent with the Y = f(X) pattern, and does not have a widely-applicable use case to warrant an exception. Furthermore, it takes ages for the Armadillo packages to be updated in various Linux distros, meaning it would take a long time for any new functionality to be sufficiently available. Case in point: ensmallen currently can only use Armadillo API up to version 9.800 due to Ubuntu 20.04 LTS.

Thanks for the clarification; I also don't want to backport specific armadillo functions because we like to support older versions. That said, I think the extra type-dependent conversion utility is good enough.

The workaround solution you proposed is a bit tedious, but unfortunately I don't think we can do much better than that. 👍

This issue has been automatically marked as stale because it has not had any recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions! 👍