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]