Complex Numbers in ZPL

This page is meant to give a summary of how to use complex numbers in ZPL programs. At this point, complex numbers are not fully implemented, but have been prototyped in order to allow users to do simple computations using them. If you find any bugs or inconsistencies in our implementation of complex numbers, pleae let us know at zpl-bugs@cs.washington.edu.

Complex Types Overview

ZPL supports three varieties of complex numbers: complex, dcomplex, and qcomplex. All three of these data types have real and imaginary components, but with differing amounts of precision, namely float, double, and quad, respsectively (on platforms that don't support quad precision, double is used instead).

Supported Operations

Complex variables and arrays of complex variables can be declared of any of the complex types in the usual manner. Complex constants can also be declared in the standard way using ZPL's record initialization syntax (identical to C's) to initialize the values. For example, the following declaration would create a double precision representation of i: constant I:dcomplex = {0,1};.

At the present, assignment (:=), equality (=), inequality (!=), addition (+), subtraction (-), multiplication (*), division (/), plus-gets (+=) and minus-gets (-=) are supported on all combinations of complex and real values. In addition, ZPL's (@), wrap, reflect, flood (>>), and remap (<##, >##) operators work on complex values as expected. Plus and multiplication reductions and scans (+<<, *<<, +||, *||) are implemented for complex values for seq, pvm, and mpi installations. Currently, times-gets (*=) and divide-gets (/=) are not implemented. In addition, none of ZPL's standard math library routines support complex values.

Unfortunately, warnings are currently not generated for using complex values with unimplemented operations. Instead, the operation will be applied to the real component of the complex value only.

Known bug: complex assignments that use the same complex variable on the LHS and RHS in such a way that assignment to the imaginary component requires using its real component as well will currently not work. For example, a := a + b; will work since the imaginary assignment of a depends only on the imaginary component of a. However, a := a * b; will not work since the imaginary assignment of a depends on the real component of a. If this causes problems for you, please mail us at the address above.

In addition, the user can access a complex number's real and imaginary components by treating the complex variable as though it was a record with fields named re and im, respectively. For example a.im := 0 would set the imaginary component of a to 0.

Text I/O

Text I/O with the console and files is supported for complex values. The default I/O for complex variables is: realval + imagvali. As with any text I/O, this control string may be over-ridden. One difference from traditional scalar I/O is that two control strings should be specified to refer to the real and imaginary parts in that order. For example, to write a complex variable using the (realval,imagval), one would use: writeln("(%f,%f)":cmplxvar);

Future Plans

It is our intention to support additional operations on complex variables such as the other shortcut assignment operations (*=, /=), scans, reductions, etc. Our implementation of these features may be somewhat demand-driven, so if you require them, please let us know at the address below.

Further Questions?

If you have further questions about complex types in ZPL, please don't hesitate to contact us at zpl-info@cs.washington.edu.