math icon indicating copy to clipboard operation
math copied to clipboard

add templates for bisect and other functions for different boost units

Open L0ric0 opened this issue 5 years ago • 6 comments

the boost::math::tools::bisect function returns std::pair<T, T> at the moment. this is ok when using c integral types for the functions. when trying to use boost units for this it is impossible to for a function that has the following name: boost::units::quantity<boost::units::si::length, double> f(boost::units::quantity<boost::units::si::time, double> t) as this is a common occurance when using boost units it wouldbe nice to have an additional template for this case (probably not only for the bisect method but all methods where the units could be different).

an example repository that shows this problem for bisect and barycentric_rational can be found at https://github.com/L0ric0/boostorg-mat-issue-314

related to #314

L0ric0 avatar Jul 07 '20 09:07 L0ric0

This would be tricky to program correctly in general, but I think you're correct that this would be useful, and the correct method would be to use decltype post C++11 to get the function return type and meta-program from there to fix up the correct types.

jzmaddock avatar Jul 07 '20 10:07 jzmaddock

to not use decltype and to make the implementation easier for now one could let the user declare the return type as a template argument (as for all use cases where units are used it should be known)

L0ric0 avatar Jul 07 '20 11:07 L0ric0

@jzmaddock The return of boost::math::tools::bisect is std::pair<T, T> but it in all test cases, and the example from @L0ric0 .first is immediately called from the return. Is .second ever a useful return value? If it is not changing bisect to auto -> decltype(f), removing all the instances of std::make_pair() and just returning what would have been .first resolves the issue. It would also be compliant with C++11. As for barycentric_rational I will have to look more thoroughly because it is part of a class and not standalone.

mborland avatar Jul 10 '20 04:07 mborland

Bisect naturally returns an interval which contains the true root - IMO yes .second can be useful, especially if the procedure terminates prior to finding a tight interval. I can see how to program the return type (probably via a trait), I just need to find some time ;)

jzmaddock avatar Jul 10 '20 08:07 jzmaddock

Having now looked into this some more, I see that it's a non-starter, I just can't get dimensioned quantities to work inside bisect> Among other things:

  • No comparison to literal zero, and no alternative (ie not usable in boolean contexts).
  • No ability to check that the endpoints bracket the root (related to no comparisons).
  • No constructor from a scalar either, so we can't construct a dimensioned zero.
  • No concept of epsilon.

There are other complications too, some I can work around others not so much. The inability to check on the sign of a dimensioned value is a killer though.

jzmaddock avatar Jul 29 '20 16:07 jzmaddock

Hey!! Are you willing to accept new contributors? I am interested into contributing to this repository so, if you could explain a bit more this feature, it would be great. Thanks

Rashika101 avatar Jan 23 '21 06:01 Rashika101