Manual: Second Half Revised
Jeffrey Oldham
oldham at codesourcery.com
Fri Jan 25 02:33:33 UTC 2002
2002-Jan-24 Jeffrey D. Oldham <oldham at codesourcery.com>
These changes continue moving the manual toward delivery.
Unfinished sections remain in the DocBook source code but are not
printed. Wordsmithing concentrated on the Arrays, Engines,
data-parallel, container views, and glossary chapters. The
incomplete index and unformatted bibliography sections are not
printed.
* Makefile (manual.dvi): Update dependences.
(%.dvi): Improve rule.
(clean): Add generated index.
* arrays.xml: Wordsmithing, some format fixes, and some glossary
links added.
* bibliography.xml: Prevent printing of incomplete bibliography.
* concepts.xml: Ensure table cells are aligned at the top of the
rows.
* data-parallel.xml: Wordsmithing, some format fixes, and some glossary
links added.
* glossary.xml: Wordsmithing and new 'see also' links added.
(reference semantics): New entry.
* manual.xml: Wordsmith partially-completed Engine chapter.
Ensure table cells are aligned at the top of the rows. Add
introductory statement to POOMA installation appendix. Turn off
index.
Applied to the mainline.
Approved by you.
Jeffrey D. Oldham
oldham at codesourcery.com
-------------- next part --------------
Index: Makefile
===================================================================
RCS file: /home/pooma/Repository/r2/docs/manual/Makefile,v
retrieving revision 1.1
diff -c -p -r1.1 Makefile
*** Makefile 2002/01/14 17:33:33 1.1
--- Makefile 2002/01/25 02:15:02
*************** CXXFLAGS= -g -Wall -pedantic -W -Wstrict
*** 25,32 ****
all: manual.ps
! manual.dvi: manual.xml introduction.xml tutorial.xml concepts.xml \
! data-parallel.xml glossary.xml bibliography.xml
%.all: %.ps %.pdf %.html
chmod 644 $*.ps $*.pdf
--- 25,33 ----
all: manual.ps
! manual.dvi: manual.xml introduction.xml template.xml tutorial.xml \
! concepts.xml arrays.xml data-parallel.xml glossary.xml \
! bibliography.xml
%.all: %.ps %.pdf %.html
chmod 644 $*.ps $*.pdf
*************** manual.dvi: manual.xml introduction.xml
*** 50,58 ****
# This rule assumes index creation.
%.dvi: %.xml genindex.sgm
! jade -D$(JADEDIR) -t sgml -d $(HTMLDOCBOOKDSL) -V html-index $(XML) $<
! perl collateindex.pl $(INDEXOPTIONS) -o genindex.sgm HTML.index
! jade -D$(JADEDIR) -t tex -d $(PRINTDOCBOOKDSL) $(XML) $< && jadetex $*.tex && jadetex $*.tex && jadetex $*.tex
genindex.sgm:
perl collateindex.pl $(INDEXOPTIONS) -N -o $@
--- 51,59 ----
# This rule assumes index creation.
%.dvi: %.xml genindex.sgm
! jade -D$(JADEDIR) -t sgml -d $(HTMLDOCBOOKDSL) -V html-index $(XML) $< && \
! perl collateindex.pl $(INDEXOPTIONS) -o genindex.sgm HTML.index && \
! jade -D$(JADEDIR) -t tex -d $(PRINTDOCBOOKDSL) -V tex-backend $(XML) $< && jadetex $*.tex && jadetex $*.tex && jadetex $*.tex
genindex.sgm:
perl collateindex.pl $(INDEXOPTIONS) -N -o $@
*************** mproof-%.ps: %.mp
*** 70,73 ****
detex $< > $@
clean:
! rm -f *.dvi *.aux *.log *.toc *.bak *.blg *.bbl *.glo *.idx *.lof *.lot *.htm *.mpx mpxerr.tex HTML.index manual.tex
--- 71,74 ----
detex $< > $@
clean:
! rm -f *.dvi *.aux *.log *.toc *.bak *.blg *.bbl *.glo *.idx *.lof *.lot *.htm *.mpx mpxerr.tex HTML.index manual.tex genindex.sgm
Index: arrays.xml
===================================================================
RCS file: /home/pooma/Repository/r2/docs/manual/arrays.xml,v
retrieving revision 1.3
diff -c -p -r1.3 arrays.xml
*** arrays.xml 2002/01/24 05:11:21 1.3
--- arrays.xml 2002/01/25 02:15:03
***************
*** 2,44 ****
<chapter id="arrays">
<title>&array; Containers</title>
! <para>A container is a class holding objects. &array;s are one of
! the two most widely used &pooma; containers since they model the
! mathematical concept of mapping indices from domains to values.
&pooma; &array;s extend built-in &cc; arrays by supporting a wider
! variety of domains, automatically handling memory allocations, and
! supporting first-class status. For example, they may be used as
operands and in assignments. In this chapter, we introduce the
concept of containers, the mathematical concept of arrays, and the
! &pooma; concept for &array;s. Before illustrating how to declare
! &array;s, we introduce &domain;s, which specify the sets of
indices. After describing how to declare the various types of
! &domain;s, we describe how to declare and use &array;s. This is
! illustrated in a &doof2d; implementation using &array;s. We end
! with a description of their implementation.</para>
<section id="arrays-containers">
<title>Containers</title>
<para>A <glossterm
! linkend="glossary-container"><firstterm>container class
! expression</firstterm></glossterm> is a class with the main
! purpose of holding objects. These stored objects, called
! <glossterm linkend="glossary-container_value"><firstterm>container
values</firstterm></glossterm> or more simply
! <quote>values</quote> or elements<quote></quote>, may be accessed
and changed, usually using indices. <quote>Container
! class</quote> is usually abbreviated
<quote>container</quote>.</para>
<para>The six &pooma; containers can be categorized into two
groups. Mathematical containers include &tensor;s, &matrix;s, and
! &vector;s, modeling tensors, matrices, and vectors, respectively.
Storage containers include &array;s, &dynamicarray;s, and
&field;s. In this chapter, we focus on simplest of these:
! &array;s. The other containers will be described in subsequent
! chapters.</para>
<para>&c; has built-in arrays, and the &cc; Standard Library
provides <type>map</type>s, <type>vector</type>s,
--- 2,46 ----
<chapter id="arrays">
<title>&array; Containers</title>
! <para>A container is an object holding objects. &array;s are one
! of the two most widely used &pooma; containers since they model the
! mathematical concept of mapping from domain indices to values.
&pooma; &array;s extend built-in &cc; arrays by supporting a wider
! variety of domains, automatically handling memory allocation, and
! having first-class status. For example, they may be used as
operands and in assignments. In this chapter, we introduce the
concept of containers, the mathematical concept of arrays, and the
! &pooma; implementation of &array;s. Before illustrating how to
! declare &array;s, we introduce &domain;s, which specify the sets of
indices. After describing how to declare the various types of
! &domain;s, we describe how to declare and use &array;s.
! <![%unfinished;[
! We end
! with a description of their implementation.
! ]]> <!-- end unfinished -->
! </para>
<section id="arrays-containers">
<title>Containers</title>
<para>A <glossterm
! linkend="glossary-container"><firstterm>container
! class</firstterm></glossterm> is a class whose main purpose is to
! hold objects. These stored objects, called <glossterm
! linkend="glossary-container_value"><firstterm>container
values</firstterm></glossterm> or more simply
! <quote>values</quote> or <quote>elements</quote>, may be accessed
and changed, usually using indices. <quote>Container
! class</quote> is usually abbreviated as
<quote>container</quote>.</para>
<para>The six &pooma; containers can be categorized into two
groups. Mathematical containers include &tensor;s, &matrix;s, and
! &vector;s, which model tensors, matrices, and vectors, respectively.
Storage containers include &array;s, &dynamicarray;s, and
&field;s. In this chapter, we focus on simplest of these:
! &array;s. &dynamicarray;s are also described.</para>
<para>&c; has built-in arrays, and the &cc; Standard Library
provides <type>map</type>s, <type>vector</type>s,
***************
*** 47,100 ****
more functionality. They automatically handle memory allocation
and deallocation and can be used in expressions and on the
left-hand side of assignments. Since &pooma; containers separate
! the container concepts of accessing and using values from storing
! values, value storage can be optimized to specific needs. For
! example, if most of an &array;'s values are known to be the same
! most of the time, a compressible engine can be used. Whenever all
! the array's values are the same, it stores only one value. At
! other times, it stores all the values. Engines will be discussed
! in <xref linkend="engines"></xref>.</para>
</section>
<section id="arrays-arrays">
<title>&array;s</title>
! <para>Mathematically, an array maps indices from a domain to
! values. Usually, the domain consists of a one-dimensional
! integral interval or it may be multidimensional. &pooma;'s
&array; container class implements this idea. Given an index,
! i.e., a position in an &array;'s &domain;, it returns the associated
! value, either by returning a stored value or by computing it. The
! use of indices, which are usually integral tuples but need not be
! zero-based or even consist of all possible integral tuples in a
! multidimensional range. Using indices permits constant-time
access to values although computing a particular value may require
significant time.</para>
<para>&pooma; &array;s are <glossterm
linkend="glossary-first_class">first-class
! types<firstterm></firstterm></glossterm> so they can be used more
! widely than built-in &cc; arrays. For example, &array;s can be
! used as operands and in assignment statements. The statement
! <statement>a = a + b;</statement> adds corresponding elements of
&array;s <varname>a</varname> and <varname>b</varname>, assigning
the sums to the &array; <varname>a</varname>. The statement
! treats each array as one object, rather than requiring the use of
one or more loops to access individual values. Data-parallel
! statements are further discussed in <xref
linkend="data_parallel"></xref>. &array;s also handle their own
memory allocation and deallocation. For example, the &array;
declaration <statement>Array<2, double, Brick>
a(vertDomain)</statement> creates an
&array; <varname>a</varname>, allocating whatever memory it
needs. When <varname>a</varname> goes out of scope, it and its
! memory is automatically deallocated. Automatic memory allocation
! and deallocation also eases copying. As we mentioned above, an
! &array;'s &engine; stores or computes its values so it, not the
! &array; itself, is responsible for memory allocation and
! deallocation. Fortunately, this distinction is usually hidden
! from the &pooma; user.</para>
<para>Individual &array; values can be accessed using parentheses,
not square brackets, as for &cc; arrays. For example,
--- 49,98 ----
more functionality. They automatically handle memory allocation
and deallocation and can be used in expressions and on the
left-hand side of assignments. Since &pooma; containers separate
! the concepts of accessing and using values from the concept of
! storing values, value storage can be optimized to specific needs.
! For example, if most of an &array;'s values are known to be
! identical most of the time, a compressible engine can be used.
! Whenever all the array's values are identical, it stores only one
! value. At other times, it stores all the values. Engines will be
! discussed in <xref linkend="engines"></xref>.</para>
</section>
<section id="arrays-arrays">
<title>&array;s</title>
! <para>Mathematically, an array maps domain indices to values.
! Usually, the domain consists of a one-dimensional integral
! interval or it may be a multidimensional domain. &pooma;'s
&array; container class implements this idea. Given an index,
! i.e., a position in an &array;'s &domain;, it returns the
! associated value, either by returning a stored value or by
! computing it. The indices are usually integral tuples but need
! not be zero-based or even consist of all possible integral tuples
! in a multidimensional range. Using indices permits constant-time
access to values although computing a particular value may require
significant time.</para>
<para>&pooma; &array;s are <glossterm
linkend="glossary-first_class">first-class
! objects<firstterm></firstterm></glossterm> so they can be used
! more easily than built-in &cc; arrays. For example, &array;s can
! be used as operands and in assignment statements. The statement
! <statement>a = a + b;</statement> adds corresponding values of
&array;s <varname>a</varname> and <varname>b</varname>, assigning
the sums to the &array; <varname>a</varname>. The statement
! treats each array as an object, rather than requiring the use of
one or more loops to access individual values. Data-parallel
! statements such as this are further discussed in <xref
linkend="data_parallel"></xref>. &array;s also handle their own
memory allocation and deallocation. For example, the &array;
declaration <statement>Array<2, double, Brick>
a(vertDomain)</statement> creates an
&array; <varname>a</varname>, allocating whatever memory it
needs. When <varname>a</varname> goes out of scope, it and its
! memory are automatically deallocated. Automatic memory allocation
! and deallocation also eases copying.</para>
<para>Individual &array; values can be accessed using parentheses,
not square brackets, as for &cc; arrays. For example,
***************
*** 108,125 ****
<para>A <glossterm
linkend="glossary-domain"><firstterm>domain</firstterm></glossterm>
! specifies the set of points on which an &array; can define values.
! These indices are the arguments placed within parentheses when
! selecting particular values, as described previously. A domain
! supported both by &array;s and by built-in &cc; arrays is an
interval [0,n-1] of integers containing all integers {0, 1, 2,
…, n-1}. For &cc;, every integer in the interval must be
included, and the minimum index must be zero. &pooma; expands the
set of permissible domains to support intervals with nonzero
! minimal indices and strides and by adding other choices.</para>
! <para>In &pooma;, &domain;s implement domains. There are four
! different categories:
<variablelist>
<varlistentry>
<term>&loc;</term>
--- 106,123 ----
<para>A <glossterm
linkend="glossary-domain"><firstterm>domain</firstterm></glossterm>
! specifies the set of points on which an array can define values.
! These indices are the arguments placed within parentheses to
! select particular values, as described previously. A domain
! supported both by &array;s and by built-in &cc; arrays is the
interval [0,n-1] of integers containing all integers {0, 1, 2,
…, n-1}. For &cc;, every integer in the interval must be
included, and the minimum index must be zero. &pooma; expands the
set of permissible domains to support intervals with nonzero
! minimal indices, nonzero strides, and other options.</para>
! <para>In &pooma;, &domain; classes implement domains. There are
! four different categories:
<variablelist>
<varlistentry>
<term>&loc;</term>
***************
*** 150,156 ****
</listitem>
</varlistentry>
</variablelist>
! One-dimensional and multidimensional versions of each categories
are supported. A multidimensional &domain; consists of the direct
product of one-dimensional &domain;s. For example, the first
dimension of a two-dimensional interval [0,3]x[2,9] is the
--- 148,154 ----
</listitem>
</varlistentry>
</variablelist>
! One-dimensional and multidimensional versions of the categories
are supported. A multidimensional &domain; consists of the direct
product of one-dimensional &domain;s. For example, the first
dimension of a two-dimensional interval [0,3]x[2,9] is the
***************
*** 178,198 ****
example, [2:4:2,6:4:-2] contains (2,6), (2,4), (4,6),
and (4,4).</para>
! <para>All the &domain; categories listed above except &grid; can be
! represented using domain triplet notation. Since the triplet
[7:7:1] represents {7}, or more simply 7, it can also
! represent <statement>Loc<1>(7)</statement>. Multidimensional
! &loc;s are similarly represented. For example,
[0:0:1,10:10:1,2:2:1] represents
<statement>Loc<3>(0,10,2)</statement>, but it is frequently
abbreviated as [0,10,2]. An &interval; [a,b] has unit stride:
! [a:b:1], while a ⦥ has specific stride s:
[a:b:s].</para>
! <para>&domain;s can be constructed by combining &domain;s of smaller
! dimension. For example, since a two-dimensional &interval; is the
! direct product of two one-dimensional &interval;s, it can be
! specified using two one-dimensional &interval;s. For example,
<statement>Interval<2>(Interval<1>(2,3),
Interval<1>(4,5))</statement> creates a [2:3:1,4:5:1]
&domain;. The resulting dimensionality equals the sum of the
--- 176,197 ----
example, [2:4:2,6:4:-2] contains (2,6), (2,4), (4,6),
and (4,4).</para>
! <para>All the &domain; categories listed above except &grid; can
! be represented using domain triplet notation. Since the triplet
[7:7:1] represents {7}, or more simply 7, it can also
! represent the one-dimensional <statement>Loc<1>(7)</statement>.
! Multidimensional &loc;s are similarly represented. For example,
[0:0:1,10:10:1,2:2:1] represents
<statement>Loc<3>(0,10,2)</statement>, but it is frequently
abbreviated as [0,10,2]. An &interval; [a,b] has unit stride:
! [a:b:1], while a ⦥ has specific stride s, e.g.,
[a:b:s].</para>
! <para>&domain;s can be constructed by combining &domain;s with
! smaller dimension. For example, since a two-dimensional
! &interval; is the direct product of two one-dimensional
! &interval;s, it can be specified using two one-dimensional
! &interval;s. For example,
<statement>Interval<2>(Interval<1>(2,3),
Interval<1>(4,5))</statement> creates a [2:3:1,4:5:1]
&domain;. The resulting dimensionality equals the sum of the
***************
*** 220,248 ****
units to the right by adding two. Multiplying a &domain; by two
multiplies its triplet's beginnings, endings, and strides by two.
&pooma; users rarely need to compare &domain;s, but we describe
! operating with the less-than operator on &interval;s. &interval;
<varname>d1</varname> < &interval; <varname>d2</varname> if the
length of <varname>d1's</varname> interval is less than
<varname>d2</varname>'s or, if equal, its beginning value is
! smaller. &domain; arithmetic is frequently used with data-parallel
! statements and container views. These will be discussed in <xref
! linkend="data_parallel"></xref> and <xref
linkend="views"></xref>.</para>
<para>The current &pooma; implementation supports &domain;s with
dimensionality between one and seven, inclusive. Since most
scientific computations use one, two, or three dimensions, this is
! usually sufficient. If more dimensions are needed, they can be
! added to the source code.</para>
<section id="arrays-domains-declarations">
<title>Declaring &domain;s</title>
<para>Since &domain;s are mainly used to declare container
! domains, we focus on declaring &domain;s. We describe a few
! &domain; operations but most, including arithmetic operations with
! &domain;s, are described in <xref linkend="views"></xref>.</para>
<para>All &domain; declarations require a dimension template
parameter <varname>&dim;</varname>. This positive integer
--- 219,248 ----
units to the right by adding two. Multiplying a &domain; by two
multiplies its triplet's beginnings, endings, and strides by two.
&pooma; users rarely need to compare &domain;s, but we describe
! operating with the less-than operator on &interval;s: &interval;
<varname>d1</varname> < &interval; <varname>d2</varname> if the
length of <varname>d1's</varname> interval is less than
<varname>d2</varname>'s or, if equal, its beginning value is
! smaller. &domain; arithmetic is frequently used with
! data-parallel statements and container views. These will be
! discussed in <xref linkend="data_parallel"></xref> and <xref
linkend="views"></xref>.</para>
<para>The current &pooma; implementation supports &domain;s with
dimensionality between one and seven, inclusive. Since most
scientific computations use one, two, or three dimensions, this is
! usually sufficient. If more dimensions than seven are needed,
! they can be added to the source code.</para>
<section id="arrays-domains-declarations">
<title>Declaring &domain;s</title>
<para>Since &domain;s are mainly used to declare container
! domains, we focus on declaring &domain;s. We subsequently
! describe a few &domain; operations but most, including arithmetic
! operations with &domain;s, are described in <xref
! linkend="views"></xref>.</para>
<para>All &domain; declarations require a dimension template
parameter <varname>&dim;</varname>. This positive integer
***************
*** 255,267 ****
one-dimensional &domain;s carry over to multidimensional
ones.</para>
! <para>To declare a &domain;, one must include the
! <filename class="headerfile">Pooma/Domains.h</filename> header
! file. However, most &pooma; programs declare &domain;s to use them
! when constructing containers. The container header files
! automatically include <filename
! class="headerfile">Pooma/Domains.h</filename> so no explicit
! inclusion is usually necessary.</para>
<section id="arrays-domains-declarations-loc">
--- 255,266 ----
one-dimensional &domain;s carry over to multidimensional
ones.</para>
! <para>To declare a &domain;, one must include the <filename
! class="headerfile">Pooma/Domains.h</filename> header file.
! However, most &pooma; programs use &domain;s when constructing
! containers. The storage container header files automatically
! include <filename class="headerfile">Pooma/Domains.h</filename>
! so no explicit inclusion is usually necessary.</para>
<section id="arrays-domains-declarations-loc">
***************
*** 292,301 ****
<entry></entry>
</row>
</tfoot>
! <tbody>
<row>
<entry><statement>Loc<1>()</statement></entry>
! <entry>points to zero.</entry>
</row>
<row>
<entry><statement>Loc<1>(const Pooma::NoInit& no)</statement></entry>
--- 291,300 ----
<entry></entry>
</row>
</tfoot>
! <tbody valign="top">
<row>
<entry><statement>Loc<1>()</statement></entry>
! <entry>indicates zero.</entry>
</row>
<row>
<entry><statement>Loc<1>(const Pooma::NoInit& no)</statement></entry>
***************
*** 330,345 ****
will be assigned later. For small &domain;s such as &loc;s, the
time savings from not initializing is small, but the
functionality is still available. The constructor taking one
! argument with type <type>&domaintemplate;1</type> converts this argument to
! an integer to specify the point. The template
! type <type>&domaintemplate;1</type> may be any type that can be converted
! to an integer, e.g., &bool;, &char;, ∫, or &double;. The
! constructors taking two and three arguments of templatized types
! facilitate converting an &interval; and a ⦥ into a &loc;.
! Since a &loc; represents a single point, the &interval;'s or
! ⦥'s first two arguments must be equal. The stride is
! ignored. Again, the templatized types may be any type that can
! be converted into an integer.</para>
<table frame="none" colsep="0" rowsep="0" tocentry="1"
orient="port" pgwide="0" id="arrays-domains-declarations-loc-multi_d_table">
--- 329,344 ----
will be assigned later. For small &domain;s such as &loc;s, the
time savings from not initializing is small, but the
functionality is still available. The constructor taking one
! argument with type <type>&domaintemplate;1</type> converts
! this argument to an integer to specify the point. The template
! type <type>&domaintemplate;1</type> may be any type that
! can be converted to an integer, e.g., &bool;, &char;, ∫, or
! &double;. The constructors taking two and three arguments of
! templatized types facilitate converting an &intervalone; and a
! &rangeone; into a &locone;. Since a &loc; represents a single
! point, the &interval;'s or ⦥'s first two arguments must be
! equal. The stride is ignored. Again, the templatized types may
! be any type that can be converted into an integer.</para>
<table frame="none" colsep="0" rowsep="0" tocentry="1"
orient="port" pgwide="0" id="arrays-domains-declarations-loc-multi_d_table">
***************
*** 359,368 ****
template parameters.</entry>
</row>
</tfoot>
! <tbody>
<row>
<entry><statement>Loc<&dim;>()</statement></entry>
! <entry>points to zero.</entry>
</row>
<row>
<entry><statement>Loc<&dim;>(const Pooma::NoInit& no)</statement></entry>
--- 358,367 ----
template parameters.</entry>
</row>
</tfoot>
! <tbody valign="top">
<row>
<entry><statement>Loc<&dim;>()</statement></entry>
! <entry>indicates zero.</entry>
</row>
<row>
<entry><statement>Loc<&dim;>(const Pooma::NoInit& no)</statement></entry>
***************
*** 465,471 ****
<entry></entry>
</row>
</tfoot>
! <tbody>
<row>
<entry><statement>Interval<1>()</statement></entry>
<entry>creates an empty, uninitialized interval.</entry>
--- 464,470 ----
<entry></entry>
</row>
</tfoot>
! <tbody valign="top">
<row>
<entry><statement>Interval<1>()</statement></entry>
<entry>creates an empty, uninitialized interval.</entry>
***************
*** 476,491 ****
</row>
<row>
<entry><statement>Interval<1>(const &domaintemplate;1& t1)</statement></entry>
! <entry>creates a &intervalone;. See the text for an explanation.</entry>
</row>
<row>
<entry><statement>Interval<1>(const &domaintemplate;1& t1, const &domaintemplate;2& t2)</statement></entry>
! <entry>creates a &intervalone; with the integers converted from
<varname>t1</varname> and <varname>t2</varname>.</entry>
</row>
<row>
<entry><statement>Interval<1>(const &domaintemplate;1& t1, const &domaintemplate;2& t2, const &domaintemplate;3& t3)</statement></entry>
! <entry>creates a &intervalone; with the integers converted from
<varname>t1</varname> and <varname>t2</varname>.
<varname>t3</varname> must equal 1.</entry>
</row>
--- 475,490 ----
</row>
<row>
<entry><statement>Interval<1>(const &domaintemplate;1& t1)</statement></entry>
! <entry>creates an &intervalone;. See the text for an explanation.</entry>
</row>
<row>
<entry><statement>Interval<1>(const &domaintemplate;1& t1, const &domaintemplate;2& t2)</statement></entry>
! <entry>creates an &intervalone; with the integers converted from
<varname>t1</varname> and <varname>t2</varname>.</entry>
</row>
<row>
<entry><statement>Interval<1>(const &domaintemplate;1& t1, const &domaintemplate;2& t2, const &domaintemplate;3& t3)</statement></entry>
! <entry>creates an &intervalone; with the integers converted from
<varname>t1</varname> and <varname>t2</varname>.
<varname>t3</varname> must equal 1.</entry>
</row>
***************
*** 497,512 ****
constructors except that &intervalone;s can have differing
beginning and ending points. See <xref
linkend="arrays-domains-declarations-interval-one_d_table"></xref>.
! The default constructor creates an empty, uninitialized interval,
! which should not be used before assigning it values. If the
! one-parameter constructor's argument is a &domain; object, it must
! be a one-dimensional &domain; object which is copied into an
! &interval; if possible; for example, it must have unit stride.
! If the one-parameter constructor's argument is not a &domain;
! object, it must be convertible to an
integer <varname>e</varname> and an interval [0:e-1:1]
! starting at zero is constructed. If two arguments are specified,
! they are assumed to be convertible to integers
<varname>b</varname> and <varname>e</varname>, specifying the
interval [b:e:1]. The three-parameter constructor is similar,
with the third argument specifying a stride, which must be
--- 496,512 ----
constructors except that &intervalone;s can have differing
beginning and ending points. See <xref
linkend="arrays-domains-declarations-interval-one_d_table"></xref>.
! The default constructor creates an empty, uninitialized
! interval, which should not be used before assigning it values.
! If the one-parameter constructor's argument is a &domain;
! object, it must be a one-dimensional &domain; object which is
! converted into an &interval; if possible; for example, it must have
! unit stride. If the one-parameter constructor's argument is not
! a &domain; object, it must be convertible to an
integer <varname>e</varname> and an interval [0:e-1:1]
! starting at zero is constructed. Note e-1, not e, is used so
! the &intervalone; has e indices. If two arguments are
! specified, they are assumed to be convertible to integers
<varname>b</varname> and <varname>e</varname>, specifying the
interval [b:e:1]. The three-parameter constructor is similar,
with the third argument specifying a stride, which must be
***************
*** 530,536 ****
template parameters.</entry>
</row>
</tfoot>
! <tbody>
<row>
<entry><statement>Interval<&dim;>()</statement></entry>
<entry>creates an empty, uninitialized &interval;, to be assigned a value later.</entry>
--- 530,536 ----
template parameters.</entry>
</row>
</tfoot>
! <tbody valign="top">
<row>
<entry><statement>Interval<&dim;>()</statement></entry>
<entry>creates an empty, uninitialized &interval;, to be assigned a value later.</entry>
***************
*** 541,578 ****
</row>
<row>
<entry><statement>Interval<&dim;>(const &domaintemplate;1& t1)</statement></entry>
! <entry>creates a &interval; using the given &domain; object.</entry>
</row>
<row>
<entry><statement>Interval<&dim;>(const &domaintemplate;1& t1, const &domaintemplate;2& t2)</statement></entry>
! <entry>creates a &interval; using the given &domain; objects.</entry>
</row>
<row>
<entry><statement>Interval<&dim;>(const &domaintemplate;1& t1, const &domaintemplate;2& t2, const &domaintemplate;3& t3)</statement></entry>
! <entry>creates a &interval; using the given &domain; objects.</entry>
</row>
<row>
<entry><statement>Interval<&dim;>(const &domaintemplate;1& t1, const
&domaintemplate;2& t2, const &domaintemplate;3& t3, const &domaintemplate;4& t4)</statement></entry>
! <entry>creates a &interval; using the given &domain; objects.</entry>
</row>
<row>
<entry><statement>Interval<&dim;>(const &domaintemplate;1& t1, const
&domaintemplate;2& t2, const &domaintemplate;3& t3, const &domaintemplate;4& t4, const &domaintemplate;5&
t5)</statement></entry>
! <entry>creates a &interval; using the given &domain; objects.</entry>
</row>
<row>
<entry><statement>Interval<&dim;>(const &domaintemplate;1& t1, const
&domaintemplate;2& t2, const &domaintemplate;3& t3, const &domaintemplate;4& t4, const &domaintemplate;5&
t5, const &domaintemplate;6& t6)</statement></entry>
! <entry>creates a &interval; using the given &domain; objects.</entry>
</row>
<row>
<entry><statement>Interval<&dim;>(const &domaintemplate;1& t1, const
&domaintemplate;2& t2, const &domaintemplate;3& t3, const &domaintemplate;4& t4, const &domaintemplate;5&
t5, const &domaintemplate;6& t6, const &domaintemplate;7& t7)</statement></entry>
! <entry>creates a &interval; using the given &domain; objects.</entry>
</row>
</tbody>
</tgroup>
--- 541,578 ----
</row>
<row>
<entry><statement>Interval<&dim;>(const &domaintemplate;1& t1)</statement></entry>
! <entry>creates an &interval; using the given &domain; object.</entry>
</row>
<row>
<entry><statement>Interval<&dim;>(const &domaintemplate;1& t1, const &domaintemplate;2& t2)</statement></entry>
! <entry>creates an &interval; using the given &domain; objects.</entry>
</row>
<row>
<entry><statement>Interval<&dim;>(const &domaintemplate;1& t1, const &domaintemplate;2& t2, const &domaintemplate;3& t3)</statement></entry>
! <entry>creates an &interval; using the given &domain; objects.</entry>
</row>
<row>
<entry><statement>Interval<&dim;>(const &domaintemplate;1& t1, const
&domaintemplate;2& t2, const &domaintemplate;3& t3, const &domaintemplate;4& t4)</statement></entry>
! <entry>creates an &interval; using the given &domain; objects.</entry>
</row>
<row>
<entry><statement>Interval<&dim;>(const &domaintemplate;1& t1, const
&domaintemplate;2& t2, const &domaintemplate;3& t3, const &domaintemplate;4& t4, const &domaintemplate;5&
t5)</statement></entry>
! <entry>creates an &interval; using the given &domain; objects.</entry>
</row>
<row>
<entry><statement>Interval<&dim;>(const &domaintemplate;1& t1, const
&domaintemplate;2& t2, const &domaintemplate;3& t3, const &domaintemplate;4& t4, const &domaintemplate;5&
t5, const &domaintemplate;6& t6)</statement></entry>
! <entry>creates an &interval; using the given &domain; objects.</entry>
</row>
<row>
<entry><statement>Interval<&dim;>(const &domaintemplate;1& t1, const
&domaintemplate;2& t2, const &domaintemplate;3& t3, const &domaintemplate;4& t4, const &domaintemplate;5&
t5, const &domaintemplate;6& t6, const &domaintemplate;7& t7)</statement></entry>
! <entry>creates an &interval; using the given &domain; objects.</entry>
</row>
</tbody>
</tgroup>
***************
*** 635,641 ****
<entry></entry>
</row>
</tfoot>
! <tbody>
<row>
<entry><statement>Range<1>()</statement></entry>
<entry>creates an empty, uninitialized range.</entry>
--- 635,641 ----
<entry></entry>
</row>
</tfoot>
! <tbody valign="top">
<row>
<entry><statement>Range<1>()</statement></entry>
<entry>creates an empty, uninitialized range.</entry>
***************
*** 665,684 ****
</table>
<para>&rangeone; constructors are the same as &intervalone;
! constructors except they create ranges, not intervals. See <xref
linkend="arrays-domains-declarations-range-one_d_table"></xref>.
The default constructor creates an empty, uninitialized range,
which should not be used before assigning it values. If the
! one-parameter constructor's argument is a &domain; object, it must
! be a one-dimensional &domain; object which is copied into a ⦥
! if possible. If the one-parameter constructor's argument is not
! a &domain; object, it must be convertible to an
integer <varname>e</varname> and a range [0:e-1:1] starting
! at zero is constructed. If two arguments are specified, they are
! assumed to be convertible to integers <varname>b</varname> and
! <varname>e</varname>, specifying the range [b:e:1]. The
! three-parameter constructor is similar, with the third argument
! specifying a stride.</para>
<table frame="none" colsep="0" rowsep="0" tocentry="1"
orient="port" pgwide="0" id="arrays-domains-declarations-ranges-multi_d_table">
--- 665,686 ----
</table>
<para>&rangeone; constructors are the same as &intervalone;
! constructors except they create ranges, not intervals. See
! <xref
linkend="arrays-domains-declarations-range-one_d_table"></xref>.
The default constructor creates an empty, uninitialized range,
which should not be used before assigning it values. If the
! one-parameter constructor's argument is a &domain; object, it
! must be a one-dimensional &domain; object which is converted
! into a ⦥ if possible. If the one-parameter constructor's
! argument is not a &domain; object, it must be convertible to an
integer <varname>e</varname> and a range [0:e-1:1] starting
! at zero is constructed. Note e-1, not e, is used so the
! &intervalone; has e indices. If two arguments are specified,
! they are assumed to be convertible to integers
! <varname>b</varname> and <varname>e</varname>, specifying the
! range [b:e:1]. The three-parameter constructor is similar, with
! the third argument specifying a stride.</para>
<table frame="none" colsep="0" rowsep="0" tocentry="1"
orient="port" pgwide="0" id="arrays-domains-declarations-ranges-multi_d_table">
***************
*** 698,704 ****
template parameters.</entry>
</row>
</tfoot>
! <tbody>
<row>
<entry><statement>Range<&dim;>()</statement></entry>
<entry>creates an empty, uninitialized ⦥, to be assigned a value later.</entry>
--- 700,706 ----
template parameters.</entry>
</row>
</tfoot>
! <tbody valign="top">
<row>
<entry><statement>Range<&dim;>()</statement></entry>
<entry>creates an empty, uninitialized ⦥, to be assigned a value later.</entry>
***************
*** 807,813 ****
<entry></entry>
</row>
</tfoot>
! <tbody>
<row>
<entry><statement>Grid<1>()</statement></entry>
<entry>creates an empty, uninitialized grid.</entry>
--- 809,815 ----
<entry></entry>
</row>
</tfoot>
! <tbody valign="top">
<row>
<entry><statement>Grid<1>()</statement></entry>
<entry>creates an empty, uninitialized grid.</entry>
***************
*** 843,856 ****
<para>&gridone;s with irregularly spaced points can be
constructed using &indirectionlistint;s. For example,
! <programlisting>
! IndirectionList<int> list(4);
! list(0) = 2;
! list(1) = 5;
! list(2) = 6;
! list(3) = 9;
! Grid<1> g(list);
! </programlisting> constructs an empty &indirectionlistint;, fills it
with ascending values, and then creates a &gridone; containing
{2, 5, 6, 9}. When creating a list, its size must be specified.
Subsequently, its values can be assigned. &indirectionlist;s can
--- 845,858 ----
<para>&gridone;s with irregularly spaced points can be
constructed using &indirectionlistint;s. For example,
! <programlisting>
! IndirectionList<int> list(4);
! list(0) = 2;
! list(1) = 5;
! list(2) = 6;
! list(3) = 9;
! Grid<1> g(list);
! </programlisting> constructs an empty &indirectionlistint;, fills it
with ascending values, and then creates a &gridone; containing
{2, 5, 6, 9}. When creating a list, its size must be specified.
Subsequently, its values can be assigned. &indirectionlist;s can
***************
*** 885,891 ****
parameters.</entry>
</row>
</tfoot>
! <tbody>
<row>
<entry><statement>Grid<&dim;>()</statement></entry>
<entry>creates an empty, uninitialized &grid;, to be assigned a value later.</entry>
--- 887,893 ----
parameters.</entry>
</row>
</tfoot>
! <tbody valign="top">
<row>
<entry><statement>Grid<&dim;>()</statement></entry>
<entry>creates an empty, uninitialized &grid;, to be assigned a value later.</entry>
***************
*** 961,973 ****
<para>Since an &array; can be queried for its domain, we briefly
describe some &domain; operations. A fuller description,
! including arithmetic operations, occur in <xref
linkend="views"></xref>. As we mentioned in <xref
linkend="arrays-domains-declarations"></xref>, the <filename
class="headerfile">Pooma/Domains.h</filename> header file
! declares &domain;s, but most container header files automatically
! include <filename class="headerfile">Pooma/Domains.h</filename>
! so no explicit inclusion of is usually necessary.</para>
<table frame="none" colsep="0" rowsep="0" tocentry="1"
orient="port" pgwide="0" id="arrays-domains-use-table">
--- 963,976 ----
<para>Since an &array; can be queried for its domain, we briefly
describe some &domain; operations. A fuller description,
! including arithmetic operations, occurs in <xref
linkend="views"></xref>. As we mentioned in <xref
linkend="arrays-domains-declarations"></xref>, the <filename
class="headerfile">Pooma/Domains.h</filename> header file
! declares &domain;s, but most storage container header files
! automatically include <filename
! class="headerfile">Pooma/Domains.h</filename> so no explicit
! inclusion is usually necessary.</para>
<table frame="none" colsep="0" rowsep="0" tocentry="1"
orient="port" pgwide="0" id="arrays-domains-use-table">
***************
*** 982,993 ****
</thead>
<tfoot>
<row>
! <entry><type>D</type> abbreviates the particular &domain;
! type, e.g., &interval; or &grid;. Other &domain; accessors
! are described in <xref linkend="views"></xref>.</entry>
</row>
</tfoot>
! <tbody>
<row rowsep="1">
<entry>Multidimensional &domain; Accessors</entry>
</row>
--- 985,996 ----
</thead>
<tfoot>
<row>
! <entry><type>D</type> abbreviates a particular &domain; type,
! e.g., &interval; or &grid;. Other &domain; accessors are
! described in <xref linkend="views"></xref>.</entry>
</row>
</tfoot>
! <tbody valign="top">
<row rowsep="1">
<entry>Multidimensional &domain; Accessors</entry>
</row>
***************
*** 1030,1041 ****
</row>
<row>
<entry><statement>D<1>::iterator begin()</statement></entry>
! <entry>returns a bidirectional iterator pointing to the
beginning domain index.</entry>
</row>
<row>
<entry><statement>D<1>::iterator end()</statement></entry>
! <entry>returns a bidirectional iterator pointing to the ending
domain index.</entry>
</row>
</tbody>
--- 1033,1044 ----
</row>
<row>
<entry><statement>D<1>::iterator begin()</statement></entry>
! <entry>returns a forward iterator pointing to the
beginning domain index.</entry>
</row>
<row>
<entry><statement>D<1>::iterator end()</statement></entry>
! <entry>returns a forward iterator pointing to the ending
domain index.</entry>
</row>
</tbody>
***************
*** 1054,1060 ****
one-dimensional &domain;s. The <methodname>operator[](int
dimension)</methodname> operator extracts the one-dimensional
&domain; corresponding to its parameter. For example, the three
! <type>Range<1></type> (one-dimensional) &domain;s can be
extracted from a <type>Range<3></type>
object <varname>r</varname> using
<statement>r[0]</statement>, <statement>r[1]</statement>, and
--- 1057,1063 ----
one-dimensional &domain;s. The <methodname>operator[](int
dimension)</methodname> operator extracts the one-dimensional
&domain; corresponding to its parameter. For example, the three
! one-dimensional <type>Range<1></type> &domain;s can be
extracted from a <type>Range<3></type>
object <varname>r</varname> using
<statement>r[0]</statement>, <statement>r[1]</statement>, and
***************
*** 1069,1075 ****
<methodname>first</methodname> and <methodname>last</methodname>
member functions return the domain's beginning and ending
indices. The <methodname>begin</methodname> and
! <methodname>end</methodname> member functions return input
iterators pointing to these respective locations. They have type
<type>D<1>::iterator</type>, where <type>D</type>
abbreviates the &domain;'s type, e.g., &interval; or &grid;.
--- 1072,1078 ----
<methodname>first</methodname> and <methodname>last</methodname>
member functions return the domain's beginning and ending
indices. The <methodname>begin</methodname> and
! <methodname>end</methodname> member functions return forward
iterators pointing to these respective locations. They have type
<type>D<1>::iterator</type>, where <type>D</type>
abbreviates the &domain;'s type, e.g., &interval; or &grid;.
***************
*** 1077,1086 ****
--> The <methodname>min</methodname> and
<methodname>max</methodname> member functions return the minimum
and maximum indices in the &domain; object, respectively. For
! &locone; and &intervalone;, these are the same as
<methodname>first</methodname> and <methodname>last</methodname>,
! but &rangeone; and &gridone; can have their largest index at the
! beginning of their &domain;s.</para>
</section>
</section>
--- 1080,1089 ----
--> The <methodname>min</methodname> and
<methodname>max</methodname> member functions return the minimum
and maximum indices in the &domain; object, respectively. For
! &locone; and &intervalone;, these yield the same values as
<methodname>first</methodname> and <methodname>last</methodname>,
! but &rangeone; and &gridone; can have their numerically largest
! index at the beginning of their &domain;s.</para>
</section>
</section>
***************
*** 1088,1100 ****
<section id="arrays-arrays_declarations">
<title>Declaring &array;s</title>
! <para>A &pooma; &array; maps indices from its &domain; to values.
! In this section, we first describe how to declare &array;s. In
! the next section, we explain how to access individual values
! stored within an &array; and &array; copy semantics.</para>
<para>&array; values need not just be stored values, as &c; arrays
! have. They can also be computed using its engine. We defer
discussion of computing values to the next chapter discussing
engines (<xref linkend="engines"></xref>). To avoid being verbose
in this chapter, when we discuss stored values, the values might
--- 1091,1105 ----
<section id="arrays-arrays_declarations">
<title>Declaring &array;s</title>
! <para>A &pooma; &array; maps &domain; indices to values. In this
! section, we describe how to declare &array;s. In the next
! section, we explain how to access individual values stored within
! an &array; and how to copy &array;s.</para>
+ <!-- FIXME: This paragraph is poorly worded. -->
+
<para>&array; values need not just be stored values, as &c; arrays
! have. They can also be computed by its engine. We defer
discussion of computing values to the next chapter discussing
engines (<xref linkend="engines"></xref>). To avoid being verbose
in this chapter, when we discuss stored values, the values might
***************
*** 1102,1177 ****
<para>Declaring an &array; requires four arguments: the domain's
dimensionality, the type of values stored or computed, a
! specification how the values are stored, and a &domain;. The
! first three arguments are template parameters since few scientific
! programs (and no &pooma; programs) need to change these values
! while a program executes. For example, an &array; cannot change
! the type of the elements it stores. Alternatively, an &array;'s
! values can be copied into another &array; having the desired type.
! Although scientific programs do not frequently change an array's
! domain, they do frequently request a subset of the array's values,
! i.e., a <glossterm linkend="glossary-view">view</glossterm>. The
! subset is specified via a &domain; so it is a run-time value.
! Views are presented in <xref linkend="views"></xref>.</para>
<para>An &array;'s first template parameter specifies its
dimensionality. This positive
! integer <varname>&dim;</varname> specifies its rank. This is
the same value as its domain's dimensionality. Theoretically, an
&array; can have any positive integer, but the &pooma; code
! currently supports <varname>&dim;</varname> at most seven. For
! almost all scientific codes, a dimension of three or four is
! sufficient, but the code can be extended to support higher
dimensions.</para>
<para>An &array;'s second template parameter specifies the type of
! its stored values. Common value types include ∫, &double;,
! &complex;, and &vector;, but any type is permissible. For
! example, an &array;'s values might be matrices or even other
&array;s. The parameter's default value is usually &double;, but
it may be changed when the &poomatoolkit; is configured.</para>
<para>An &array;'s third parameter specifies how its data is
! stored by an &engine; and its values accessed. The argument is a
! tag indicating a particular type of &engine;. Permissible tags
! include &brick;, &compressiblebrick;, and
<type>ConstantFunction</type>. The &brick; tag indicates all
&array; values will be explicitly stored, just as built-in &c;
! arrays do. If the &array;s frequently stores exactly the same
! value in every position, a &compressiblebrick; &engine;, which
! reduces its space requirements to a constant whenever all its
! values are the same, is appropriate. A
! <type>ConstantFunction</type> &engine; returns the same value for
! all indices.</para>
<para>Even though every &array; container has an engine to store
! its values and permit access to individual values, an &array; is
! conceptually separated from engines. An engine's role is
! low-level, storing values and permitting access to individual
! values. As we indicated above, the storage can be optimized to
! fit specific situations such as few nonzero values and computing
! values using a function applied to another engine's values. An
! &array;'s role is high-level, supporting access to groups of
! values. They handle memory allocation and deallocation. &array;s
! can be used in data-parallel expressions, e.g., adding all the
! values in one &array; to all the values in another. (See <xref
! linkend="data_parallel"></xref> for more information.) Subsets of
! &array; values, frequently used in data-parallel statements, can
! be obtained. (See <xref linkend="views"></xref> for more
! information.) Even though engines and &array;s are conceptually
! separate, higher-level &array;s provide access to lower-level
! &engine;s. Users usually have an &array; create its &engine;,
! rarely explicitly creating &engine;s themselves. Also, &array;s
! provide access to individual values. In short, &pooma; users use
! &array;s, only dealing with how they are implemented (engines)
! upon declaration. For more description of &engine;s, see <xref
linkend="engines"></xref>.</para>
-
- <para>The engine parameter's default value is usually &brick;, but
- it may be changed when the &poomatoolkit; is configured.</para>
! <para>An &array;'s one constructor argument is its domain. The
! domain specifies its extent and simultaneously how many values it
can return. All the provided &domain; objects are combined to
yield an <type>Interval<&dim;></type>, where &dim; matches
the &array;'s first template parameter. Since an &interval;
--- 1107,1186 ----
<para>Declaring an &array; requires four arguments: the domain's
dimensionality, the type of values stored or computed, a
! specification how the values are stored or computed, and a
! &domain;. The first three arguments are template parameters since
! few scientific programs need to (and no &pooma; programs can)
! change these values while a program executes. For example, an
! &array; cannot change the type of the values it stores, but an
! &array;'s values can be copied into another &array; having the
! desired type. Although scientific programs do not frequently
! change an array's domain, they do frequently request a subset of
! the array's values, i.e., a <glossterm
! linkend="glossary-view">view</glossterm>. The subset is specified
! via a &domain; so it is a run-time value. Views are presented in
! <xref linkend="views"></xref>.</para>
<para>An &array;'s first template parameter specifies its
dimensionality. This positive
! integer <varname>&dim;</varname> specifies its rank and has
the same value as its domain's dimensionality. Theoretically, an
&array; can have any positive integer, but the &pooma; code
! currently supports a dimensionality of at most seven. For almost
! all scientific codes, a dimension of three or four is sufficient,
! but the &pooma; code can be extended to support higher
dimensions.</para>
<para>An &array;'s second template parameter specifies the type of
! its stored or computed values. Common value types include ∫,
! &double;, &complex;, and &vector;, but any type is permissible.
! For example, an &array;'s values might be matrices or even other
&array;s. The parameter's default value is usually &double;, but
it may be changed when the &poomatoolkit; is configured.</para>
<para>An &array;'s third parameter specifies how its data is
! stored or computed by an &engine; and its values accessed. The
! argument is a tag indicating a particular type of &engine;.
! Permissible tags include &brick;, &compressiblebrick;, and
<type>ConstantFunction</type>. The &brick; tag indicates all
&array; values will be explicitly stored, just as built-in &c;
! arrays do. If an &array; frequently stores exactly the same value
! in every position, a &compressiblebrick; &engine;, which reduces
! its space requirements to a constant whenever all its values are
! the same, is appropriate. A <type>ConstantFunction</type>
! &engine; returns the same value for all indices. Some &engine;s
! compute values, e.g., applying a function to every value in
! another &engine;. These &engine;s are discussed in <xref
! linkend="engines"></xref>. To avoid being verbose in the rest of
! this chapter, we abbreviate <quote>store or compute values</quote>
! as <quote>store values</quote>. The engine parameter's default
! value is usually &brick;, but it may be changed when the
! &poomatoolkit; is configured.</para>
<para>Even though every &array; container has an engine to store
! its values and permit access to individual values, the concept of
! an &array; is conceptually separate from the concept of an engine.
! An engine's role is low-level, storing values and permitting
! access to individual values. As we indicated above, the storage
! can be optimized to fit specific situations such as few nonzero
! values and computing values using a function applied to another
! engine's values. An &array;'s role is high-level, supporting
! access to groups of values. &array;s can be used in data-parallel
! expressions, e.g., adding all the values in one &array; to all the
! values in another. (See <xref linkend="data_parallel"></xref> for
! more information.) Subsets of &array; values, frequently used in
! data-parallel statements, can be obtained. (See <xref
! linkend="views"></xref> for more information.) Even though
! engines and &array;s are conceptually separate, higher-level
! &array;s provide access to lower-level &engine;s. Users usually
! have an &array; create its &engine;(s), rarely explicitly creating
! &engine;s themselves. Also, &array;s support access to individual
! values. In short, &pooma; users use &array;s, only dealing with
! how they are implemented (engines) when declaring them. For a
! description of &engine;s, see <xref
linkend="engines"></xref>.</para>
! <para>An &array;'s one run-time argument is its domain. The
! domain specifies its extent and consequently how many values it
can return. All the provided &domain; objects are combined to
yield an <type>Interval<&dim;></type>, where &dim; matches
the &array;'s first template parameter. Since an &interval;
***************
*** 1185,1190 ****
--- 1194,1240 ----
required, the &pooma; code can be extended to the desired number
of dimensions.</para>
+ <para>&array; constructors are listed in <xref
+ linkend="arrays-arrays_declarations-table"></xref>. An &array;'s
+ three template parameters for dimensionality, value type, and
+ engine type are abbreviated <varname>D</varname>,
+ <varname>T</varname>, and <varname>E</varname>. Template
+ parameters for domain types are named <varname>DT1</varname>,
+ …, <varname>DT7</varname>. The first constructor, with no
+ domain arguments, creates an empty, uninitialized &array; for
+ which a domain must be specified before it is used. Specify the
+ array's domain using its <methodname>initialize</methodname>
+ function. The next seven constructors combine their domain
+ arguments to compute the resulting &array;'s domain. These are
+ combined in the same way that multidimensional &interval;s are
+ constructed. (See <xref
+ linkend="arrays-domains-declarations-intervals-multi_d_table"></xref>
+ and the following text.) The domain objects, having types
+ <type>&domaintemplate;1</type>, …,
+ <type>&domaintemplate;7</type>, can have any type that can be
+ converted into an integer, into a single-dimensional &domain;
+ object that can be converted into a single-dimensional &interval;,
+ or to a multidimensional &domain; object that itself can be
+ converted into an &interval;. The total dimensionality of all the
+ arguments' types should
+ <emphasis>equal</emphasis> <varname>&dim;</varname>, unlike
+ &interval; construction which permits total dimensionality less
+ than or equal to <varname>&dim;</varname>. One-dimensional
+ &domain; objects that can be converted into one-dimensional
+ &interval;s include &locone;s, &intervalone;s, and &rangeone;s
+ with unit strides. To initialize all of an &array;'s values to a
+ specific value, use one of the final seven constructors, each
+ taking a particular value, wrapped as a <type>ModelElement</type>.
+ These constructors use the given domain objects the same way as
+ the preceding constructors but assign <varname>model</varname> to
+ every &array; value. <varname>model</varname>'s type is
+ <type>ModelElement<T></type>, rather than
+ <varname>T</varname>, to differentiate it from an ∫, which can
+ also be used to specify a domain object.
+ <type>ModelElement</type> just stores an element of any type
+ <varname>T</varname>, which must match the &array;'s value
+ type <varname>T</varname>.</para>
+
<table frame="none" colsep="0" rowsep="0" tocentry="1"
orient="port" pgwide="0" id="arrays-arrays_declarations-table">
<title>Declaring &array;s</title>
***************
*** 1206,1212 ****
integers.</entry>
</row>
</tfoot>
! <tbody>
<row>
<entry><statement>Array<&dim;,T,E>()</statement></entry>
<entry>creates an empty, uninitialized &array; which must be
--- 1256,1262 ----
integers.</entry>
</row>
</tfoot>
! <tbody valign="top">
<row>
<entry><statement>Array<&dim;,T,E>()</statement></entry>
<entry>creates an empty, uninitialized &array; which must be
***************
*** 1310,1368 ****
</tgroup>
</table>
- <para>&array; constructors are listed in <xref
- linkend="arrays-arrays_declarations-table"></xref>. An &array;s'
- three template parameters for dimensionality, value type, and
- engine type are abbreviated <varname>D</varname>,
- <varname>T</varname>, and <varname>E</varname>. Template
- parameters for domain types are named <varname>DT1</varname>,
- …, <varname>DT7</varname>. The first constructor, with no
- domain arguments, creates an empty, uninitialized &array; for
- which a domain must be specified before it is used. Specify the
- array's domain using its <methodname>initialize</methodname> function.
- The next seven constructors combine their domain arguments to
- compute the resulting &array;'s domain. These are combined in the
- same way that multidimensional &interval;s are constructed. (See
- <xref
- linkend="arrays-domains-declarations-intervals-multi_d_table"></xref>
- and the following text.) The domain objects, having types
- <type>&domaintemplate;1</type>, …,
- <type>&domaintemplate;7</type>, can have any type that can be
- converted into an integer, into a single-dimensional &domain;
- object that can be converted into a single-dimensional &interval;,
- or to a multidimensional &domain; object that itself can be
- converted into an &interval;. The total dimensionality of all the
- arguments' types should
- <emphasis>equal</emphasis> <varname>&dim;</varname>, unlike
- &interval; construction which permits total dimensionality less
- than or equal to <varname>&dim;</varname>. One-dimensional
- &domain; objects that can be converted into one-dimensional
- &interval;s include &locone;s, &intervalone;s, and &rangeone;s
- with unit strides. To initialize all of an &array; values to a
- specific value, use one of the final seven constructors, each
- taking a particular value, wrapped as a <type>ModelElement</type>.
- These constructors use the given domain objects the same way as
- the preceding constructors but assign <varname>model</varname> to
- every &array; value. <varname>model</varname>'s type
- <type>ModelElement<T></type> rather than
- <varname>T</varname> to differentiate it from an ∫, which can
- also be used to specify a domain object.
- <type>ModelElement</type> just stores an element of any type
- <varname>T</varname>, which must match the &array;'s value
- type.</para>
-
<para>We illustrate creating &array;s. To create a
three-dimensional &array; <varname>a</varname> explicitly
storing &double; floating-point values, use
<programlisting>
Interval<1> D(6);
Interval<3> I3(D,D,D);
! Array<3,double,Brick> a(I3);.
</programlisting> The template parameters specify its dimensionality,
the type of its values, and a &brick; &engine; type, which
explicitly stores values. Its domain, which must have three
dimensions, is specified by an <type>Interval<3></type>
! object which consists of a [0,5] intervals for all its three
dimensions. Since &double; and &brick; are usually the default
template parameters, they can be omitted so these declarations are
equivalent:
--- 1360,1377 ----
</tgroup>
</table>
<para>We illustrate creating &array;s. To create a
three-dimensional &array; <varname>a</varname> explicitly
storing &double; floating-point values, use
<programlisting>
Interval<1> D(6);
Interval<3> I3(D,D,D);
! Array<3,double,Brick> a(I3);
</programlisting> The template parameters specify its dimensionality,
the type of its values, and a &brick; &engine; type, which
explicitly stores values. Its domain, which must have three
dimensions, is specified by an <type>Interval<3></type>
! object which consists of [0,5] intervals for all its three
dimensions. Since &double; and &brick; are usually the default
template parameters, they can be omitted so these declarations are
equivalent:
*************** Array<3> a_duplicate2(I3);.
*** 1372,1383 ****
</programlisting> To create a similar &array; with a domain of
[0:1:1, 0:2:1, 0:0:1], use
<programlisting>
! Array<3> b(2,3,1);.
! </programlisting> Specifying an integer <varname>i</varname>
indicates a one-dimensional zero-based &interval; [0:i-1:1]. To
! store &bool;s, specify &bool; as the second template argument:
<programlisting>
! Array<2,bool> c(2,3);.
</programlisting> To specify a default &array; value of &true;, use
<statement>ModelElement<bool>(true)</statement>:
<programlisting>
--- 1381,1392 ----
</programlisting> To create a similar &array; with a domain of
[0:1:1, 0:2:1, 0:0:1], use
<programlisting>
! Array<3> b(2,3,1);
! </programlisting> since specifying an integer <varname>i</varname>
indicates a one-dimensional zero-based &interval; [0:i-1:1]. To
! store booleans, specify &bool; as the second template argument:
<programlisting>
! Array<2,bool> c(2,3);
</programlisting> To specify a default &array; value of &true;, use
<statement>ModelElement<bool>(true)</statement>:
<programlisting>
*************** Array<2,bool> c(2,3, ModelElement&
*** 1385,1395 ****
</programlisting> To create a one-dimensional &array; containing
seven &double;s all equaling π, use
<programlisting>
! Array<1,double,CompressibleBrick> d(7, ModelElement<double>(4.0*atan(1.0)));.
</programlisting> We use a &compressiblebrick; &engine;, rather than
! a &brick; &engine;, so all seven values will be stored once rather
! than seven times when they are all the same.</para>
<table frame="none" colsep="0" rowsep="0" tocentry="1"
orient="port" pgwide="0" id="arrays-arrays_declarations-initialize_table">
<title>Initializing &array;s' Domains</title>
--- 1394,1432 ----
</programlisting> To create a one-dimensional &array; containing
seven &double;s all equaling π, use
<programlisting>
! const double pi = 4.0*atan(1.0);
! Array<1,double,CompressibleBrick> d(7, ModelElement<double>(pi));.
</programlisting> We use a &compressiblebrick; &engine;, rather than
! a &brick; &engine;, so all seven values will be stored in one
! location rather than in seven separate locations when they are all the
! same.</para>
+ <para>An uninitialized &array;, created using its parameter-less
+ constructor, must have a specified domain before it can be used.
+ For example, one must use the parameter-less &array; constructor
+ when creating an array of &array;s using
+ <keywordname>new</keywordname> so their domains must be specified.
+ (It would probably be better to create an &array; of &array;s
+ since memory allocation and deallocation would automatically be
+ handled.) &array;'s <methodname>initialize</methodname> functions
+ accept the same set of domain object specifications and model
+ elements that the &array; constructors do, creating the specified
+ domain. See <xref
+ linkend="arrays-arrays_declarations-initialize_table"></xref>.
+ For example, both <varname>a</varname> and <varname>b</varname>
+ are two-dimensional &array;s of &float;s with a [2:7:1,-2:4:1]
+ domains:
+ <programlisting>
+ // Create an Array and its domain.
+ Array<2,float,Brick> a(Interval<1>(2,7), Interval<1>(-2,4));
+
+ // Create an Array without a domain and then specify its domain.
+ Array<2,float,Brick> b();
+ b.initialize(Interval<1>(2,7), Interval<1>(-2,4));.
+ </programlisting> Invoking <methodname>initialize</methodname> on an
+ &array; with an existing domain yields unspecified behavior. All
+ &array; values may be lost and memory may be leaked.</para>
+
<table frame="none" colsep="0" rowsep="0" tocentry="1"
orient="port" pgwide="0" id="arrays-arrays_declarations-initialize_table">
<title>Initializing &array;s' Domains</title>
*************** Array<1,double,CompressibleBrick>
*** 1413,1419 ****
integers.</entry>
</row>
</tfoot>
! <tbody>
<!-- Omit Indirection Array initialize because it does not exist! -->
<!-- Omit the two Array<D1,T1,E1> functions, which should not be used by users. -->
<row>
--- 1450,1456 ----
integers.</entry>
</row>
</tfoot>
! <tbody valign="top">
<!-- Omit Indirection Array initialize because it does not exist! -->
<!-- Omit the two Array<D1,T1,E1> functions, which should not be used by users. -->
<row>
*************** object or integer.</entry>
*** 1455,1480 ****
<row>
<entry><statement>initialize(const DT1& t1,
const ModelElement<T>& model)</statement></entry>
! <entry>creates the &array;'s domain using the given &domain; object and
then initializes all entries using <varname>model</varname>.</entry>
</row>
<row>
<entry><statement>initialize(const DT1& t1, const DT2& t2,
const ModelElement<T>& model)</statement></entry>
! <entry>creates the &array;'s domain using the given &domain; objects and
then initializes all entries using <varname>model</varname>.</entry>
</row>
<row>
<entry><statement>initialize(const DT1& t1, const DT2& t2, const DT3& t3,
const ModelElement<T>& model)</statement></entry>
! <entry>creates the &array;'s domain using the given &domain; objects and
then initializes all entries using <varname>model</varname>.</entry>
</row>
<row>
<entry><statement>initialize(const DT1& t1, const
DT2& t2, const DT3& t3, const DT4& t4,
const ModelElement<T>& model)</statement></entry>
! <entry>creates the &array;'s domain using the given &domain; objects and
then initializes all entries using <varname>model</varname>.</entry>
</row>
<row>
--- 1492,1520 ----
<row>
<entry><statement>initialize(const DT1& t1,
const ModelElement<T>& model)</statement></entry>
! <entry>creates the &array;'s domain using the given &domain;
! object or integer and
then initializes all entries using <varname>model</varname>.</entry>
</row>
<row>
<entry><statement>initialize(const DT1& t1, const DT2& t2,
const ModelElement<T>& model)</statement></entry>
! <entry>creates the &array;'s domain using the given &domain;
! objects and integers and
then initializes all entries using <varname>model</varname>.</entry>
</row>
<row>
<entry><statement>initialize(const DT1& t1, const DT2& t2, const DT3& t3,
const ModelElement<T>& model)</statement></entry>
! <entry>creates the &array;'s domain using the given &domain;
! objects and integers and
then initializes all entries using <varname>model</varname>.</entry>
</row>
<row>
<entry><statement>initialize(const DT1& t1, const
DT2& t2, const DT3& t3, const DT4& t4,
const ModelElement<T>& model)</statement></entry>
! <entry>creates the &array;'s domain using the given &domain; objects and integers and
then initializes all entries using <varname>model</varname>.</entry>
</row>
<row>
*************** object or integer.</entry>
*** 1482,1488 ****
DT2& t2, const DT3& t3, const DT4& t4, const DT5&
t5,
const ModelElement<T>& model)</statement></entry>
! <entry>creates the &array;'s domain using the given &domain; objects and
then initializes all entries using <varname>model</varname>.</entry>
</row>
<row>
--- 1522,1528 ----
DT2& t2, const DT3& t3, const DT4& t4, const DT5&
t5,
const ModelElement<T>& model)</statement></entry>
! <entry>creates the &array;'s domain using the given &domain; objects and integers and
then initializes all entries using <varname>model</varname>.</entry>
</row>
<row>
*************** object or integer.</entry>
*** 1490,1496 ****
DT2& t2, const DT3& t3, const DT4& t4, const DT5&
t5, const DT6& t6,
const ModelElement<T>& model)</statement></entry>
! <entry>creates the &array;'s domain using the given &domain; objects and
then initializes all entries using <varname>model</varname>.</entry>
</row>
<row>
--- 1530,1536 ----
DT2& t2, const DT3& t3, const DT4& t4, const DT5&
t5, const DT6& t6,
const ModelElement<T>& model)</statement></entry>
! <entry>creates the &array;'s domain using the given &domain; objects and integers and
then initializes all entries using <varname>model</varname>.</entry>
</row>
<row>
*************** object or integer.</entry>
*** 1498,1534 ****
DT2& t2, const DT3& t3, const DT4& t4, const DT5&
t5, const DT6& t6, const DT7& t7,
const ModelElement<T>& model)</statement></entry>
! <entry>creates the &array;'s domain using the given &domain; objects and
then initializes all entries using <varname>model</varname>.</entry>
</row>
</tbody>
</tgroup>
</table>
-
- <para>An uninitialized &array;, created using the parameter-less
- constructor, must have a specified domain before it can be used.
- For example, one must use the parameter-less &array; constructor
- when creating an array of &array;s using
- <keywordname>new</keywordname> (although it would probably be
- better to create an &array; of &array;s since memory allocation
- and deallocation would automatically be handled) so their domains
- must be specified. &array;'s <methodname>initialize</methodname>
- functions accept the same set of domain object specifications and
- model elements that the &array; constructors do, creating the
- specified domain. See <xref
- linkend="arrays-arrays_declarations-initialize_table"></xref>.
- For example, both <varname>a</varname> and <varname>b</varname>
- are two-dimensional &array;s of &float;s with a [2:7:1,-2:4:1]
- domains:
- <programlisting>
- // Create an Array and its domain.
- Array<2,float,Brick> a(Interval<1>(2,7), Interval<1>(-2,4));
- // Create an Array without a domain and then specify its domain.
- Array<2,float,Brick> b();
- b.initialize(Interval<1>(2,7), Interval<1>(-2,4));.
- </programlisting> Invoking <methodname>initialize</methodname> on an
- &array; with an existing domain is unspecified. All &array;
- values may be lost and memory may be leaked.</para>
</section>
--- 1538,1549 ----
DT2& t2, const DT3& t3, const DT4& t4, const DT5&
t5, const DT6& t6, const DT7& t7,
const ModelElement<T>& model)</statement></entry>
! <entry>creates the &array;'s domain using the given &domain; objects and integers and
then initializes all entries using <varname>model</varname>.</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
*************** std::cout &openopen; a(2,-2) &openopen;
*** 1571,1586 ****
std::cout &openopen; a.read(2,-2) &openopen; std::endl;
</programlisting> Using <methodname>read</methodname> sometimes
permits the optimizer to produce faster executing code.</para>
-
- <example id="arrays-arrays_use-copy_example">
- <title>Copying &array;s</title>
- &array-copy;
- </example>
! <para>Copying &array;s requires little execution time because they
! have reference semantics. That is, a copy of an &array; and the
! &array; itself share the same underlying data. Changing a value
! in one changes it in the other. <xref
linkend="arrays-arrays_use-copy_example"></xref> illustrates this
behavior. Initially, all values in the array <varname>a</varname>
are 4. The <varname>b</varname> array is initialized using
--- 1586,1598 ----
std::cout &openopen; a.read(2,-2) &openopen; std::endl;
</programlisting> Using <methodname>read</methodname> sometimes
permits the optimizer to produce faster executing code.</para>
! <para>Copying &array;s requires little execution time because
! &array;s have <glossterm
! linkend="glossary-reference_semantics"><firstterm>reference
! semantics</firstterm></glossterm>. That is, a copy of an &array;
! and the &array; itself share the same underlying data. Changing a
! value in one changes it in the other. <xref
linkend="arrays-arrays_use-copy_example"></xref> illustrates this
behavior. Initially, all values in the array <varname>a</varname>
are 4. The <varname>b</varname> array is initialized using
*************** std::cout &openopen; a.read(2,-2) &openo
*** 1589,1598 ****
changes the latter's value. Function arguments are also
initialized so changing their underlying values also changes the
calling function's values. For example, the
! <function>changeValue</function> function changes the value with
! index (0,0) of both its function argument
and <varname>a</varname>.</para>
<para>The separation between a higher-level &array; and its
lower-level &engine; storage permits fast copying. An &array;'s
only data member is its engine, which itself has reference
--- 1601,1615 ----
changes the latter's value. Function arguments are also
initialized so changing their underlying values also changes the
calling function's values. For example, the
! <function>changeValue</function> function changes the value at
! index (0,0) for both its function argument
and <varname>a</varname>.</para>
+ <example id="arrays-arrays_use-copy_example">
+ <title>Copying &array;s</title>
+ &array-copy;
+ </example>
+
<para>The separation between a higher-level &array; and its
lower-level &engine; storage permits fast copying. An &array;'s
only data member is its engine, which itself has reference
*************** std::cout &openopen; a.read(2,-2) &openo
*** 1608,1613 ****
--- 1625,1645 ----
<varname>a</varname>'s values do not change <varname>b</varname>'s
values or vice versa.</para>
+ <para>The &array; class has internal type definitions and
+ constants useful for both compile-time and run-time computations.
+ See <xref linkend="arrays-arrays_use-compile_time_table"></xref>.
+ These may be accessed using the &array;'s type and the scope
+ resolution operator (<operator>::</operator>). The table begins
+ with a list of internal type definitions, e.g.,
+ <statement>Array<&dim;,T,E>::This_t</statement>. A
+ <glossterm linkend="glossary-layout">layout</glossterm> maps a
+ domain index to a particular processor and memory used to compute
+ the associated value.<!-- FIXME: Add a reference to the
+ corresponding chapter. --> The two internal enumerations
+ <fieldsynopsis><varname>dimensions</varname></fieldsynopsis> and
+ <fieldsynopsis><varname>rank</varname></fieldsynopsis> both record
+ the &array;'s dimension.</para>
+
<table frame="none" colsep="0" rowsep="0" tocentry="1"
orient="port" pgwide="0" id="arrays-arrays_use-compile_time_table">
<title>&array; Internal Type Definitions and Compile-Time Constants</title>
*************** std::cout &openopen; a.read(2,-2) &openo
*** 1619,1625 ****
<entry>meaning</entry>
</row>
</thead>
! <tbody>
<row>
<entry><type>This_t</type></entry>
<entry>the &array;'s type <type>Array<&dim;,T,E></type>.</entry>
--- 1651,1657 ----
<entry>meaning</entry>
</row>
</thead>
! <tbody valign="top">
<row>
<entry><type>This_t</type></entry>
<entry>the &array;'s type <type>Array<&dim;,T,E></type>.</entry>
*************** std::cout &openopen; a.read(2,-2) &openo
*** 1650,1687 ****
<entry>the type of the &array;'s layout.</entry>
</row>
<row>
! <entry><fieldsynopsis>
! <modifier>const</modifier>
! <type>int</type>
! <varname>dimensions</varname></fieldsynopsis></entry>
<entry>the number &dim; of dimensions of the &array;.</entry>
</row>
<row>
! <entry><fieldsynopsis>
! <modifier>const</modifier>
! <type>int</type>
! <varname>rank</varname></fieldsynopsis></entry>
<entry>synonym for <varname>dimensions</varname>.</entry>
</row>
</tbody>
</tgroup>
</table>
! <para>The &array; class has internal type definitions and
! constants useful for both compile-time and run-time computations.
! See <xref linkend="arrays-arrays_use-compile_time_table"></xref>.
! These may be accessed using the &array;'s type and the scope
! resolution operator (<operator>::</operator>). The table begins
! with a list of internal type definitions, e.g.,
! <statement>Array<&dim;,T,E>::Domain_t</statement>. Member
! functions use some of these types. A <glossterm
! linkend="glossary-layout">layout</glossterm> maps a domain index
! to a particular processor and memory used to compute the
! associated value.<!-- FIXME: Add a reference to the corresponding
! chapter. --> The two internal enumerations
! <fieldsynopsis><varname>dimensions</varname></fieldsynopsis> and
! <fieldsynopsis><varname>rank</varname></fieldsynopsis> both record
! the &array;'s dimension.</para>
<table frame="none" colsep="0" rowsep="0" tocentry="1"
orient="port" pgwide="0" id="arrays-arrays_use-accessor_table">
--- 1682,1723 ----
<entry>the type of the &array;'s layout.</entry>
</row>
<row>
! <entry><statement>const int dimensions</statement></entry>
<entry>the number &dim; of dimensions of the &array;.</entry>
</row>
<row>
! <entry><statement>const int rank</statement></entry>
<entry>synonym for <varname>dimensions</varname>.</entry>
</row>
</tbody>
</tgroup>
</table>
! <para>The &array; class has several member functions easing access
! to its domain and engine. The first ten functions listed in <xref
! linkend="arrays-arrays_use-accessor_table"></xref> ease access to
! &array; domains. The first three functions are synonyms all
! returning the &array;'s domain, which has type
! <type>Array<&dim;,T,E>::Domain_t</type> (abbreviated
! <type>Domain_t</type> in the table). The next seven functions
! query the domain. <methodname>first</methodname>,
! <methodname>last</methodname>, and <methodname>length</methodname>
! return the first index, last index, and number of indices for the
! specified dimension. The domain's dimensions are numbered 0, 1,
! …,
! <statement>Array<&dim;,T,E>::dimensions</statement>-1. If
! these values are needed for all dimensions, use
! <methodname>firsts</methodname>, <methodname>lasts</methodname>,
! and <methodname>lengths</methodname>. The returned
! <type>Loc<&dim;></type>s have &dim; entries, one for each
! dimension. <methodname>size</methodname> returns the total number
! of indices in the entire domain. This is the product of all the
! dimensions' <methodname>length</methodname>s. The
! <methodname>layout</methodname> member function returns the
! &array;'s layout, which specifies the mapping of indices to
! processors and memory.<!-- FIXME: Add a reference to the
! corresponding chapter. --> The last two functions return the
! &array;'s engine.</para>
<table frame="none" colsep="0" rowsep="0" tocentry="1"
orient="port" pgwide="0" id="arrays-arrays_use-accessor_table">
*************** std::cout &openopen; a.read(2,-2) &openo
*** 1697,1707 ****
<tfoot>
<row>
<entry>Internal type definitions, e.g., <type>Domain_t</type>,
! are listed without a class type prefix
<statement>Array<&dim;,T,E>::</statement>.</entry>
</row>
</tfoot>
! <tbody>
<row>
<entry><statement>Domain_t domain()</statement></entry>
<entry>returns the &array;'s domain.</entry>
--- 1733,1743 ----
<tfoot>
<row>
<entry>Internal type definitions, e.g., <type>Domain_t</type>,
! are listed here without the class type prefix
<statement>Array<&dim;,T,E>::</statement>.</entry>
</row>
</tfoot>
! <tbody valign="top">
<row>
<entry><statement>Domain_t domain()</statement></entry>
<entry>returns the &array;'s domain.</entry>
*************** std::cout &openopen; a.read(2,-2) &openo
*** 1716,1728 ****
</row>
<row>
<entry><statement>int first(int dim)</statement></entry>
! <entry>returns the first (smallest) index value for the
! specified dimension.</entry>
</row>
<row>
<entry><statement>int last(int dim)</statement></entry>
! <entry>returns the last (largest) index value for the
! specified dimension.</entry>
</row>
<row>
<entry><statement>int length(int dim)</statement></entry>
--- 1752,1764 ----
</row>
<row>
<entry><statement>int first(int dim)</statement></entry>
! <entry>returns the first index value for the specified
! dimension.</entry>
</row>
<row>
<entry><statement>int last(int dim)</statement></entry>
! <entry>returns the last index value for the specified
! dimension.</entry>
</row>
<row>
<entry><statement>int length(int dim)</statement></entry>
*************** std::cout &openopen; a.read(2,-2) &openo
*** 1731,1743 ****
</row>
<row>
<entry><statement>Loc<Dim> firsts()</statement></entry>
! <entry>returns the first (smallest) index values for all the
dimensions.</entry>
</row>
<row>
<entry><statement>Loc<Dim> lasts()</statement></entry>
! <entry>returns the last (largest) index values for all the
! specified dimensions.</entry>
</row>
<row>
<entry><statement>Loc<Dim> lengths()</statement></entry>
--- 1767,1779 ----
</row>
<row>
<entry><statement>Loc<Dim> firsts()</statement></entry>
! <entry>returns the first index values for all the
dimensions.</entry>
</row>
<row>
<entry><statement>Loc<Dim> lasts()</statement></entry>
! <entry>returns the last index values for all the specified
! dimensions.</entry>
</row>
<row>
<entry><statement>Loc<Dim> lengths()</statement></entry>
*************** std::cout &openopen; a.read(2,-2) &openo
*** 1750,1756 ****
</row>
<row>
<entry><statement>Layout_t layout()</statement></entry>
! <entry>returns the &array;'s domain.</entry>
</row>
<row>
<entry><statement>Engine_t engine()</statement></entry>
--- 1786,1792 ----
</row>
<row>
<entry><statement>Layout_t layout()</statement></entry>
! <entry>returns the &array;'s layout.</entry>
</row>
<row>
<entry><statement>Engine_t engine()</statement></entry>
*************** std::cout &openopen; a.read(2,-2) &openo
*** 1764,1806 ****
</tgroup>
</table>
! <para>The &array; class has several member functions easing access
! to its domain and engine. The first ten functions listed in <xref
! linkend="arrays-arrays_use-accessor_table"></xref> ease access to
! &array; domains. The first three functions are synonyms all
! returning the &array;'s domain, which has type
! <type>Array<&dim;,T,E>::Domain_t</type>, abbreviated
! <type>Domain_t</type> in the table. The next seven functions
! query the domain. <methodname>first</methodname>,
! <methodname>last</methodname>, and <methodname>length</methodname>
! return the smallest, largest, and number of indices for the
! specified dimension. The domain's dimensions are numbered 0, 1,
! …,
! <statement>Array<&dim;,T,E>::dimensions</statement>-1. If
! these values are needed for all dimensions, use
! <methodname>firsts</methodname>, <methodname>lasts</methodname>,
! and <methodname>lengths</methodname>. The returned
! <type>Loc<&dim;></type>s have &dim; entries, one for each
! dimension. <methodname>size</methodname> returns the total number
! of indices in the entire domain. This is the product of all the
! dimensions' <methodname>length</methodname>s. The
! <methodname>layout</methodname> member function returns the
! &array;'s layout, which specifies the mapping of indices to
! processors and memory.<!-- FIXME: Add a reference to the
! corresponding chapter. --> The last two functions return the
! &array;'s engine.</para>
<example id="arrays-arrays_use-members_example">
<title>Using &array; Member Functions</title>
&array-size;
<calloutlist>
- <callout arearefs="arrays-arrays_use-members-example-compare_size">
- <para>The <methodname>size</methodname> is invoked by
- prepending the &array;'s name followed by a period. This
- assertion is unnecessary, but the
- <function>computeArraySize</function> function further
- illustrates using member functions.</para>
- </callout>
<callout arearefs="arrays-arrays_use-members-example-template_parameters">
<para>These template parameters, used in the &array;
parameter's type, permit the function to work with any
--- 1800,1830 ----
</tgroup>
</table>
! <para>We illustrate using &array; member functions in <xref
! linkend="arrays-arrays_use-members_example"></xref>. The program
! computes the total number of &array;'s indices, comparing the
! result with invoking its <methodname>size</methodname> method.
! Since the &array;'s name is <varname>a</varname>,
! <statement>a.size()</statement> returns its size. The
! <function>computeArraySize</function> function also computes the
! &array;'s size. This templated function uses its three template
! parameters to accept any &array;, regardless of its dimension,
! value type, or &engine; tag. It begins by obtaining the range of
! indices for all dimensions and their lengths. Only the latter is
! necessary for the computation, but using the former further
! illustrates using member functions. The domain's size is the
! product of the length of each dimension. Since the lengths are
! stored in the <type>Loc<&dim></type>
! <varname>lens</varname>, <statement>lens[d]</statement> is a
! <type>Loc<1></type>, for which its
! <methodname>first</methodname> member function extracts the
! length. The <methodname>length</methodname> &array; member
! function is used in the <function>PAssert</function>.</para>
<example id="arrays-arrays_use-members_example">
<title>Using &array; Member Functions</title>
&array-size;
<calloutlist>
<callout arearefs="arrays-arrays_use-members-example-template_parameters">
<para>These template parameters, used in the &array;
parameter's type, permit the function to work with any
*************** std::cout &openopen; a.read(2,-2) &openo
*** 1815,1849 ****
<para><statement>lens[d]</statement> returns a
<type>Loc<1></type> for
dimension <varname>d</varname>'s length. Invoking
! <type>Loc<1></type> <methodname>first</methodname>method
yields its value.</para>
</callout>
<callout arearefs="arrays-arrays_use-members-example-check_length">
<para>This comparison is unnecessary but further illustrates
using member functions.</para>
</callout>
</calloutlist>
</example>
-
- <para>We illustrate using &array; member functions in <xref
- linkend="arrays-arrays_use-members_example"></xref>. The program
- computes the total number of &array;'s indices, comparing the
- result with invoking its <methodname>size</methodname> method.
- Since the &array;'s name is <varname>a</varname>,
- <statement>a.size()</statement> returns its size.
- <function>computeArraySize</function> also computes the &array;'s
- size. This templated function uses its three template parameters
- to accept any &array;, regardless of its dimension, value type, or
- &engine; tag. It begins by obtaining the range of indices for all
- dimensions and their lengths. Only the latter is necessary for
- the computation, but the former further illustrate using member
- functions. The domain's size is the product of the length of each
- dimension. Since the lengths are stored in the
- <type>Loc<&dim></type> <varname>lens</varname>,
- <statement>lens[d]</statement> is a <type>Loc<1></type>, for
- which its <methodname>first</methodname> extracts the length. The
- <methodname>length</methodname> &array; member function is used in
- the <function>PAssert</function>.</para>
</section>
--- 1839,1860 ----
<para><statement>lens[d]</statement> returns a
<type>Loc<1></type> for
dimension <varname>d</varname>'s length. Invoking
! <type>Loc<1></type> <methodname>first</methodname> method
yields its value.</para>
</callout>
<callout arearefs="arrays-arrays_use-members-example-check_length">
<para>This comparison is unnecessary but further illustrates
using member functions.</para>
</callout>
+ <callout arearefs="arrays-arrays_use-members-example-compare_size">
+ <para>The <methodname>size</methodname> is invoked by
+ prepending the &array;'s name followed by a period. This
+ assertion is unnecessary, but the
+ <function>computeArraySize</function> function further
+ illustrates using member functions.</para>
+ </callout>
</calloutlist>
</example>
</section>
*************** std::cout &openopen; a.read(2,-2) &openo
*** 1851,1942 ****
<title>&dynamicarray;s</title>
<para>&array;s have fixed domains so the set of valid indices
! remains fixed after declaration. The &dynamicarray; class
! supports one-dimensional domains that can be resized even while
! the array is used.</para>
<para>&dynamicarray;'s interface extends the one-dimensional
interface of an &array; by adding member functions to change the
domain's size. It is declared in <filename
class="libraryfile">Pooma/DynamicArrays.h</filename>. A
&dynamicarray; has two, not three, template parameters, omitting
! the array's dimensionality. The first
parameter <type>T</type> specifies the type of stored values.
! Its default value is usually &double;, but it may be changed when
! the &poomatoolkit; is configured. The second parameter specifies
! an &engine; via a tag. The engine must support a domain with
! dynamic resizing. For example, the &dynamic; &engine; is
! analogous to a one-dimensional &brick; &engine; supporting a
! dynamically-resizable domain. It is also usually the default
! value for this tag. For example, <statement>DynamicArray<>
! d0(1);</statement>, <statement>DynamicArray<double>
! d1(1);</statement>, and <statement>DynamicArray<double,
! Dynamic> d2(1);</statement> all declare the same
! &dynamicarray;s explicitly storing one &double; value. A
! &dynamicarray; automatically allocates its initial memory and
! deallocates its final memory, just as an &array; does.</para>
- <table frame="none" colsep="0" rowsep="0" tocentry="1"
- orient="port" pgwide="0" id="arrays-dynamic_arrays-change_size">
- <title>Changing a &dynamicarray;'s Domain</title>
-
- <tgroup cols="2" align="left">
- <thead>
- <row>
- <entry>&dynamicarray; member function</entry>
- <entry>description</entry>
- </row>
- </thead>
- <tfoot>
- <row>
- <entry>This table omits member functions designed for
- distributed computation.</entry>
- </row>
- </tfoot>
- <tbody>
- <row>
- <entry><statement>void create(int num)</statement></entry>
- <entry>extend the current domain by the requested number of
- elements.</entry>
- </row>
- <row>
- <entry><statement>void destroy(const Dom& killList)</statement></entry>
- <entry>remove the elements specified by the indices in the
- given &domain; argument. <quote>Backfill</quote> moves
- elements from the end of the domain to replace the deleted
- elements.</entry>
- </row>
- <row>
- <entry><statement>void destroy(Iter killBegin, Iter killEnd)</statement></entry>
- <entry>remove the elements specified by the indices in the
- container range [begin,end) specified by the random-access
- iterators. <quote>Backfill</quote> moves elements from the
- end of the domain to replace the deleted elements.</entry>
- </row>
- <row>
- <entry><statement>void destroy(const Dom& killList, const
- DeleteMethod& method)</statement></entry>
-
- <entry>remove the elements specified by the indices in the
- given &domain; argument. Deleted elements can be replaced by
- <type>BackFill</type>'ing, i.e., moving data from the domain's
- end to fill removed elements, or by <type>ShiftUp</type>'ing,
- i.e., compacting all data but maintaining relative ordering.</entry>
- </row>
- <row>
- <entry><statement>void destroy(Iter killBegin, Iter killEnd,
- const DeleteMethod& method)</statement></entry>
- <entry>remove the elements specified by the indices in the
- container range [begin,end) specified by the random-access
- iterators. Deleted elements can be replaced by
- <type>BackFill</type>'ing, i.e., moving data from the domain's
- end to fill removed elements, or by <type>ShiftUp</type>'ing,
- i.e., compacting all data but maintaining relative ordering.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
<para>The <methodname>create</methodname> and
<methodname>destroy</methodname> member functions permit changing
a &dynamicarray;'s domain. <xref
--- 1862,1895 ----
<title>&dynamicarray;s</title>
<para>&array;s have fixed domains so the set of valid indices
! remains fixed after creation. The <glossterm
! linkend="glossary-dynamicarray">&dynamicarray;
! class</glossterm><!-- FIXME: Add firstterm here. --> supports
! one-dimensional domains that can be resized even while the array
! is used.</para>
<para>&dynamicarray;'s interface extends the one-dimensional
interface of an &array; by adding member functions to change the
domain's size. It is declared in <filename
class="libraryfile">Pooma/DynamicArrays.h</filename>. A
&dynamicarray; has two, not three, template parameters, omitting
! the array's dimensionality which must be one. The first
parameter <type>T</type> specifies the type of stored values.
! Its default value is usually &double;, but this may be changed
! when the &poomatoolkit; is configured. The second parameter
! specifies an &engine; via an &engine; tag. The engine must
! support a domain with dynamic resizing. For example, the
! &dynamic; &engine; is analogous to a one-dimensional &brick;
! &engine; supporting a dynamically-resizable domain. It is also
! usually the default value for this tag. For example,
! <statement>DynamicArray<> d0(1);</statement>,
! <statement>DynamicArray<double> d1(1);</statement>, and
! <statement>DynamicArray<double, Dynamic> d2(1);</statement>
! all declare the same &dynamicarray;s explicitly storing one
! &double; value. A &dynamicarray; automatically allocates its
! initial memory and deallocates its final memory, just as an
! &array; does.</para>
<para>The <methodname>create</methodname> and
<methodname>destroy</methodname> member functions permit changing
a &dynamicarray;'s domain. <xref
*************** std::cout &openopen; a.read(2,-2) &openo
*** 1948,1954 ****
for <type>T</type>. Existing values are copied.</para>
<table frame="none" colsep="0" rowsep="0" tocentry="1"
! orient="port" pgwide="0" id="arrays-dynamic_arrays-table">
<title>Changing a &dynamicarray;'s Domain</title>
<tgroup cols="2" align="left">
--- 1901,1907 ----
for <type>T</type>. Existing values are copied.</para>
<table frame="none" colsep="0" rowsep="0" tocentry="1"
! orient="port" pgwide="0" id="arrays-dynamic_arrays-change_size">
<title>Changing a &dynamicarray;'s Domain</title>
<tgroup cols="2" align="left">
*************** std::cout &openopen; a.read(2,-2) &openo
*** 1964,1970 ****
distributed computation.</entry>
</row>
</tfoot>
! <tbody>
<row>
<entry><statement>void create(int num)</statement></entry>
<entry>extend the current domain by the requested number of
--- 1917,1923 ----
distributed computation.</entry>
</row>
</tfoot>
! <tbody valign="top">
<row>
<entry><statement>void create(int num)</statement></entry>
<entry>extend the current domain by the requested number of
*************** std::cout &openopen; a.read(2,-2) &openo
*** 1972,2019 ****
</row>
<row>
<entry><statement>void destroy(const Dom& killList)</statement></entry>
! <entry>remove the elements specified by the indices in the
! given &domain; argument. <quote>Backfill</quote> moves
! elements from the end of the domain to replace the deleted
! elements.</entry>
</row>
<row>
<entry><statement>void destroy(Iter killBegin, Iter killEnd)</statement></entry>
! <entry>remove the elements specified by the indices in the
container range [begin,end) specified by the random-access
! iterators. <quote>Backfill</quote> moves elements from the
! end of the domain to replace the deleted elements.</entry>
</row>
<row>
<entry><statement>void destroy(const Dom& killList, const
DeleteMethod& method)</statement></entry>
! <entry>remove the elements specified by the indices in the
! given &domain; argument. Deleted elements can be replaced by
<type>BackFill</type>'ing, i.e., moving data from the domain's
! end to fill removed elements, or by <type>ShiftUp</type>'ing,
! i.e., compacting all data but maintaining relative ordering.</entry>
</row>
<row>
<entry><statement>void destroy(Iter killBegin, Iter killEnd,
const DeleteMethod& method)</statement></entry>
! <entry>remove the elements specified by the indices in the
container range [begin,end) specified by the random-access
! iterators. Deleted elements can be replaced by
<type>BackFill</type>'ing, i.e., moving data from the domain's
! end to fill removed elements, or by <type>ShiftUp</type>'ing,
! i.e., compacting all data but maintaining relative ordering.</entry>
</row>
</tbody>
</tgroup>
</table>
! <para>The <methodname>destroy</methodname> deletes specified
! indices. The indices may be specified using either a &domain;
! object (<type>Interval<1></type>,
<type>Range<1></type>, or <type>IndirectionList</type>) or
! in a container specified using random-access iterators. For
! example, every other element from a ten-element
array <varname>d</varname> might be removed using
<statement>Range<1>(0,9,2)</statement>. Alternatively,
<programlisting>
--- 1925,1975 ----
</row>
<row>
<entry><statement>void destroy(const Dom& killList)</statement></entry>
! <entry>remove the values specified by the indices in the given
! &domain; argument. The <quote>Backfill</quote> method moves
! values from the end of the domain to replace the deleted
! values.</entry>
</row>
<row>
<entry><statement>void destroy(Iter killBegin, Iter killEnd)</statement></entry>
! <entry>remove the values specified by the indices in the
container range [begin,end) specified by the random-access
! iterators. The <quote>Backfill</quote> method moves values
! from the end of the domain to replace the deleted
! values.</entry>
</row>
<row>
<entry><statement>void destroy(const Dom& killList, const
DeleteMethod& method)</statement></entry>
! <entry>remove the values specified by the indices in the
! given &domain; argument. Deleted values can be replaced by
<type>BackFill</type>'ing, i.e., moving data from the domain's
! end to fill removed values, or by <type>ShiftUp</type>'ing,
! i.e., compacting all data but maintaining the relative
! ordering.</entry>
</row>
<row>
<entry><statement>void destroy(Iter killBegin, Iter killEnd,
const DeleteMethod& method)</statement></entry>
! <entry>remove the values specified by the indices in the
container range [begin,end) specified by the random-access
! iterators. Deleted values can be replaced by
<type>BackFill</type>'ing, i.e., moving data from the domain's
! end to fill removed values, or by <type>ShiftUp</type>'ing,
! i.e., compacting all data but maintaining the relative
! ordering.</entry>
</row>
</tbody>
</tgroup>
</table>
! <para>The <methodname>destroy</methodname> member function deletes
! the specified indices. The indices may be specified using either
! a &domain; object (<type>Interval<1></type>,
<type>Range<1></type>, or <type>IndirectionList</type>) or
! by random-access iterators pointing into a container. For
! example, every other value from a ten-value
array <varname>d</varname> might be removed using
<statement>Range<1>(0,9,2)</statement>. Alternatively,
<programlisting>
*************** d.destroy(killList, killList+5);
*** 2023,2048 ****
removed, other indices are moved into their positions. Using the
<type>BackFill</type> method moves the last index and its
associated value into deleted index's position. Thus, the total
! number of indices is decreased by one, but the indices can be
reordered. Using the <type>ShiftUp</type> method ensures the
! indices' orders are maintained by <quote>shifting</quote> all
! elements left (or up) so all <quote>gaps</quote> between indices
disappear. For example, consider removing the first index from a
domain.
<informaltable frame="none" colsep="0" rowsep="0" tocentry="1"
orient="port" pgwide="0" id="arrays-dynamic_arrays-destroy_example">
<tgroup cols="2" align="left">
! <tbody>
<row>
<entry>original indices:</entry>
<entry>0 1 2 3</entry>
</row>
<row>
! <entry><methodname>destroy</methodname> using <type>BackFill</type></entry>
<entry>3 1 2</entry>
</row>
<row>
! <entry><methodname>destroy</methodname> using <type>ShiftUp</type></entry>
<entry>1 2 3</entry>
</row>
</tbody>
--- 1979,2004 ----
removed, other indices are moved into their positions. Using the
<type>BackFill</type> method moves the last index and its
associated value into deleted index's position. Thus, the total
! number of indices is decreased by one, but the indices are
reordered. Using the <type>ShiftUp</type> method ensures the
! order of the indices is preserved by <quote>shifting</quote> all
! values left (or up) so all <quote>gaps</quote> between indices
disappear. For example, consider removing the first index from a
domain.
<informaltable frame="none" colsep="0" rowsep="0" tocentry="1"
orient="port" pgwide="0" id="arrays-dynamic_arrays-destroy_example">
<tgroup cols="2" align="left">
! <tbody valign="top">
<row>
<entry>original indices:</entry>
<entry>0 1 2 3</entry>
</row>
<row>
! <entry><methodname>destroy</methodname> using <type>BackFill</type>:</entry>
<entry>3 1 2</entry>
</row>
<row>
! <entry><methodname>destroy</methodname> using <type>ShiftUp</type>:</entry>
<entry>1 2 3</entry>
</row>
</tbody>
*************** d.destroy(killList, killList+5);
*** 2054,2101 ****
that <type>BackFill</type> moves exactly as many indices as are
deleted, while <type>ShiftUp</type> can shift all indices in a
domain. Thus, <type>BackFill</type> is the default method. When
! multiple indices are deleted, they are deleted from the largest to
! the smallest. When using the <type>BackFill</type> method, some
! indices may be moved repeatedly. For example, consider removing
! indices 0 and 2 from original indices of 0 1 2 3. Removing 2
! yields 0 1 3. Removing 0 yields 3 1. Using an object with the
! desired type to indicate which fill method is desired, i.e.,
! <statement>BackFill()</statement> or
<statement>ShiftUp()</statement>.</para>
- <example id="arrays-dynamic_arrays-example">
- <title>Example Using &dynamicarray;s</title>
-
- &dynamicarray-example;
- <calloutlist>
- <callout arearefs="arrays-dynamic_arrays-example-header">
- <para>This header file declares &dynamicarray;s.</para>
- </callout>
- <callout arearefs="arrays-dynamic_arrays-example-identical_declarations">
- <para>These three declarations yield equivalent
- &dynamicarray;s, storing one &double; value.</para>
- </callout>
- <callout arearefs="arrays-dynamic_arrays-example-extension">
- <para>This <methodname>create</methodname> member function adds
- five indices to the end of the domain.</para>
- </callout>
- <callout arearefs="arrays-dynamic_arrays-example-access">
- <para>&dynamicarray; values are accessed the same way as
- &array; values.</para>
- </callout>
- <callout arearefs="arrays-dynamic_arrays-example-destroy_range">
- <para>The ⦥ object specifies that every other index
- should be removed. The <statement>BackFill()</statement>
- object is unnecessary since it is the default replacement
- method.</para>
- </callout>
- <callout arearefs="arrays-dynamic_arrays-example-destroy_iterators">
- <para>This <methodname>destroy</methodname> call is equivalent
- to the previous one but uses iterators.</para>
- </callout>
- </calloutlist>
- </example>
-
<para>We illustrate &dynamicarray; resizing in <xref
linkend="arrays-dynamic_arrays-example"></xref>. &dynamicarray;s
are declared in <filename
--- 2010,2025 ----
that <type>BackFill</type> moves exactly as many indices as are
deleted, while <type>ShiftUp</type> can shift all indices in a
domain. Thus, <type>BackFill</type> is the default method. When
! multiple indices are deleted, they are deleted from the last
! (largest) to the first (smallest). When using the
! <type>BackFill</type> method, some indices may be moved
! repeatedly. For example, consider removing indices 0 and 2 from
! original indices of 0 1 2 3. Removing 2 yields 0 1 3 because 3 is
! moved into 2's position. Removing 0 yields 3 1 because 3 is again
! moved. Use an object with the desired type to indicate which fill
! method is desired, i.e., <statement>BackFill()</statement> or
<statement>ShiftUp()</statement>.</para>
<para>We illustrate &dynamicarray; resizing in <xref
linkend="arrays-dynamic_arrays-example"></xref>. &dynamicarray;s
are declared in <filename
*************** d.destroy(killList, killList+5);
*** 2104,2110 ****
require two, not three, template arguments because the array must
be one-dimensional. The three arrays, each having one &double;
value, are equivalent. (The &poomatoolkit; can be configured to
! support different default values.) Invoking
<varname>d0</varname>'s <methodname>create</methodname> with an
argument of five increases its domain size from one to six. The
additional indices are added to the end of the domain so the value
--- 2028,2034 ----
require two, not three, template arguments because the array must
be one-dimensional. The three arrays, each having one &double;
value, are equivalent. (The &poomatoolkit; can be configured to
! support different default template values.) Invoking
<varname>d0</varname>'s <methodname>create</methodname> with an
argument of five increases its domain size from one to six. The
additional indices are added to the end of the domain so the value
*************** d.destroy(killList, killList+5);
*** 2113,2143 ****
all values equal to their indices. This illustrates that
&dynamicarray; values are accessed the same way as &array; values.
For example, <statement>d0(i)</statement> accesses the
! <varname>i</varname>th value. The
! <methodname>destroy</methodname> removes every other index from
! the array. The one-dimensional ⦥ specifies these indices by
! specifying the domain's entire interval and a stride of 2.
The <statement>BackFill</statement> function call creates a
<type>BackFill</type> object indicating the <type>BackFill</type>
method should be used. We illustrate the steps of this method:
<informaltable frame="none" colsep="0" rowsep="0" tocentry="1"
orient="port" pgwide="0" id="arrays-dynamic_arrays-program_example">
<tgroup cols="2" align="left">
! <tbody>
<row>
<entry>original indices:</entry>
<entry>0 1 2 3 4 5</entry>
</row>
<row>
! <entry>delete index 4</entry>
<entry>0 1 2 3 5</entry>
</row>
<row>
! <entry>delete index 2</entry>
<entry>0 1 5 3</entry>
</row>
<row>
! <entry>delete index 0</entry>
<entry>3 1 5</entry>
</row>
</tbody>
--- 2037,2067 ----
all values equal to their indices. This illustrates that
&dynamicarray; values are accessed the same way as &array; values.
For example, <statement>d0(i)</statement> accesses the
! <varname>i</varname><superscript>th</superscript> value. The
! <methodname>destroy</methodname> member function removes every
! other index from the array because the one-dimensional ⦥
! specifies the domain's entire interval with a stride of 2.
The <statement>BackFill</statement> function call creates a
<type>BackFill</type> object indicating the <type>BackFill</type>
method should be used. We illustrate the steps of this method:
<informaltable frame="none" colsep="0" rowsep="0" tocentry="1"
orient="port" pgwide="0" id="arrays-dynamic_arrays-program_example">
<tgroup cols="2" align="left">
! <tbody valign="top">
<row>
<entry>original indices:</entry>
<entry>0 1 2 3 4 5</entry>
</row>
<row>
! <entry>delete index 4:</entry>
<entry>0 1 2 3 5</entry>
</row>
<row>
! <entry>delete index 2:</entry>
<entry>0 1 5 3</entry>
</row>
<row>
! <entry>delete index 0:</entry>
<entry>3 1 5</entry>
</row>
</tbody>
*************** d.destroy(killList, killList+5);
*** 2146,2152 ****
Since multiple indices are specified, the rightmost one is removed
first, i.e., index 4. The rightmost index 5 is moved
into 4's position. When removing index 2, the index
! originally at 5 is moved again into 2's position. Finally,
index 0 is replaced by index 3. The rest of the program
repeats the computation, using the random-access iterator version
of <methodname>destroy</methodname>. Since this &dynamicarray;'s
--- 2070,2076 ----
Since multiple indices are specified, the rightmost one is removed
first, i.e., index 4. The rightmost index 5 is moved
into 4's position. When removing index 2, the index
! originally at 5 is again moved into 2's position. Finally,
index 0 is replaced by index 3. The rest of the program
repeats the computation, using the random-access iterator version
of <methodname>destroy</methodname>. Since this &dynamicarray;'s
*************** d.destroy(killList, killList+5);
*** 2158,2166 ****
--- 2082,2125 ----
method is specified, the default <type>BackFill</type> method is
used. All the &dynamicarray;s' unallocated memory is
deallocated.</para>
+
+ <example id="arrays-dynamic_arrays-example">
+ <title>Example Using &dynamicarray;s</title>
+
+ &dynamicarray-example;
+ <calloutlist>
+ <callout arearefs="arrays-dynamic_arrays-example-header">
+ <para>This header file declares &dynamicarray;s.</para>
+ </callout>
+ <callout arearefs="arrays-dynamic_arrays-example-identical_declarations">
+ <para>These three declarations yield equivalent
+ &dynamicarray;s, storing one &double; value.</para>
+ </callout>
+ <callout arearefs="arrays-dynamic_arrays-example-extension">
+ <para>This <methodname>create</methodname> member function call
+ adds five indices to the end of the domain.</para>
+ </callout>
+ <callout arearefs="arrays-dynamic_arrays-example-access">
+ <para>&dynamicarray; values are accessed the same way as
+ &array; values.</para>
+ </callout>
+ <callout arearefs="arrays-dynamic_arrays-example-destroy_range">
+ <para>The ⦥ object specifies that every other index
+ should be removed. The <statement>BackFill()</statement>
+ object is unnecessary since it is the default replacement
+ method.</para>
+ </callout>
+ <callout arearefs="arrays-dynamic_arrays-example-destroy_iterators">
+ <para>This <methodname>destroy</methodname> call is equivalent
+ to the previous one but uses iterators.</para>
+ </callout>
+ </calloutlist>
+ </example>
+
</section>
+ <![%unfinished;[
<section id="arrays-doof2d">
<title>An &array; Implementation of &doof2d;</title>
*************** d.destroy(killList, killList+5);
*** 2177,2181 ****
--- 2136,2141 ----
to describe how a programmer would implement a new type of domain?
Probably not.</para>
</section>
+ ]]> <!-- end unfinished -->
</chapter>
Index: bibliography.xml
===================================================================
RCS file: /home/pooma/Repository/r2/docs/manual/bibliography.xml,v
retrieving revision 1.1
diff -c -p -r1.1 bibliography.xml
*** bibliography.xml 2002/01/04 17:42:43 1.1
--- bibliography.xml 2002/01/25 02:15:03
***************
*** 1,5 ****
--- 1,7 ----
<!-- Bibliography -->
+ <![%unfinished;[
+
<bibliography id="bibliography">
<title>Bibliography</title>
*************** Array. 1995. unpublished. Available a
*** 275,277 ****
--- 277,281 ----
</bibliography>
+
+ ]]> <!-- end unfinished -->
Index: concepts.xml
===================================================================
RCS file: /home/pooma/Repository/r2/docs/manual/concepts.xml,v
retrieving revision 1.8
diff -c -p -r1.8 concepts.xml
*** concepts.xml 2002/01/24 05:11:21 1.8
--- concepts.xml 2002/01/25 02:15:04
***************
*** 57,63 ****
<entry>Computation Environment</entry>
</row>
</thead>
! <tbody>
<row>
<entry>&array;</entry>
<entry>element-wise</entry>
--- 57,63 ----
<entry>Computation Environment</entry>
</row>
</thead>
! <tbody valign="top">
<row>
<entry>&array;</entry>
<entry>element-wise</entry>
***************
*** 136,142 ****
orient="port" pgwide="0" id="concepts-containers-table">
<title>&pooma; Container Summary</title>
<tgroup cols="2" align="left">
! <tbody>
<row>
<entry><glossterm
linkend="glossary-array">&array;</glossterm></entry>
--- 136,142 ----
orient="port" pgwide="0" id="concepts-containers-table">
<title>&pooma; Container Summary</title>
<tgroup cols="2" align="left">
! <tbody valign="top">
<row>
<entry><glossterm
linkend="glossary-array">&array;</glossterm></entry>
***************
*** 265,271 ****
orient="port" pgwide="0" id="concepts-containers-choice_table">
<title>Choosing a &pooma; Container</title>
<tgroup cols="2" align="left">
! <tbody>
<row>
<entry>If modeling mathematical entries,</entry>
<entry>use a &vector;, &matrix;, or &tensor;.</entry>
--- 265,271 ----
orient="port" pgwide="0" id="concepts-containers-choice_table">
<title>Choosing a &pooma; Container</title>
<tgroup cols="2" align="left">
! <tbody valign="top">
<row>
<entry>If modeling mathematical entries,</entry>
<entry>use a &vector;, &matrix;, or &tensor;.</entry>
Index: data-parallel.xml
===================================================================
RCS file: /home/pooma/Repository/r2/docs/manual/data-parallel.xml,v
retrieving revision 1.2
diff -c -p -r1.2 data-parallel.xml
*** data-parallel.xml 2002/01/24 05:11:21 1.2
--- data-parallel.xml 2002/01/25 02:15:05
***************
*** 1,16 ****
<chapter id="data_parallel">
<title>Data-Parallel Expressions</title>
! <para>In the previous sections, we accessed container values one at
a time. Accessing more than one value in a container required a
writing an explicit loop. Scientists and engineers commonly
operate on sets of values, treated as an aggregate. For example, a
vector is a one-dimension collection of data and two vectors can be
added together. A matrix is a two-dimensional collection of data,
! and a scalar and a matrix are multiplied. A <glossterm
linkend="glossary-data_parallel"><firstterm>data-parallel
expression</firstterm></glossterm> simultaneously uses multiple
! container values. &pooma; supports data-parallel syntax.</para>
<para>After introducing data-parallel expressions and statements,
we present the corresponding &pooma; syntax. Then we present its
--- 1,17 ----
<chapter id="data_parallel">
<title>Data-Parallel Expressions</title>
! <para>In the previous chapters, we accessed container values one at
a time. Accessing more than one value in a container required a
writing an explicit loop. Scientists and engineers commonly
operate on sets of values, treated as an aggregate. For example, a
vector is a one-dimension collection of data and two vectors can be
added together. A matrix is a two-dimensional collection of data,
! and a scalar and a matrix can be multiplied. A <glossterm
linkend="glossary-data_parallel"><firstterm>data-parallel
expression</firstterm></glossterm> simultaneously uses multiple
! container values. &pooma; supports data-parallel
! expressions.</para>
<para>After introducing data-parallel expressions and statements,
we present the corresponding &pooma; syntax. Then we present its
***************
*** 61,73 ****
<para>&pooma; containers can be used in data-parallel expressions
and statements. The basic guidelines are simple:
<itemizedlist>
! <listitem>
! <para>The &cc; built-in and mathematical operators operate on
an entire container by operating element-wise on its values.</para>
! </listitem>
<listitem>
<para>Binary operators operate only on containers with the same
! domain types by combining values with the same indices. If the
result is a container, it has a domain equal to the left operand's
domain.</para>
</listitem>
--- 62,74 ----
<para>&pooma; containers can be used in data-parallel expressions
and statements. The basic guidelines are simple:
<itemizedlist>
! <listitem>
! <para>The &cc; built-in and mathematical operators operate on
an entire container by operating element-wise on its values.</para>
! </listitem>
<listitem>
<para>Binary operators operate only on containers with the same
! domain types and by combining values with the same indices. If the
result is a container, it has a domain equal to the left operand's
domain.</para>
</listitem>
***************
*** 79,86 ****
</itemizedlist>
</para>
! <para>The operators operate element-wise on containers' values.
! For example, if <varname>A</varname> is a one-dimensional array,
<statement>-<varname>A</varname></statement> is a one-dimensional
array with the same size such that the value at the
i<superscript>th</superscript> position equals -A(i). If
--- 80,88 ----
</itemizedlist>
</para>
! <para>The data-parallel operators operate element-wise on
! containers' values. For example, if <varname>A</varname> is a
! one-dimensional array,
<statement>-<varname>A</varname></statement> is a one-dimensional
array with the same size such that the value at the
i<superscript>th</superscript> position equals -A(i). If
***************
*** 91,114 ****
corresponding values in <varname>A</varname> and
<varname>B</varname>.</para>
- <figure float="1" id="data_parallel-use-addition_example">
- <title>Adding &array;s with Different Domains</title>
- <mediaobject>
- <imageobject>
- <imagedata fileref="figures/data-parallel.212" format="EPS" align="center"></imagedata>
- </imageobject>
- <textobject>
- <phrase>Adding two arrays with different domains adds values
- with the same indices.</phrase>
- </textobject>
- <caption>
- <para>Adding &array;s with different domains is supported.
- Solid lines indicate the domains' extent. Values with the same
- indices are added.</para>
- </caption>
- </mediaobject>
- </figure>
-
<para>Binary operators operate on containers with the same domain
types. The domain's indices need not be the same, but the result
will have a domain equal to the left operand. For example, the
--- 93,98 ----
*************** Interval<1> H(0,2), I(1,3), J(2,4);
*** 131,155 ****
Array<2, double, Brick> A(I,I), B(J,H);
// ... fill A and B with values ...
... = A + B;
! </programlisting>Both <varname>A</varname> and
! <varname>B</varname> have domains of two-dimensional intervals so
! they may be added, but their domains' extent differ, as indicated
! by the solid lines in the figure. The sum has domain equal to the
! left operand's domain. Values with the same indices are added. For
! example, <statement>A(2,2)</statement> and
! <statement>B(2,2)</statement> are added. <varname>B</varname>'s
! domain does not include index (1,1) so, when adding
! <statement>A(1,1)</statement> and <statement>B(1,1)</statement>,
! the default value for <varname>B</varname>'s value type is used.
! Usually this is 0. Thus, <statement>A(1,1) +
! B(1,1)</statement> equals <statement>9 + 0</statement>.</para>
!
! <para>Operations with &array;s and scalar values are supported.
! Conceptually, a scalar value can be thought of as an &array; with
! any desired domain and having the same value everywhere. For
! example, consider
<programlisting>
! Array<1, double, Brick> D(Interval<1>(7,10));
D += 2*D + 7;
</programlisting><statement>2*D</statement> obeys the guidelines
because the scalar <statement>2</statement> can be thought of as
--- 115,159 ----
Array<2, double, Brick> A(I,I), B(J,H);
// ... fill A and B with values ...
... = A + B;
! </programlisting></para>
!
! <figure float="1" id="data_parallel-use-addition_example">
! <title>Adding &array;s with Different Domains</title>
! <mediaobject>
! <imageobject>
! <imagedata fileref="figures/data-parallel.212" format="EPS" align="center"></imagedata>
! </imageobject>
! <textobject>
! <phrase>Adding two arrays with different domains adds values
! with the same indices.</phrase>
! </textobject>
! <caption>
! <para>Adding &array;s with different domains is supported.
! Solid lines indicate the domains' extent. Values with the same
! indices are added.</para>
! </caption>
! </mediaobject>
! </figure>
!
! <para>Both <varname>A</varname> and <varname>B</varname> have
! domains of two-dimensional intervals so they may be added, but
! their domains' extent differ, as indicated by the solid lines in
! the figure. The sum has domain equal to the left operand's
! domain. Values with the same indices are added. For example,
! <statement>A(2,2)</statement> and <statement>B(2,2)</statement>
! are added. <varname>B</varname>'s domain does not include index
! (1,1) so, when adding <statement>A(1,1)</statement> and
! <statement>B(1,1)</statement>, the default value for
! <varname>B</varname>'s value type is used. Usually this
! is 0. Thus, <statement>A(1,1) + B(1,1)</statement> equals
! <statement>9 + 0</statement>.</para>
!
! <para>Operations with both &array;s and scalar values are
! supported. Conceptually, a scalar value can be thought of as an
! &array; with any desired domain and having the same value
! everywhere. For example, consider
<programlisting>
! Array<1, double, Brick> D(Interval<1>(7,10));
D += 2*D + 7;
</programlisting><statement>2*D</statement> obeys the guidelines
because the scalar <statement>2</statement> can be thought of as
*************** D += 2*D + 7;
*** 163,180 ****
not first convert scalar values to arrays but instead uses them
directly in expressions.</para>
! <para>Assignment to containers is also supported. The domain
types of the assignment's left-hand side and its right-hand side
must be the same. Their indices need not be the same, but they
must correspond. That is, the domains must be <glossterm
! linkend="glossary-conformable_domains"><firstterm>conformable
! domains</firstterm></glossterm>, or have the <quote>same
! shape</quote>, i.e., have the same number of indices for each
! dimension. For example, the one-dimensional interval [0,3] is
! conformable to the one-dimensional interval [1,4] because they
! both have the same number of indices in each dimension. The
! domains of <varname>A</varname> and <varname>B</varname>, as
! declared
<programlisting>
Interval<1> H(0,2), I(1,3), J(2,4), K(0,4);
Array<2, double, Brick> A(I,I), B(H,J), C(I,K);
--- 167,183 ----
not first convert scalar values to arrays but instead uses them
directly in expressions.</para>
! <para>Assignments to containers are also supported. The domain
types of the assignment's left-hand side and its right-hand side
must be the same. Their indices need not be the same, but they
must correspond. That is, the domains must be <glossterm
! linkend="glossary-conformable_domains"><firstterm>conformable</firstterm></glossterm>,
! or have the <quote>same shape</quote>, i.e., have the same number
! of indices for each dimension. For example, the one-dimensional
! interval [0,3] is conformable to the one-dimensional interval
! [1,4] because they both have the same number of indices in each
! dimension. The domains of <varname>A</varname> and
! <varname>B</varname>, as declared
<programlisting>
Interval<1> H(0,2), I(1,3), J(2,4), K(0,4);
Array<2, double, Brick> A(I,I), B(H,J), C(I,K);
*************** Array<2, double, Brick> A(I,I), B(H,J),
*** 182,188 ****
number of indices. <varname>A</varname> and <varname>C</varname>
are not conformable because, while their first dimensions are
conformable, their second dimensions are not conformable. It has
! three indices while the other has four. We define <glossterm
linkend="glossary-conformable_containers"><firstterm>conformable
containers</firstterm></glossterm> to be containers with
conformable domains.</para>
--- 185,191 ----
number of indices. <varname>A</varname> and <varname>C</varname>
are not conformable because, while their first dimensions are
conformable, their second dimensions are not conformable. It has
! three indices while the other has five. We define <glossterm
linkend="glossary-conformable_containers"><firstterm>conformable
containers</firstterm></glossterm> to be containers with
conformable domains.</para>
*************** Array<1, double, Brick> A(Interval<1>(0,
*** 222,228 ****
Array<1, double, Brick> B(Interval<1>(1,3));
A = 1.0;
B = 2.0;
! std::cout << A-B << std::endl;
</programlisting> yields
<computeroutput>
(000:002:001) = 1 -1 -1</computeroutput>. The initial
--- 225,231 ----
Array<1, double, Brick> B(Interval<1>(1,3));
A = 1.0;
B = 2.0;
! std::cout &openopen; A-B &openopen; std::endl;
</programlisting> yields
<computeroutput>
(000:002:001) = 1 -1 -1</computeroutput>. The initial
*************** std::cout << A-B << std::endl;
*** 233,261 ****
<para>The following four tables list the data-parallel operators
that operate on &array;s. <xref
linkend="data_parallel-use-operators_table"></xref> lists standard
! &cc; operators that can be applied to &array;s and constant values
! if appropriate. Each unary operator takes an &array; parameter
! and returns an &array;. The types of the two &array;s need not be
! the same. For example, <operator>!</operator> can take an
! <type>Array<bool></type>, <type>Array<int></type>,
! <type>Array<long></type>, or any other value type to which
! <operator>!</operator> can be applied. The result is an
! <type>Array<bool></type>. Each binary operator also returns
! an &array;. When specifying two &array;s or an &array; and a
! constant value, a full set of operators is supported. When
! specifying an &array; and a &tensor;, &matrix;, or &vector;, a
! more limited set of operators is supported. For example,
! <operator>==</operator> can take two &array;s, an &array; and a
! constant value, or a constant value and an &array;. If given two
! &array;s, corresponding values are used. If a parameter is a
! constant value, its same value is the used with each &array;
! value. The <operator>+</operator> supports the same set of
! parameters but also supports adding an &array; and a &tensor;, an
! &array; and a &matrix;, an &array; and a &vector;, a &tensor; and
! an &array;, a &matrix; and an &array;, and a &vector; and an
! &array;. For these cases, the &array; must have a value type that
! can be added to the other argument. For example, a &vector; can
! be added to an &array; of &vector;s.</para>
<table frame="none" colsep="0" rowsep="0" tocentry="1"
orient="port" pgwide="0" id="data_parallel-use-operators_table">
--- 236,264 ----
<para>The following four tables list the data-parallel operators
that operate on &array;s. <xref
linkend="data_parallel-use-operators_table"></xref> lists standard
! &cc; operators that can be applied to &array;s and also scalar
! values if appropriate. Each unary operator takes an &array;
! parameter and returns an &array;. The types of the two &array;s
! need not be the same. For example, <operator>!</operator> can
! take an <type>Array<bool></type>,
! <type>Array<int></type>, <type>Array<long></type>, or
! any other value type to which <operator>!</operator> can be
! applied. The result is an <type>Array<bool></type>. Each
! binary operator also returns an &array;. When specifying two
! &array;s or an &array; and a scalar value, a full set of operators
! is supported. When specifying an &array; and a &tensor;,
! &matrix;, or &vector;, a more limited set of operators is
! supported. For example, <operator>==</operator> can take two
! &array;s, an &array; and a scalar value, or a scalar value and an
! &array;. If given two &array;s, corresponding values are used.
! If an argument is a scalar value, its same value is the used with
! each &array; value. The <operator>+</operator> supports the same
! set of parameters but also supports adding an &array; and a
! &tensor;, an &array; and a &matrix;, an &array; and a &vector;, a
! &tensor; and an &array;, a &matrix; and an &array;, and a &vector;
! and an &array;. For these cases, the &array; must have a value
! type that can be added to the other argument. For example, a
! &vector; can be added to an &array; of &vector;s.</para>
<table frame="none" colsep="0" rowsep="0" tocentry="1"
orient="port" pgwide="0" id="data_parallel-use-operators_table">
*************** std::cout << A-B << std::endl;
*** 268,287 ****
<entry>supported operators</entry>
</row>
</thead>
! <tbody>
<row>
<entry>unary operators </entry>
<entry><operator>+</operator>, <operator>-</operator>, <operator>~</operator>, <operator>!</operator></entry>
</row>
<row>
! <entry>binary operators with at least one array and at most
! one value</entry>
<entry><operator>+</operator>, <operator>-</operator>, <operator>*</operator>, <operator>/</operator>, <operator>%</operator>, <operator>&</operator>, <operator>|</operator>, <operator>^</operator>, <operator><</operator>, <operator><=</operator>, <operator>>=</operator>, <operator>></operator>, <operator>==</operator>, <operator>!=</operator>, <operator>&&</operator>, <operator>||</operator>, <operator>&openopen;</operator>, <operator>&closeclose;</operator></entry>
</row>
<row>
! <entry>binary operators with at least one array and at most
one &tensor;, &matrix;, or &vector;</entry>
! <entry><operator>+</operator>, <operator>-</operator>, <operator>*</operator>, <operator>/</operator>, <operator>%</operator>, <operator>&</operator>, <operator>|</operator>, <operator>^</operator>, <operator>==</operator>, <operator>!=</operator></entry>
</row>
</tbody>
</tgroup>
--- 271,294 ----
<entry>supported operators</entry>
</row>
</thead>
! <tbody valign="top">
<row>
<entry>unary operators </entry>
<entry><operator>+</operator>, <operator>-</operator>, <operator>~</operator>, <operator>!</operator></entry>
</row>
<row>
! <entry>binary operators with at least one &array; and at most
! one scalar value</entry>
<entry><operator>+</operator>, <operator>-</operator>, <operator>*</operator>, <operator>/</operator>, <operator>%</operator>, <operator>&</operator>, <operator>|</operator>, <operator>^</operator>, <operator><</operator>, <operator><=</operator>, <operator>>=</operator>, <operator>></operator>, <operator>==</operator>, <operator>!=</operator>, <operator>&&</operator>, <operator>||</operator>, <operator>&openopen;</operator>, <operator>&closeclose;</operator></entry>
</row>
<row>
! <entry>binary operators with at least one &array; and at most
one &tensor;, &matrix;, or &vector;</entry>
! <entry><operator>+</operator>, <operator>-</operator>,
! <operator>*</operator>, <operator>/</operator>,
! <operator>%</operator>, <operator>&</operator>,
! <operator>|</operator>, <operator>^</operator>,
! <operator>==</operator>, <operator>!=</operator></entry>
</row>
</tbody>
</tgroup>
*************** std::cout << A-B << std::endl;
*** 291,302 ****
expressions appear in <xref
linkend="data_parallel-use-math_functions_table"></xref>. For
example, applying <function>cos</function> to an &array; of values
! with type <type>T</type> yields an array of the same type.
! The functions are split into five sections:
! <itemizedlist>
! <listitem>
! <para>trigonometric and hyperbolic functions,</para>
! </listitem>
<listitem>
<para>functions computing absolute values, rounding functions,
and modulus functions,</para>
--- 298,309 ----
expressions appear in <xref
linkend="data_parallel-use-math_functions_table"></xref>. For
example, applying <function>cos</function> to an &array; of values
! with type <type>T</type> yields an &array; with the same
! type. The functions are split into five sections:
! <itemizedlist>
! <listitem>
! <para>trigonometric and hyperbolic functions,</para>
! </listitem>
<listitem>
<para>functions computing absolute values, rounding functions,
and modulus functions,</para>
*************** std::cout << A-B << std::endl;
*** 312,326 ****
</listitem>
</itemizedlist>
Several data-parallel functions require inclusion of header files
! declaring the underlying element-wise function. These header
files are listed at the beginning of each section. For the
data-parallel operator to be applicable, it must operate on the
&array;'s type. For example, <function>cos</function> can be
! applied on &array;s of ∫, &double;, and even &bool;, but
applying on &array;s of pointers is not supported because
! <function>cos</function> cannot be called with a pointer argument.</para>
! <para>A few functions deserve explanation. The
<function>PETE_identity</function> function applies the identity
operation to the array. That is, the returned array has values
equaling the argument's values. <function>pow2</function>,
--- 319,334 ----
</listitem>
</itemizedlist>
Several data-parallel functions require inclusion of header files
! declaring their underlying element-wise function. These header
files are listed at the beginning of each section. For the
data-parallel operator to be applicable, it must operate on the
&array;'s type. For example, <function>cos</function> can be
! applied on &array;s of ∫, &double;, and even &bool;, but
applying on &array;s of pointers is not supported because
! <function>cos</function> cannot be called with a pointer
! argument.</para>
! <para>Two functions deserve special explanation. The
<function>PETE_identity</function> function applies the identity
operation to the array. That is, the returned array has values
equaling the argument's values. <function>pow2</function>,
*************** std::cout << A-B << std::endl;
*** 347,380 ****
choices for the template type parameters.</entry>
</row>
</tfoot>
! <tbody>
<row rowsep="1">
<entry>Trigonometric and Hyperbolic Functions</entry>
<entry><statement>#include <math.h></statement></entry>
</row>
<row>
<entry><statement>Array<T> cos (const Array<T>& A)</statement></entry>
! <entry>Returns the cosines of the array's values.</entry>
</row>
<row>
<entry><statement>Array<T> sin (const Array<T>& A)</statement></entry>
! <entry>Returns the sines of the array's values.</entry>
</row>
<row>
<entry><statement>Array<T> tan (const Array<T>& A)</statement></entry>
! <entry>Returns the tangents of the array's values.</entry>
</row>
<row>
<entry><statement>Array<T> acos (const Array<T1>& A)</statement></entry>
! <entry>Returns the arc cosines of the array's values.</entry>
</row>
<row>
<entry><statement>Array<T> asin (const Array<T1>& A)</statement></entry>
! <entry>Returns the arc sines of the array's values.</entry>
</row>
<row>
<entry><statement>Array<T> atan (const Array<T1>& A)</statement></entry>
! <entry>Returns the arc tangents of the array's values.</entry>
</row>
<row>
<entry><statement>Array<T> atan2 (const Array<T1>& A, const Array<T2>& B)</statement></entry>
--- 355,388 ----
choices for the template type parameters.</entry>
</row>
</tfoot>
! <tbody valign="top">
<row rowsep="1">
<entry>Trigonometric and Hyperbolic Functions</entry>
<entry><statement>#include <math.h></statement></entry>
</row>
<row>
<entry><statement>Array<T> cos (const Array<T>& A)</statement></entry>
! <entry>Returns the cosines of the &array;'s values.</entry>
</row>
<row>
<entry><statement>Array<T> sin (const Array<T>& A)</statement></entry>
! <entry>Returns the sines of the &array;'s values.</entry>
</row>
<row>
<entry><statement>Array<T> tan (const Array<T>& A)</statement></entry>
! <entry>Returns the tangents of the &array;'s values.</entry>
</row>
<row>
<entry><statement>Array<T> acos (const Array<T1>& A)</statement></entry>
! <entry>Returns the arc cosines of the &array;'s values.</entry>
</row>
<row>
<entry><statement>Array<T> asin (const Array<T1>& A)</statement></entry>
! <entry>Returns the arc sines of the &array;'s values.</entry>
</row>
<row>
<entry><statement>Array<T> atan (const Array<T1>& A)</statement></entry>
! <entry>Returns the arc tangents of the &array;'s values.</entry>
</row>
<row>
<entry><statement>Array<T> atan2 (const Array<T1>& A, const Array<T2>& B)</statement></entry>
*************** std::cout << A-B << std::endl;
*** 398,412 ****
</row>
<row>
<entry><statement>Array<T> cosh (const Array<T>& A)</statement></entry>
! <entry>Returns the hyperbolic cosines of the array's values.</entry>
</row>
<row>
<entry><statement>Array<T> sinh (const Array<T>& A)</statement></entry>
! <entry>Returns the hyperbolic sines of the array's values.</entry>
</row>
<row>
<entry><statement>Array<T> tanh (const Array<T>& A)</statement></entry>
! <entry>Returns the hyperbolic tangents of the array's values.</entry>
</row>
<row rowsep="1">
<entry>Absolute Value, Rounding, and Modulus Functions</entry>
--- 406,420 ----
</row>
<row>
<entry><statement>Array<T> cosh (const Array<T>& A)</statement></entry>
! <entry>Returns the hyperbolic cosines of the &array;'s values.</entry>
</row>
<row>
<entry><statement>Array<T> sinh (const Array<T>& A)</statement></entry>
! <entry>Returns the hyperbolic sines of the &array;'s values.</entry>
</row>
<row>
<entry><statement>Array<T> tanh (const Array<T>& A)</statement></entry>
! <entry>Returns the hyperbolic tangents of the &array;'s values.</entry>
</row>
<row rowsep="1">
<entry>Absolute Value, Rounding, and Modulus Functions</entry>
*************** std::cout << A-B << std::endl;
*** 415,435 ****
<row>
<entry><statement>Array<T> fabs (const Array<T1>& A)</statement></entry>
<entry>Returns the absolute values of the floating point
! numbers in the array.</entry>
! </row>
! <row>
! <entry><statement>Array<T> ceil (const Array<T1>& A)</statement></entry>
! <entry>For each of the array's values, return the integer
! larger than or equal to it (as a floating point number).</entry>
</row>
<row>
<entry><statement>Array<T> ceil (const Array<T1>& A)</statement></entry>
! <entry>For each of the array's values, return the integer
larger than or equal to it (as a floating point number).</entry>
</row>
<row>
<entry><statement>Array<T> floor (const Array<T1>& A)</statement></entry>
! <entry>For each of the array's values, return the integer
smaller than or equal to it (as a floating point number).</entry>
</row>
<row>
--- 423,438 ----
<row>
<entry><statement>Array<T> fabs (const Array<T1>& A)</statement></entry>
<entry>Returns the absolute values of the floating point
! numbers in the &array;.</entry>
</row>
<row>
<entry><statement>Array<T> ceil (const Array<T1>& A)</statement></entry>
! <entry>For each of the &array;'s values, return the integer
larger than or equal to it (as a floating point number).</entry>
</row>
<row>
<entry><statement>Array<T> floor (const Array<T1>& A)</statement></entry>
! <entry>For each of the &array;'s values, return the integer
smaller than or equal to it (as a floating point number).</entry>
</row>
<row>
*************** std::cout << A-B << std::endl;
*** 438,444 ****
<varname>A</varname>'s values with the corresponding value
in <varname>B</varname>. The results have the same signs
as <varname>A</varname> and absolute values less than the
! absolute values of values in <varname>B</varname>.</entry>
</row>
<row>
<entry><statement>Array<T> fmod (const Array<T1>& A, const T2& r)</statement></entry>
--- 441,447 ----
<varname>A</varname>'s values with the corresponding value
in <varname>B</varname>. The results have the same signs
as <varname>A</varname> and absolute values less than the
! absolute values of <varname>B</varname>.</entry>
</row>
<row>
<entry><statement>Array<T> fmod (const Array<T1>& A, const T2& r)</statement></entry>
*************** std::cout << A-B << std::endl;
*** 453,459 ****
<varname>l</varname> with the values
in <varname>B</varname>. The results have the same signs
as <varname>l</varname> and absolute values less than the
! absolute values of values in <varname>B</varname>.</entry>
</row>
<row rowsep="1">
<entry>Powers, Exponentiation, and Logarithmic Functions</entry>
--- 456,462 ----
<varname>l</varname> with the values
in <varname>B</varname>. The results have the same signs
as <varname>l</varname> and absolute values less than the
! absolute values of <varname>B</varname>.</entry>
</row>
<row rowsep="1">
<entry>Powers, Exponentiation, and Logarithmic Functions</entry>
*************** std::cout << A-B << std::endl;
*** 461,471 ****
</row>
<row>
<entry><statement>Array<T> PETE_identity (const Array<T>& A)</statement></entry>
! <entry>Returns the array. That is, it applies the identity operation.</entry>
</row>
<row>
<entry><statement>Array<T> sqrt (const Array<T>& A)</statement></entry>
! <entry>Returns the square roots of the array's values.</entry>
</row>
<row>
<entry><statement>Array<T> pow (const Array<T1>& A, const Array<T2>& B)</statement></entry>
--- 464,474 ----
</row>
<row>
<entry><statement>Array<T> PETE_identity (const Array<T>& A)</statement></entry>
! <entry>Returns the &array;. That is, it applies the identity operation.</entry>
</row>
<row>
<entry><statement>Array<T> sqrt (const Array<T>& A)</statement></entry>
! <entry>Returns the square roots of the &array;'s values.</entry>
</row>
<row>
<entry><statement>Array<T> pow (const Array<T1>& A, const Array<T2>& B)</statement></entry>
*************** std::cout << A-B << std::endl;
*** 501,507 ****
<row>
<entry><statement>Array<T> ldexp (const Array<T1>& A, int r)</statement></entry>
<entry>Multiplies <varname>A</varname>'s values by two raised
! to the <varname>r</varname>'th power.</entry>
</row>
<row>
<entry><statement>Array<T> ldexp (const T1& l, const Array<int>& B)</statement></entry>
--- 504,511 ----
<row>
<entry><statement>Array<T> ldexp (const Array<T1>& A, int r)</statement></entry>
<entry>Multiplies <varname>A</varname>'s values by two raised
! to the <varname>r</varname><subscript>th</subscript>
! power.</entry>
</row>
<row>
<entry><statement>Array<T> ldexp (const T1& l, const Array<int>& B)</statement></entry>
*************** std::cout << A-B << std::endl;
*** 510,524 ****
</row>
<row>
<entry><statement>Array<T> exp (const Array<T>& A)</statement></entry>
! <entry>Returns the exponentiations of the array's values.</entry>
</row>
<row>
<entry><statement>Array<T> log (const Array<T>& A)</statement></entry>
! <entry>Returns the natural logarithms of the array's values.</entry>
</row>
<row>
<entry><statement>Array<T> log10 (const Array<T>& A)</statement></entry>
! <entry>Returns the base-10 logarithms of the array's values.</entry>
</row>
<row rowsep="1">
<entry>Functions Involving Complex Numbers</entry>
--- 514,528 ----
</row>
<row>
<entry><statement>Array<T> exp (const Array<T>& A)</statement></entry>
! <entry>Returns the exponentiations of the &array;'s values.</entry>
</row>
<row>
<entry><statement>Array<T> log (const Array<T>& A)</statement></entry>
! <entry>Returns the natural logarithms of the &array;'s values.</entry>
</row>
<row>
<entry><statement>Array<T> log10 (const Array<T>& A)</statement></entry>
! <entry>Returns the base-10 logarithms of the &array;'s values.</entry>
</row>
<row rowsep="1">
<entry>Functions Involving Complex Numbers</entry>
*************** std::cout << A-B << std::endl;
*** 561,578 ****
<entry><statement>Array<complex<T&closeclose; polar (const Array<T1>& A, const Array<T2>& B)</statement></entry>
<entry>Returns the complex numbers created from polar
coordinates (magnitudes and phase angles) in corresponding
! arrays.</entry>
</row>
<row>
<entry><statement>Array<complex<T&closeclose; polar (const T1& l, const Array<T2>& A)</statement></entry>
<entry>Returns the complex numbers created from polar
coordinates with magnitude <varname>l</varname> and
! phase angles in the array.</entry>
</row>
<row>
<entry><statement>Array<complex<T&closeclose; polar (const Array<T1>& A, const T2& r)</statement></entry>
<entry>Returns the complex numbers created from polar
! coordinates with magnitudes in the array and phase
angle <varname>r</varname>.</entry>
</row>
<row rowsep="1">
--- 565,582 ----
<entry><statement>Array<complex<T&closeclose; polar (const Array<T1>& A, const Array<T2>& B)</statement></entry>
<entry>Returns the complex numbers created from polar
coordinates (magnitudes and phase angles) in corresponding
! &array;s.</entry>
</row>
<row>
<entry><statement>Array<complex<T&closeclose; polar (const T1& l, const Array<T2>& A)</statement></entry>
<entry>Returns the complex numbers created from polar
coordinates with magnitude <varname>l</varname> and
! phase angles in the &array;.</entry>
</row>
<row>
<entry><statement>Array<complex<T&closeclose; polar (const Array<T1>& A, const T2& r)</statement></entry>
<entry>Returns the complex numbers created from polar
! coordinates with magnitudes in the &array; and phase
angle <varname>r</varname>.</entry>
</row>
<row rowsep="1">
*************** std::cout << A-B << std::endl;
*** 599,612 ****
</row>
<row>
<entry><statement>Array<T> dot (const Array<T1>& A, const Array<T2>& B)</statement></entry>
! <entry>Returns the dot products of values in the two arrays.
Value type <type>T</type> equals the type of the
<function>dot</function> operating on <type>T1</type>
and <type>T2</type>.</entry>
</row>
<row>
<entry><statement>Array<T> dot (const Array<T1>& A, const T2& r)</statement></entry>
! <entry>Returns the dot products of values in the array
with <varname>r</varname>.
Value type <type>T</type> equals the type of the
<function>dot</function> operating on <type>T1</type>
--- 603,616 ----
</row>
<row>
<entry><statement>Array<T> dot (const Array<T1>& A, const Array<T2>& B)</statement></entry>
! <entry>Returns the dot products of values in the two &array;s.
Value type <type>T</type> equals the type of the
<function>dot</function> operating on <type>T1</type>
and <type>T2</type>.</entry>
</row>
<row>
<entry><statement>Array<T> dot (const Array<T1>& A, const T2& r)</statement></entry>
! <entry>Returns the dot products of values in the &array;
with <varname>r</varname>.
Value type <type>T</type> equals the type of the
<function>dot</function> operating on <type>T1</type>
*************** std::cout << A-B << std::endl;
*** 615,635 ****
<row>
<entry><statement>Array<T> dot (const T1& l, const Array<T2>& A)</statement></entry>
<entry>Returns the dot products of <varname>l</varname> with
! values in the array. Value type <type>T</type> equals the type of the
<function>dot</function> operating on <type>T1</type>
and <type>T2</type>.</entry>
</row>
<row>
- <entry><statement>Array<T> dot (const Array<T1>& A, const T2& B)</statement></entry>
- <entry>Returns the dot products of values in the array
- Value type <type>T</type> equals the type of the
- <function>dot</function> operating on <type>T1</type>
- and <type>T2</type>.</entry>
- </row>
- <row>
<entry><statement>Array<Tensor<T&closeclose; outerProduct (const Array<T1>& A, const Array<T2>& B)</statement></entry>
<entry>Returns tensors created by computing the outer product
! of corresponding vectors in the two arrays. Value
type <type>T</type> equals the type of the product of
<type>T1</type> and <type>T2</type>. The vectors
must have the same length.</entry>
--- 619,632 ----
<row>
<entry><statement>Array<T> dot (const T1& l, const Array<T2>& A)</statement></entry>
<entry>Returns the dot products of <varname>l</varname> with
! values in the &array;. Value type <type>T</type> equals the type of the
<function>dot</function> operating on <type>T1</type>
and <type>T2</type>.</entry>
</row>
<row>
<entry><statement>Array<Tensor<T&closeclose; outerProduct (const Array<T1>& A, const Array<T2>& B)</statement></entry>
<entry>Returns tensors created by computing the outer product
! of corresponding vectors in the two &array;s. Value
type <type>T</type> equals the type of the product of
<type>T1</type> and <type>T2</type>. The vectors
must have the same length.</entry>
*************** std::cout << A-B << std::endl;
*** 637,643 ****
<row>
<entry><statement>Array<Tensor<T&closeclose; outerProduct (const T1& l, const Array<T2>& A)</statement></entry>
<entry>Returns tensors created by computing the outer product
! of <varname>l</varname> with the vectors in the array. Value
type <type>T</type> equals the type of the product of
<type>T1</type> and <type>T2</type>. The vectors
must have the same length.</entry>
--- 634,640 ----
<row>
<entry><statement>Array<Tensor<T&closeclose; outerProduct (const T1& l, const Array<T2>& A)</statement></entry>
<entry>Returns tensors created by computing the outer product
! of <varname>l</varname> with the vectors in the &array;. Value
type <type>T</type> equals the type of the product of
<type>T1</type> and <type>T2</type>. The vectors
must have the same length.</entry>
*************** std::cout << A-B << std::endl;
*** 645,651 ****
<row>
<entry><statement>Array<Tensor<T&closeclose; outerProduct (const Array<T1>& A, const T2& r)</statement></entry>
<entry>Returns tensors created by computing the outer product
! of vectors in the array with <varname>r</varname>. Value
type <type>T</type> equals the type of the product of
<type>T1</type> and <type>T2</type>. The vectors
must have the same length.</entry>
--- 642,648 ----
<row>
<entry><statement>Array<Tensor<T&closeclose; outerProduct (const Array<T1>& A, const T2& r)</statement></entry>
<entry>Returns tensors created by computing the outer product
! of vectors in the &array; with <varname>r</varname>. Value
type <type>T</type> equals the type of the product of
<type>T1</type> and <type>T2</type>. The vectors
must have the same length.</entry>
*************** std::cout << A-B << std::endl;
*** 654,660 ****
<entry><statement>TinyMatrix<T> outerProductAsTinyMatrix (const Array<T1>& A, const
Array<T2>& B)</statement></entry>
<entry>Returns matrices created by computing the outer product
! of corresponding vectors in the two arrays. Value
type <type>T</type> equals the type of the product of
<type>T1</type> and <type>T2</type>. The vectors must have
the same length.</entry>
--- 651,657 ----
<entry><statement>TinyMatrix<T> outerProductAsTinyMatrix (const Array<T1>& A, const
Array<T2>& B)</statement></entry>
<entry>Returns matrices created by computing the outer product
! of corresponding vectors in the two &array;s. Value
type <type>T</type> equals the type of the product of
<type>T1</type> and <type>T2</type>. The vectors must have
the same length.</entry>
*************** std::cout << A-B << std::endl;
*** 663,669 ****
<entry><statement>TinyMatrix<T> outerProductAsTinyMatrix (const T1& l, const
Array<T2>& A)</statement></entry>
<entry>Returns matrices created by computing the outer
! product of <varname>l</varname> with the vectors in the array. Value
type <type>T</type> equals the type of the product of
<type>T1</type> and <type>T2</type>. The vectors must
have the same length.</entry>
--- 660,666 ----
<entry><statement>TinyMatrix<T> outerProductAsTinyMatrix (const T1& l, const
Array<T2>& A)</statement></entry>
<entry>Returns matrices created by computing the outer
! product of <varname>l</varname> with the vectors in the &array;. Value
type <type>T</type> equals the type of the product of
<type>T1</type> and <type>T2</type>. The vectors must
have the same length.</entry>
*************** std::cout << A-B << std::endl;
*** 672,678 ****
<entry><statement>TinyMatrix<T> outerProductAsTinyMatrix (const
Array<T1>& A, const T2& r)</statement></entry>
<entry>Returns matrices created by computing the outer
! product of the vectors in the array
with <varname>r</varname>. Value
type <type>T</type> equals the type of the product of
<type>T1</type> and <type>T2</type>. The vectors must
--- 669,675 ----
<entry><statement>TinyMatrix<T> outerProductAsTinyMatrix (const
Array<T1>& A, const T2& r)</statement></entry>
<entry>Returns matrices created by computing the outer
! product of the vectors in the &array;
with <varname>r</varname>. Value
type <type>T</type> equals the type of the product of
<type>T1</type> and <type>T2</type>. The vectors must
*************** std::cout << A-B << std::endl;
*** 701,828 ****
<entry>effect</entry>
</row>
</thead>
! <tbody>
<row>
<entry><statement>Array<T> max (const Array<T1>& A, const Array<T2>& B)</statement></entry>
! <entry>Returns the maximum of corresponding array values.</entry>
</row>
<row>
<entry><statement>Array<T> max (const T1& l, const Array<T2>& A)</statement></entry>
! <entry>Returns the maximums of <varname>l</varname> with the array's values.</entry>
</row>
<row>
<entry><statement>Array<T> max (const Array<T1>& A, const T2& r)</statement></entry>
! <entry>Returns the maximums of the array's values with <varname>r</varname>.</entry>
</row>
<row>
<entry><statement>Array<T> min (const Array<T1>& A, const Array<T2>& B)</statement></entry>
! <entry>Returns the minimum of corresponding array values.</entry>
</row>
<row>
<entry><statement>Array<T> min (const T1& l, const Array<T2>& A)</statement></entry>
! <entry>Returns the minimums of <varname>l</varname> with the array's values.</entry>
</row>
<row>
<entry><statement>Array<T> min (const Array<T1>& A, const T2& r)</statement></entry>
! <entry>Returns the minimums of the array's values with <varname>r</varname>.</entry>
</row>
<row>
<entry><statement>Array<bool> LT (const Array<T1>& A, const Array<T2>& B)</statement></entry>
<entry>Returns booleans from using the less-than
! operator < to compare corresponding array values in
<varname>A</varname> and <varname>B</varname>.</entry>
</row>
<row>
<entry><statement>Array<bool> LT (const T1& r, const Array<T2>& A)</statement></entry>
<entry>Returns booleans from using the less-than
! operator < to compare <varname>l</varname> with the array's
values.</entry>
</row>
<row>
<entry><statement>Array<bool> LT (const Array<T1>& A, const T2& r)</statement></entry>
<entry>Returns booleans from using the less-than
! operator < to compare the array's
values with <varname>r</varname>.</entry>
</row>
<row>
<entry><statement>Array<bool> LE (const Array<T1>& A, const Array<T2>& B)</statement></entry>
<entry>Returns booleans from using the less-than-or-equal
! operator ≤ to compare array values in
<varname>A</varname> and <varname>B</varname>.</entry>
</row>
<row>
<entry><statement>Array<bool> LE (const T1& l, const Array<T2>& A)</statement></entry>
<entry>Returns booleans from using the less-than-or-equal
! operator ≤ to compare <varname>l</varname> with the array's values.</entry>
</row>
<row>
<entry><statement>Array<bool> LE (const Array<T1>& A, const T2& r)</statement></entry>
<entry>Returns booleans from using the less-than-or-equal
! operator ≤ to compare the array's values
with <varname>r</varname>.</entry>
</row>
<row>
<entry><statement>Array<bool> GE (const Array<T1>& A, const Array<T2>& B)</statement></entry>
<entry>Returns booleans from using the greater-than-or-equal
! operator ≥ to compare array values in
<varname>A</varname> and <varname>B</varname>.</entry>
</row>
<row>
<entry><statement>Array<bool> GE (const T1& l, const Array<T2>& A)</statement></entry>
<entry>Returns booleans from using the greater-than-or-equal
! operator ≥ to compare <varname>l</varname> with the array's values.</entry>
</row>
<row>
<entry><statement>Array<bool> GE (const Array<T1>& A, const T2& r)</statement></entry>
<entry>Returns booleans from using the greater-than-or-equal
! operator ≥ to compare the array's values with <varname>r</varname>.</entry>
</row>
<row>
<entry><statement>Array<bool> GT (const Array<T1>& A, const Array<T2>& B)</statement></entry>
<entry>Returns booleans from using the greater-than
! operator > to compare array values in
<varname>A</varname> and <varname>B</varname>.</entry>
</row>
<row>
<entry><statement>Array<bool> GT (const T1& l, const Array<T2>& A)</statement></entry>
<entry>Returns booleans from using the greater-than
! operator > to compare <varname>l</varname> with the array's values.</entry>
</row>
<row>
<entry><statement>Array<bool> GT (const Array<T1>& A, const T2& r)</statement></entry>
<entry>Returns booleans from using the greater-than
! operator > to compare the array's values with <varname>r</varname>.</entry>
</row>
<row>
<entry><statement>Array<bool> EQ (const Array<T1>& A, const Array<T2>& B)</statement></entry>
<entry>Returns booleans from determining whether
! corresponding array values in <varname>A</varname> and
<varname>B</varname> are equal.</entry>
</row>
<row>
<entry><statement>Array<bool> EQ (const T1& l, const Array<T2>& A)</statement></entry>
<entry>Returns booleans from determining whether
! <varname>l</varname> equals the array's values..</entry>
</row>
<row>
<entry><statement>Array<bool> EQ (const Array<T1>& A, const T2& r)</statement></entry>
! <entry>Returns booleans from determining whether the array's values equal <varname>r</varname>.</entry>
</row>
<row>
<entry><statement>Array<bool> NE (const Array<T1>& A, const Array<T2>& B)</statement></entry>
<entry>Returns booleans from determining whether
! corresponding array values in <varname>A</varname> and
<varname>B</varname> are not equal.</entry>
</row>
<row>
<entry><statement>Array<bool> NE (const T1& l, const Array<T2>& A)</statement></entry>
<entry>Returns booleans from determining whether
! <varname>l</varname> does not equal the array's values.</entry>
</row>
<row>
<entry><statement>Array<bool> NE (const Array<T1>& A, const T2& r)</statement></entry>
<entry>Returns booleans from determining whether the
! array's values are not equal to <varname>r</varname>.</entry>
</row>
<!-- FIXME: Add dotdot from src/Array/PoomaArrayOperators.h if it is defined. -->
</tbody>
--- 698,825 ----
<entry>effect</entry>
</row>
</thead>
! <tbody valign="top">
<row>
<entry><statement>Array<T> max (const Array<T1>& A, const Array<T2>& B)</statement></entry>
! <entry>Returns the maximum of corresponding &array; values.</entry>
</row>
<row>
<entry><statement>Array<T> max (const T1& l, const Array<T2>& A)</statement></entry>
! <entry>Returns the maximums of <varname>l</varname> with the &array;'s values.</entry>
</row>
<row>
<entry><statement>Array<T> max (const Array<T1>& A, const T2& r)</statement></entry>
! <entry>Returns the maximums of the &array;'s values with <varname>r</varname>.</entry>
</row>
<row>
<entry><statement>Array<T> min (const Array<T1>& A, const Array<T2>& B)</statement></entry>
! <entry>Returns the minimum of corresponding &array; values.</entry>
</row>
<row>
<entry><statement>Array<T> min (const T1& l, const Array<T2>& A)</statement></entry>
! <entry>Returns the minimums of <varname>l</varname> with the &array;'s values.</entry>
</row>
<row>
<entry><statement>Array<T> min (const Array<T1>& A, const T2& r)</statement></entry>
! <entry>Returns the minimums of the &array;'s values with <varname>r</varname>.</entry>
</row>
<row>
<entry><statement>Array<bool> LT (const Array<T1>& A, const Array<T2>& B)</statement></entry>
<entry>Returns booleans from using the less-than
! operator <operator><</operator> to compare corresponding &array; values in
<varname>A</varname> and <varname>B</varname>.</entry>
</row>
<row>
<entry><statement>Array<bool> LT (const T1& r, const Array<T2>& A)</statement></entry>
<entry>Returns booleans from using the less-than
! operator <operator><</operator> to compare <varname>l</varname> with the &array;'s
values.</entry>
</row>
<row>
<entry><statement>Array<bool> LT (const Array<T1>& A, const T2& r)</statement></entry>
<entry>Returns booleans from using the less-than
! operator <operator><</operator> to compare the &array;'s
values with <varname>r</varname>.</entry>
</row>
<row>
<entry><statement>Array<bool> LE (const Array<T1>& A, const Array<T2>& B)</statement></entry>
<entry>Returns booleans from using the less-than-or-equal
! operator <operator><=</operator> to compare &array; values in
<varname>A</varname> and <varname>B</varname>.</entry>
</row>
<row>
<entry><statement>Array<bool> LE (const T1& l, const Array<T2>& A)</statement></entry>
<entry>Returns booleans from using the less-than-or-equal
! operator <operator><=</operator> to compare <varname>l</varname> with the &array;'s values.</entry>
</row>
<row>
<entry><statement>Array<bool> LE (const Array<T1>& A, const T2& r)</statement></entry>
<entry>Returns booleans from using the less-than-or-equal
! operator <operator><=</operator> to compare the &array;'s values
with <varname>r</varname>.</entry>
</row>
<row>
<entry><statement>Array<bool> GE (const Array<T1>& A, const Array<T2>& B)</statement></entry>
<entry>Returns booleans from using the greater-than-or-equal
! operator <operator>>=</operator> to compare &array; values in
<varname>A</varname> and <varname>B</varname>.</entry>
</row>
<row>
<entry><statement>Array<bool> GE (const T1& l, const Array<T2>& A)</statement></entry>
<entry>Returns booleans from using the greater-than-or-equal
! operator <operator>>=</operator> to compare <varname>l</varname> with the &array;'s values.</entry>
</row>
<row>
<entry><statement>Array<bool> GE (const Array<T1>& A, const T2& r)</statement></entry>
<entry>Returns booleans from using the greater-than-or-equal
! operator <operator>>=</operator> to compare the &array;'s values with <varname>r</varname>.</entry>
</row>
<row>
<entry><statement>Array<bool> GT (const Array<T1>& A, const Array<T2>& B)</statement></entry>
<entry>Returns booleans from using the greater-than
! operator <operator>></operator> to compare &array; values in
<varname>A</varname> and <varname>B</varname>.</entry>
</row>
<row>
<entry><statement>Array<bool> GT (const T1& l, const Array<T2>& A)</statement></entry>
<entry>Returns booleans from using the greater-than
! operator <operator>></operator> to compare <varname>l</varname> with the &array;'s values.</entry>
</row>
<row>
<entry><statement>Array<bool> GT (const Array<T1>& A, const T2& r)</statement></entry>
<entry>Returns booleans from using the greater-than
! operator <operator>></operator> to compare the &array;'s values with <varname>r</varname>.</entry>
</row>
<row>
<entry><statement>Array<bool> EQ (const Array<T1>& A, const Array<T2>& B)</statement></entry>
<entry>Returns booleans from determining whether
! corresponding &array; values in <varname>A</varname> and
<varname>B</varname> are equal.</entry>
</row>
<row>
<entry><statement>Array<bool> EQ (const T1& l, const Array<T2>& A)</statement></entry>
<entry>Returns booleans from determining whether
! <varname>l</varname> equals the &array;'s values.</entry>
</row>
<row>
<entry><statement>Array<bool> EQ (const Array<T1>& A, const T2& r)</statement></entry>
! <entry>Returns booleans from determining whether the &array;'s values equal <varname>r</varname>.</entry>
</row>
<row>
<entry><statement>Array<bool> NE (const Array<T1>& A, const Array<T2>& B)</statement></entry>
<entry>Returns booleans from determining whether
! corresponding &array; values in <varname>A</varname> and
<varname>B</varname> are not equal.</entry>
</row>
<row>
<entry><statement>Array<bool> NE (const T1& l, const Array<T2>& A)</statement></entry>
<entry>Returns booleans from determining whether
! <varname>l</varname> does not equal the &array;'s values.</entry>
</row>
<row>
<entry><statement>Array<bool> NE (const Array<T1>& A, const T2& r)</statement></entry>
<entry>Returns booleans from determining whether the
! &array;'s values are not equal to <varname>r</varname>.</entry>
</row>
<!-- FIXME: Add dotdot from src/Array/PoomaArrayOperators.h if it is defined. -->
</tbody>
*************** std::cout << A-B << std::endl;
*** 832,838 ****
<para>The table of miscellaneous functions (<xref
linkend="data_parallel-use-misc_functions_table"></xref>) contains
two functions. <function>peteCast</function> casts all values in
! an array to the type specified by the first parameter. The
<function>where</function> function generalizes the trinary
<operator>?:</operator> operator. Using its first &array;
argument as boolean values, it returns an &array; of just two
--- 829,835 ----
<para>The table of miscellaneous functions (<xref
linkend="data_parallel-use-misc_functions_table"></xref>) contains
two functions. <function>peteCast</function> casts all values in
! an &array; to the type specified by its first parameter. The
<function>where</function> function generalizes the trinary
<operator>?:</operator> operator. Using its first &array;
argument as boolean values, it returns an &array; of just two
*************** std::cout << A-B << std::endl;
*** 849,863 ****
<entry>effect</entry>
</row>
</thead>
! <tbody>
<row>
<entry><statement>Array<T> peteCast (const T1&, const Array<T>& A)</statement></entry>
! <entry>Returns the casting of the array's values to type <type>T1</type>.</entry>
</row>
<row>
<entry><statement>Array<T> where (const Array<T1>& A, const T2& t, const T3& f)</statement></entry>
<entry>Generalizes the <operator>?:</operator> operator,
! returning an array of <varname>t</varname> and
<varname>f</varname> values depending on whether
<varname>A</varname>'s values are true or false,
respectively.</entry>
--- 846,860 ----
<entry>effect</entry>
</row>
</thead>
! <tbody valign="top">
<row>
<entry><statement>Array<T> peteCast (const T1&, const Array<T>& A)</statement></entry>
! <entry>Returns the casting of the &array;'s values to type <type>T1</type>.</entry>
</row>
<row>
<entry><statement>Array<T> where (const Array<T1>& A, const T2& t, const T3& f)</statement></entry>
<entry>Generalizes the <operator>?:</operator> operator,
! returning an &array; of <varname>t</varname> and
<varname>f</varname> values depending on whether
<varname>A</varname>'s values are true or false,
respectively.</entry>
*************** std::cout << A-B << std::endl;
*** 871,878 ****
values. Frequently, operating on a subset is useful. In &pooma;,
a subset of a container's values is called a view. Combining
views and data-parallel expressions will enable us to more
! succinctly and more easily write the diffusion program. Views are
! discussed in the next chapter.</para>
</section>
--- 868,875 ----
values. Frequently, operating on a subset is useful. In &pooma;,
a subset of a container's values is called a view. Combining
views and data-parallel expressions will enable us to more
! succinctly and more easily write the &doof2d; diffusion program.
! Views are discussed in the next chapter.</para>
</section>
*************** std::cout << A-B << std::endl;
*** 885,915 ****
these statements may create and destroy containers holding
intermediate values, slowing execution considerably.
In 1995, Todd <!-- FIXME: Add citations to vandevoorde-95 and
! veldhuizen-95. --> Veldhuizen and David Vandevoorde developed an
! expression-template technique to transform arithmetic expressions
! involving array-like containers into efficient loops without using
! temporaries. Despite its perceived complexity, &pooma;
! incorporated the technology. The framework called &pete, the
! <application>Portable Expression Template Engine</application>
! framework, is also available separately from &pooma; at
! <ulink url="http://www.acl.lanl.gov/pete/"></ulink>.</para>
! <para>In this section, we first describe how a &naive;
implementation may slow execution. Then, we describe &pete;'s
! faster implementation. A data-parallel statement is converted
into a parse tree, rather than immediately evaluating it. The
parse tree has two representations. Its run-time representation
holds run-time values. Its compile-time representation records
the types of the tree's values. After a parse tree for the entire
statement is constructed, it is evaluated. Since it is a
data-parallel statement, this evaluation involves at least one
! loop. At run time, each loop iteration, the value of one
container value is computed and assigned. At compile time, when
the code for the loop iteration is produced, the parse tree's
types are traversed and code is produced without the need for any
intermediate values. We present the implementation in <xref
! linkend="data_parallel-implementation-pete"></xref>, but first we
! explain the difficulties caused by the &naive; implementation.</para>
<section id="data_parallel-implementation-naive">
<title>&naivecap; Implementation</title>
--- 882,913 ----
these statements may create and destroy containers holding
intermediate values, slowing execution considerably.
In 1995, Todd <!-- FIXME: Add citations to vandevoorde-95 and
! veldhuizen-95. --> Veldhuizen and David Vandevoorde each developed
! an expression-template technique to transform arithmetic
! expressions involving array-like containers into efficient loops
! without using temporaries. Despite its perceived complexity,
! &pooma; incorporated the technology. The framework called &pete,
! the <application>Portable Expression Template Engine</application>
! framework, is also available separately from &pooma; at <ulink
! url="http://www.acl.lanl.gov/pete/"></ulink>.</para>
! <para>In this chapter, we first describe how a &naive;
implementation may slow execution. Then, we describe &pete;'s
! faster implementation. &pete; converts a data-parallel statement
into a parse tree, rather than immediately evaluating it. The
parse tree has two representations. Its run-time representation
holds run-time values. Its compile-time representation records
the types of the tree's values. After a parse tree for the entire
statement is constructed, it is evaluated. Since it is a
data-parallel statement, this evaluation involves at least one
! loop. At run time, for each loop iteration, the value of one
container value is computed and assigned. At compile time, when
the code for the loop iteration is produced, the parse tree's
types are traversed and code is produced without the need for any
intermediate values. We present the implementation in <xref
! linkend="data_parallel-implementation-pete"></xref>, but first we
! explain the difficulties caused by the &naive;
! implementation.</para>
<section id="data_parallel-implementation-naive">
<title>&naivecap; Implementation</title>
*************** Array<1, double, Brick> A(I), B(I);
*** 923,933 ****
A = 1.0;
B = 2.0;
A += -A + 2*B;
! std::cout << A << std::endl;
</programlisting> Our goal is to transform the data-parallel
statement <statement>A += -A + 2*B</statement> into a single
! loop, preferably without intermediary containers. To simplify
! notation, let <type>Ar</type> abbreviate the type
<type>Array<1, double, Brick></type>.</para>
<para>Using overloaded arithmetic operators would require using
--- 921,931 ----
A = 1.0;
B = 2.0;
A += -A + 2*B;
! std::cout &openopen; A &openopen; std::endl;
</programlisting> Our goal is to transform the data-parallel
statement <statement>A += -A + 2*B</statement> into a single
! loop, preferably without using intermediary containers. To
! simplify notation, let <type>Ar</type> abbreviate the type
<type>Array<1, double, Brick></type>.</para>
<para>Using overloaded arithmetic operators would require using
*************** std::cout << A << std::endl;
*** 952,967 ****
Template Engine</application> framework, to evaluate
data-parallel statements using efficient loops without
intermediate values. &pete; uses expression-template technology.
! Instead of aggressively evaluating a data-parallel statement's
! subexpressions, it defers evaluation, instead building a parse
! tree of the required computations. The parse tree's type records
! the types of each of its subtrees. Then, the parse tree is
! evaluated using an evaluator determined by the left-hand side's
! type. This container type determines how to loop through its
! domain. Each loop iteration, the corresponding value of the
! right-hand side is evaluated. No intermediate loops or temporary
! values are needed.</para>
<figure float="1" id="data_parallel-implementation-pete-tree_figure">
<title>Annotated Parse Tree for <statement>-A + 2*B</statement></title>
<mediaobject>
--- 950,983 ----
Template Engine</application> framework, to evaluate
data-parallel statements using efficient loops without
intermediate values. &pete; uses expression-template technology.
! Instead of evaluating a data-parallel statement's subexpressions
! at solely at run time, it evaluates the code at both run time and
! at compile time. At compile time, it builds a parse tree of the
! required computations. The parse tree's type records the types
! of each of its subtrees. Then, the parse tree is evaluated at
! compile time using an evaluator determined by the left-hand
! side's type. This container type determines how to loop through
! its domain. Each loop iteration of the resulting run time code,
! the corresponding value of the right-hand side is evaluated. No
! intermediate loops or temporary values are needed.</para>
+ <para>Before explaining the implementation, let us illustrate
+ using our example statement <statement>A += -A + 2*B</statement>.
+ Evaluating the right-hand side creates a parse tree similar to
+ the one in <xref
+ linkend="data_parallel-implementation-pete-tree_figure"></xref>.
+ For example, the overloaded unary minus operator yields a tree
+ node representing <statement>-A</statement>, having a unary-minus
+ function object, and having type
+ <type>Expression<UnaryNode<OpMinus,Ar&closeclose;</type>.
+ The binary nodes continue the construction process yielding a
+ parse tree object for the entire right-hand side and having type
+ <type>Expression<BinaryNode<OpAdd, UnaryNode<OpMinus,
+ Ar>,
+ BinaryNode<OpMultiply<Scalar<int>,Ar&closecloseclose;</type>.
+ Evaluating the left-hand side yields an object
+ representing <varname>A</varname>.</para>
+
<figure float="1" id="data_parallel-implementation-pete-tree_figure">
<title>Annotated Parse Tree for <statement>-A + 2*B</statement></title>
<mediaobject>
*************** std::cout << A << std::endl;
*** 979,1025 ****
</mediaobject>
</figure>
- <para>Before explaining the implementation, let us illustrate
- using our example statement <statement>A += -A + 2*B</statement>.
- Evaluating the right-hand side creates a parse tree similar to
- the one in <xref
- linkend="data_parallel-implementation-pete-tree_figure"></xref>.
- For example, the overloaded unary minus operator yields a tree
- node representing <statement>-A</statement>, having a unary-minus
- function object, and having type
- <type>Expression<UnaryNode<OpMinus,Ar&closeclose;</type>.
- The binary nodes continue the construction process yielding a
- parse tree object for the entire right-hand side and having type
- <type>Expression<BinaryNode<OpAdd, UnaryNode<OpMinus,
- Ar>,
- BinaryNode<OpMultiply<Scalar<int>,Ar&closecloseclose;</type>.
- Evaluating the left-hand side yields an object
- representing <varname>A</varname>.</para>
-
<para>Finally, the assignment operator <statement>+=</statement>
calls the <function>evaluate</function> function corresponding to
the left-hand side's type. At compile time, it produces the code
for the computation. Since this templated function is
specialized on the type of the left-hand side, it generates a
! loop through the left-hand side's container. In the loop body,
! the <function>forEach</function> function produces code for the
! right-hand side expression at a specific position using a
! post-order parse-tree traversal. At a leaf, this evaluation
! queries the leaf's container for a specified value or extracts a
! scalar value. At an interior node, its children's results are
! combined using its function operator. One loop performs the
! entire assignment. It is important to note that the type of the
! entire right-hand side is known at compile time. Thus, all of
! these <function>evaluate</function>,
<function>forEach</function>, and function operator function
calls can be inlined at compile time to yield simple code without
any temporary containers and hopefully as fast as hand-written
loops!</para>
! <para>To implement this scheme, we need &pooma; code to both
! create the parse tree and to evaluate it. We describe parse tree
! creation first. Parse trees consist of leaves,
! <type>UnaryNode</type>s, <type>BinaryNode</type>s, and
<type>TrinaryNode</type>s. Since <type>TrinaryNode</type>s are
similar to <type>BinaryNode</type>s, we omit describing them. A
<type>BinaryNode</type>'s three template parameters correspond to
--- 995,1024 ----
</mediaobject>
</figure>
<para>Finally, the assignment operator <statement>+=</statement>
calls the <function>evaluate</function> function corresponding to
the left-hand side's type. At compile time, it produces the code
for the computation. Since this templated function is
specialized on the type of the left-hand side, it generates a
! loop iterating through the left-hand side's container. To
! produce the loop body, the <function>forEach</function> function
! produces code for the right-hand side expression at a specific
! position using a post-order parse-tree traversal. At a leaf,
! this evaluation queries the leaf's container for a specified
! value or extracts a scalar value. At an interior node, its
! children's results are combined using its function operator. One
! loop performs the entire assignment. It is important to note
! that the type of the entire right-hand side is known at compile
! time. Thus, all of these <function>evaluate</function>,
<function>forEach</function>, and function operator function
calls can be inlined at compile time to yield simple code without
any temporary containers and hopefully as fast as hand-written
loops!</para>
! <para>To implement this scheme, we need &pooma; (really &pete;)
! code to both create the parse tree and to evaluate it. We
! describe parse tree creation first. Parse trees consist of
! leaves, <type>UnaryNode</type>s, <type>BinaryNode</type>s, and
<type>TrinaryNode</type>s. Since <type>TrinaryNode</type>s are
similar to <type>BinaryNode</type>s, we omit describing them. A
<type>BinaryNode</type>'s three template parameters correspond to
*************** std::cout << A << std::endl;
*** 1050,1056 ****
<para><type>BinaryNode</type> does not need to store any
representation of the node's operation. Instead the
! <type>Op</type> type is an empty structure declaring a function
object. For example, <type>OpAdd</type>'s function object is
declared as
<programlisting>
--- 1049,1055 ----
<para><type>BinaryNode</type> does not need to store any
representation of the node's operation. Instead the
! <type>Op</type> type is an empty structure defining a function
object. For example, <type>OpAdd</type>'s function object is
declared as
<programlisting>
*************** struct CreateLeaf<Array<Dim, T, En
*** 1116,1127 ****
<para>Now that we have defined the node classes, the &cc;
arithmetic operators must be overloaded to return the appropriate
! parse tree. For example, unary minus operator
! <function>operator-</function> overloaded to accept an &array;
! argument should create a <type>UnaryNode</type> having an &array;
as its child, which will be a leaf:
<programlisting>
! template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<OpUnaryMinus,
typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
operator-(const Array<D1,T1,E1> & l)
--- 1115,1126 ----
<para>Now that we have defined the node classes, the &cc;
arithmetic operators must be overloaded to return the appropriate
! parse tree. For example, the unary minus operator
! <function>operator-</function> is overloaded to accept an &array;
! argument. It should create a <type>UnaryNode</type> having an &array;
as its child, which will be a leaf:
<programlisting>
! template<int D1,class T1,class E1>
inline typename MakeReturn<UnaryNode<OpUnaryMinus,
typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
operator-(const Array<D1,T1,E1> & l)
*************** operator-(const Array<D1,T1,E1> &a
*** 1144,1183 ****
type from <type>Expression</type>'s internal
<type>Expression_t</type> type.</para>
! <para>Specialized all the operators for &array;s using such
! complicated is likely to be error-prone so &pete; provides a way
! to automate it. Using its <command>MakeOperators</command>
! command with this input:
<programlisting>
! classes
-----
ARG = "int D[n],class T[n],class E[n]"
CLASS = "Array<D[n],T[n],E[n]>"
</programlisting> automatically generates code for all the needed operators.
The <quote>[n]</quote> strings are used to number arguments for binary
and ternary operators.</para>
! <para>Assignment operators must also be specialized for &array;.
Inside the &array; class definition, each such operator just
! invokes the <function>assign</function> function with a corresponding
! function object. For example, <function>operator+=</function>
! invokes <statement>assign(*this, rhs, OpAddAssign())</statement>.
! <varname>rhs</varname> is the parse tree object for the right-hand
! side. Calling this function invokes
! <function>evaluate</function>, which begins the evaluation.</para>
! <para>Before we explain the evaluation, let us summarize the
effect of the code so far described. If we are considering run
! time, parse trees for the left-hand and right-hand sides have been
! constructed. If we are considering compile time, the types of
! these parse trees are known. At compile time, the
! <function>evaluate</function> function described below will
! generate a loop through the left-hand side container's domain.
! The loop's body will have code computing a container's value. At
! run time, this code will read values from containers, but the
! run-time parse tree object itself will not traversed!</para>
! <para>We now explore the evaluation, concentrating on compile
time, not run time. <function>evaluate</function> is an
overloaded function specialized on the type of the left-hand side.
In our example, the left-hand side is a one-dimensional &array;,
--- 1143,1185 ----
type from <type>Expression</type>'s internal
<type>Expression_t</type> type.</para>
! <para>Specializing all the operators for &array;s using such
! complicated functions is likely to be error-prone so &pete;
! provides a way to automate their creation. Using its
! <command>MakeOperators</command> command with this input:
<programlisting>
! classes
-----
ARG = "int D[n],class T[n],class E[n]"
CLASS = "Array<D[n],T[n],E[n]>"
</programlisting> automatically generates code for all the needed operators.
The <quote>[n]</quote> strings are used to number arguments for binary
and ternary operators.</para>
+
! <para>Assignment operators must also be specialized for &array;.
Inside the &array; class definition, each such operator just
! invokes the <function>assign</function> function with a
! corresponding function object. For example,
! <function>operator+=</function> invokes <statement>assign(*this,
! rhs, OpAddAssign())</statement>. <varname>rhs</varname> is the
! parse tree object for the right-hand side. Calling this function
! invokes <function>evaluate</function>, which begins the
! evaluation.</para>
! <para>Before we explain the evaluation, let us summarize the
effect of the code so far described. If we are considering run
! time evaluation, parse trees for the left-hand and right-hand
! sides have been constructed. If we are considering compile time
! evaluation, the types of these parse trees are known. At compile
! time, the <function>evaluate</function> function described below
! will generate a loop iterating through the left-hand side
! container's domain. The loop's body will have code computing a
! container's value. At run time, this code will read values from
! containers, but the run-time parse tree object itself will not
! traversed!</para>
! <para>We now explore the evaluation, concentrating on compile
time, not run time. <function>evaluate</function> is an
overloaded function specialized on the type of the left-hand side.
In our example, the left-hand side is a one-dimensional &array;,
*************** forEach(const Expression& e, const L
*** 1205,1211 ****
nodes, it combines the results using the <type>CombineTag</type>
operator <varname>c</varname>. It inlines into a call to
<programlisting>
! ForEach<Expression, LeafTag, CombineTag>::apply(e, f, c).
</programlisting> The <function>apply</function> function continues
the traversal through the tree. For our example,
<type>LeafTag</type> equals <type>EvalLeaf<1></type>, and
--- 1207,1213 ----
nodes, it combines the results using the <type>CombineTag</type>
operator <varname>c</varname>. It inlines into a call to
<programlisting>
! ForEach<Expression, LeafTag, CombineTag>::apply(e, f, c).
</programlisting> The <function>apply</function> function continues
the traversal through the tree. For our example,
<type>LeafTag</type> equals <type>EvalLeaf<1></type>, and
*************** for (int i = A.domain[0].first(); i < en
*** 1282,1292 ****
code.</para>
<para>&pete;'s expression template technology may be complicated,
! using parse trees and their types, but the code they produce is
! not. Using the technology is also easy. All data-parallel
! statements are automatically converted. In the next chapter, we
! explore views of containers, permitting use of container subsets
! and making data-parallel expressions even more useful.</para>
</section>
</section>
--- 1284,1294 ----
code.</para>
<para>&pete;'s expression template technology may be complicated,
! using parse trees and their types, but the produced code is not.
! Using the technology is also easy. All data-parallel statements
! are automatically converted. In the next chapter, we explore
! views of containers, permitting use of container subsets and
! making data-parallel expressions even more useful.</para>
</section>
</section>
Index: glossary.xml
===================================================================
RCS file: /home/pooma/Repository/r2/docs/manual/glossary.xml,v
retrieving revision 1.8
diff -c -p -r1.8 glossary.xml
*** glossary.xml 2002/01/24 05:11:21 1.8
--- glossary.xml 2002/01/25 02:15:05
***************
*** 11,19 ****
--- 11,21 ----
should finish a sentence. The rest of the definition should
consist of complete sentences. -->
+ <![%unfinished;[
<para>ADD: Make sure all entries are indexed and perhaps point back
to their first use. WARNING: This is constructed by hand so it is
likely to be full of inconsistencies and errors.</para>
+ ]]> <!-- end unfinished -->
<glossdiv id="glossary-a">
<title>A</title>
***************
*** 29,42 ****
<glossentry id="glossary-array">
<glossterm>&array;</glossterm>
<glossdef>
! <para>a &pooma; container generalizing &c; arrays and mapping
! indices to values. Constant-time access to values is supported,
! ignoring the time to compute the values if applicable. &array;s
! are <link linkend="glossary-first_class">first-class
! object</link>s. <link
linkend="glossary-dynamicarray">&dynamicarray;</link>s and <link
linkend="glossary-field">&field;</link>s generalize
&array;.</para>
<glossseealso otherterm="glossary-dynamicarray">&dynamicarray;</glossseealso>
<glossseealso otherterm="glossary-field">&field;</glossseealso>
</glossdef>
--- 31,46 ----
<glossentry id="glossary-array">
<glossterm>&array;</glossterm>
<glossdef>
! <para>a &pooma; <link
! linkend="glossary-container">container</link> generalizing &c;
! arrays and mapping indices to values. Constant-time access to
! values is supported, ignoring the time to compute the values if
! applicable. &array;s are <link
! linkend="glossary-first_class">first-class object</link>s. <link
linkend="glossary-dynamicarray">&dynamicarray;</link>s and <link
linkend="glossary-field">&field;</link>s generalize
&array;.</para>
+ <glossseealso otherterm="glossary-container">container</glossseealso>
<glossseealso otherterm="glossary-dynamicarray">&dynamicarray;</glossseealso>
<glossseealso otherterm="glossary-field">&field;</glossseealso>
</glossdef>
***************
*** 63,82 ****
<glossdef>
<para>a <link linkend="glossary-domain">domain</link> element of
a <link linkend="glossary-field">&field;</link>. Both <link
! linkend="glossary-array">&array;</link> and &field; domain
elements are denoted by indices, but a cell exists in space. For
example, it might be a rectangle or rectangular
parallelepiped.</para>
<glossseealso otherterm="glossary-field">&field;</glossseealso>
</glossdef>
</glossentry>
<glossentry id="glossary-cell_size">
<glossterm>cell size</glossterm>
<glossdef>
! <para>specifies a &field; cell's dimensions e.g., its
width, height, and depth, in &space;. This is frequently
used to specify a mesh.</para>
<glossseealso otherterm="glossary-mesh">mesh</glossseealso>
<glossseealso otherterm="glossary-corner_position">corner position</glossseealso>
</glossdef>
--- 67,90 ----
<glossdef>
<para>a <link linkend="glossary-domain">domain</link> element of
a <link linkend="glossary-field">&field;</link>. Both <link
! linkend="glossary-array">&array;</link> and &field; domain
elements are denoted by indices, but a cell exists in space. For
example, it might be a rectangle or rectangular
parallelepiped.</para>
+ <glossseealso otherterm="glossary-cell_size">cell size</glossseealso>
<glossseealso otherterm="glossary-field">&field;</glossseealso>
+ <glossseealso otherterm="glossary-mesh">mesh</glossseealso>
</glossdef>
</glossentry>
<glossentry id="glossary-cell_size">
<glossterm>cell size</glossterm>
<glossdef>
! <para>specifies a <link linkend="glossary-field">&field;</link>
! <link linkend="glossary-cell">cell</link>'s dimensions e.g., its
width, height, and depth, in &space;. This is frequently
used to specify a mesh.</para>
+ <glossseealso otherterm="glossary-cell">cell</glossseealso>
<glossseealso otherterm="glossary-mesh">mesh</glossseealso>
<glossseealso otherterm="glossary-corner_position">corner position</glossseealso>
</glossdef>
***************
*** 85,99 ****
<glossentry id="glossary-communication_library">
<glossterm>communication library</glossterm>
<glossdef>
! <para>software library passing information among contexts, usually
! using messages.</para>
! <glossseealso otherterm="glossary-distributed">distributed computing environment</glossseealso>
</glossdef>
</glossentry>
<glossentry id="glossary-compilation_time">
<glossterm>compilation time</glossterm>
! <glosssee otherterm="glossary-compilation_time"></glosssee>
</glossentry>
<glossentry id="glossary-compile_time">
--- 93,109 ----
<glossentry id="glossary-communication_library">
<glossterm>communication library</glossterm>
<glossdef>
! <para>software library passing information among <glossterm
! linkend="glossary-context">contexts</glossterm>, usually using
! messages.</para> <glossseealso
! otherterm="glossary-distributed">distributed computing
! environment</glossseealso>
</glossdef>
</glossentry>
<glossentry id="glossary-compilation_time">
<glossterm>compilation time</glossterm>
! <glosssee otherterm="glossary-compile_time"></glosssee>
</glossentry>
<glossentry id="glossary-compile_time">
***************
*** 141,147 ****
<para>domains with the <quote>same shape</quote> so that
corresponding dimensions have the same number of elements.
Scalars, deemed conformable with any domain, get
! <quote>expanded</quote> to the domain's shape. Binary operators
can operate on containers with conformable domains.</para>
<glossseealso otherterm="glossary-conformable_containers">conformable containers</glossseealso>
<glossseealso otherterm="glossary-data_parallel">data parallel</glossseealso>
--- 151,157 ----
<para>domains with the <quote>same shape</quote> so that
corresponding dimensions have the same number of elements.
Scalars, deemed conformable with any domain, get
! <quote>expanded</quote> to the domain's shape. Assignment
can operate on containers with conformable domains.</para>
<glossseealso otherterm="glossary-conformable_containers">conformable containers</glossseealso>
<glossseealso otherterm="glossary-data_parallel">data parallel</glossseealso>
***************
*** 178,184 ****
<glossterm>context</glossterm>
<glossdef>
<para>a collection of shared memory and processors that can execute
! a program of a portion of a program. It can have one or more
processors, but all these processors must access the same shared
memory. Usually the computer and its operating system, not the
programmer, determine the available contexts.</para>
--- 188,194 ----
<glossterm>context</glossterm>
<glossdef>
<para>a collection of shared memory and processors that can execute
! a program or a portion of a program. It can have one or more
processors, but all these processors must access the same shared
memory. Usually the computer and its operating system, not the
programmer, determine the available contexts.</para>
***************
*** 193,198 ****
--- 203,209 ----
<para>indicates how a container's patches are mapped to
processors and shared memory. Two common choices are
distribution among the various processors and replication.</para>
+ <glossseealso otherterm="glossary-context">context</glossseealso>
<glossseealso otherterm="glossary-patch">patch</glossseealso>
</glossdef>
</glossentry>
***************
*** 214,221 ****
<glossentry id="glossary-data_parallel">
<glossterm>data parallel</glossterm>
<glossdef>
! <para>describes an expression representing a subset of a
! container's values. For example,
<statement>sin(&container;)</statement> is an expression
indicating that the <function>sin</function> is applied to each
value in container &container;.</para>
--- 225,232 ----
<glossentry id="glossary-data_parallel">
<glossterm>data parallel</glossterm>
<glossdef>
! <para>describes an expression involving a (non-singleton) subset
! of a container's values. For example,
<statement>sin(&container;)</statement> is an expression
indicating that the <function>sin</function> is applied to each
value in container &container;.</para>
***************
*** 258,264 ****
2stride, …, end}. <varname>end</varname> is in the set
only if it equals <varname>begin</varname> plus some integral
multiple of <varname>stride</varname>. This notation can
! abbreviate most domains. It is extended to multiple dimensions by
separating the dimensions' sets with commas:
[<varname>begin0</varname>:<varname>end0</varname>:<varname>stride0</varname>,<varname>begin1</varname>:<varname>end1</varname>:<varname>stride1</varname>].</para>
<glossseealso otherterm="glossary-domain">domain</glossseealso>
--- 269,275 ----
2stride, …, end}. <varname>end</varname> is in the set
only if it equals <varname>begin</varname> plus some integral
multiple of <varname>stride</varname>. This notation can
! abbreviate many domains. It is extended to multiple dimensions by
separating the dimensions' sets with commas:
[<varname>begin0</varname>:<varname>end0</varname>:<varname>stride0</varname>,<varname>begin1</varname>:<varname>end1</varname>:<varname>stride1</varname>].</para>
<glossseealso otherterm="glossary-domain">domain</glossseealso>
***************
*** 268,279 ****
<glossentry id="glossary-dynamicarray">
<glossterm>&dynamicarray;</glossterm>
<glossdef>
! <para>a &pooma; container generalizing one-dimensional <link
! linkend="glossary-array">&array;</link>s by supporting domain
! resizing at run-time. It maps indices to values in constant-time
! access, ignoring the time to compute the values if applicable.
! &dynamicarray;s are <link
linkend="glossary-first_class">first-class object</link>s.</para>
<glossseealso otherterm="glossary-array">&array;</glossseealso>
<glossseealso otherterm="glossary-field">&field;</glossseealso>
</glossdef>
--- 279,292 ----
<glossentry id="glossary-dynamicarray">
<glossterm>&dynamicarray;</glossterm>
<glossdef>
! <para>a &pooma; <link
! linkend="glossary-container">container</link> generalizing
! one-dimensional <link linkend="glossary-array">&array;</link>s by
! supporting domain resizing at run-time. It maps indices to values
! in constant time, ignoring the time to compute the values if
! applicable. &dynamicarray;s are <link
linkend="glossary-first_class">first-class object</link>s.</para>
+ <glossseealso otherterm="glossary-container">container</glossseealso>
<glossseealso otherterm="glossary-array">&array;</glossseealso>
<glossseealso otherterm="glossary-field">&field;</glossseealso>
</glossdef>
***************
*** 292,298 ****
<glossterm>element wise</glossterm>
<glossdef>
<para>describes accesses to individual values within a container.
! For example, <statement>&container(i,j)</statement> represents one
particular value in the container &container;.</para>
<glossseealso otherterm="glossary-data_parallel">data parallel</glossseealso>
<glossseealso otherterm="glossary-relation">relation</glossseealso>
--- 305,311 ----
<glossterm>element wise</glossterm>
<glossdef>
<para>describes accesses to individual values within a container.
! For example, <statement>&container(-4,3)</statement> represents one
particular value in the container &container;.</para>
<glossseealso otherterm="glossary-data_parallel">data parallel</glossseealso>
<glossseealso otherterm="glossary-relation">relation</glossseealso>
***************
*** 303,314 ****
<glossentry id="glossary-engine">
<glossterm>engine</glossterm>
<glossdef>
! <para>stores and, if necessary, computes a <link
linkend="glossary-container">container</link>'s values. These can
be specialized, e.g., to minimize storage when a domain has few
distinct values. Separating a container and its storage also
permits <link linkend="glossary-view">views</link> of a
container.</para>
<glossseealso otherterm="glossary-container">&engine;</glossseealso>
<glossseealso otherterm="glossary-view">view of a container</glossseealso>
</glossdef>
--- 316,328 ----
<glossentry id="glossary-engine">
<glossterm>engine</glossterm>
<glossdef>
! <para>stores or computes a <link
linkend="glossary-container">container</link>'s values. These can
be specialized, e.g., to minimize storage when a domain has few
distinct values. Separating a container and its storage also
permits <link linkend="glossary-view">views</link> of a
container.</para>
+ <glossseealso otherterm="glossary-brick">&brick; &engine;</glossseealso>
<glossseealso otherterm="glossary-container">&engine;</glossseealso>
<glossseealso otherterm="glossary-view">view of a container</glossseealso>
</glossdef>
***************
*** 362,375 ****
<glossentry id="glossary-field">
<glossterm>&field;</glossterm>
<glossdef>
! <para>a &pooma; container representing an &array; with spatial
! extent. It also supports multiple values and multiple materials
! indexed by the same value. It maps indices to values in constant
! time, ignoring the time to compute the values if applicable. It
! also supports geometric computations such as the distance between
! two <link linkend="glossary-cell">cell</link>s and normals to a
! cell. &field;s are <link
! linkend="glossary-first_class">first-class object</link>s.</para>
<glossseealso otherterm="glossary-array">&array;</glossseealso>
<glossseealso otherterm="glossary-dynamicarray">&dynamicarray;</glossseealso>
</glossdef>
--- 376,394 ----
<glossentry id="glossary-field">
<glossterm>&field;</glossterm>
<glossdef>
! <para>a &pooma; <link
! linkend="glossary-container">container</link> representing an
! &array; with spatial extent. It also supports multiple values and
! multiple materials having the same index. It maps indices to
! values in constant time, ignoring the time to compute the values
! if applicable. It also supports geometric computations such as
! the distance between two <link
! linkend="glossary-cell">cell</link>s and normals to a cell.
! &field;s are <link linkend="glossary-first_class">first-class
! object</link>s.</para>
! <glossseealso otherterm="glossary-container">container</glossseealso>
! <glossseealso otherterm="glossary-cell">cell</glossseealso>
! <glossseealso otherterm="glossary-mesh">mesh</glossseealso>
<glossseealso otherterm="glossary-array">&array;</glossseealso>
<glossseealso otherterm="glossary-dynamicarray">&dynamicarray;</glossseealso>
</glossdef>
***************
*** 379,385 ****
<glossterm>first-class type</glossterm>
<glossdef>
<para>a type of object with all the capabilities of the built-in
! type with the most capabilities. For example, <type>char</type>
and <type>int</type> are first-class types in &cc; because they
may be declared anywhere, stored in automatic variables, accessed
anywhere, copied, and passed by both value and reference.
--- 398,404 ----
<glossterm>first-class type</glossterm>
<glossdef>
<para>a type of object with all the capabilities of the built-in
! type having the most capabilities. For example, <type>char</type>
and <type>int</type> are first-class types in &cc; because they
may be declared anywhere, stored in automatic variables, accessed
anywhere, copied, and passed by both value and reference.
*************** guard layer</glossseealso>
*** 477,483 ****
<glossentry id="glossary-instantiation">
<glossterm>instantiation</glossterm>
! <glosssee>template instantiation</glosssee>
</glossentry>
<glossentry id="glossary-indices">
--- 496,502 ----
<glossentry id="glossary-instantiation">
<glossterm>instantiation</glossterm>
! <glosssee otherterm="glossary-template_instantiation">template instantiation</glosssee>
</glossentry>
<glossentry id="glossary-indices">
*************** guard layer</glossseealso>
*** 559,567 ****
<glossterm>mesh</glossterm>
<glossdef>
<para>a &field;'s map from indices to geometric values such as
! cell size, edge length, and cell normals. In other words, it
specifies a &field;'s <quote>spatial extent</quote>.</para>
<glossseealso otherterm="glossary-field">&field;</glossseealso>
<glossseealso otherterm="glossary-layout">layout</glossseealso>
</glossdef>
</glossentry>
--- 578,589 ----
<glossterm>mesh</glossterm>
<glossdef>
<para>a &field;'s map from indices to geometric values such as
! <link linkend="glossary-cell_size">cell size</link>, edge length, and cell normals. In other words, it
specifies a &field;'s <quote>spatial extent</quote>.</para>
<glossseealso otherterm="glossary-field">&field;</glossseealso>
+ <glossseealso otherterm="glossary-cell">cell</glossseealso>
+ <glossseealso otherterm="glossary-cell_size">cell size</glossseealso>
+ <glossseealso otherterm="glossary-corner_position">corner position</glossseealso>
<glossseealso otherterm="glossary-layout">layout</glossseealso>
</glossdef>
</glossentry>
*************** guard layer</glossseealso>
*** 657,663 ****
linkend="glossary-range">domain triplets</link> [b:e:s], can also
be represented mathematically as an integral interval [b,e] with
stride s, i.e., {a, a+s, a+2s, …, b}. It is
! generalized to &n;-dimensional range as the direct product of
one-dimensional ranges.</para>
<glossseealso otherterm="glossary-stride">stride</glossseealso>
<glossseealso otherterm="glossary-interval">interval</glossseealso>
--- 679,685 ----
linkend="glossary-range">domain triplets</link> [b:e:s], can also
be represented mathematically as an integral interval [b,e] with
stride s, i.e., {a, a+s, a+2s, …, b}. It is
! generalized to an &n;-dimensional range as the direct product of
one-dimensional ranges.</para>
<glossseealso otherterm="glossary-stride">stride</glossseealso>
<glossseealso otherterm="glossary-interval">interval</glossseealso>
*************** guard layer</glossseealso>
*** 665,670 ****
--- 687,702 ----
</glossdef>
</glossentry>
+ <glossentry id="glossary-reference_semantics">
+ <glossterm>reference semantics</glossterm>
+ <glossdef>
+ <para>a copy of an object <varname>o</varname> refers to the
+ object <varname>o</varname> such that changing either one
+ also changes the other. This is the opposite of value
+ semantics.</para>
+ </glossdef>
+ </glossentry>
+
<glossentry id="glossary-relation">
<glossterm>relation</glossterm>
<glossdef>
*************** guard layer</glossseealso>
*** 717,728 ****
<glossentry id="glossary-stencil">
<glossterm>stencil</glossterm>
<glossdef>
! <para>set of values neighboring a container value and a function
using those values to compute it. For example, the stencil in a
! two-dimensional Conway game of life consists of a value's eight
! neighbors and a function that sets the value to
! <quote>live</quote> if it is already live or it has exactly three
! live neighbors.</para>
<glossseealso otherterm="glossary-data_parallel">data parallel</glossseealso>
<glossseealso otherterm="glossary-element_wise">element wise</glossseealso>
<glossseealso otherterm="glossary-relation">relation</glossseealso>
--- 749,760 ----
<glossentry id="glossary-stencil">
<glossterm>stencil</glossterm>
<glossdef>
! <para>set of values neighboring a container index and a function
using those values to compute it. For example, the stencil in a
! two-dimensional Conway game of life consists of an index's eight
! neighbors and a function that sets its value to
! <quote>live</quote> if it is already live and it has two neighbors
! or it has exactly three live neighbors.</para>
<glossseealso otherterm="glossary-data_parallel">data parallel</glossseealso>
<glossseealso otherterm="glossary-element_wise">element wise</glossseealso>
<glossseealso otherterm="glossary-relation">relation</glossseealso>
*************** guard layer</glossseealso>
*** 768,775 ****
</indexterm>
class or function definition having template parameters.
These parameters' values are used at compile time, not run time,
! so they may include types and other compile-time values.
! <!-- FIXME: Strengthen this definition. --></para>
<glossseealso otherterm="glossary-template_instantiation">template instantiation</glossseealso>
<glossseealso otherterm="glossary-template_specialization">template specialization</glossseealso>
</glossdef>
--- 800,806 ----
</indexterm>
class or function definition having template parameters.
These parameters' values are used at compile time, not run time,
! so they may include types and other compile-time values.</para>
<glossseealso otherterm="glossary-template_instantiation">template instantiation</glossseealso>
<glossseealso otherterm="glossary-template_specialization">template specialization</glossseealso>
</glossdef>
*************** guard layer</glossseealso>
*** 788,793 ****
--- 819,825 ----
foo</statement> with the type &double; and the constant
integer 3. Template instantiation is analogous to applying a
function to function arguments.</para>
+ <glossseealso otherterm="glossary-template">template</glossseealso>
</glossdef>
</glossentry>
*************** guard layer</glossseealso>
*** 800,805 ****
--- 832,838 ----
</indexterm>
class or function definition for a particular (special)
subset of template arguments.</para>
+ <glossseealso otherterm="glossary-template">template</glossseealso>
</glossdef>
</glossentry>
*************** guard layer</glossseealso>
*** 843,849 ****
<primary>traits class</primary>
</indexterm>
a class containing one or more traits all describing a particular
! type's chacteristics.</para>
<glossseealso otherterm="glossary-trait">trait</glossseealso>
</glossdef>
</glossentry>
--- 876,882 ----
<primary>traits class</primary>
</indexterm>
a class containing one or more traits all describing a particular
! type's characteristics.</para>
<glossseealso otherterm="glossary-trait">trait</glossseealso>
</glossdef>
</glossentry>
Index: manual.xml
===================================================================
RCS file: /home/pooma/Repository/r2/docs/manual/manual.xml,v
retrieving revision 1.9
diff -c -p -r1.9 manual.xml
*** manual.xml 2002/01/24 05:11:21 1.9
--- manual.xml 2002/01/25 02:15:08
***************
*** 150,155 ****
--- 150,157 ----
<!-- The "Range" domain type. -->
<!ENTITY rangeone "<type>Range<1></type>">
<!-- The "Range<1>" one-dimensional domain type. -->
+ <!ENTITY remote "<type>Remote</type>">
+ <!-- The "Remote" engine type. -->
<!ENTITY replicatedtag "<type>ReplicatedTag</type>">
<!-- The ReplicatedTag Layout type. -->
<!ENTITY stencil "<type>Stencil</type>">
***************
*** 390,417 ****
<para>We begin this chapter by introducing the concept of an engine
and how it is used. Then, we describe the various &engine;s that
&pooma; provides, separating them into engines that store values
! and engines that compute values. Finally, we describe how the
&engine;s are implemented, using tags to differentiate engines and
! reference-counted pointers to their underlying data.</para>
<section id="engines-concept">
<title>The Concept</title>
<para>An engine performs the low-level value storage, computation,
! and element-wise access for a container. The &pooma; &engine;
! class and its specializations implement the concept. An engine
! has a domain and accessor functions returning individual elements.
! Given an index within the domain, an engine's
<methodname>operator()</methodname> function returns the
associated value, which can be used or changed. Its
! <methodname>read</methodname> returns the same value for only use,
! not modification. The acceptable indices are determined by each
! &engine;. Most accept indices specified using ∫ and
! <type>Loc<&dim;></type> parameters, but an &engine; might
! accept string or floating-point parameters. An &engine;'s layout
! specifies maps its domain indices to the processors and memory
! used to store and compute the associated values.</para>
<para>Since an engine's main role is to return the individual
values associated with specific domain indices, any implementation
--- 392,424 ----
<para>We begin this chapter by introducing the concept of an engine
and how it is used. Then, we describe the various &engine;s that
&pooma; provides, separating them into engines that store values
! and engines that compute values.
! <![%unfinished;[
! Finally, we describe how the
&engine;s are implemented, using tags to differentiate engines and
! reference-counted pointers to their underlying data.
! ]]> <!-- end unfinished -->
! </para>
<section id="engines-concept">
<title>The Concept</title>
<para>An engine performs the low-level value storage, computation,
! and element-wise access for a container. An engine has a domain
! and accessor functions returning individual elements. The &pooma;
! &engine; class and its specializations implement the engine
! concept. Given an index within the domain, an &engine;'s
<methodname>operator()</methodname> function returns the
associated value, which can be used or changed. Its
! <methodname>read</methodname> member function returns the same
! value but permitting only use, not modification. The acceptable
! indices are determined by each &engine;. Most accept indices
! specified using ∫ and <type>Loc<&dim;></type>
! parameters, but an &engine; might accept string or floating-point
! parameters. An &engine;'s layout specifies maps its domain
! indices to the processors and memory used to store and compute the
! associated values.</para>
<para>Since an engine's main role is to return the individual
values associated with specific domain indices, any implementation
***************
*** 437,477 ****
object</glossterm> to each value returned by another &engine;. A
<type>CompFwd</type> &engine; projects components from another
&engine;. For example, <type>CompFwd</type> will use the second
! components of each vector in an &array; to form its own &array;.
! Since each container has one or more &engine;s, we can also
describe the latter category as containers that compute their
values using other containers' values. A &multipatch; &engine;
distributes its domain among various processors and memory spaces,
each responsible for computing values associated with a portion,
! or patch, of the domain.</para>
<para>Just as multiple containers can use the same engine,
multiple &engine;s can use the same underlying data. As we
mentioned in <xref linkend="arrays-arrays_use"></xref>, &engine;s
! have reference semantics. So a copy of an &engine; has a
! reference-counted pointer to an &engine;'s data (if any exists).
Thus, copying an &engine; or a container requires little execution
time. If an &engine; has the same data as another &engine; but it
needs its own data to modify, the
! <methodname>makeOwnCopy</methodname> creates such a copy.</para>
<para>&engine;s are rarely explicitly declared. Instead a
! container is declared using an &engine; tag, and the container,
creates the specified &engine; to deal with its values. For
example, a &brick; &engine; is explicitly declared as
<type>Engine<&dim;,T,Brick></type>, but they are more
frequently created by containers, e.g.,
! <type>Array<&dim;,T,Brick></type>. The first two template
! parameters specify the domain's dimensionality and the value type,
! as described in <xref
linkend="arrays-arrays_declarations"></xref>. Unlike container
declarations, the third template parameter, the &engine; tag,
specifies which &engine; specialization to use. For example, the
! &brick; engine tag indicates a brick &engine; should be used.
Some &engine;s, such as <type>CompFwd</type>, are rarely declared
even using &engine; tags. Instead the &array;'s
<methodname>comp</methodname> and
! <methodname>readComp</methodname> methods return views of
containers using <type>CompFwd</type> &engine;s.</para>
</section>
--- 444,487 ----
object</glossterm> to each value returned by another &engine;. A
<type>CompFwd</type> &engine; projects components from another
&engine;. For example, <type>CompFwd</type> will use the second
! components of each &vector; in an &array; to form its own &array;.
! Since each container has at least one &engine;, we can also
describe the latter category as containers that compute their
values using other containers' values. A &multipatch; &engine;
distributes its domain among various processors and memory spaces,
each responsible for computing values associated with a portion,
! or patch, of the domain. The &remote; &engine; also supports
! distributed computation.</para>
<para>Just as multiple containers can use the same engine,
multiple &engine;s can use the same underlying data. As we
mentioned in <xref linkend="arrays-arrays_use"></xref>, &engine;s
! have <glossterm linkend="glossary-reference_semantics">reference
! semantics</glossterm>. A copy of an &engine; has a
! reference-counted pointer to the &engine;'s data (if any exists).
Thus, copying an &engine; or a container requires little execution
time. If an &engine; has the same data as another &engine; but it
needs its own data to modify, the
! <methodname>makeOwnCopy</methodname> member function creates such
! a copy.</para>
<para>&engine;s are rarely explicitly declared. Instead a
! container is declared using an &engine; tag, and the container
creates the specified &engine; to deal with its values. For
example, a &brick; &engine; is explicitly declared as
<type>Engine<&dim;,T,Brick></type>, but they are more
frequently created by containers, e.g.,
! <type>Array<&dim;,T,Brick></type>. An &engine;'s first two
! template parameters specify the domain's dimensionality and the
! value type, as described in <xref
linkend="arrays-arrays_declarations"></xref>. Unlike container
declarations, the third template parameter, the &engine; tag,
specifies which &engine; specialization to use. For example, the
! &brick; &engine; tag indicates a &brick; &engine; should be used.
Some &engine;s, such as <type>CompFwd</type>, are rarely declared
even using &engine; tags. Instead the &array;'s
<methodname>comp</methodname> and
! <methodname>readComp</methodname> member functions return views of
containers using <type>CompFwd</type> &engine;s.</para>
</section>
***************
*** 482,501 ****
<para>In this section, we describe the different types of
&engine;s and illustrate their creation, when appropriate. First,
we describe &engine;s that explicitly store values and then
! &engine;s that compute values.</para>
! <table frame="none" colsep="0" rowsep="0" tocentry="1"
! orient="port" pgwide="0" id="engines-types-table">
! <title>Types of &engine;s</title>
! <tgroup cols="2" align="left">
<thead>
<row>
<entry>&engine; tag</entry>
<entry>description</entry>
</row>
</thead>
! <tbody>
<row rowsep="1">
<entry>&engine;s That Store</entry>
</row>
--- 492,512 ----
<para>In this section, we describe the different types of
&engine;s and illustrate their creation, when appropriate. First,
we describe &engine;s that explicitly store values and then
! &engine;s that compute values. See <xref
! linkend="engines-types-table"></xref>.</para>
! <table frame="none" colsep="0" rowsep="0" tocentry="1"
! orient="port" pgwide="0" id="engines-types-table">
! <title>Types of &engine;s</title>
! <tgroup cols="2" align="left">
<thead>
<row>
<entry>&engine; tag</entry>
<entry>description</entry>
</row>
</thead>
! <tbody valign="top">
<row rowsep="1">
<entry>&engine;s That Store</entry>
</row>
***************
*** 506,512 ****
<row>
<entry>&compressiblebrick;</entry>
<entry>stores all values, reducing storage requirements when
! all values are the same.</entry>
</row>
<row>
<entry>&dynamic;</entry>
--- 517,523 ----
<row>
<entry>&compressiblebrick;</entry>
<entry>stores all values, reducing storage requirements when
! all values are identical.</entry>
</row>
<row>
<entry>&dynamic;</entry>
***************
*** 520,526 ****
<row>
<entry><type>CompFwd</type></entry>
<entry>extracts specified components of an engine's vectors,
! tensors, arrays, etc.; usually created using
<methodname>comp</methodname> container function.</entry>
</row>
<row>
--- 531,537 ----
<row>
<entry><type>CompFwd</type></entry>
<entry>extracts specified components of an engine's vectors,
! tensors, arrays, etc.; usually created using the
<methodname>comp</methodname> container function.</entry>
</row>
<row>
***************
*** 529,535 ****
</row>
<row>
<entry><type>IndexFunction<FunctionObject></type></entry>
! <entry>makes the <type>FunctionObject</type> function of
indices behave like a container.</entry>
</row>
<row>
--- 540,546 ----
</row>
<row>
<entry><type>IndexFunction<FunctionObject></type></entry>
! <entry>makes the <type>FunctionObject</type>'s function of
indices behave like a container.</entry>
</row>
<row>
***************
*** 538,558 ****
data-parallel expressions.</entry>
</row>
<row>
! <entry><type>Stencil<Function,
! Expression></type></entry>
<entry>applies a stencil computation (<type>Function</type>)
! to its input (<type>Expression</type>), usually a container;
! usually created by applying a <type>Stencil</type> object to
! a container. A stencil computation can use multiple
! neighboring input values.</entry>
</row>
<row>
<entry><type>UserFunctionEngine<Function,
Expression></type></entry>
<entry>applies the given function (or <glossterm
linkend="glossary-function_object">function
! object</glossterm>) to its input (<type>Expression</type>),
! usually a container; usually created by applying a
<type>UserFunction</type> object to a container. The
function implements a one-to-one mapping from its input to
values.</entry>
--- 549,568 ----
data-parallel expressions.</entry>
</row>
<row>
! <entry><type>Stencil<Function, Expression></type></entry>
<entry>applies a stencil computation (<type>Function</type>)
! to its input (<type>Expression</type>) which is usually a
! container; usually created by applying a <type>Stencil</type>
! object to a container. A stencil computation can use
! multiple neighboring input values.</entry>
</row>
<row>
<entry><type>UserFunctionEngine<Function,
Expression></type></entry>
<entry>applies the given function (or <glossterm
linkend="glossary-function_object">function
! object</glossterm>) to its input (<type>Expression</type>)
! which is usually a container; usually created by applying a
<type>UserFunction</type> object to a container. The
function implements a one-to-one mapping from its input to
values.</entry>
***************
*** 581,631 ****
</tgroup>
</table>
! <para>&brick; &engine;s explicitly store values just like &c;
arrays. &compressiblebrick; &engine;s optimize their storage
! requirements when all values are the same. Most &array;s use one
of these two &engine;s. &brick;s are the default &engine;s for
! &array; and &field; containers because each of their values are
! explicitly stored. Explicitly storing all an engine's value can
! require a large amount of space, particularly if all these values
! are the same. If all a compressible brick &engine;'s values are
! the same, the engine stores that one value rather than many, many
! copies of the same value. These engines can both save time as
! well as space. Initializing a compressible engine requires
! setting only one value, not every value. Using less storage space
! may permit more useful values to be stored in cache, improving
! cache performance. Reading a value in a compressed &engine; using
! <methodname>read</methodname> is as fast as reading a value in a
! &brick; &engine;, but writing a value always requires an
! additional <keywordname>if</keywordname> conditional. Thus, if an
! &engine; occasionally has multiple different values during its
! life time, a &compressiblebrick; &engine; may be faster than a
! &brick; &engine;. If an &engine; is created and its values are
! mostly read, not written, a &compressiblebrick; &engine; may also
! be faster. Otherwise, a &brick; &engine; may be preferable.
! Timing the same program using the two different &engine; types
! will reveal which is faster for a particular situation.</para>
!
! <para>In distributed computing, many &engine;s may have few
! nonzero values so &compressiblebrick; &engine;s may be preferable.
! For distributed computing, a container's domain is partitioned
! into regions each computed by a separate processor and &engine;.
! If the computation is concentrated in sections of the domain, many
! &engine;s may have few, if any, nonzero values. Thus,
! &compressiblebrick; &engine;s may be preferable for distributed
! computing.</para>
<para>Both &brick; and &compressiblebrick; &engine;s have
<methodname>read</methodname> and
! <methodname>operator()</methodname> members with ∫ and &loc;
! parameters. The parameters should match the &array;'s
dimensionality. For example, if &array; <varname>a</varname> has
dimensionality 3, <function>a.read(int, int, int)</function>
and <function>a(int, int, int)</function> should be used. The
former returns a value that cannot be modified, while the latter
! can be changed. Using the <methodname>read</methodname> can lead
! to faster code. Alternatively, an index can be specified using a
! &loc;. For example,
<statement>a.read(Loc<3>(1,-2,5))</statement> and
<statement>a(Loc<3>(1,-2,5))</statement> are equivalent to
<statement>a.read(1,-2,5))</statement> and
--- 591,642 ----
</tgroup>
</table>
! <!-- FIXME: Place in firstterm. -->
! <para><glossterm linkend="glossary-brick">&brick;
! &engine;s</glossterm> explicitly store values just like &c;
arrays. &compressiblebrick; &engine;s optimize their storage
! requirements when all values are identical. Many &array;s use one
of these two &engine;s. &brick;s are the default &engine;s for
! &array; and &field; containers because they explicitly store each
! value. This explicit storage can require a large amount of space,
! particularly if all these values are the same. If all a
! compressible brick &engine;'s values are identical, the &engine;
! stores that one value rather than many, many copies of the same
! value. These engines can both save time as well as space.
! Initializing a compressible engine requires setting only one
! value, not every value. Using less storage space may also permit
! more useful values to be stored in cache, improving cache
! performance. Reading a value in a compressed &engine; using the
! <methodname>read</methodname> member function is as fast as
! reading a value in a &brick; &engine;, but writing a value always
! requires executing an additional <keywordname>if</keywordname>
! conditional. Thus, if an &engine; infrequently has multiple
! different values during its life time, a &compressiblebrick;
! &engine; may be faster than a &brick; &engine;. If an &engine; is
! created and its values are mostly read, not written, a
! &compressiblebrick; &engine; may also be faster. Otherwise, a
! &brick; &engine; may be preferable. Timing the same program using
! the two different &engine; types will reveal which is faster for a
! particular situation. In distributed computing, many &engine;s
! may have few nonzero values so &compressiblebrick; &engine;s may
! be preferable. For distributed computing, a container's domain is
! partitioned into regions each computed by a separate processor and
! &engine;. If the computation is concentrated in sections of the
! domain, many &engine;s may have few, if any, nonzero values.
! Thus, &compressiblebrick; &engine;s may be preferable for
! distributed computing.</para>
<para>Both &brick; and &compressiblebrick; &engine;s have
<methodname>read</methodname> and
! <methodname>operator()</methodname> member functions taking ∫
! and &loc; parameters. The parameters should match the &array;'s
dimensionality. For example, if &array; <varname>a</varname> has
dimensionality 3, <function>a.read(int, int, int)</function>
and <function>a(int, int, int)</function> should be used. The
former returns a value that cannot be modified, while the latter
! can be changed. Using the <methodname>read</methodname> member
! function can lead to faster code. Alternatively, an index can be
! specified using a &loc;. For example,
<statement>a.read(Loc<3>(1,-2,5))</statement> and
<statement>a(Loc<3>(1,-2,5))</statement> are equivalent to
<statement>a.read(1,-2,5))</statement> and
***************
*** 641,650 ****
<methodname>operator()</methodname> take <type>Loc<1></type>
or one ∫ parameter. In addition, the one-dimensional domain
can be dynamically resized using <methodname>create</methodname>
! and <methodname>destroy</methodname>; see .
! HERE Dynamic. How does one change the domain size? What is the model?</para>
<!-- HERE: Array cannot forward domain size changes to underlying Dynamic Engine. -->
<para>Types of &engine;s:
--- 652,666 ----
<methodname>operator()</methodname> take <type>Loc<1></type>
or one ∫ parameter. In addition, the one-dimensional domain
can be dynamically resized using <methodname>create</methodname>
! and <methodname>destroy</methodname>.
! <![%unfinished;[
! ; see .
! HERE Dynamic. How does one change the domain size? What is the model?
! ]]> <!-- end unfinished -->
! </para>
+ <![%unfinished;[
<!-- HERE: Array cannot forward domain size changes to underlying Dynamic Engine. -->
<para>Types of &engine;s:
*************** HERE Dynamic. How does one change the do
*** 706,711 ****
--- 722,728 ----
types of engines likely to be used by &pooma; programmers and how
to declare containers using them. Should I list the other engines
that are automatically created?</para>
+ ]]> <!-- end unfinished -->
</section>
</chapter>
*************** HERE Dynamic. How does one change the do
*** 729,745 ****
<![%temporary;[
<para>A <glossterm linkend="glossary-view"><firstterm>view of a
! container &container;</firstterm></glossterm> is a container
! accessing a subset of &container;'s domain &containerdomain;
! and values. The subset can include all of &containerdomain;.
! A <quote>view</quote> is so named because it is a different way to
! access, or view, another container's values. Both the container
! and its view share the same underlying engine so changing values in
! one also changes them in the other.</para>
<para>A view is created by following a container's name by
! parentheses containing a domain &containerdomain;. For
! example, consider this code extracted from <xref
linkend="tutorial-array_parallel-doof2d"></xref> in <xref
linkend="tutorial-array_data_parallel"></xref>.
<programlisting>
--- 746,762 ----
<![%temporary;[
<para>A <glossterm linkend="glossary-view"><firstterm>view of a
! container</firstterm></glossterm> is a container accessing a subset
! of &container;'s domain and values. The subset can include all of
! the container's domain. A <quote>view</quote> is so named because
! it is a different way to access, or view, another container's
! values. Both the container and its view share the same underlying
! engine so changing values in one also changes them in the
! other.</para>
<para>A view is created by following a container's name by
! parentheses containing a domain. For example, consider this code
! extracted from <xref
linkend="tutorial-array_parallel-doof2d"></xref> in <xref
linkend="tutorial-array_data_parallel"></xref>.
<programlisting>
*************** a(I,J) = (1.0/9.0) *
*** 922,928 ****
<para>create, copy, and destroy operations (mostly table)</para>
</listitem>
<listitem>
! <para>nonmodifying operations (mostly table)</para>
</listitem>
<listitem>
<para>assignments (mostly table)</para>
--- 939,945 ----
<para>create, copy, and destroy operations (mostly table)</para>
</listitem>
<listitem>
! <para>non-modifying operations (mostly table)</para>
</listitem>
<listitem>
<para>assignments (mostly table)</para>
*************** a(I,J) = (1.0/9.0) *
*** 1082,1088 ****
<entry>description</entry>
</row>
</thead>
! <tbody>
<row>
<entry>&inform; <varname>pinfo</varname></entry>
<entry>output stream used to print informative messages to the
--- 1099,1105 ----
<entry>description</entry>
</row>
</thead>
! <tbody valign="top">
<row>
<entry>&inform; <varname>pinfo</varname></entry>
<entry>output stream used to print informative messages to the
*************** UNFINISHED</para>
*** 1939,1945 ****
<entry>Interpretation</entry>
</row>
</thead>
! <tbody>
<row>
<entry><varname>Dim</varname></entry>
<entry><para>dimension</para></entry>
--- 1956,1962 ----
<entry>Interpretation</entry>
</row>
</thead>
! <tbody valign="top">
<row>
<entry><varname>Dim</varname></entry>
<entry><para>dimension</para></entry>
*************** UNFINISHED</para>
*** 1971,1977 ****
<entry>Interpretation</entry>
</row>
</thead>
! <tbody>
<row>
<entry><fieldsynopsis><varname>This_t</varname></fieldsynopsis></entry>
<entry><para>the &array; object's type</para></entry>
--- 1988,1994 ----
<entry>Interpretation</entry>
</row>
</thead>
! <tbody valign="top">
<row>
<entry><fieldsynopsis><varname>This_t</varname></fieldsynopsis></entry>
<entry><para>the &array; object's type</para></entry>
*************** UNFINISHED</para>
*** 2032,2038 ****
<entry>Effect</entry>
</row>
</thead>
! <tbody>
<row>
<entry>
<constructorsynopsis>
--- 2049,2055 ----
<entry>Effect</entry>
</row>
</thead>
! <tbody valign="top">
<row>
<entry>
<constructorsynopsis>
*************** UNFINISHED</para>
*** 2104,2110 ****
<entry>Effect</entry>
</row>
</thead>
! <tbody>
<row>
<entry>
<methodsynopsis>
--- 2121,2127 ----
<entry>Effect</entry>
</row>
</thead>
! <tbody valign="top">
<row>
<entry>
<methodsynopsis>
*************** UNFINISHED</para>
*** 2187,2193 ****
<entry>Effect</entry>
</row>
</thead>
! <tbody>
<row>
<entry>
<methodsynopsis>
--- 2204,2210 ----
<entry>Effect</entry>
</row>
</thead>
! <tbody valign="top">
<row>
<entry>
<methodsynopsis>
*************** UNFINISHED</para>
*** 2223,2229 ****
<entry>Effect</entry>
</row>
</thead>
! <tbody>
<row>
<entry>
<methodsynopsis>
--- 2240,2246 ----
<entry>Effect</entry>
</row>
</thead>
! <tbody valign="top">
<row>
<entry>
<methodsynopsis>
*************** UNFINISHED</para>
*** 2269,2275 ****
<entry>Effect</entry>
</row>
</thead>
! <tbody>
<row>
<entry>
<methodsynopsis>
--- 2286,2292 ----
<entry>Effect</entry>
</row>
</thead>
! <tbody valign="top">
<row>
<entry>
<methodsynopsis>
*************** UNFINISHED</para>
*** 2307,2313 ****
<entry>Meaning</entry>
</row>
</thead>
! <tbody>
<row>
<entry>
<fieldsynopsis>
--- 2324,2330 ----
<entry>Meaning</entry>
</row>
</thead>
! <tbody valign="top">
<row>
<entry>
<fieldsynopsis>
*************** UNFINISHED</para>
*** 2433,2439 ****
<entry>Value</entry>
</row>
</thead>
! <tbody>
<row>
<entry>
<funcsynopsis>
--- 2450,2456 ----
<entry>Value</entry>
</row>
</thead>
! <tbody valign="top">
<row>
<entry>
<funcsynopsis>
*************** UNFINISHED</para>
*** 2914,2920 ****
<entry>Description</entry>
</row>
</thead>
! <tbody>
<row>
<entry><type>NoMesh<Dim></type></entry>
<entry><para>no physical spacing, causing a &field; to mimic
--- 2931,2937 ----
<entry>Description</entry>
</row>
</thead>
! <tbody valign="top">
<row>
<entry><type>NoMesh<Dim></type></entry>
<entry><para>no physical spacing, causing a &field; to mimic
*************** UNFINISHED</para>
*** 2992,2998 ****
<entry>Description</entry>
</row>
</thead>
! <tbody>
<row>
<entry><para>Brick</para></entry>
<entry><para><literal>Brick</literal></para></entry>
--- 3009,3015 ----
<entry>Description</entry>
</row>
</thead>
! <tbody valign="top">
<row>
<entry><para>Brick</para></entry>
<entry><para><literal>Brick</literal></para></entry>
*************** UNFINISHED</para>
*** 3585,3591 ****
<title>Particles</title>
<para><filename
! class="libraryfile">docs/ParticlesDoc.txt</filename> has
out-of-date information.</para>
<para>See Section 3.2.3 of
--- 3602,3608 ----
<title>Particles</title>
<para><filename
! class="libraryfile">docs/ParticlesDoc.txt</filename> has
out-of-date information.</para>
<para>See Section 3.2.3 of
*************** UNFINISHED</para>
*** 3703,3711 ****
--- 3720,3736 ----
<appendix id="installation">
<title>Obtaining and Installing &pooma;</title>
+ <![%temporary;[
+ <para>In <xref linkend="tutorial-installation"></xref>, we described
+ how to install &pooma;. In the following section, we describe how
+ to install &pooma; to support distributed computation.</para>
+ ]]> <!-- end temporary -->
+
+ <![%unfinished;[
<para>ADD: Write this section, including extensive instructions
for Unix, MS Windows, and MacOS. List the configuration options.
Be sure to describe configuring for parallel execution.</para>
+ ]]> <!-- end unfinished -->
<section id="installation-distributed_computing">
<title>Supporting Distributed Computation</title>
*************** UNFINISHED</para>
*** 3724,3743 ****
<para>&cheetah;, and thus &pooma;, can use Ralf Engelschall's &mm;
Shared Memory Library to pass messages between processors. For
example, the &author; uses this library on a two-processor
! computer running &linux;. The library, available at
! http://www.engelschall.com/sw/mm/, is available for free and has
! been successfully tested on a variety of Unix platforms.</para>
<para>We describe how to download and install the &mm; library.
<orderedlist spacing="compact">
! <listitem>
! <para>Download the library from the &pooma; Download page
! available off the &pooma; home page (&poomahomepage;).</para>
! </listitem>
<listitem>
<para>Extract the source code using <command>tar xzvf
! mm-1.1.3.tar.gz</command>. Move into the resulting source
! code directory <filename
class="directory">mm-1.1.3</filename>.</para>
</listitem>
<listitem>
--- 3749,3770 ----
<para>&cheetah;, and thus &pooma;, can use Ralf Engelschall's &mm;
Shared Memory Library to pass messages between processors. For
example, the &author; uses this library on a two-processor
! computer running &linux;. The library, available at <ulink
! url="http://www.engelschall.com/sw/mm/">http://www.engelschall.com/sw/mm/</ulink>,
! is available for free and has been successfully tested on a
! variety of Unix platforms.</para>
<para>We describe how to download and install the &mm; library.
<orderedlist spacing="compact">
! <listitem>
! <para>Download the library from the &pooma; Download page
! (&poomadownloadpage;) available off the &pooma; home page
! (&poomahomepage;).</para>
! </listitem>
<listitem>
<para>Extract the source code using <command>tar xzvf
! mm-1.1.3.tar.gz</command>. Change directories into the
! resulting source code directory <filename
class="directory">mm-1.1.3</filename>.</para>
</listitem>
<listitem>
*************** UNFINISHED</para>
*** 3754,3763 ****
&dashdash;prefix=${HOME}/pooma/mm-1.1.3</command>.</para>
</listitem>
<listitem>
! <para>Create the library by issuing the <command>make</command>
! command. This compiles the source code using a &c; compiler. To
! use a different compiler than the &mm; configuration chooses, set
! the <envar>CC</envar> to the compiler before configuring.</para>
</listitem>
<listitem>
<para>Optionally test the library by issuing the <command>make
--- 3781,3792 ----
&dashdash;prefix=${HOME}/pooma/mm-1.1.3</command>.</para>
</listitem>
<listitem>
! <para>Create the library by issuing the
! <command>make</command> command. This compiles the source
! code using a &c; compiler. To use a different compiler than
! the &mm; configuration chooses, set the <envar>CC</envar>
! environment variable to the desired compiler before
! configuring.</para>
</listitem>
<listitem>
<para>Optionally test the library by issuing the <command>make
*************** UNFINISHED</para>
*** 3791,3798 ****
<para>&cheetah;'s messaging is implemented using an underlying
messaging library such as the Message Passing Interface (&mpi;)
! Communications Library (FIXME: xref linkend="mpi99", <ulink
! url="http://www-unix.mcs.anl.gov/mpi/"></ulink>) or the &mm;
Shared Memory Library. &mpi; works on a wide variety of platforms
and has achieved widespread usage. &mm; works under Unix on any
computer with shared memory. Both libraries are available for
--- 3820,3831 ----
<para>&cheetah;'s messaging is implemented using an underlying
messaging library such as the Message Passing Interface (&mpi;)
! Communications Library
! <![%unfinished;[
! (FIXME: xref linkend="mpi99", <ulink
! url="http://www-unix.mcs.anl.gov/mpi/"></ulink>)
! ]]> <!-- end unfinished -->
! or the &mm;
Shared Memory Library. &mpi; works on a wide variety of platforms
and has achieved widespread usage. &mm; works under Unix on any
computer with shared memory. Both libraries are available for
*************** UNFINISHED</para>
*** 3803,3814 ****
<orderedlist spacing="compact">
<listitem>
<para>Download the library from the &pooma; Download page
! available off the &pooma; home page (&poomahomepage;).</para>
</listitem>
<listitem>
<para>Extract the source code using <command>tar xzvf
! cheetah-1.0.tgz</command>. Move into the resulting source code
! directory <filename
class="directory">cheetah-1.0</filename>.</para>
</listitem>
<listitem>
--- 3836,3848 ----
<orderedlist spacing="compact">
<listitem>
<para>Download the library from the &pooma; Download page
! (&poomadownloadpage;) available off the &pooma; home page
! (&poomahomepage;).</para>
</listitem>
<listitem>
<para>Extract the source code using <command>tar xzvf
! cheetah-1.0.tgz</command>. Change directories into the
! resulting source code directory <filename
class="directory">cheetah-1.0</filename>.</para>
</listitem>
<listitem>
*************** UNFINISHED</para>
*** 3935,3941 ****
installed &cheetah; library. For
example, <command>declare -x
CHEETAHDIR=${HOME}/pooma/cheetah-1.0</command> specifies the
! installation directory used in the previous section.</para>
</listitem>
<listitem>
<para>When configuring &pooma;, specify the
--- 3969,3977 ----
installed &cheetah; library. For
example, <command>declare -x
CHEETAHDIR=${HOME}/pooma/cheetah-1.0</command> specifies the
! installation directory used in the previous section. If using
! the <application>csh</application> shell, use <command>setenv
! CHEETAHDIR ${HOME}/pooma/cheetah-1.0</command>.</para>
</listitem>
<listitem>
<para>When configuring &pooma;, specify the
*************** UNFINISHED</para>
*** 4137,4142 ****
--- 4173,4180 ----
<!-- Index -->
+ <![%unfinished;[
&genindex.sgm;
+ ]]> <!-- end unfinished -->
</book>
More information about the pooma-dev
mailing list