 # Boost :

Subject: Re: [boost] [units] - learning to use
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2011-11-25 00:36:56

AMDG

On 11/24/2011 06:25 AM, Janek Kozicki wrote:
> Hi, I wrote a short function that integrates Huyghens spherical wave
> for diffraction. (This is a single slit experiment btw).
>
> I have some questions, marked with (*)
>
> double integral(
> const quantity<length> x // x - position where light intensity is calculated
> , const quantity<length> R // R - distance from slit to screen
> , const quantity<length> D // D - slit width
> , const quantity<length> lambda // lambda - wavelength
> , double steps // steps - number of integration steps // (*)
> )
> {
> complex<double> i(0,1);
> complex<double> a(0);
> static const double pi = 3.14159265358979323846; // (**)
> quantity<wavenumber,complex<double> > k=2*pi/lambda;
> quantity<length> d=-0.5*D; // d - position on the slit
> quantity<length> dd=D/steps; // dd - width of integral step
> // integrate from -d to d: exp(i*k*r)/r
> for( ; d<= 0.5*D ; d+=dd )
> {
> quantity<length> r=sqrt(pow<2>(R)+pow<2>(x-d));
> a += (dd*exp(i*k*r)/r).value(); // (***)
> }
> return pow<2>(abs(a));
> }
>
> (*)
> it should be `int steps` but if I write it this way I get a compilation error here:
> quantity<length> dd=D/steps; // dd - width of integral step
> That looks like a conversion problem.
>

Try D/double(steps). Matthias, I seem to recall that the
reason we disabled generic multiplication was that it
was causing ambiguities with user defined types. Do
you think it would be a good idea to enable arithmetic
with any built-in arithmetic type?

> (**)
> why do I need to define pi ? I expected to find it somewhere, but I couldn't.
>

Try boost::math?

> (***)
> it seems strange that I need to take .value() here. The result is
> dimensionless, why can't it directly convert to complex<double> ?
> There is a risk that .value() would be expressed in millimeters or
> angstroms or whatever (maybe depending on dd), and then .value()
> would return a wrongly scaled number?
>

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.

>
> Another question, why this works:
>
> quantity<length> wavelength ( 632.8 *nano*meters);
>
> and this does not?
>
> quantity<length> wavelength = 632.8 *nano*meters;
>
> Of course I know about extra copying, and waste of CPU resources on
> execution, when compiler isn't able to optimize this away (and
> usually it is able to do that). But why the heck this simple
> assignment can't work?
>

This isn't assignment. It's copy construction and
requires an implicit conversion which is forbidden.

> PS: I am attaching a short test version of this program, it's in
> polish, but I hope you don't mind.
>