previous up next print clean
Next: OPERATOR Up: C++ in physical science: Previous: DEFINITIONS


An object of class ${\tt <type\gt space}$, the class to represent a physical space, has two parts. The first part is a multi-dimensional array of numbers representing the sampled data or model. This array can contain floating point values or complex numbers. The second part is a set of axes that describe the physical dimensions of the data or model space.

Every dimension of a ${\tt <type\gt space}$ has an axis associated with it, which defines an origin, length, and sampling interval (delta) for the axis, as well as a label. Thus, a ${\tt <type\gt space}$ is meant as a collection of real physical data, rather than an abstract collection of numbers. This is ideal for scientific applications, as in geophysics.

The publicly accessible member functions that manipulate objects of the class ${\tt <type\gt space}$ are relatively few, as operators are the main method of transforming a space. The most important member functions are:

There are two ways to create a space:

The first is to read it from a SEP cube dataset on disk. The SEP cube dataformat consists of two parts, an ASCII header file that contains the parameters describing the dataset, and a data file containing the actual data. The following paragraphs taken from PVI describe the basic parameters defined in a header file.

A cube has three axes. The number of points on the 1-axis is n1. A Fortran declaration of a cube could be real mydata(n1,n2,n3). For a plane, n3=1, and for a line, n2=1. In addition, many programs take ``1'' as the default for an undefined value of n2 or n3. The physical location of the single data value mydata(1,1,1), like a mathematical origin (o1,o2,o3), is denoted by the three real variables o1, o2, and o3. The data-cube values are presumed to be uniformly spaced along these axes like the mathematical increments $(\Delta_1,\Delta_2,\Delta_3)$, which may be negative and are denoted by the three real variables d1, d2, and d3.

Each axis has a label, and naturally these labels are called label1, label2, and label3. Examples of labels are kilometers, sec, Hz, and "offset, km". Most often, label1="time, sec". Altogether that is $2+3\times 4$parameters, and there is an optional title parameter that is interpreted by most of the plot programs. An example is title="Yilmaz and Cumro Canada profile 25".

These parameters are used to initialize the axes of a ${\tt <type\gt space}$ and the datafile is read to initialize the matrix. Building a ${\tt <type\gt space}$ from a SEP cube dataset is a two stage process. First the input dataset is initialized by creating a `` SepInput'' object and then the ${\tt <type\gt space}$ is constructed using the SepInput object as a parameter. The SepInput class is a C++ class that encapsulates interaction with a SEP cube dataset Dulac and Nichols (1989).

  // Declare a pointer to a SepInput object and assign to it a new object
  // that is constructed by reading the seplib header supplied on stdin.
  SepInput * inData = new SepInput( ``stdin'' ) ;

  // Declare and create an instance of a floatspace object, called myspace.
  // The object is created from the whole of the previously defined
  // input dataset.
  floatspace myspace(inData);

The second way to create a space is to create a matrix, using the matrix constructors, and also an Axislist, which is the class that defines the axes for a space. In our applications this method is seldom used, except in generating test cases. The dot-product test routine described in the appendix uses this type of constructor to build spaces containing random numbers.

All the basic arithmetic operations (addition, subtraction, multiplication, and division) are defined for spaces, both by single values and element-by-element by a conformable spaces. A conformable space is one that has matching shape and axes. If you have one space that is a $10\times200$ function of space and time it cannot be added to a $10\times200$ function of velocity and zero-offset-time. Even if two spaces are both $10\times200$functions of space and time, they can only be added if the axis starting values and increments match. This high level of error checking is invisible to the user of the class but it helps prevent many errors, both coding errors and conceptual errors have been detected by these checks.

Assuming space1, space2 and space3 are conformable spaces, the following code fragment demonstrates the manipulation of spaces.

space1 = space2 * 2.0 + .001;
space2 = space1 + space3;
Note that this code fragment would also be legitimate code for objects that were space-arrays as long as the arrays, and the individual elements were conformable.

The details of the internal structure of a space are hidden from the user and the mathematical operators are provided by the space class. This results in very clean code that is very close to the mathematical representation of the operations required.

Anything else you wish to do to a space is done by an operator. Operators are are written in such a way that they have more direct access to the private members of a space (the mechanism for doing this in C++ is to make them a friend class to the space class.) They can directly access the matrix class that is at the heart of a space. This gives operators extra power in manipulating spaces, since operators are designed to be the primary method for transforming spaces.

At the moment the matrix classes we use are the M++ classes from Dyad Software Co. 1991. The reason that, in later examples, the type of the elements appears in the space definition is that M++ does not support templated classes. In the future we hope to use a new public domain matrix class that supports templates so that all our code will be written in a manner that is independent of the type of the matrix elements.

previous up next print clean
Next: OPERATOR Up: C++ in physical science: Previous: DEFINITIONS
Stanford Exploration Project