In many cases variable definitions are simple expressions involving other variables. For these cases, Opus provides an expression language that allows them to be defined succinctly, rather than requiring the Opus user to write new variable definitions in Python. (The expression language has been added recently to Opus, and there are many explicitly declared variables in the existing UrbanSim package that are no longer needed -- they could be written as expressions instead in the specifications. We plan to remove these unneeded variables in the future.)
The syntax of the expression language is that of Python, but the semantics are somewhat different -- for example, a name like gridcell.distance_to_cbd is a reference to the value of that variable. (If you just evaluated this in a Python shell you'd get an error, saying that the gridcell package didn't have a distance_to_cbd attribute.) Here is a simple example:
>>> locations.compute_variables(["sqrt(gridcell.distance_to_cbd)"])
array([ 2.23606798, 3.16227766, 2.23606798, 1. , 4.47213595,
0. , 2.64575131, 2.64575131, 1.73205081])
The expressions are fed to the compute_variables method of Dataset (Section 21.3.1), just as for simple variable references. (In fact, given a new expression, Opus will compose a new variable definition, including a compute and a dependencies method, which computes the value of that expression. It then saves the new variable definition in case the same expression is encountered again. However, the user need not be concerned about this.) The compute_variables method evaluates each variable (or expression) in turn, and returns the value of the last one.
An expression consists of an attribute name, or a function or operation applied to other expressions. This definition is recursive, so that a function or operation can be applied to expressions composed from other expressions. For example, here are some legal expressions: