In call to function %fn%, the %n% parameter, «%name%», should be numeric.
- In call to function Sequence, the first parameter, «start», should be numeric.
- In call to function Uniform, the second parameter, «max», should be numeric.
Some examples that cause this error
The appropriate remedy will usually depend on the specific situation and what you want to do with the non-numeric cells.
Sometimes this error is encountered when some cells in the parameter are Null. If you encounter this error when calling your own User-Defined Function, where you declared the given parameter as Number, then a Null value will trigger this error. You can add the OrNull qualifier to also allow Nulls, and then make sure that the definition of your function deals with missing values in an appropriate manner. The following is an example of a parameters declaration that uses OrNull:
Function MyFun(X: Number OrNull[I]; I: Index)
While most built-in functions treat Null as a missing value and ignore it, not all built-in functions and not all parameters are able handle missing values. In such cases, you will need to figure out the appropriate logic for handling the missing values in your particular case. For example, instead of:
Invert(A, I, J)
You might need to write:
Invert(If A = Null Then 0 Else A, I, J)
Hybrid Textual and Numeric
When you have an array that contains a mixture of textual and numeric values, including possible the empty text,
"", and you want to perform a purely numeric operation over the array, then it is natural that this error message would appear. The message may even occur when you think you have protected against it by using an If-Then-Else, as in this example (where
A contains a mixture of numeric and textual):
Then Uniform(0, A)
Why does this complain about the second parameter of Uniform being non-numeric, when you've checked specifically for this case in the If? This happens because Analytica carries out its computations as array operations. When it evaluates
Uniform(0, A), it does so as an array operation over the entire array
A, even though it appears within the If. The If then keeps only those slices where IsNumber(A) was true. However, when
A is atomic (scalar) in the above expression, then there is no problem, since in that case only the Else clause will be evaluated. Thus, the trick in a case like this is to ensure that
A must be atomic when the expression is evaluated. You can do this with a Var..Do declaration such as this:
Var A_atomic := A Do
Then Uniform(0, A_atomic)
The brackets after
A_atomic contain the indexes of
A_atomic -- in this case they are empty, which states that
A_atomic has no indexes, i.e., is atomic. When the original
A is an array, then the If will be iterated appropriately.
As long as
A is not already a local variable, you can actually use a somewhat more natural declaration syntax as follows:
Var A := A Do
Then Uniform(0, A)
Here we don't even change the name of
A. You can read this as a declaration -- "treat
A in the following expression as if it has no indexes, i.e., is atomic". You can even use this equivalent form:
Atomic A := A Do;
Then Uniform(0, A)
Another variation on this technique is to replace the offending function with a User-Defined Function that handles the non-numeric in an acceptable way without an error. For example, we could do this:
Function MyUniform(lb, ub: atom)
Definition: If IsNumber(lb) And IsNumber(ub) Then Uniform(lb, ub) Else Null
Using this function, then the array-valued If-Then-Else can be used without problem:
Then MyUniform(0, A)
Finally, another technique is to adjust the non-numeric parameter to be numeric in those cases that will ultimately be ignored, like this:
Then Uniform(0, If IsNumber(A) Then A Else 1)
Or using a User-Defined Function approach:
Function MyUniform(lb, ub)
Definition: Uniform(If IsNumber(lb) Then lb Else 0, If IsNumber(ub) Then ub Else 1)
Although it may seem counter-intuitive, this latter approach typified by the last two examples will often be the fastest to evaluate, especially when high-dimensional arrays are involved. Intuition may tell you that it is wasteful, since the function in question (i.e., Uniform) is being evaluated on all the cases that will eventually be ignored, while in the earlier cases the iteration is designed to avoid that computation entirely. However, because of the efficiencies that result from array-processing, and the avoidance of having to break arrays into atoms and then reassemble them later, it is not unheard of for the parameter modification method to evaluate hundreds of times faster. In most variables in your model, readability and understandability should trump these performance differences, because in most places the performance difference won't be significance to your full-model evaluation time. However, time-consuming models usually have a couple variables that dominate computation time, and for those few variables, the performance improvement may outweigh clarity. In Analytica Enterprise, the Performance Profiler can be used to locate the few variables that take a long time to evaluate.