Difference between revisions of "Associative vs. Positional Indexing"

Line 30: Line 30:
  
 
Positions in Analytica are always 1-based, and range from 1 to [[Size]](I).
 
Positions in Analytica are always 1-based, and range from 1 to [[Size]](I).
 +
 +
For text elements, associational lookup is case-sensitive.
  
 
= Associative / Positional Duals =
 
= Associative / Positional Duals =
Line 40: Line 42:
 
|-
 
|-
 
| [[Subscript/Slice Operator|A[I=x] ]] || [[Subscript/Slice Operator|A[@I=n] ]] ||
 
| [[Subscript/Slice Operator|A[I=x] ]] || [[Subscript/Slice Operator|A[@I=n] ]] ||
 +
|-
 +
| [[Subscript/Slice Operator|A[I=J] ]] || [[Subscript/Slice Operator|A[@I=@J] ]] || variation refered to as re-indexing
 
|-
 
|-
 
| [[Subscript]](A,I,x) || [[Slice]](A,I,n) ||
 
| [[Subscript]](A,I,x) || [[Slice]](A,I,n) ||
Line 63: Line 67:
 
There is no logical associational dual.
 
There is no logical associational dual.
 
|-
 
|-
| [[SortIndex]](A,I) ||  ? || See below
+
| [[SortIndex]](A,I) ||  Index J:=@I Do SortIndex(A[@I=@J],J) || no built-in positional dual
 
|-
 
|-
| [[Subset]](D) ||  ? || see below
+
| [[Subset]](D) ||  Index I:=1..Size(D) Do Subset(Array(I,D)) || D must be 1-D. No built-in positional dual.
 
|-
 
|-
| [[Unique]](A,I) || ? || see below
+
| [[Unique]](A,I) || Index J:=@I Do Unique(A[@I=@J],J) || no built-in positional dual
 
|}
 
|}
  
= Functions without Duals =
+
= When to Use Assocational vs. Positional =
 +
 
 +
When it is preferable to use associational (subscript) indexing, when is it better to use positional (slice) indexing, and when ''must'' you use one or the other.
 +
 
 +
Associational (subscript) indexing is the more commonly used in variable definitions because it tends to result in more flexible models.  If a new element it inserted into an index, say Division, expressions such as
 +
Expenses[Division='Marketing']
 +
continue to refer to the correct data, while the positional dual, Expenses[@Division=6], would break in such a case.
 +
 
 +
On the other hand, if an index has, or potential may have, duplicate elements, then associational indexing is ambiguous.  In this case, positional indexing is required to avoid the abiguity.  For this reason, positional indexing is often preferred in the definitions of [[User-Defined Functions]], where you may not want to assume uniqueness of elements in an index.  It is usually a poor practice to create indexes with duplicate elements, but there are occassionally legitimate cases for having non-unique elements.
 +
 
 +
A second case where positional indexing is appropriate is when dealing with square matricies.  Square matricies have two indexes of the same length.  If you can be certain that the two indexes have exactly the same elements, then associational indexes works fine, but in the more general case where only the length can be assumed, then positional indexes must be used.
 +
 
 +
Finally, some operations are inherently positional or associational by the nature of what is being done.  For example, refering the the previous element of an array, A[@I=@I-1], is inherently positional.  An "outer join" of two arrays, such as Salary_by_paygrade[Person=Paygrade_by_person], is naturally associational.
  
Three built-in Analytica functions, [[SortIndex]], [[Subset]] and [[Unique]], are missing a built-in dual function.  All three are associational, and in these three cases positional equivalents do make sense and are needed on occassion.  Until such duals are added to the set of built-in Analytica functions, the following discussions how to express the positional equivalents.
+
= [[Table Splicing]] =
  
[[SortIndex]](A,I) returns a permutation of I such that A[I=SortIndex(A,I)] are in ascending sorted orderHowever, if I might contains duplicates, the result of SortIndex does not unique identify the corresponding element, in which case a positional dual of SortIndex must be used.  This is accomplished as follows:
+
When an index changes, perhaps because a user inserted or deleted elements, or because something impacting the computation of its [[IndexValue]] changed, [[Table|edit tables]] based on that index must be splicedThis means that rows may need to be moved around, deleted, or added (with empty or default values).  This modification of existing edit tables is referred to as [[Table Splicing|splicing]]. 
  
  Index J:=@I Do SortIndex(A[@I=J],J)
