Blitz logo

Blitz Support :

From: Julian Cummings (cummings_at_[hidden])
Date: 2003-12-10 14:25:19


Hello Andrius,

Andrius Kurtinaitis wrote:

> Hello,
>
> thank you for the quick reply.
> I have three ternary functions and a long expression where I want to
> use these expressions like that:
>
> result[1] = (a_very_long_expression) + ternary_funtion_1( a1, a2, a3 );
> result[2] = (a_very_long_expression) + ternary_funtion_2( a1, a2, a3 );
> result[3] = (a_very_long_expression) + ternary_funtion_3( a1, a2, a3 );
>
> I do not want to repeat the long expressions like this because they
> are really long and I edit them sometimes and I want to keep them
> identical.
> I can't define long expressions as functions because they would take
> more than three arguments.
> I could write that the other way:
>
> for(int i=0; i<3 i++)
> result[i] = (a_very_long_expression);
> result[1] += ternary_funtion_1( a1, a2, a3 );
> result[2] += ternary_funtion_2( a1, a2, a3 );
> result[3] += ternary_funtion_3( a1, a2, a3 );
>
> But then, according to blitz manual, the loops will not be optimized
> so well. Maybe this is not so important at the moment...

You might consider using a preprocessor macro to represent your very
long expression, if you are just worried about cut-and-paste coding
errors. Unfortunately, there is no nice way to capture a subexpression
as a handy object in blitz. This was a feature we added in Pooma by
allowing an expression to be represented as an Array containing an
"expression engine" that could evaluate the expression as needed to
return array element values. It was a slick idea, but there is a
significant cost in terms of internal code complexity and added pain and
torture for the C++ compiler.

>
> I have another one question. I am coding a leap-frog-like finite
> difference scheme. But I do not see any way in blitz++ to apply a
> stencil to only even (or only odd) components of the Array. Is it not
> possible with blitz++ or I simply did not found it yet?

I think the best way to handle this is with strided array access using
Range objects.

const int N = 100;
blitz::Array<double,1> A(N);
blitz::Range even(2,N-2,2), odd(1,N-3,2);

A(even) = 0.5 * (A(even+1) - A(even-1));
A(odd) = 0.5 * (A(odd+1) - A(odd-1));

This is a brain-dead example, but it should give you the basic idea.
 You can get a reference to a strided view of an Array (even or odd
components only) with the appropriate Range object. You can shift a
Range for finite differencing by adding or subtracting an int. And you
can use the Array copy constructor or reference() method to store a
strided Array view as a separate object, which can then be passed to a
differencing stencil. Thus:

blitz::Array<double,1> Aeven = A(even);
blitz::Array<double,1> Aodd = A(odd);

Aeven = central12(Aeven);
Aodd = central12(Aodd);

Regards, Julian C.

-- 
Dr. Julian C. Cummings                       E-mail: cummings_at_[hidden]
California Institute of Technology           Phone:  626-395-2543
1200 E. California Blvd., Mail Code 158-79   Fax:    626-584-5917
Pasadena, CA 91125