Boost logo

Boost :

Subject: Re: [boost] [units] - learning to use
From: Matthias Schabel (boost_at_[hidden])
Date: 2011-11-28 11:01:31


> I might have got something wrong, and missed probably something in
> the manual... So what is a better way of writing this line in the
> code?
>
> a += (dd*exp(i*k*r)/r).value();
>
> The result of dd*exp(i*k*r)/r is dimensionless, but direct assignment
> (copy construction) isn't working here. And I would really admire if
> the code could look in a sane way, like this:
>
> a += dd*exp(i*k*r)/r;
>
> This would look, like I'm not really worrying about using
> boost::units, just benefit from all the unit checking, and no extra
> code to type. (and change k to use double, not complex ;)
> Also I am suspicious that currently my code has a bug here, exactly
> where the .value() is taken. Because `dd` and `r` are units of different
> scale.

I don't think you missed anything and I think that your second expression should work as expected. I would
consider it a flaw in Boost.Units that this does not currently work and a flaw in C++ that getting a (relatively)
simple mathematical concept like dimensional analysis to function in a library is as difficult as it is...

>>> This is an idiosyncrasy of overload resolution.
>>> std::complex::operator+= is a template, so an
>>> implicit conversion doesn't work. The template
>>> argument can't be deduced.
>>
>> Perhaps we should flesh out the toy complex implementation we wrote
>> and incorporate it in the units library? It is a fairly common thing
>> to use together with units and, as I understand it, the standard only
>> defines complex for a subset of built in types...
>
> that would be great. Because there is no physical reason why
> wavenumber k would need to be complex.
> It seems like allowing to perform a conversion from double to
> complex is reasonable. Only opposite conversion has reasons to fail.
> Just like converting double to int has reasons to fail. But
> converting int to double should work flawlessly.

I think we should be able to get such things to behave sensibly.

>>>> quantity<length> wavelength ( 632.8 *nano*meters);
>>>> quantity<length> wavelength = 632.8 *nano*meters;
>> Although, in Janek's defense, this seems overly restrictive. Can we
>> allow copy construction between scaled units and the corresponding
>> unscaled unit without introducing undesirable side effects?
>
> I would really appreciate that :) It would simplify code. Also
> because I cannot put 632.8*nano*meters directly as arguments to
> function call.

The currently sanctioned approach to function arguments is to use templates to accept any unit of the
appropriate dimension, but it does make more sense to allow implicit conversion in the special case
of scaled units. The only issue is the danger of roundoff/truncation problems.

> btw, how usually do you define those scaled units to be a little more
> convenient to use? I mean, just type: 632.8*nm
> Is there some header to include, to benefit from all standard SI
> system prefixes? It would be great, it's a standard after all :)
> And those short names are carefully designed to not have any unit
> name clashes.

I guess we could have a header corresponding to each SI unit that contains predefined scaled units
for each of the SI prefixes.

> Of course while writing C++ code we might end up with variables
> names & units names clashing, like using single letter 'm' for
> 'meter', but this is why we have an si:: namespace after all. And if
> my code grows a little bigger I will definitely switch to:
> 632.8*si::nm
>
> If you will have some changes in library that will need testing
> I will gladly try it.
>
> If you tell me how to define si::km, si::m, si::kN, si::GJ I can
> generate for you a header file with all possible units. Though
> 'micro' is not in latin alphabet. So micro meter is not possible, aww..

I'll try to get you something to start with later today.

Matthias


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk