📄 blitz_2.html
字号:
</UL><P>Indexing, subarrays and slicing all use the overloaded parenthesis<CODE>operator()</CODE>.</P><P>As a running example, we'll consider the three dimensional array picturedbelow, which has index ranges (0..7, 0..7, 0..7). Shaded portions of thearray show regions which have been obtained by indexing, creating asubarray, and slicing.</P><P><center> <CENTER><IMG SRC="slice.gif" ALT="slice"></CENTER></center><center> Examples of array indexing, subarrays, and slicing.</center></P><P><HR SIZE="6"><A NAME="SEC52"></A><TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0><TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC51"> < </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC53"> > </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC34"> << </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC34"> Up </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_3.html#SEC80"> >> </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz.html#SEC_Top">Top</A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_toc.html#SEC_Contents">Contents</A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_abt.html#SEC_About"> ? </A>]</TD></TR></TABLE><H3> 2.4.1 Indexing </H3><!--docid::SEC52::--><P>There are two ways to get a single element from an array. The simplest isto provide a set of integer operands to <CODE>operator()</CODE>:</P><P><TABLE><tr><td> </td><td class=example><pre>A(7,0,0) = 5; cout << "A(7,0,0) = " << A(7,0,0) << endl;</pre></td></tr></table></P><P>This version of indexing is available for arrays of rank one through eleven.If the array object isn't <CODE>const</CODE>, the return type of<CODE>operator()</CODE> is a reference; if the array object is <CODE>const</CODE>, thereturn type is a value.</P><P>You can also get an element by providing an operand of type<CODE>TinyVector<int,N_rank></CODE> where <CODE>N_rank</CODE> is the rank of the arrayobject:</P><P><TABLE><tr><td> </td><td class=example><pre>TinyVector<int,3> index;index = 7, 0, 0;A(index) = 5;cout << "A(7,0,0) = " << A(index) << endl;</pre></td></tr></table></P><P>This version of <CODE>operator()</CODE> is also available in a const-overloadedversion.</P><P>It's possible to use fewer than <CODE>N_rank</CODE> indices. However, missingindices are <STRONG>assumed to be zero</STRONG>, which will cause bounds errors ifthe valid index range does not include zero (e.g. Fortran arrays). For thisreason, and for code clarity, it's a bad idea to omit indices.</P><P><HR SIZE="6"><A NAME="SEC53"></A><TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0><TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC52"> < </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC54"> > </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC54"> << </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC34"> Up </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_3.html#SEC80"> >> </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz.html#SEC_Top">Top</A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_toc.html#SEC_Contents">Contents</A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_abt.html#SEC_About"> ? </A>]</TD></TR></TABLE><H3> 2.4.2 Subarrays </H3><!--docid::SEC53::--><P>You can obtain a subarray by providing <CODE>Range</CODE> operands to<CODE>operator()</CODE>. A <CODE>Range</CODE> object represents a set of regularlyspaced index values. For example,</P><P><TABLE><tr><td> </td><td class=example><pre>Array<int,3> B = A(Range(5,7), Range(5,7), Range(0,2));</pre></td></tr></table></P><P>The object B now refers to elements (5..7,5..7,0..2) of the array A.</P><P>The returned subarray is of type <CODE>Array<T_numtype,N_rank></CODE>. This meansthat subarrays can be used wherever arrays can be: in expressions, aslvalues, etc. Some examples:</P><P><TABLE><tr><td> </td><td class=example><pre>// A three-dimensional stencil (used in solving PDEs)Range I(1,6), J(1,6), K(1,6);B = (A(I,J,K) + A(I+1,J,K) + A(I-1,J,K) + A(I,J+1,K) + A(I,J-1,K) + A(I,J+1,K) + A(I,J,K+1) + A(I,J,K-1)) / 7.0;// Set a subarray of A to zeroA(Range(5,7), Range(5,7), Range(5,7)) = 0.;</pre></td></tr></table></P><P>The bases of the subarray are equal to the bases of the original array:</P><P><TABLE><tr><td> </td><td class=example><pre>Array<int,2> D(Range(1,5), Range(1,5)); // 1..5, 1..5Array<int,2> E = D(Range(2,3), Range(2,3)); // 1..2, 1..2</pre></td></tr></table></P><P>An array can be used on both sides of an expression only if the subarraysdon't overlap. If the arrays overlap, the result may depend on the order inwhich the array is traversed. </P><P><HR SIZE="6"><A NAME="SEC54"></A><TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0><TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC53"> < </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC55"> > </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC55"> << </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC34"> Up </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_3.html#SEC80"> >> </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz.html#SEC_Top">Top</A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_toc.html#SEC_Contents">Contents</A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_abt.html#SEC_About"> ? </A>]</TD></TR></TABLE><H3> 2.4.3 RectDomain and StridedDomain </H3><!--docid::SEC54::--><P>The classes <CODE>RectDomain</CODE> and <CODE>StridedDomain</CODE>, defined in<CODE>blitz/domain.h</CODE>, offer a dimension-independent notation for subarrays.</P><P><CODE>RectDomain</CODE> and <CODE>StridedDomain</CODE> can be thought of as a<CODE>TinyVector<Range,N></CODE>. Both have a vector of lower- and upper-bounds;<CODE>StridedDomain</CODE> has a stride vector. For example, the subarray:</P><P><TABLE><tr><td> </td><td class=example><pre>Array<int,2> B = A(Range(4,7), Range(8,11)); // 4..7, 8..11</pre></td></tr></table></P><P>could be obtained using <CODE>RectDomain</CODE> this way:</P><P><TABLE><tr><td> </td><td class=example><pre>TinyVector<int,2> lowerBounds(4, 8);TinyVector<int,2> upperBounds(7, 11);RectDomain<2> subdomain(lowerBounds, upperBounds);Array<int,2> B = A(subdomain);</pre></td></tr></table></P><P>Here are the prototypes of <CODE>RectDomain</CODE> and <CODE>StridedDomain</CODE>.</P><P><TABLE><tr><td> </td><td class=example><pre>template<int N_rank>class RectDomain {public: RectDomain(const TinyVector<int,N_rank>& lbound, const TinyVector<int,N_rank>& ubound); const TinyVector<int,N_rank>& lbound() const; int lbound(int i) const; const TinyVector<int,N_rank>& ubound() const; int ubound(int i) const; Range operator[](int rank) const; void shrink(int amount); void shrink(int dim, int amount); void expand(int amount); void expand(int dim, int amount);};template<int N_rank>class StridedDomain {public: StridedDomain(const TinyVector<int,N_rank>& lbound, const TinyVector<int,N_rank>& ubound, const TinyVector<int,N_rank>& stride); const TinyVector<int,N_rank>& lbound() const; int lbound(int i) const; const TinyVector<int,N_rank>& ubound() const; int ubound(int i) const; const TinyVector<int,N_rank>& stride() const; int stride(int i) const; Range operator[](int rank) const; void shrink(int amount); void shrink(int dim, int amount); void expand(int amount); void expand(int dim, int amount);};</pre></td></tr></table></P><P><A NAME="Slicing combo"></A><HR SIZE="6"><A NAME="SEC55"></A><TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0><TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC54"> < </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC56"> > </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC51"> << </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC34"> Up </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC59"> >> </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz.html#SEC_Top">Top</A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_toc.html#SEC_Contents">Contents</A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_abt.html#SEC_About"> ? </A>]</TD></TR></TABLE><H3> 2.4.4 Slicing </H3><!--docid::SEC55::--><P>A combination of integer and Range operands produces a <STRONG>slice</STRONG>. Eachinteger operand reduces the rank of the array by one. For example:</P><P><TABLE><tr><td> </td><td class=example><pre>Array<int,2> F = A(Range::all(), 2, Range::all());Array<int,1> G = A(2, 7, Range::all());</pre></td></tr></table></P><P>Range and integer operands can be used in any combination, for arraysup to rank 11.</P><P><STRONG>Note:</STRONG> Using a combination of integer and Range operands requires anewer language feature (partial ordering of member templates) which not allcompilers support. If your compiler does provide this feature,<CODE>BZ_PARTIAL_ORDERING</CODE> will be defined in <CODE><blitz/config.h></CODE>. Ifnot, you can use this workaround:</P><P><TABLE><tr><td> </td><td class=example><pre>Array<int,3> F = A(Range::all(), Range(2,2), Range::all());Array<int,3> G = A(Range(2,2), Range(7,7), Range::all());</pre></td></tr></table></P><P><HR SIZE="6"><A NAME="SEC56"></A><TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0><TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC55"> < </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC57"> > </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC57"> << </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_2.html#SEC34"> Up </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_3.html#SEC80"> >> </A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz.html#SEC_Top">Top</A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_toc.html#SEC_Contents">Contents</A>]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="blitz_abt.html#SEC_About"> ? </A>]</TD></TR></TABLE><H3> 2.4.5 More about Range objects </H3><!--docid::SEC56::--><P>A <CODE>Range</CODE> object represents an ordered set of uniformly spacedintegers. Here are some examples of using Range objects to obtainsubarrays:</P><P><TABLE><tr><td> </td><td class=smallexample><FONT SIZE=-1><pre>#include <blitz/array.h>using namespace blitz;int main(){ Array<int,1> A(7); A = 0, 1, 2, 3, 4, 5, 6; cout << A(Range::all()) << endl // [ 0 1 2 3 4 5 6 ] << A(Range(3,5)) << endl // [ 3 4 5 ] << A(Range(3,toEnd)) << endl // [ 3 4 5 6 ] << A(Range(fromStart,3)) << endl // [ 0 1 2 3 ] << A(Range(1,5,2)) << endl // [ 1 3 5 ] << A(Range(5,1,-2)) << endl // [ 5 3 1 ]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -