# Tutorial: Arrays

Release: |
---|

This section (page) introduces you to Intelligent Arrays, which is source of much of Analytica's power and flexibility. An array is a table of values, with one, two, or more dimensions. Even if you often skip tutorials, you may find it valuable to go through this section, because Analytica arrays have some unique aspects different from other modeling tools and computer languages. And it's essential to understand the basics of arrays before you can use Analytica effectively.

This chapter shows you how to:

- Create and define an Index
- Define an array variable as a Table
- Understand principles of array abstraction when combining arrays in an expression
- Use conditional expressions and logical values when defining an array
- Define variables using Expression syntax
- Use local values to simplify an expression
- Analyze a multi-dimensional result by pivoting indexes
- Reduce an array using subscripts
- Use array reducing functions such as Sum() and NPV()

In the previous chapter you defined a single variable, **Miles per gallon**, as a list of values. This is an example of a simple one-dimensional array. When you defined **Fuel cost** using the **Miles per gallon** array variable as an input, it also became an array. This demonstrates the concept of array abstraction. Array variables can be used just like ordinary variables in expressions. Whenever you expand an index of the array to include more values, or even add an entirely new index along a new dimension, all dependent variables downstream will be extended automatically! Intelligent arrays allow you to scale your model without making any changes to the design.

This section covers lots of ground. The example model is simple, but demonstrates many important array concepts. The approach is streamlined so you can learn the key ideas with-out getting bogged down with procedural details. You should already be familiar with the basic mechanics of Analytica‘s user interface, and know how to:

- Create a new model; Open an existing model; Save; Save As... (See Tutorial: Open a model to browse)
- Create and define new variables; Enter attributes in Attribute or Object windows; Draw influence arrows between nodes. (See Tutorial: Create a model)

## Summarize variables using Expression syntax

You will need to know how to enter definitions directly as Expressions. Every variable type and every functional expression can be represented this way. In addition to its usefulness in building models, expression syntax is a convenient and efficient way to summarize examples in the documentation. For example, this summarizes the **Car cost **model from the previous section:

`Variable MPY := 12K`

`Variable MPG := Sequence(20, 50, 5)`

`Variable Fuel_price := 3`

`Variable Fuel_cost := MPY*Fuel_price/MPG`

We summarize new variables in this form in this section. It is also widely used throughout the Wiki:

