⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arrays-indirect.texi

📁 A C++ class library for scientific computing
💻 TEXI
字号:
@cindex indirection@cindex Array indirection@strong{Indirection} is the ability to modify or access an array at a set ofselected index values.  Blitz++ provides several forms of indirection: @itemize @bullet@item  @strong{Using a list of array positions}: this approach is usefulif you need to modify an array at a set of scattered points.@item  @strong{Cartesian-product indirection}: as an example, for atwo-dimensional array you might have a list @code{I} of rows and a list@code{J} of columns, and you want to modify the array at all (i,j) positionswhere i is in @code{I} and j is in @code{J}.  This is a @strong{cartesianproduct} of the index sets @code{I} and @code{J}.@item  @strong{Over a set of strips}: for efficiency, you can represent anarbitrarily-shaped subset of an array as a list of one-dimensional strips.This is a useful way of handling @strong{Regions Of Interest} (ROIs).@end itemize@center @image{indirect}@center Three styles of indirection. @footnote{From top to bottom: (1) using a list of array positions; (2) Cartesian-product indirection; (3) using a set of strips to represent an arbitrarily-shaped subset of an array.}@cindex STL, for indirectionIn all cases, Blitz++ expects a Standard Template Library container.  Someuseful STL containers are @code{list<>}, @code{vector<>}, @code{deque<>} and@code{set<>}.  Documentation of these classes is often provided with yourcompiler, or see also the good documentation at@uref{http://www.sgi.com/Technology/STL/}.  STL containers are used becausethey are widely available and provide easier manipulation of ``sets'' thanBlitz++ arrays.  For example, you can easily expand and merge sets which arestored in STL containers; doing this is not so easy with Blitz++ arrays,which are designed for numerical work.STL containers are generally included by writing@example#include <list>   // for list<>#include <vector> // for vector<>#include <deque>  // for deque<>#include <set>    // for set<>@end example@cindex [] operator, for indirectionThe @code{[]} operator is overloaded on arrays so that the syntax@code{array[container]} provides an indirect view of the array.  So far,this indirect view may only be used as an lvalue (i.e.@: on the left-hand sideof an assignment statement).The examples in the next sections are available in the Blitz++ distributionin @file{<examples/indirect.cpp>}.@section Indirection using lists of array positions@cindex Array indirection list of positions@cindex indirection list of positionsThe simplest kind of indirection uses a list of points.  For one-dimensionalarrays, you can just use an STL container of integers.  Example:@example  Array<int,1> A(5), B(5);  A = 0;  B = 1, 2, 3, 4, 5;  vector<int> I;  I.push_back(2);  I.push_back(4);  I.push_back(1);  A[I] = B;@end exampleAfter this code, the array A contains @code{[ 0 2 3 0 5 ]}.Note that arrays on the right-hand-side of the assignment must have the sameshape as the array on the left-hand-side (before indirection).  In thestatement @code{A[I] = B}, A and B must have the same shape, not I and B.For multidimensional arrays, you can use an STL container of@code{TinyVector<int,N_rank>} objects.  Example:@example  Array<int,2> A(4,4), B(4,4);  A = 0;  B = 10*tensor::i + tensor::j;  typedef TinyVector<int,2> coord;  list<coord> I;  I.push_back(coord(1,1));  I.push_back(coord(2,2));  A[I] = B;@end exampleAfter this code, the array A contains:@example  0   0   0   0  0  11   0   0  0   0  22   0  0   0   0   0@end example(The @code{tensor::i} notation is explained in the section on indexplaceholders @ref{Index placeholders}).@section Cartesian-product indirection@cindex Array indirection Cartesian-product@cindex indirection Cartesian-productThe Cartesian product of the sets I, J and K is the set of (i,j,k) tuplesfor which i is in I, j is in J, and k is in K.  Blitz++ implements cartesian-product indirection using an @strong{adaptor}which takes a set of STL containers and iterates through their Cartesianproduct.  Note that the cartesian product is never explicitly created.  Youcreate the Cartesian-product adaptor by calling the function:@exampletemplate<class T_container>indexSet(T_container& c1, T_container& c2, ...)@end exampleThe returned adaptor can then be used in the @code{[]} operator of an arrayobject.Here is a two-dimensional example:@cindex rank-1 update@example  Array<int,2> A(6,6), B(6,6);  A = 0;  B = 10*tensor::i + tensor::j;  vector<int> I, J;  I.push_back(1);  I.push_back(2);  I.push_back(4);  J.push_back(0);  J.push_back(2);  J.push_back(5);  A[indexSet(I,J)] = B;@end exampleAfter this code, the A array contains:@example 0   0   0   0   0   010   0  12   0   0  1520   0  22   0   0  25 0   0   0   0   0   040   0  42   0   0  45 0   0   0   0   0   0@end exampleAll the containers used in a cartesian product must be the same type (e.g.all @code{vector<int>} or all @code{set<TinyVector<int,2> >}), but they maybe different sizes.  Singleton containers (containers containing a singlevalue) are fine.@section Indirection with lists of strips@cindex Array indirection list of strips@cindex indirection list of stripsYou can also do indirection with a container of one-dimensional@strong{strips}.  This is useful when you want to manipulate somearbitrarily-shaped, well-connected subdomain of an array.  By representingthe subdomain as a list of strips, you allow Blitz++ to operate on vectors,rather than scattered points; this is much more efficient.@findex RectDomain<N>Strips are represented by objects of type @code{RectDomain<N>}, where@code{N} is the dimensionality of the array.  The @code{RectDomain<N>} classcan be used to represent any rectangular subdomain, but for indirection itis only used to represent strips.You create a strip by using this function:@findex strip()@exampleRectDomain<N> strip(TinyVector<int,N> start,                    int stripDimension, int ubound);@end exampleThe @code{start} parameter is where the strip starts; @code{stripDimension}is the dimension in which the strip runs; @code{ubound} is the last indexvalue for the strip.  For example, to create a 2-dimensional strip from(2,5) to (2,9), one would write:@exampleTinyVector<int,2> start(2,5);RectDomain<2> myStrip = strip(start,secondDim,9);@end exampleHere is a more substantial example which creates a list of stripsrepresenting a circle subset of an array:@example  const int N = 7;  Array<int,2> A(N,N), B(N,N);  typedef TinyVector<int,2> coord;  A = 0;  B = 1;  double centre_i = (N-1)/2.0;  double centre_j = (N-1)/2.0;  double radius = 0.8 * N/2.0;  // circle will contain a list of strips which represent a circular  // subdomain.  list<RectDomain<2> > circle;  for (int i=0; i < N; ++i)  @{    double jdist2 = pow2(radius) - pow2(i-centre_i);    if (jdist2 < 0.0)      continue;    int jdist = int(sqrt(jdist2));    coord startPos(i, int(centre_j - jdist));    circle.push_back(strip(startPos, secondDim, int(centre_j + jdist)));  @}  // Set only those points in the circle subdomain to 1  A[circle] = B;@end exampleAfter this code, the A array contains:@example  0  0  0  0  0  0  0  0  0  1  1  1  0  0  0  1  1  1  1  1  0  0  1  1  1  1  1  0  0  1  1  1  1  1  0  0  0  1  1  1  0  0  0  0  0  0  0  0  0@end example

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -