Next: Array usertype, Up: Customized Arrays [Contents][Index]
Multicomponent arrays have elements which are vectors. Examples of such arrays are vector fields, colour images (which contain, say, RGB tuples), and multispectral images. Complex-valued arrays can also be regarded as multicomponent arrays, since each element is a 2-tuple of real values.
Here are some examples of multicomponent arrays:
// A 3-dimensional array; each element is a length 3 vector of float Array<TinyVector<float,3>,3> A; // A complex 2-dimensional array Array<complex<double>,2> B; // A 2-dimensional image containing RGB tuples struct RGB24 { unsigned char r, g, b; }; Array<RGB24,2> C;
Blitz++ provides some special support for such arrays. The most important is the ability to extract a single component. For example:
Array<TinyVector<float,3>,2> A(128,128); Array<float,2> B = A.extractComponent(float(), 1, 3); B = 0;
The call to extractComponent
returns an array of floats; this array
is a view of the second component of each element of A. The arguments of
extractComponent
are: (1) the type of the component (in this example,
float); (2) the component number to extract (numbered 0, 1, ... N-1); and
(3) the number of components in the array.
This is a little bit messy, so Blitz++ provides a handy shortcut using
operator[]
:
Array<TinyVector<float,3>,2> A(128,128); A[1] = 0;
The number inside the square brackets is the component number. However, for
this operation to work, Blitz++ has to already know how many components
there are, and what type they are. It knows this already for
TinyVector
and complex<T>
. If you use your own type, though,
you will have to tell Blitz++ this information using the macro
BZ_DECLARE_MULTICOMPONENT_TYPE()
. This macro has three arguments:
BZ_DECLARE_MULTICOMPONENT_TYPE(T_element, T_componentType, numComponents)
T_element
is the element type of the array. T_componentType
is the type of the components of that element. numComponents
is the
number of components in each element.
An example will clarify this. Suppose we wanted to make a colour image,
stored in 24-bit HSV (hue-saturation-value) format. We can make a class
HSV24
which represents a single pixel:
#include <blitz/array.h> using namespace blitz; class HSV24 { public: // These constants will makes the code below cleaner; we can // refer to the components by name, rather than number. static const int hue=0, saturation=1, value=2; HSV24() { } HSV24(int hue, int saturation, int value) : h_(hue), s_(saturation), v_(value) { } // Some other stuff here, obviously private: unsigned char h_, s_, v_; };
Right after the class declaration, we will invoke the macro
BZ_DECLARE_MULTICOMPONENT_TYPE
to tell Blitz++ about HSV24:
// HSV24 has 3 components of type unsigned char BZ_DECLARE_MULTICOMPONENT_TYPE(HSV24, unsigned char, 3);
Now we can create HSV images and modify the individual components:
int main() { Array<HSV24,2> A(128,128); // A 128x128 HSV image ... // Extract a greyscale version of the image Array<unsigned char,2> A_greyscale = A[HSV24::value]; // Bump up the saturation component to get a // pastel effect A[HSV24::saturation] *= 1.3; // Brighten up the middle of the image Range middle(32,96); A[HSV24::value](middle,middle) *= 1.2; }
Since complex arrays are used frequently, Blitz++ provides two special methods for getting the real and imaginary components:
Array<complex<float>,2> A(32,32); real(A) = 1.0; imag(A) = 0.0;
The function real(A)
returns an array view of the real component;
imag(A)
returns a view of the imaginary component.
Note: Blitz++ provides numerous math functions defined over complex-valued
arrays, such as conj
, polar
, arg
, abs
,
cos
, pow
, etc. See the section on math functions
(Math functions 1) for details.
Blitz++ provides a function zip()
which lets you combine two or more
expressions into a single component. For example, you can combine two real
expressions into a complex expression, or three integer expressions into an
HSV24 expression. The function has this syntax:
resultexpr zip(expr1, expr2, T_element) resultexpr zip(expr1, expr2, expr3, T_element) ** not available yet resultexpr zip(expr1, expr2, expr3, expr4, T_element) ** not available yet
The types resultexpr
, expr1
and expr2
are array
expressions. The third argument is the type you want to create. For
example:
int N = 16; Array<complex<float>,1> A(N); Array<float,1> theta(N); ... A = zip(cos(theta), sin(theta), complex<float>());
The above line is equivalent to:
for (int i=0; i < N; ++i) A[i] = complex<float>(cos(theta[i]), sin(theta[i]));
Next: Array usertype, Up: Customized Arrays [Contents][Index]