Next: Math functions 1, Previous: Expression evaluation, Up: Array Expressions [Contents][Index]
Blitz++ provides objects called index placeholders which represent array indices. They can be used directly in expressions.
There is a distinct index placeholder type associated with each dimension of
an array. The types are called firstIndex, secondIndex,
thirdIndex, ..., tenthIndex, eleventhIndex.
Here’s an example of using an index placeholder:
Array<float,1> A(10); firstIndex i; A = i;
This generates code which is similar to:
for (int i=0; i < A.length(); ++i)
A(i) = i;
Here’s an example which fills an array with a sampled sine wave:
Array<float,1> A(16); firstIndex i; A = sin(2 * M_PI * i / 16.);
If your destination array has rank greater than 1, you may use multiple index placeholders:
// Fill a two-dimensional array with a radially
// symmetric, decaying sinusoid
// Create the array
int N = 64;
Array<float,2> F(N,N);
// Some parameters
float midpoint = (N-1)/2.;
int cycles = 3;
float omega = 2.0 * M_PI * cycles / double(N);
float tau = - 10.0 / N;
// Index placeholders
firstIndex i;
secondIndex j;
// Fill the array
F = cos(omega * sqrt(pow2(i-midpoint) + pow2(j-midpoint)))
* exp(tau * sqrt(pow2(i-midpoint) + pow2(j-midpoint)));
Here’s a plot of the resulting array:
You can use index placeholder expressions in up to 11 dimensions. Here’s a three dimensional example:
// Fill a three-dimensional array with a Gaussian function
Array<float,3> A(16,16,16);
firstIndex i;
secondIndex j;
thirdIndex k;
float midpoint = 15/2.;
float c = - 1/3.0;
A = exp(c * (sqr(i-midpoint) + sqr(j-midpoint)
+ sqr(k-midpoint)));
You can mix array operands and index placeholders:
Array<int,1> A(5), B(5); firstIndex i; A = 0, 1, 1, 0, 2; B = i * A; // Results in [ 0, 1, 2, 0, 8 ]
For your convenience, there is a namespace within blitz
called tensor which declares all the index placeholders:
namespace blitz {
namespace tensor {
firstIndex i;
secondIndex j;
thirdIndex k;
...
eleventhIndex t;
}
}
So instead of declaring your own index placeholder objects, you can just say
namespace blitz::tensor;
when you would like to use them. Alternately, you can just preface all the
index placeholders with tensor::, for example:
A = sin(2 * M_PI * tensor::i / 16.);
This will make your code more readable, since it is immediately clear that
i is an index placeholder, rather than a scalar value.
When operands of different numeric types are used in an expression, the
result gets promoted according to the usual C-style type promotion. For
example, the result of adding an Array<int> to an
Arrray<float> will be promoted to float. Generally, the
result is promoted to whichever type has greater precision.
The rules for type promotion of user-defined types (or types from another library) are a bit complicated. Here’s how a pair of operand types are promoted:
complex<float>, complex<double>, and complex<long
double>.
sizeof()). The rationale is that more storage space probably
indicates more precision.
If you wish to alter the default type promotion rules above, you have two choices:
promote_trait<A,B> which is declared in
<blitz/promote.h>.
<blitz/ops.h>.
Note that you can do these specializations in your own header files (you don’t have to edit promote.h or ops.h).
There are some inconvenient aspects of C-style type promotion. For example, when you divide two integers in C, the result gets truncated. The same problem occurs when dividing two integer arrays in Blitz++:
Array<int,1> A(4), B(4); Array<float,1> C(4); A = 1, 2, 3, 5; B = 2, 2, 2, 7; C = A / B; // Result: [ 0 1 1 0 ]
The usual solution to this problem is to cast one of the operands to a
floating type. For this purpose, Blitz++ provides a function
cast(expr,type) which will cast the result of expr as
type:
C = A / cast(B, float()); // Result: [ 0.5 1 1.5 0.714 ]
The first argument to cast() is an array or expression. The second
argument is a dummy object of the type to which you want to cast. Once
compilers support templates more thoroughly, it will be possible to use this
cast syntax:
C = A / cast<float>(B);
But this is not yet supported.
Next: Math functions 1, Previous: Expression evaluation, Up: Array Expressions [Contents][Index]