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

📄 arrays-expr.texi

📁 A C++ class library for scientific computing
💻 TEXI
📖 第 1 页 / 共 3 页
字号:
@end ifnottex@math{A} is a rank 3 tensor (a three dimensional array), @math{B} is a rank2 tensor (a two dimensional array), and @math{C} is a rank 1 tensor (a onedimensional array).  The above expression sets @code{A(i,j,k) = B(i,j) * C(k)}.To implement this product using Blitz++, we'll need the arrays and someindex placeholders:@cindex index placeholders used for tensor notation@exampleArray<float,3> A(4,4,4);Array<float,2> B(4,4);Array<float,1> C(4);firstIndex i;    // Alternately, could just saysecondIndex j;   // using namespace blitz::tensor;thirdIndex k;@end exampleHere's the Blitz++ code which is equivalent to the tensor expression:@exampleA = B(i,j) * C(k);@end exampleThe index placeholder arguments tell an array how to map its dimensions ontothe dimensions of the destination array.  For example, here's somereal-world tensor notation:@tex$$ C^{ijk} = A^{ij} x^{k} - A^{jk} y^{i} $$@end tex@html<pre> ijk    ij k    jk iC    = A  x  - A  y</pre>@end html@ifnottex@ifnothtml@example ijk    ij k    jk iC    = A  x  - A  y@end example@end ifnothtml@end ifnottexIn Blitz++, this would be coded as:@exampleusing namespace blitz::tensor;C = A(i,j) * x(k) - A(j,k) * y(i);@end exampleThis tensor expression can be visualized in the following way:@center @image{tensor1}@center Examples of array indexing, subarrays, and slicing.Here's an example which computes an outer product of two one-dimensionalarrays:@cindex outer product@cindex kronecker product@cindex tensor product@smallexample@include examples/outer.texi@end smallexampleAnd the output:@smallexample@include examples/outer.out@end smallexampleIndex placeholders can @emph{not} be used on the left-hand side of anexpression.  If you need to reorder the indices, you must do this on theright-hand side.In real-world tensor notation, repeated indices imply a contraction (orsummation).  For example, this tensor expression computes a matrix-matrixproduct:@tex$$ C^{ij} = A^{ik} B^{kj} $$@end tex@html<pre> ij    ik  kjC   = A   B</pre>@end html@ifnottex@ifnothtml@example ij    ik  kjC   = A   B@end example@end ifnothtml@end ifnottexThe repeated k index is interpreted as meaning@tex$$ c_{ij} = \sum_{k} a_{ik} b_{kj} $$@end tex@html<pre>c    = sum of {a   * b  } over k ij             ik    kj</pre>@end html@ifnottex@ifnothtml@examplec    = sum of @{a   * b  @} over k ij              ik    kj@end example@end ifnothtml@end ifnottex@cindex contraction@cindex tensor contractionIn Blitz++, repeated indices do @emph{not} imply contraction.  If you wantto contract (sum along) an index, you must use the @code{sum()} function:@exampleArray<float,2> A, B, C;   // ...firstIndex i;secondIndex j;thirdIndex k;C = sum(A(i,k) * B(k,j), k);@end exampleThe @code{sum()} function is an example of an @emph{array reduction},described in the next section.Index placeholders can be used in any order in an expression.  This examplecomputes a kronecker product of a pair of two-dimensional arrays, andpermutes the indices along the way:@exampleArray<float,2> A, B;   // ...Array<float,4> C;      // ...fourthIndex l;C = A(l,j) * B(k,i);@end exampleThis is equivalent to the tensor notation@tex$$ C^{ijkl} = A^{lj} B^{ki} $$@end tex@html<pre> ijkl    lj kiC     = A  B </pre>@end html@ifnottex@ifnothtml@example ijkl    lj kiC     = A  B@end example@end ifnothtml@end ifnottexTensor-like notation can be mixed with other array notations:@exampleArray<float,2> A, B;  // ...Array<double,4> C;    // ...C = cos(A(l,j)) * sin(B(k,i)) + 1./(i+j+k+l);@end example@cindex tensor notation efficiency issuesAn important efficiency note about tensor-like notation: the right-hand sideof an expression is @emph{completely evaluated} for @emph{every} element inthe destination array.  For example, in this code:@exampleArray<float,1> x(4), y(4);Array<float,2> A(4,4):A = cos(x(i)) * sin(y(j));@end exampleThe resulting implementation will look something like this:@examplefor (int n=0; n < 4; ++n)  for (int m=0; m < 4; ++m)    A(n,m) = cos(x(n)) * sin(y(m));@end exampleThe functions @code{cos} and @code{sin} will be invoked sixteen times each.It's possible that a good optimizing compiler could hoist the @code{cos}evaluation out of the inner loop, but don't hold your breath -- there's alot of complicated machinery behind the scenes to handle tensor notation,and most optimizing compilers are easily confused.  In a situation like theabove, you are probably best off manually creating temporaries for@code{cos(x)} and @code{sin(y)} first.@section Array reductions@cindex Array reductions@cindex reductionsCurrently, Blitz++ arrays support two forms of reduction:@itemize @bullet@item      Reductions which transform an array into a scalar (for example,summing the elements).  These are referred to as @strong{completereductions}.@item      Reducing an N dimensional array (or array expression) to an N-1dimensional array expression.  These are called @strong{partial reductions}.@end itemize@cindex Array reductions complete@cindex complete reductions@cindex reductions complete@section Complete reductionsComplete reductions transform an array (or array expression) into a scalar.  Here are some examples:@example Array<float,2> A(3,3);A = 0, 1, 2,    3, 4, 5,    6, 7, 8;cout << sum(A) << endl          // 36     << min(A) << endl          // 0     << count(A >= 4) << endl;  // 5@end exampleHere are the available complete reductions:@table @code@item sum()@cindex @code{sum()} reductionSummation (may be promoted to a higher-precision type)@item product()@cindex @code{product()} reductionProduct @item mean()@cindex @code{mean()} reductionArithmetic mean (promoted to floating-point type if necessary) @item min()@cindex @code{min()} reductionMinimum value @item max()@cindex @code{max()} reductionMaximum value @item minIndex()@cindex @code{minIndex()} reductionIndex of the minimum value (@code{TinyVector<int,N_rank>})@item maxIndex()@cindex @code{maxIndex()} reductionIndex of the maximum value (@code{TinyVector<int,N_rank>})@item count()@cindex @code{count()} reductionCounts the number of times the expression is logical true (@code{int})@item any()@cindex @code{any()} reductionTrue if the expression is true anywhere (@code{bool})@item all()@cindex @code{all()} reductionTrue if the expression is true everywhere (@code{bool})@end table@strong{Note:} @code{minIndex()} and @code{maxIndex()} return TinyVectors, even when the rank of the array (or array expression) is 1.Reductions can be combined with @code{where} expressions (@ref{Where expr})to reduce over some part of an array.  For example, @code{sum(where(A > 0,A, 0))} sums only the positive elements in an array.@section Partial Reductions@cindex Array reductions partial@cindex partial reductions@cindex reductions partialHere's an example which computes the sum of each row of a two-dimensionalarray:@exampleArray<float,2> A;    // ...Array<float,1> rs;   // ...firstIndex i;secondIndex j;rs = sum(A, j);@end exampleThe reduction @code{sum()} takes two arguments:@itemize @bullet@item     The first argument is an array or array expression.@item     The second argument is an index placeholder indicating thedimension over which the reduction is to occur.  @end itemizeReductions have an @strong{important restriction}: It is currently onlypossible to reduce over the @emph{last} dimension of an array or arrayexpression.  Reducing a dimension other than the last would require Blitz++to reorder the dimensions to fill the hole left behind.  For example, inorder for this reduction to work:@exampleArray<float,3> A;   // ...Array<float,2> B;   // ...secondIndex j;// Reduce over dimension 2 of a 3-D array?B = sum(A, j);@end exampleBlitz++ would have to remap the dimensions so that the third dimensionbecame the second.  It's not currently smart enough to do this.However, there is a simple workaround which solves some of the problemscreated by this limitation: you can do the reordering manually, prior to thereduction:@exampleB = sum(A(i,k,j), k);@end exampleWriting @code{A(i,k,j)} interchanges the second and third dimensions,permitting you to reduce over the second dimension.  Here's a list of thereduction operations currently supported:@table @code@item sum()    Summation@item product() Product @item mean()   Arithmetic mean (promoted to floating-point type if necessary)@item min()    Minimum value@item max()    Maximum value@item minIndex() Index of the minimum value (int)@item maxIndex() Index of the maximum value (int)@item count()    Counts the number of times the expression is logical true (int)@item any()      True if the expression is true anywhere (bool)@item all()      True if the expression is true everywhere (bool)@item first()   First index at which the expression is logical true (int); if the expressionis logical true nowhere, then @code{tiny(int())} (INT_MIN) is returned.@item last()     Last index at which the expression is logical true (int); if the expressionis logical true nowhere, then @code{huge(int())} (INT_MAX) is returned.  @end tableThe reductions @code{any()}, @code{all()}, and @code{first()} haveshort-circuit semantics: the reduction will halt as soon as the answer isknown.  For example, if you use @code{any()}, scanning of the expressionwill stop as soon as the first true value is encountered.To illustrate, here's an example:@exampleArray<int, 2> A(4,4);A =  3,   8,   0,   1,     1,  -1,   9,   3,     2,  -5,  -1,   1,     4,   3,   4,   2;Array<float, 1> z;firstIndex i;secondIndex j;z = sum(A(j,i), j);@end exampleThe array @code{z} now contains the sum of @code{A} along each column:@example[ 10    5     12    7 ]@end exampleThis table shows what the result stored in @code{z} would be if@code{sum()} were replaced with other reductions:@examplesum                     [         10         5        12         7 ]mean                    [        2.5      1.25         3      1.75 ]min                     [          1        -5        -1         1 ]minIndex                [          1         2         2         0 ]max                     [          4         8         9         3 ]maxIndex                [          3         0         1         1 ]first((A < 0), j)       [ -2147483648        1         2 -2147483648 ]product                 [         24       120         0         6 ]count((A(j,i) > 0), j)  [          4         2         2         4 ]any(abs(A(j,i)) > 4, j) [          0         1         1         0 ]all(A(j,i) > 0, j)      [          1         0         0         1 ]@end exampleNote: the odd numbers for first() are @code{tiny(int())} i.e.@: the smallestnumber representable by an int.  The exact value is machine-dependent.@cindex Array reductions chaining@cindex partial reductions chaining@cindex reductions chainingThe result of a reduction is an array expression, so reductionscan be used as operands in an array expression:@exampleArray<int,3> A;Array<int,2> B;Array<int,1> C;   // ...secondIndex j;thirdIndex k;B = sqrt(sum(sqr(A), k));// Do two reductions in a rowC = sum(sum(A, k), j);@end exampleNote that this is not allowed:@exampleArray<int,2> A;firstIndex i;secondIndex j;// Completely sum the array?int result = sum(sum(A, j), i);@end exampleYou cannot reduce an array to zero dimensions!  Instead, use one of theglobal functions described in the previous section.@node Where expr@section where statements@cindex @code{where} statements@cindex functional if (@code{where})@cindex @code{if} (@code{where})Blitz++ provides the @code{where} function as an array expression version of the@code{( ? : )} operator.  The syntax is:@examplewhere(array-expr1, array-expr2, array-expr3)@end exampleWherever @code{array-expr1} is true, @code{array-expr2} is returned.  Where@code{array-expr1} is false, @code{array-expr3} is returned.  For example,suppose we wanted to sum the squares of only the positive elements of anarray.  This can be implemented using a where function:@exampledouble posSquareSum = sum(where(A > 0, pow2(A), 0));@end example

⌨️ 快捷键说明

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