+
For a given index, you can specify whether tables that depend on it should splice associationally or positionally when the index value changes. See [[Table Splicing]] for more information.

Revision as of 19:31, 2 May 2007


When accessing array elements from Analyica expressions, we must identify which position along an index that we wish to access. In Analytica, this can usually be done either associatively or positionally.

Suppose Index Year has the following elements:

Year→

2007 2008 2009 2010 2011 2012

And variable Earnings evaluates to an array indexed by Year,

Year → 2007 2008 2009 2010 2011 2012
Earnings→ 4.5M 5.6M 6.6M 7.9M 9.0M 10.1M

Then we can access particular elements of Earnings either associatively:

Earnings[Year=2009] → 6.6M

or by position:

Earnings[@Year=3] → 6.6M

Referring to an index element associatively is generally refered to as subscripting, and can also be accomplished using the [{Subscript]] function, which is equivalent to the above, e.g.:

Subscript(Earnings,Year,2009) → 6.6M

Referring to an index element by position is called slicing, and can equivalently be accomplished using the Slice function, e.g.:

Slice(Earnings,Year,3) → 6.6M

Positions in Analytica are always 1-based, and range from 1 to Size(I).

For text elements, associational lookup is case-sensitive.

Associative / Positional Duals

In Analytica, there are many functions that either require an index element be specified, or return an index position or element. Most functions that identify to an index element associationally have a positional dual, and vise versa. The following table indicates associational / positional duals.

Associational / Positional Duals
Associational By Position Notes
A[I=x] A[@I=n]
A[I=J] A[@I=@J] variation refered to as re-indexing
Subscript(A,I,x) Slice(A,I,n)
Slice(I,n) @[I=x] Slice(I,n) : returns the nth element of an index.

@[I=x]  : returns the position of element x in an index.

ArgMax(A,I) ArgMax(A,I,position:true)
ArgMin(A,I) ArgMin(A,I,position:true)
Choice(I,n) Choice(I,n,result:I) The second parameter is always positional.

The return value here is the element of I or the position along I.

For x:=I Do... For n:=@I Do...
IndexValue(I) @I

or 1..Size(I) || The elements of an index or the position along an index.

SubIndex(A,U,I) PositionInIndex(A,U,I)
(no equiv) Rank(A,I) Rank is related to SortIndex, returns positions.

There is no logical associational dual.

SortIndex(A,I) Index J:=@I Do SortIndex(A[@I=@J],J) no built-in positional dual
Subset(D) Index I:=1..Size(D) Do Subset(Array(I,D)) D must be 1-D. No built-in positional dual.
Unique(A,I) Index J:=@I Do Unique(A[@I=@J],J) no built-in positional dual

When to Use Assocational vs. Positional

When it is preferable to use associational (subscript) indexing, when is it better to use positional (slice) indexing, and when must you use one or the other.

Associational (subscript) indexing is the more commonly used in variable definitions because it tends to result in more flexible models. If a new element it inserted into an index, say Division, expressions such as

Expenses[Division='Marketing']

continue to refer to the correct data, while the positional dual, Expenses[@Division=6], would break in such a case.

On the other hand, if an index has, or potential may have, duplicate elements, then associational indexing is ambiguous. In this case, positional indexing is required to avoid the abiguity. For this reason, positional indexing is often preferred in the definitions of User-Defined Functions, where you may not want to assume uniqueness of elements in an index. It is usually a poor practice to create indexes with duplicate elements, but there are occassionally legitimate cases for having non-unique elements.

A second case where positional indexing is appropriate is when dealing with square matricies. Square matricies have two indexes of the same length. If you can be certain that the two indexes have exactly the same elements, then associational indexes works fine, but in the more general case where only the length can be assumed, then positional indexes must be used.

Finally, some operations are inherently positional or associational by the nature of what is being done. For example, refering the the previous element of an array, A[@I=@I-1], is inherently positional. An "outer join" of two arrays, such as Salary_by_paygrade[Person=Paygrade_by_person], is naturally associational.

Table Splicing

When an index changes, perhaps because a user inserted or deleted elements, or because something impacting the computation of its IndexValue changed, edit tables based on that index must be spliced. This means that rows may need to be moved around, deleted, or added (with empty or default values). This modification of existing edit tables is referred to as splicing.

For a given index, you can specify whether tables that depend on it should splice associationally or positionally when the index value changes. See Table Splicing for more information.

Comments


You are not allowed to post comments.