Difference between revisions of "Flatten"

m (4.7 -> 5.0)
(Examples - Multi-D transforming function and Multi-D reducing function)
Line 19: Line 19:
 
== Examples ==
 
== Examples ==
  
TBD
+
=== Applying a 1-D [[array-reducing functions|array-reducing function]] across multiple dimensions ===
 +
 
 +
[[:category:Array-reducing functions|Many array-reducing functions]] operate over one index and return a scalar result. For example, <code>[[Median]](a, I)</code> computes the median of a data set along index <code>I</code>. Suppose you have a 2-D array, and you want the median value across both indexes. This is an example where you need to force a 1-D array-reducing function to operate over two or more indexes. This can be accomplished by flattening the array and then applying the array-reducing function.
 +
 
 +
:<code>A := </code>[[image:Two-D Rank input.png]]
 +
 
 +
:<code>[[Var]] b:=[[Flatten]](A, In1, In2) Do [[Median]](b, b.K)</code> &rarr; 46
 +
 
 +
This method easily generalizes to more than two indexes, e.g., for four indexes:
 +
:<code>[[Var]] b:=[[Flatten]](A, In1, In2, In3, In4) Do [[Median]](b, b.K)</code>
 +
 
 +
To apply the reducing function over all indexes of the array, without knowing the number of indexes in advance, use [[Repeated parameter forwarding]], e.g.,
 +
:<code>[[Var]] b:=[[Flatten]](A, ...[[IndexesOf]](A)) Do [[Median]](b, b.K)</code>
 +
 
 +
Many built-in array-reducing functions (including [[Sum]], [[Max]], [[Min]], [[Product]], [[Average]]) already accept multiple indexes, making this technique unnecessary. With these you can just list the indexes to reduce over, e.g., <code>[[Sum]](A, In1, In2, In3)</code>.
 +
 
 +
=== Applying a 1-D [[Transforming functions|transforming function]] across multiple dimensions ===
 +
 
 +
Situations sometime arise where you would like to apply [[:category:Transforming functions|an existing transforming function]] to a multidimensional array, such that the transformation should simultaneously operate over two or more indexes, but the existing function was created to operate over a single index.  A transformation function is a function that takes an array as input, and produces an array having the same dimensions as the input.
 +
 
 +
One example is the [[Rank]] function, which operates over a single index. Suppose you want to apply it over 2 or more dimensions. You can do this by flattening the input array, applying [[Rank]] to the flattened 1-D result and then unflattening the result.
 +
 
 +
:<code>A := </code>[[image:Two-D Rank input.png]]
 +
 
 +
:<code>[[Var]] b := [[Flatten]]( A, In1, In2 ) Do [[Unflatten]]( [[Rank]]( b, b.K ), b.K, In1, In2 )</code> &rarr;
 +
:::[[image:Two-D Rank Result.png]]
 +
 
 +
Notice that the smallest cell in the input has a rank of 1, and the largest value has a rank of 25.
 +
 
 +
The above example does a 2-D Rank calculation, and the same idea could be used for a 3-D (and so on) rank, e.g.,
 +
:<code>[[Var]] b := [[Flatten]]( A, In1, In2, In3 ) Do [[Unflatten]]( [[Rank]]( b, b.K ), b.K, In1, In2, In3 )</code>
 +
 
 +
This can be generalized to a [[User-Defined Function]] that works with any number of dimensions, by using [[Repeated parameter forwarding]] as follows.
 +
 
 +
:<code>[[User-Defined Function|Function]] RankMultiD( a : Array[I] ; I : ... index )</code>
 +
:'''Definition:''' <code>[[Var]] b := [[Flatten]]( a, ...I ) Do [[Unflatten]]( [[Rank]]( b, b.K ), b.K, ...I )</code>
 +
 
 +
You can use this function to compute [[Rank]] over three dimensions as
 +
:<code>RankMultiD( A, In1, In2, In3 )</code>
 +
