[Dune-devel] [PATCH] Use unqualified calls to allow ADL.
Carsten Gräser
graeser at mi.fu-berlin.de
Tue Sep 1 15:37:08 CEST 2015
Hi Christian,
Am 01.09.2015 um 15:06 schrieb Christian Engwer:
> Hi Carsten,
>
> (a) the double cast is only used, if K is an integer type.
argh, of course you're right. However the precision issue
still persists for types that don't fit into double, e.g.,
long long. While not even the standard guarantees the
existence of an sqrt function which enough precision
(long double may only have 64bit), we may want to be
able to customize here.
> (b) fvmeta is one of the ancient artifacts that are there from the
> (nearly) very beginning and the design is far from nice
> (c) I guess Peter was the inital author, but this will be kind of
> tricky to find out, as the content was moved around quite often.
> (d) I currently don't see where the current code fails with user
> defined types.
Up to the precision issue, I had the same impression.
> (e) the ADL is here quite new (from june), perhaps it isn't in the
> release branch?
I can't remember, that/when I merged it, but it's indeed in
the release branch.
Carsten
>
> Hi Atgeirr,
>
> if it fails this is definitely a bug and must be fixed. Could you
> please send a test example.
>
> Ciao
> Christian
>
> On Tue, Sep 01, 2015 at 02:45:48PM +0200, Carsten Gräser wrote:
>> Dear Atgeirr,
>> thanks for the patch. To in corporate it in dune 2.4 I'd first
>> like to see it in the master and then merge from there. Hence
>> I'd prefer a patch against master. However, I'm unclear if we should
>> merge this.
>>
>> It seems to me that fvmeta already uses proper adl internally.
>> So there seems to be no need to add this on top. The only place
>> that does not seem to be fully generic is the square root, that
>> does first cast to double for non-complex types and hence be
>> inexact if your type has higher precision. The latter might
>> just be an error.
>>
>> But even for this you could customize by spezializing the
>> struct fvmeta:Sqrt. The question is if this is the "official"
>> customization point, which is an interface decision that
>> I'd like to have discussed before. Perhaps the inventor of
>> fvmeta (Christian?) can comment on what he had in mind.
>>
>> Best,
>> Carsten
>>
>>
>>
>>
>>
>> What exactly would you like to customize?
>> Am 01.09.2015 um 11:22 schrieb Atgeirr Rasmussen:
>>> From 476d7e2e9ac446568ded32e41e5d9e2265eded85 Mon Sep 17 00:00:00 2001
>>> From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= <atgeirr at sintef.no>
>>> Date: Tue, 1 Sep 2015 10:53:25 +0200
>>> Subject: [PATCH] Use unqualified calls to allow ADL.
>>>
>>> In order to have argument-dependent-lookup for calls to absreal()
>>> and the other functions defined in the fvmeta namespace, the calls
>>> must be unqualified.
>>>
>>> This makes it easier to use FieldVector/FieldMatrix with user-defined types.
>>>
>>> I posted this to the developer list, if I should have used another channel, please
>>> tell me (and sorry!).
>>>
>>> I hope it is possible to get this in the release, the patch has been made
>>> against the 2.4 branch. Please tell me if you'd prefer a patch against the
>>> master branch. Also, the patch contain many repeated comments explaining
>>> the reason for the using-statements, if you'd rather be without them I'll change it.
>>>
>>> ---
>>> dune/common/densematrix.hh | 20 ++++++++++++--------
>>> dune/common/densevector.hh | 17 +++++++++++------
>>> 2 files changed, 23 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/dune/common/densematrix.hh b/dune/common/densematrix.hh
>>> index d3ed73f..951810c 100644
>>> --- a/dune/common/densematrix.hh
>>> +++ b/dune/common/densematrix.hh
>>> @@ -553,9 +553,10 @@ namespace Dune
>>> //! frobenius norm: sqrt(sum over squared values of entries)
>>> typename FieldTraits<value_type>::real_type frobenius_norm () const
>>> {
>>> + using fvmeta::sqrt; // Must make unqualified calls to allow argument dependent lookup.
>>> typename FieldTraits<value_type>::real_type sum=(0.0);
>>> for (size_type i=0; i<rows(); ++i) sum += (*this)[i].two_norm2();
>>> - return fvmeta::sqrt(sum);
>>> + return sqrt(sum);
>>> }
>>>
>>> //! square of frobenius norm, need for block recursion
>>> @@ -815,7 +816,8 @@ namespace Dune
>>> // LU decomposition of A in A
>>> for (size_type i=0; i<rows(); i++) // loop over all rows
>>> {
>>> - typename FieldTraits<value_type>::real_type pivmax=fvmeta::absreal(A[i][i]);
>>> + using fvmeta::absreal; // Must make unqualified calls to allow argument dependent lookup.
>>> + typename FieldTraits<value_type>::real_type pivmax=absreal(A[i][i]);
>>>
>>> // pivoting ?
>>> if (pivmax<pivthres)
>>> @@ -824,7 +826,7 @@ namespace Dune
>>> size_type imax=i;
>>> typename FieldTraits<value_type>::real_type abs(0.0);
>>> for (size_type k=i+1; k<rows(); k++)
>>> - if ((abs=fvmeta::absreal(A[k][i]))>pivmax)
>>> + if ((abs=absreal(A[k][i]))>pivmax)
>>> {
>>> pivmax = abs; imax = k;
>>> }
>>> @@ -856,6 +858,7 @@ namespace Dune
>>> template <class V>
>>> inline void DenseMatrix<MAT>::solve(V& x, const V& b) const
>>> {
>>> + using fvmeta::absreal; // Must make unqualified calls to allow argument dependent lookup.
>>> // never mind those ifs, because they get optimized away
>>> if (rows()!=cols())
>>> DUNE_THROW(FMatrixError, "Can't solve for a " << rows() << "x" << cols() << " matrix!");
>>> @@ -863,7 +866,7 @@ namespace Dune
>>> if (rows()==1) {
>>>
>>> #ifdef DUNE_FMatrix_WITH_CHECKING
>>> - if (fvmeta::absreal((*this)[0][0])<FMatrixPrecision<>::absolute_limit())
>>> + if (absreal((*this)[0][0])<FMatrixPrecision<>::absolute_limit())
>>> DUNE_THROW(FMatrixError,"matrix is singular");
>>> #endif
>>> x[0] = b[0]/(*this)[0][0];
>>> @@ -873,7 +876,7 @@ namespace Dune
>>>
>>> field_type detinv = (*this)[0][0]*(*this)[1][1]-(*this)[0][1]*(*this)[1][0];
>>> #ifdef DUNE_FMatrix_WITH_CHECKING
>>> - if (fvmeta::absreal(detinv)<FMatrixPrecision<>::absolute_limit())
>>> + if (absreal(detinv)<FMatrixPrecision<>::absolute_limit())
>>> DUNE_THROW(FMatrixError,"matrix is singular");
>>> #endif
>>> detinv = 1.0/detinv;
>>> @@ -886,7 +889,7 @@ namespace Dune
>>>
>>> field_type d = determinant();
>>> #ifdef DUNE_FMatrix_WITH_CHECKING
>>> - if (fvmeta::absreal(d)<FMatrixPrecision<>::absolute_limit())
>>> + if (absreal(d)<FMatrixPrecision<>::absolute_limit())
>>> DUNE_THROW(FMatrixError,"matrix is singular");
>>> #endif
>>>
>>> @@ -924,6 +927,7 @@ namespace Dune
>>> template<typename MAT>
>>> inline void DenseMatrix<MAT>::invert()
>>> {
>>> + using fvmeta::absreal; // Must make unqualified calls to allow argument dependent lookup.
>>> // never mind those ifs, because they get optimized away
>>> if (rows()!=cols())
>>> DUNE_THROW(FMatrixError, "Can't invert a " << rows() << "x" << cols() << " matrix!");
>>> @@ -931,7 +935,7 @@ namespace Dune
>>> if (rows()==1) {
>>>
>>> #ifdef DUNE_FMatrix_WITH_CHECKING
>>> - if (fvmeta::absreal((*this)[0][0])<FMatrixPrecision<>::absolute_limit())
>>> + if (absreal((*this)[0][0])<FMatrixPrecision<>::absolute_limit())
>>> DUNE_THROW(FMatrixError,"matrix is singular");
>>> #endif
>>> (*this)[0][0] = field_type( 1 ) / (*this)[0][0];
>>> @@ -941,7 +945,7 @@ namespace Dune
>>>
>>> field_type detinv = (*this)[0][0]*(*this)[1][1]-(*this)[0][1]*(*this)[1][0];
>>> #ifdef DUNE_FMatrix_WITH_CHECKING
>>> - if (fvmeta::absreal(detinv)<FMatrixPrecision<>::absolute_limit())
>>> + if (absreal(detinv)<FMatrixPrecision<>::absolute_limit())
>>> DUNE_THROW(FMatrixError,"matrix is singular");
>>> #endif
>>> detinv = field_type( 1 ) / detinv;
>>> diff --git a/dune/common/densevector.hh b/dune/common/densevector.hh
>>> index 6dacfe6..417f6bc 100644
>>> --- a/dune/common/densevector.hh
>>> +++ b/dune/common/densevector.hh
>>> @@ -579,27 +579,31 @@ namespace Dune {
>>> //! simplified one norm (uses Manhattan norm for complex values)
>>> typename FieldTraits<value_type>::real_type one_norm_real () const
>>> {
>>> + using fvmeta::absreal; // Must make unqualified calls to allow argument dependent lookup.
>>> typename FieldTraits<value_type>::real_type result( 0 );
>>> for (size_type i=0; i<size(); i++)
>>> - result += fvmeta::absreal((*this)[i]);
>>> + result += absreal((*this)[i]);
>>> return result;
>>> }
>>>
>>> //! two norm sqrt(sum over squared values of entries)
>>> typename FieldTraits<value_type>::real_type two_norm () const
>>> {
>>> + using fvmeta::abs2; // Must make unqualified calls to allow argument dependent lookup.
>>> + using fvmeta::sqrt; // Must make unqualified calls to allow argument dependent lookup.
>>> typename FieldTraits<value_type>::real_type result( 0 );
>>> for (size_type i=0; i<size(); i++)
>>> - result += fvmeta::abs2((*this)[i]);
>>> - return fvmeta::sqrt(result);
>>> + result += abs2((*this)[i]);
>>> + return sqrt(result);
>>> }
>>>
>>> //! square of two norm (sum over squared values of entries), need for block recursion
>>> typename FieldTraits<value_type>::real_type two_norm2 () const
>>> {
>>> + using fvmeta::abs2; // Must make unqualified calls to allow argument dependent lookup.
>>> typename FieldTraits<value_type>::real_type result( 0 );
>>> for (size_type i=0; i<size(); i++)
>>> - result += fvmeta::abs2((*this)[i]);
>>> + result += abs2((*this)[i]);
>>> return result;
>>> }
>>>
>>> @@ -625,14 +629,15 @@ namespace Dune {
>>> typename FieldTraits<value_type>::real_type infinity_norm_real () const
>>> {
>>> using std::max;
>>> + using fvmeta::absreal; // Must make unqualified calls to allow argument dependent lookup.
>>>
>>> if (size() == 0)
>>> return 0.0;
>>>
>>> ConstIterator it = begin();
>>> - typename FieldTraits<value_type>::real_type max_val = fvmeta::absreal(*it);
>>> + typename FieldTraits<value_type>::real_type max_val = absreal(*it);
>>> for (it = it + 1; it != end(); ++it)
>>> - max_val = max(max_val, fvmeta::absreal(*it));
>>> + max_val = max(max_val, absreal(*it));
>>>
>>> return max_val;
>>> }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: OpenPGP digital signature
URL: <https://lists.dune-project.org/pipermail/dune-devel/attachments/20150901/ffed6aee/attachment.sig>
More information about the Dune-devel
mailing list