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]