Or, you can use this to compute the rank over all indexes of <code>A</code>, without knowing in advance what they are, using [[Repeated parameter forwarding]] as
 +
:<code>RankMultiD( A, ...[[IndexesOf]](A) )</code>
  
 
==History==
 
==History==

Revision as of 17:57, 10 June 2016

new to Analytica 5.0

Flatten(x, I..., resultIndex)

Flattens the cells of a multi-dimensional array into a one-dimensional vector.

You should usually specify the indexes of «x» that you want to flatten over. For example, Flatten(x, In1, In2, In3) returns a one-dimensional array having the same values as the 3-dimensional array «x». The indexes listed first vary the slowest.

If you already have a result index, K for the final result, specify it by name using

Flatten(x, In1, In2, In3, resultIndex: K)

If you omit «resultIndex», a local index is created for you with the name .K. If your «resultIndex» is shorter than the number of cells, the flattened result is truncated, or if it is too long the result is null-padded.

Because a local index is created for the result, to define an index from the result of Flatten, you should surround it in CopyIndex(...).

If you omit «I» (the indexes to flatten), then all indexes of «x» are used, but you don't have explicit control over what order is used.

Examples

Applying a 1-D array-reducing function across multiple dimensions

Many array-reducing functions operate over one index and return a scalar result. For example, Median(a, I) computes the median of a data set along index I. Suppose you have a 2-D array, and you want the median value across both indexes. This is an example where you need to force a 1-D array-reducing function to operate over two or more indexes. This can be accomplished by flattening the array and then applying the array-reducing function.

A := Two-D Rank input.png
Var b:=Flatten(A, In1, In2) Do Median(b, b.K) → 46

This method easily generalizes to more than two indexes, e.g., for four indexes:

Var b:=Flatten(A, In1, In2, In3, In4) Do Median(b, b.K)

To apply the reducing function over all indexes of the array, without knowing the number of indexes in advance, use Repeated parameter forwarding, e.g.,

Var b:=Flatten(A, ...IndexesOf(A)) Do Median(b, b.K)

Many built-in array-reducing functions (including Sum, Max, Min, Product, Average) already accept multiple indexes, making this technique unnecessary. With these you can just list the indexes to reduce over, e.g., Sum(A, In1, In2, In3).

Applying a 1-D transforming function across multiple dimensions

Situations sometime arise where you would like to apply an existing transforming function to a multidimensional array, such that the transformation should simultaneously operate over two or more indexes, but the existing function was created to operate over a single index. A transformation function is a function that takes an array as input, and produces an array having the same dimensions as the input.

One example is the Rank function, which operates over a single index. Suppose you want to apply it over 2 or more dimensions. You can do this by flattening the input array, applying Rank to the flattened 1-D result and then unflattening the result.

A := Two-D Rank input.png
Var b := Flatten( A, In1, In2 ) Do Unflatten( Rank( b, b.K ), b.K, In1, In2 )
Two-D Rank Result.png

Notice that the smallest cell in the input has a rank of 1, and the largest value has a rank of 25.

The above example does a 2-D Rank calculation, and the same idea could be used for a 3-D (and so on) rank, e.g.,

Var b := Flatten( A, In1, In2, In3 ) Do Unflatten( Rank( b, b.K ), b.K, In1, In2, In3 )

This can be generalized to a User-Defined Function that works with any number of dimensions, by using Repeated parameter forwarding as follows.

Function RankMultiD( a : Array[I] ; I : ... index )
Definition: Var b := Flatten( a, ...I ) Do Unflatten( Rank( b, b.K ), b.K, ...I )

You can use this function to compute Rank over three dimensions as

RankMultiD( A, In1, In2, In3 )

Or, you can use this to compute the rank over all indexes of A, without knowing in advance what they are, using Repeated parameter forwarding as

RankMultiD( A, ...IndexesOf(A) )

History

See Also

Comments


You are not allowed to post comments.