- The first term indicates the Class of the object being defined. Classes include
**Decision, Variable, Chance, Objective, Module, Index, Constant**and**Function**. - The second termis the Identifier for the object. (Identifiers may not contain spaces.)
`:=`

) sometimes known as the assignment operator.- The definition is an expression, which could be a number, function call, probability distribution, table, or other expression. It may refer to other variables (the "Inputs" of this variable. You could even copy the expression directly into the Definition of a variable or function. The expressions are marked as
`<code>`

.

## Fast Tony’s Generic Wheels

In this chapter you extend the **Car cost **model to address an important decision scenario: the purchase of a new car. There are three cars to choose from: * Standard*,

*and*

**SUV***.*

**Hybrid**There are also three finance options: * Cash purchase*,

*, or*

**Lease***. Fast Tony has presented you with an array of decision possibilities, a 3 x 3 array to be exact. Your objective is to determine the option with the lowest total cash outflow over a 24-month period, including fuel. (Maintenance costs are covered under warranty as long as Fast Tony’s cousin, Greasy Tony, is on his feet that day.) Ownership equity will be represented as a positive cash flow on the last period.*

**Loan**## Continue with model

In this chapter, you will continue with the model you developed in Tutorial: Create a model. The model from the end of Tutorial: Create a model can be found in the **Tutorial Models** directory. Select **Open** on the **File** menu.

*Example Models*button.

**Tutorial Models**folder.

## Create an index variable

Index variables define the categories along a dimension of an array. They are represented by index nodes (parallelogram shapes) in the influence diagram. In this example, your decision will be arrayed by **Car type** and **Finance Option** so you will need to define an index for each of these dimensions. Index variables are generally defined as a *list of labels* or a *list of values* representing categories in the array.

(For the finance options you will leave out "Loan" for now. It will be added later.)

`Index Car_type := ['Standard', 'SUV', 'Hybrid']`

`Index Finance_option := ['Purchase', 'Lease']`

**List of text**from the expression popup menu

*in the Expression popup menu, you can select*

**List of Text****Expression**and enter the definition directly using Expression syntax. Simply list the values separated by commas and encase them in square brackets

`[ ]`

. Note that all text values in Expression syntax must be enclosed in quotes (single or double).## Defining a variable as a table

Each of the cars has a unique purchase price. You will define **Car price** as a * Table* indexed by

**Car type**. In this context, a "table" does not necessarily have two dimensions. It can have one (as in this case), two, three or more.

`Variable Car_price := Table(Car_type)(22K, 40K, 24K)`

**Car price**.

*.*

**Table****Car type**index and click the transfer button to move it to the selected indexes list. Click

**OK**.

After you close the Indexes dialog an Edit table will appear.

Enter the following values for *Car price*:

- Standard: '
**22K'** - SUV:
**40K'** - Hybrid: '
**24K'**

**Tab**or

**Shift+Tab**to move through the cells.

You can draw influence arrows from index nodes to table variables to pre-populate the Indexes dialog with the chosen indexes. Influence arrows from index nodes are invisible by default but can be made visible by choosing the Diagram menu and selecting * Set diagram style*.

Next you will create a variable for lease payments. Fast Tony lists the following monthly payments for the two-year lease option:

- Standard: '
**$400'** - SUV:
**$700'** - Hybrid: '
**$500'**

**Lease Payment** is similar to the **Car price** variable. But this time you will enter the definition directly using expression syntax instead of using the edit table.

`Variable Lease_payment := Table(Car_type)(400, 700, 500)`

**Lease payment**

As you can see, Table definitions follow a specific syntax. The **Table **declaration is followed by two lists enclosed in parentheses. The first list contains the indexes by which the table will be arrayed. (In this simple example there is only one index but there can be many.) The second list contains the values.

**It is important for the values to be in the same order as the index categories.** Recall that the Car type index was defined as:

`Index Car_type := ['Standard', 'SUV', 'Hybrid']`

which matches the respective order of values in the **Lease payment **variable. The same principle applies when there is more than one index. For example, a two dimensional array might look like:

- Table (Index_abc, Index_123)
- ('a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3')

It is generally easier to use an edit table when multiple dimensions are involved.

Finally, re-define the existing **Miles per gallon **variable as a table indexed by **Car type**. The MPG values for Standard, SUV and Hybrid are 28, 23, and 45 respectively.

`Variable Mpg := Table(Car_type)(28, 23, 45)`

Select the **Miles per gallon **variable.

Open the Definition field and select from the Expression popup menu. Enter the new definition as shown above.

## Combine arrays

Now that you have established purchase and lease payments, you can combine them in one variable. This time the index will be **Finance Option**.

`Variable Payments := Table (Finance_option)(Car_price, Lease_payment)`

Create a new variable titled **Payments**.

Open the definition field and select * Table* from the Expression popup menu.

The Indexes dialog appears. Select the Finance option index and transfer it to selected indexes list. Click **OK**. An edit table will appear.

You may have noticed an important difference between this table and the previous tables. In the previous tables you entered number values into the table cells, but this time you are entering expressions! Expressions are valid entries for table cells. With very few exceptions they can be as complex as anything you might enter in a standard definition line, including formulas, logical expressions and conditional expressions. You will see more examples of this later in the chapter.

Now look at the result of this new variable.

Select the **Payments** variable and click the **Results** button ()

Something interesting has happened! Notice that the array contains two dimensions even though only one index is called out in the definition of the array:

`Variable Payments := Table (Finance_option)(Car_price, Lease_payment)`

Why is **Car type** included in the result when **Finance_option** is the only index included in the definition of the table?

The **Car type** index is included because it is an index of the input variables **Car price** and **Lease payment**.

You have just encountered one of the most powerful features of Analytica’s array abstraction: The dimensions of arrayed input variables will automatically be incorporated into the resulting output of an expression. The general principle of array abstraction can be summarized as follows:

**In Analytica, the result of an expression is arrayed by the union set of dimensions from all input variables, and the definition of the expression itself.**

## Add a dimension to an array

So far, the Payments variable is not very useful for comparing the purchase and lease options. Lease payments are paid every month instead of just once, and there is still ownership equity to consider. In order to represent payments as a stream of cash flows over time, you will need to add a new dimension to the Payments array:

Create and define a new index titled Period. Define it as a sequence of months from 0 to 24.

`Index Period := Sequence(0, 24)`

There is a special shortcut syntax for sequences that have a step value of one: Type the starting value, followed by two periods (..), followed by the final value. For example, the **Period** index can be defined as: `Index Period := 0..24`

Next, you will edit the **Payments** definition to include the new index. Try using the edit table for this:

There is a button in the top left corner of the edit table, labeled with a parallelogram. Click this button to open the Indexes window. Then add **Period** to the list of selected indexes.

*Index button*in the top-left corner of the edit table.

**Period**index and add it to the Selected Indexes list.

The edit table should now look like this:

**Period**index has been added to the

**Payments**array.

The subset of an array corresponding to a singe index value is referred to as a slice. When you expanded the **Payments** array to include a new index, the original values (expressions in this case) were copied into all new slices along the **Period** index.

The **Payments** array is not yet accurate. Under the Purchase column you should have zero values for all periods except Period 0. Lease payments should be included in periods 1 through 24 but not Period 0. It would not take too much effort to edit all the cells to be the way you want them to be. The final definition of the array would look something like this:

Although this would work, it would not be a very efficient approach. In general, whenever you find yourself editing tables in the same way you would edit a spreadsheet, you are not benefiting from the advantages of array abstraction.

## Use conditional expressions

Expressions can include conditional statements using If...then...else syntax. The condition can be based on a variable or an index value. This is a very useful way of defining array variables. For example, the cash flow for purchasers can be represented as:

Likewise, the cash flow for lease holders can be represented as:

Specifying a condition based on **Period** will automatically add the **Period** index to the array. This would have been a better way to add a new dimension to the **Payments** variable, compared to the example above.

Let’s revert the Payments variable to the way it was before adding the Period index:

`Variable Payments := Table(Finance_option)(Car_price, Lease_payment)`

As you did in the section above, Select the **Payments** variable, open the edit table, and click the Index button in the top left corner.

Select the **Period** index in the Selected Indexes list and transfer it back to left hand box. Click **OK**. Answer **Yes** when the warning appears:

This time you will add the **Period** index by including it in a conditional expression. Edit the cells to include conditional expressions:

`Variable Payments := Table(Finance_option)`

Let’s take a step back to consider how many indexes are now included in the **Payments **array:

**Finance_option**is called out specifically as a table index**Period**is the basis for a condition statement within an expression**Car_type**is an index of the**Car price**and**Lease payment**input variables. Therefore, you can expect that**Payments**will be a three-dimensional array.

Conditional expressions can have nested If-Then-Else statements. In fact, it would be possible to define the **Payments **array using only one conditional expression:

`Variable Payments :=`

This would be equivalent to the table definition above.

Logical statements can also be used to specify a condition. They are enclosed in parentheses and include an equal sign. When used in a mathematical expression, a logical statement assumes a value of one if true, or zero if false. For example:

`24*(2 + 2 = 4) → 24`

`24*(2 + 2 = 5) → 0`

Hence another equivalent to the previous table definition is

## View the results of a multi-dimensional array

Representing a multi-dimensional array on a two-dimensional screen presents a challenge. When viewing results in tabular form, Analytica will display only a two-dimensional slice of the data. You can change the orientation and selection of data by *pivoting *the table. To do this, select the desired row and column indexes from the row and column pop-up menus. Any leftover indexes become *slicer indexes *for which only slice of data (corresponding to a single index value) can be displayed at a time.

Select the Payments variable and click the Results button ().

Select the table view button ().

You can experiment by selecting different row and column indexes, and by changing the value of the slicer index.

Now click on the graph view button ()

The vertical axis of the graph represents data values. The graph indexes can be pivoted to select the desired horizontal axis, key, and slicer index. You can experiment with various graph configurations and slicer values.

You can explore various chart types and options by selecting * Graph Setup*... from the Result menu. For more details about graphs reference Tutorial: Reviewing a model.

## Add a new value to an index

Fast Tony’s loan financing terms require 10% down and 2% of the purchase price per month for 60 months. His financing manager, Big Anthony, explains that at a 12% nominal interest rate (1% per month compounded monthly), the load will be paid off in 60 months. There are severe penal- ties for delinquency but none of them are expressed in dollar values.

One of the advantages of *intelligent arrays *is that they are easily expandable. So far, you have set up cash flows for purchasers and lease holders. Adding a third financing option is a simple matter of adding a new value to the **Finance option **index.

`Index Finance_option := ['Purchase','Lease','Loan']`

Select the * Finance option *index and open the Definition field. Select

*from the Expression popup menu. You will see a list of current values in the definition field. Select the bottom value (*

**List of Text****Lease**) and press the

**down-arrow**key. A new box appears at the bottom of the list. By default the previous label is copied down. Change the new value to

*.*

**Loan**

**List of Text**from the Expression pop-up menu.

*Enter*.

**Loan**as the new value.

Now select the Payments variable and click the Results button ().

A new column appears with zero values by default.

Now you will need to add an expression for loan payments in the edit table:

`Car_price*(If Period = 0 then 10% else 2%)`

Select the **Payments** variable. Open the Definition field, then click the * Edit table* button.

Recall that the input variable **Car price** is indexed by **Car type**. Therefore, your new expression will be evaluated separately for the Standard car, the SUV and the Hybrid. The new expression also references the **Period** index, so it will be evaluated separately for each period as well.

## Using local values and indexes in an expression

Now that you have established all the cash outflows, you can start thinking about how much ownership equity you will have at the end of the 24-month period. Unavoidably you will need to calculate the remaining loan balance at that time. The financial dynamics of a typical loan include compound interest offset by fixed payment amounts. Although the formula for loan balances can be derived fairly easily, this section will focus on how to apply the formula rather than explaining the formula itself. Readers are invited to verify on their own if they wish:

Assuming that a constant amount is paid and nominal interest is compounded every month:

`B0`

= Starting balance of the loan`12%`

= Nominal interest rate`60`

= The total number of periods required to pay off the loan`Period`

= A number from 0 to 24 representing the current period`B(Period)`

= The remaining loan balance for the current period- Let
`A = (1 + 12% / 12)`

`B(Period) = B0 * (A^60 - A^Period) / (A^60 - 1)`

It is easy to verify that `B(0) = B0`

and `B(60)=0`

as required.

The quantity `A`

appears several times in this formula so it makes sense to define it as an intermediate variable. To do the same thing in Analytica, you could define a new variable called `A`

and use it as an input to the loan balance variable. But this would clutter your diagram with an unnecessary node.

Analytica allows *local* values and indexes to be used temporarily within a definition. In this case you will define a local identifier.

Create a new variable titled **Loan balance** and enter the following definition:

`Variable Loan_balance :=`

`Local A := (1 + 12%/12);`

`Car_price * (1 - 10%) * (A^60 - A^Period)/(A^60 - 1)`

Syntax rules for local objects are as follows:

- The instruction line starts with
`Local`

or`LocalIndex`

to declare a local value or index. - The declaration is followed by an identifier. This can be anything you choose but it must not be identical to any other input contained in the expression.
- The
*assignment operator*`:=`

comes next (colon followed by an equal sign), followed by an expression defining the object. - A semicolon (
`;`

) is required to end the instruction line. You may choose to have a visual break (Enter key) after the semicolon for appearance purposes but this is optional. Analytica only looks at semicolons to mark line breaks in code. Each local identifier declaration must be on a separate code line. - The final line of instruction contains the definition as usual. All declared local values and indexes will be available to use in expressions.

Local variables are used temporarily and then forgotten after the expression is evaluated. Therefore, the same local identifier (i.e. `A`

) can be used in any number of nodes without conflict.

A final note about the expression for **Loan Balance**:

Although **Period **is an index, you have used it here as a variable in a mathematical expression. This is possible because **Period **is a list of numerical values. It would not have been possible to use **Car type **or **Finance option **in a mathematical formula since they are lists of labels (although they could be used in logical or conditional statements). In general, you can think of an index as a one-dimensional array that uses its own values as an index.

By the principles of array abstraction, you should expect **Loan Balance **to be a two-dimensional array indexed by **Car type **(an index of **Car price**) and **Period**.

The Future Value function Fv is a convenient way to calculate loan balances and annuity values without using formulas. Arguments in order are: Interest rate per period, Future period, Payments (negative for payouts), Initial value. For example, **Loan Balance** could be defined as: `Fv(1%, Period, -Car_price*2%, Car_price*90%)`

See Financial functions in the Analytica User Guide.

## Reduce an array using subscripts

Sometimes you may want to reference part of an array variable without using all of its available indexes. Subscripts allow you to reference a slice of an array, effectively eliminating one or more dimensions. The subscript specifies indexes and their desired values for the slice. It is enclosed in square brackets placed immediately after the identifier for the array. For example:

The subscript has reduced a two-dimensional array to a one-dimensional array

`Variable Final_period_balance := Loan_balance[Period = 24]`

This refers only to the **Loan Balance **values that correspond to Period 24. Recall that **Loan Balance **is a two-dimensional array indexed by **Period **and **Car Type**. The subscripted reference above will eliminate the **Period **dimension and return a one-dimensional array indexed only by **Car_type**.

It is possible to eliminate multiple dimensions by including multiple indexes in the subscript, separated by commas. For example:

`Variable Final_period_balance := Loan_balance[Period = 24, Car_type = 'SUV']`

The result of this expression will be a single value corresponding to the loan balance at Period 24 for the SUV: 24.11K

An Index value can also be selected according to its position in the index rather than the actual value. To make a positional reference, place the "at" symbol (cat) in front of the index identifier. For example, 'SUV' is second in the order of values for the **Car type **index.

The following subscript references are equivalent:

`Loan_balance[Car_type = 'SUV']`

`Loan_balance[@Car_type = 2]`

The verbal terminology for this reference would be: "**Loan_balance **sliced at position of **Car_type **equal to 2".

## Complete cash flows

Now you can add a variable to represent the amount of ownership equity you will have after 24 months. Of course this will depend on the finance option.

Assume that the value of every car depreciates by 35% over two years.

- Cash purchasers’ equity will be:
**Car_price (1 - 35%)** - Lease holders’ equity will be zero
- Loaners’ equity will be the difference between car value and the loan balance at Period 24:
**Car_price (1 - 35%) - Loan_balance[Period = 24]**

The **Equity **variable has only two dimensions: **Car type **and **Finance option**.

It refers to a single slice of the **Period **index.

You can define the **Equity **variable as a table indexed by **Finance option**. Each of the expressions above can be entered into the appropriate cell in the edit table:

`Variable Equity := Table(Finance_option)`

`(Car_price*(1 - 35%), 0, (Car_price*(1 - 35%) - Loan_balance[Period = 24]))`

Alternatively, you can use conditional and logical statements as follows:

`Variable Equity := If Finance_option = 'Lease' then 0 else`

`Car_price*(1 - 35%) - (Finance_option = 'Loan')*Loan_balance[Period = 24]`

Once again, consider how many dimensions your new variable will have. At first you might be tempted to list the indexes as follows:

**Finance option**(Specified as a table index or used in a conditional expression)**Car type**(Index of the input variables**Car price**and**Loan balance**)**Period**(Index of the input variable**Loan balance**)

But **Loan balance **is not an input to this expression; only a slice of it is used. The slice is arrayed only by **Car type**. Therefore, the Equity variable will be indexed by **Finance option **and **Car type **but not by **Period**.

**Equity**variable has only two dimensions:

**Car type**and

**Finance option**.

It refers to a single slice of the

**Period**index.

## Combine dissimilar arrays

Now that you have established payments and ownership equity, you can combine them into a single cash flow variable. **Payments **will be represented as negative cash flows. **Equity **will be represented as a positive cash flow on the last period.

Create a new variable titled **Cash flow **and enter the following definition:

`Variable Cash_flow := If Period = 24 then Equity - Payments else -Payments`

In this expression you have combined arrays with different numbers of dimensions:

**Payments**is indexed by**Car type**,**Finance option**and**Period.**- Equity
**is indexed only by**Car type**and**Finance option**.**

There is no ambiguity here since **(Equity - Payments) **applies to a slice along the **Period** index. The slice is called out in the conditional statement.

Notice that **Equity **and **Payments[Period = 24] **have the same dimensions.

There are other situations where you may want to use a scalar variable (not an array) as an input to an array. Similarly, you may want use an array as an input to another array that has more dimensions. In this situation Analytica will repeat the values of the smaller array for each slice along the new dimensions.

For example, suppose you want to incorporate monthly fuel cost into the **Cash flow **variable.

Here again you are combining two dissimilar arrays:

**Cash flow**is indexed by**Car type**,**Finance option**and**Period****Fuel cost**is indexed only by**Car type**

Create a new variable titled **Cash flow with fuel **and define it as follows:

`Variable Cash_flow_with_fuel :=`

`If Period = 0 then Cash_flow else Cash_flow - Fuel_cost/12`

In this example, **Fuel cost **is applied to multiple slices along new dimensions:

- All
**Period**values except Period 0 - All three
**Finance option**categories.

Select **Cash_flow_with_fuel **and click the Results button ()

You will notice "Totals" check boxes next to the row and column index pop-up menus. Checking the box next to **Period **will allow you to see totals along that index.

## Array-Reducing Functions

A function that reduces one or more indexes of an array is referred to as an array reducing function. The output of an array reducing function will have fewer dimensions than the input array. For example, the following expression will determine the sum of cash flows over all periods:

`Variable Total_cash_flow := Sum(Cash_flow_with_fuel, Period)`

The input array is indexed by **Car type**, **Finance option **and **Period**. The output will be a two- dimensional array indexed by **Car type **and **Finance option**. In this example the **Period **dimension has been reduced.

- The first argument of the Sum() function is the identifier of the variable to be operated on.
- This is followed by a list of indexes separated by commas. These are the indexes over which the function will operate.

In this example you have taken a sum over a single index.

Similar examples of array-reducing functions include Max(), Min(), Product() and Average().

## Net Present Value (NPV) analysis

If someone offered you a choice of receiving $100 today or receiving $100 two years from now, which would you choose? If you choose to receive it immediately, you can invest in a low risk bond with an annual return of, say, 6%. In two years the investment will be worth about $112. Clearly these two alternatives do not have equal value. Conversely, you would probably prefer to pay an obligation later rather than sooner.

*Net present value *(NPV) analysis is a way to compare various scenarios that involve inflows and outflows of money at different time periods. It converts a stream of cash flows to an equivalent scenario where all money is exchanged in a single transaction at the present time. The interest rate that can be achieved in a low risk investment is referred to as the *discount rate*. For example, given a discount rate of 6%, the NPV of $112 paid two years in the future would be $100.

By taking a simple sum of cash flows as in the example above, you have ignored the time value of money. A Net Present Value analysis is more useful in this case. The NPV() function in Analytica makes this easy. It is another example of an array reducing function.

Assume the discount rate is 0.5% per month. Create an objective node titled **Cash flow NPV**.

(Objective nodes are represented by the hexagon shape on the node palette.)

Apply the following definition:

`Objective Cash_flow_NPV := NPV(0.5%, Cash_flow_with_fuel, Period)`

- The first argument of the NPV function is the discount rate per period.
- The second argument is the identifier for the variable containing cash flows.
- The third argument is the index containing period values.

The analysis is complete!

## Summary

In this chapter you have:

- Learned Expression syntax
- Created and defined index variables
- Created array variables as tables dimensioned along established indexes
- Expanded arrays by adding new indexes
- Expanded indexes by adding new index values
- Created examples that demonstrate the basic principle of array abstraction:
**The result of an expression is arrayed by the***union set*of dimensions from all input variables, and the definition of the expression itself. - Used conditional and logical statements within an expression
- Established local values in the definition field
- Analyzed a multi-dimensional result by pivoting indexes
- Reduced array variables using subscripts
- Applied array-reducing functions to arrays

## See Also

- Array
- Table
- Creating Arrays (Tables)
- Intelligent Arrays
- Arrays and Indexes
- Indexes and arrays: An introduction
- Creating an index
- Functions that create indexes
- Array-reducing functions
- Array functions
- Array Manipulation Examples and Challenge Problems
- Array Function Example Variables
- Multidimensional arrays
- Expression Syntax
- Expressions
- The Expression popup menu
- Class
- Classes of variables and other objects
- Local Values
- Subscript
- Subscript and slice of a subarray
- Identifier
- Modeling Depreciation
- NPV
- Choice menus and Checkboxes in an edit table
- Dynamic Simulation
- Tutorial videos
- Intelligent Array Abstraction (explanatory video on YouTube)
- Intro-to-arrays (Part 1).wmv (an explanatory video about Analytica arrays and indexes (part 1); requires Windows Media player)
- Intro-to-arrays (Part 2).wmv (an explanatory video about Analytica arrays and indexes (part 2); requires Windows Media player)

Enable comment auto-refresher