Changes in 4.0 that could impact 3.x models
This page contains issues that could arise when migrating a model created in Analytica 3.1 to Analytica 4.0.
Syntactic Differences
For uses Index Values
(beginning 4.0.0.35)
When X is a self-indexed variable,
For j := X do expr
assigns j successively to be an element of IndexValue(X). Formerly, in the 1-D self-indexed case, For would assign j from the actual value of X (Mid or Sample). Note: If you really do want to iterate over the value of a self-indexed variable, rather than over its index, use:
For j[] := X do expr
Table syntax
(For builds 4.0.0.31 thru 4.0.0.34)
The Syntax for a Table (or ProbTable, DetermTable) is, and has always been:
Table(I, J)(expr1, expr2, expr3, ...)
with commas between each cell expression. However, Analytica 3.1 would accept expressions separated by spaces only, i.e.:
Table(I, J)(expr1 expr2 expr3 ...)
Analytica 4.0 no longer accepts tables definitions where the commas are missing. If you load (or type) a table expression with spaces instead of commas, Analytica 4.0 will automatically re-write the definition to contain commas (starting with build 4.0.0.35 beta).
This change is made so that in the future blank (not-yet-defined) cells are possible in a table definition.
Tables inside an expression
A Table function appearing inside an expression (i.e., not at the top level), now generates an error if the values are not explicitly specified. For example:
Dynamic(Table(I), Self[Time - 1] + 1)
will generate an error, while in Analytica 3.1 this did not cause an error. If you have an expression like this, just simply replace the Table expression with a zero, or with Array(I,J,K,0), e.g.:
Dynamic(0, Self[Time - 1] + 1) Dynamic(Array(I, 0), Self[Time - 1] + 1)
Note: In general, it is a bad idea to use the Table within an expression, unless you are absolutely certain that the table indexes will never change in length. When Table appears as the outermost function, Analytica automatically splices the table definition whenever a table index changes; however, this automatic splicing does not occur when the Table expression is embedded.
Intolerance of missing trailing quote
For a string definition, Analytica 3.1 tolerated a missing trailing quote without complaining. Analytica 4.0 correctly flags this as a syntax error. So, for example, a definition such as
'Hello world
needs to be corrected, adding the closing quote:
'Hello world'
Evaluation Differences
Multiplication of NaN or INF by zero
See Ana:IEEE 754 Binary Floating Point Arithmetic. In 3.1, (0*INF) or (0*NaN) returned 0. Now it returns NaN and issues a warning (if Show Result Warnings is on).
Deprecation of Undefined for Null
Formerly, two special values, Undefined and Null served different purposes within Analytica. To simplify things so that modelers don't have to understand the difference, Analytica is moving towards exposing only Null, deprecating the use of Undefined. Several functions that used to return Undefined under certain circumstances now return Null. These include: Attrib of Obj and MdTable.
Setting an attribute to Null now removes the value (formerly it set it to the special value Null, setting to Undefined removed the value).
Although Analytica internally can distinguish between an attribute set to Null and an undefined/uncomputed attribute, this distinction is no longer exposed to Analytica expressions. (Although if you really needed to, you could resort to typescript for this).
These change is highly unlikely to impact existing models, since the method for testing for Undefined formerly has been via the function IsUndef, which returns true for Undefined or Null. Thus, it is only in exceptional circumstances that these changes would have any impact on computations. However, it is possibly you may see <<null>> in your result tables where there was formerly a blank (Undefined displays as a blank).
Slicing or Subscripting on Out-Of-Range Value
When n is NOT a valid position for index I, and I is NOT an index of A, then Slice(A,I,n) or A[@I = n] now issues a warning and returns NULL if warnings are ignored. Similarly, if x is NOT an element of I, and I is NOT an index of A, then Subscript(A,I,x) or A[I=x] issues a warning and returns Null. However, in Analytica 3.1, when I was not an index of A, the original value A was returned in all cases, even when the position or element was out-of-range. If this difference impacts your existing model, you will probably see some results become Null in 4.0. Ensure that the "Show Result Warnings" preference is on, and the warning should guide you to the variable where this is occurring.
Local index operator, A.I, uses Context
When the A.I operator is used in Sample mode, the result may be different between Analytica 3.1 and Analytica 4.0 when the result of A has a different dimensionality in Mid mode than it does in Sample mode. Formerly, A.I was always equivalent to Mid(A).I, but in Analytica 4.0 (starting with 4.0.0.47), Sample(A.I) is equivalent to Sample(A).I. If A is based on a local index (declared via Index..Do), then Mid(A).I and Sample(A).I refer to two different local indexes. It would be very rare for this to impact an existing model, but it could.
Button Scripting
No Invalidation Without Change
Some models set a variable's definition from a button script as a way to invalidate cached values of previously computed results. When you set a definition to the same value that is already there, Analytica 3.1 would invalidate downstream results, while Analytica 4.0 may recognize that no change has occurred and therefore not invalidate downstream results. A typical example where this might cause an incompatibility is the following section of a model:
Variable Reset := 1 Variable X := Reset ; Uniform(0,1) Button Resample, Script: Reset := 1
In Analytica 3.1, pressing the button will force X to be resampled, while in Analytica 4.0, it will not (since the value of Reset is not being changed). To fix this, change the script to:
(Reset := Reset + 1)
where parens are required here. This will ensure that the value is changed each time and thus avoid this difference.
Optimizer
LpStatusNum and LpStatusText values changed
The set of status messages returned from the Frontline Solver have changed. The numeric status codes returned from LpStatusNum are not the same as they were in Analytica 3.1, so any expression that conditioned behavior based on those codes may need to be updated. Checking the LpStatusText visually is a bit safer, since the result is at least in English.
Forward Compatibility
If you need to use a model created in Analytica 4.0 from Analytica 3.1, a few words are in order.
You can load models saved from Analytica 4.0 into Analytica 3.1. When doing so, a warning is issued.
If you use any features new to or different in Analytica 4.0, these will not transfer to Analytica 3.1. These features are numerous, and if you use 4.0 very long, you'll probably use a lot of these. Therefore, it is pretty likely you'll want your end-users to view using Analytica 4.0.
If you save your model from Analytica 3.1, some data recognized only to Analytica 4.0 may be lost. Analytica 3.1 does not have a place to data associated with attributes that have been added to 4.0, so when it is saved, these won't be in the Analytica 3.1 model. However, if that saved model is opened in Analytica 3.1 again, you won't get a warning any more.
If extended characters (above ascii 128) are used in your model, for example in titles, these will not be the same when loaded into Analytica 3.1. This will impact models using non-English characters (accents, etc). (these characters are translated when 3.1 models are loaded into 4.0, but the reverse direction is not possible).
If computed indexes have changed in your model prior to saving, and tables depending on those indexes have not been accessed, it is possible that some table will be saved in an "unspliced" state. These table definitions may be appear broken when loaded into Analytica 3.1. To avoid this, you can either access the tables before saving (from 4.0), or you can cause all tables to splice by following these steps:
- Press F12 (to access the Typescript window)
- In the typescript window, type:
splicetable all
After this step, your model will be saved without any unspliced tables.
Enable comment auto-refresher