Blitz logo

Blitz Support :

From: Julian Cummings (cummings_at_[hidden])
Date: 2005-06-21 22:46:42


Hello Peter,

> I forgot to mention, that I've done my tests on arrays with
> complex numbers.
>
> I've found that the main reason for slowing down blitz is the
> absence of a constructor which takes indices, e.g.:
>
> firstIndex x;
> secondIndex y;
> A = A * exp( complex<double>(x,y) );
>
> At least, I've found no way to compile this code.

The problem here is a slight misunderstanding of the role of the index
placeholder objects firstIndex, secondIndex, etc. These objects act like
Arrays in Array expressions, not like scalars. So you cannot pass them to a
constructor for a scalar like std::complex<double>.

What you need to do instead is multiply the Arrays represented by the
placeholders x and y by the appropriate scalar constants. Instead of
complex<double>(x,y), you would write

complex<double>(1,0)*(1.0*x)+complex<double>(0,1)*(1.0*y)

The (1.0*x) and (1.0*y) are needed to produce Array expressions with numtype
of double instead of int. The GNU C++ compiler only seems to define
complex<T1>*T2 if T1=T2 and does not promote int to double automatically in
this case. (Is this standard behavior?)

>
>
> Introducing a helperfunction does the job:
>
> complex<double> cplx(double re, double im){
> return complex<double>(re,im);
> }
>
>
> But if I build more complex functions like
>
> complex<double> cplx3(double re, double im, double d){...}
>
> the compiler can't convert the ET type:
>
> double a,b;
> firstIndex x;
> A = A * exp(cplx3(a,b,sqrt(x));
>
> gcc:
> cannot convert `blitz::_bz_ArrayExpr<blitz::
> _bz_ArrayExprUnaryOp<blitz::IndexPlaceholder<0>,
> blitz::Fn_sqrt<int> > >'
> to `double' for argument `3' to
> `std::complex<double> cplx3(double, double, double)'

Same problem here. You should not be trying to convert an Array expression
with numtype of double into a scalar double. Construct the appropriate
Array expression of numtype complex<double> instead as illustrated above.

>
> (I've here a BZ_DEFINE_TERNARY_FUNC_RET macro which I could
> submit if you are intested)
>

I'm not sure that such a beast is ever needed in practice. Can you give an
example of a ternary math functor that you want to apply to Arrays?

>
> > The blitz Arrays have iterators which are now more or less STL
> > compliant. This allows you to write a generic loop over Array
> > elements and do whatever calculation you want to each element. The
> > iterator type also has a special position() member that returns the
> > current Array indices in a TinyVector of ints. So you could say
> >
> > #define DIM 2
> > Array<double,DIM>::iterator it, iend = A.end(); for (it =
> A.begin();
> > it != iend; ++it) {
> > TinyVector<int,DIM> pos = it.position();
> > *it = *it * exp(sqrt(dot(pos,pos))); }
>
> So I must do the loop by hand, hoped that there is also a
> blitz like solution.

The point of this is to show a dimension-independent means looping over
Array elements. I think perhaps what you are looking for is an iota functor
that takes an Array and produces the element position vector for each
element. No such thing currently exists, but you could easily create and
store such an Array yourself for later use (e.g., by using the zip()
function to zip together scalar index placeholders into an Array of
TinyVectors of ints).

Regards, Julian C.

Dr. Julian C. Cummings
Staff Scientist, CACR/Caltech
(626) 395-2543
cummings_at_[hidden]