Yes, you can. This is done by putting the matrix name in double quotes
(e.g. "wod76d"
), optionally preceded by a matrix type specifier
(e.g. mf"wod76d"
). In order to be able to access matrices by
names the matrix names must be unique, either with respect to all matrices
(if no matrix type prefix is used) or with respect to the given type
(if an explicit matrix type is specified).
This can be done using the keywords p
and q
, which represent
the origin and destination zone numbers. The subexpression (p!=q)
(or (p.ne.q)
if you prefer Fortran type operators) yields 0 for
the O-D pairs on the diagonal (intrazonal trips) and 1 for
all off-diagonal O-D pairs. Thus, the matrix calculation
mf
X = (p!=q)*mf
X
removes all intrazonal trips from matrix mf
X.
The macro
matreg.mac
shows how the matrix calculator can be used to implement a
multiple linear regression on arbitrary matrix data.
With the introduction of the g
and r
floating point registers
in Release 8, the implementation of lookup tables (not just for matrix
calculations) has become considerably more efficient.
In a nutshell, there are 250 g
-restigers
(named g1
the g250
) which are
a direct mapping of the put()/get()
stack registers of the EMME/2
expression evaluator. Thus, e.g. a value stored in the register g27
by
the macro command
~g27=715.23
will be returned in an algebraic
expression by the instrisic call get(27)
. (Note that the g-registers
will be initialized at the beginning of each new module!)
The following little macro shows the pinciple how to implement a lookup table:
~/ LOOKUP: Example macro for implementing a lookup table ~o|32 / suppress all pauses in macros (always useful!) 3.21 / call module 3.21 1 / matrix calculations 'y' / save results mf10 / in temporary matrix y / initialize or change header if it exists tmpres / result matrix example for of lookup table information ~?q=1 y / initialize matrix values 0 / to 0 ~/ ~/ lookup table: ~g1=.0627 / store up to 250 values of lookup table in get()/put() stack ~g2=.1736 / here we assume that the lookup table contains values that ~g3=.2018 / correspond to 5 minutes increments in travel times ~g4=.2217 ~g5=.1520 ~g6=.1199 ~g7=.0582 ~g8=.0078 ~g9=.0019 ~g10=.0004 / the travel times are assumed to be stored in mf05 ~/ ~/ matrix expression (divide by interval and add 1 to start with g1): get(mf05/5+1) / no constraint matrix n / no submatrix ~?q=2 2 / report to printer q / back to primary select ~/ macro LOOKUP terminated
In principle, this can be done with module 3.22, after having prepared the corresponding 3rd dimension index matrix and the group-to-group totals. However, the preparation of this input data is rather cumbersome, and the imposed maximum of 99 third dimension constraints in module 3.22 is often too limiting in this context.
Fortunately, a specialized macro
balance3.mac
is available which solves this problem very easily and without any
restriction regarding the number of groups.
Note that this macro is not based on module 3.22, but uses the matrix calculator (module 3.21) to implement this special type of balancing.
The macro
balmprod.mac
can be used to perform this task.
It allows the specification of several production types (each with its
own production vector and friction matrix) which are balanced against a
single attraction vector.
In the standard version
it handles up to four different production types, but it can be easily modified
to handle more, would this ever become necessary.
Note that this macro is not based on module 3.22, but uses the matrix calculator (module 3.21) to implement this special type of balancing.
In the EMME/2 Users Manual an example is give how to use module 3.23,
``Matrix Convolutions'', to implement a simple P&R parking lot
choice model which picks the parking lot that minimizes some given
disutility. The macros
splitmat.mac
and
legimped.mac
can be used in this context to compute the corresponding intermediate auto
and transit demand matrices and the impedance matrices that correspond
to the auto and transit part of the P&R trips.
A more complex logit based P&R parking lot choice model is described in the paper ``Computing Activity Chain Based Trip Distribution Models''.
The paper ``Computing Activity Chain Based Trip Distribution Models'' shows how to convert logit models based on multi-leg activity chains into a series of simple matrix multiplications which can be be implemented using convolution computations in module 3.23.
If you experience that some matrix operation (calculation, balancing, ...)
is suddenly much slower that usual, this might be due to one or several
of the implied full matrices being stored in columnwise format
instead of the standard rowwise format. You can check if you data bank
contains columnwise matrices by looking for a warning of the type
Data bank contains XX columnwise matrices.
when entering module 3.12. Unless you have explicitly chosen to
use columnwise matrices for some special reason, the existence of
columnwise matrices in a data bank is usually a sign of trouble.
In EMME/2 full matrices are usually stored and accessed in row dominant format, i.e. each row of the matrix is stored as one file record. This format allows efficient matrix access by origin zones, which is the standard way EMME/2 modules access full matrices.
EMME/2 also allows storing of matrices in column dominant format, as so called
columnwise matrices. Such matrices are displayed with a flag /c
in the matrix directory. Under normal circumstances, columnwise matrices
are never used explicitly by the user, but are reserved for transient internal
use in certain EMME/2 modules.
When using columnwise matrices in normal matrix operations which operate row-by-row, each matrix element must be accessed on disk with a separate I/O operation. This will cause the operation to be much slower (10 to 100 times!) than when using normal rowwise matrices.
The only module in the current implementation of EMME/2 which uses columnwise matrices is the transit assignment. Since it needs to access all matrices by destinations (remember that the transit assignment is based on the optimal strategy to reach a given destination), all involved matrices are converted to columnwise storage format at the beginning of the assignment and transformed back to their original format at the end. If now a transit assignment is aborted by resetting or switching of the computer or by a system crash, the matrices used in the transit assignment remain columnwise.
A columnwise matrix can be converted back to a rowwise storage format
with module 3.12 option 3= modify a matrix
. Note that this module
also displays a warning message at the beginning if it detects any columnwise
matrices in the data bank.
The standard answer to this question is ``No!''. Normally,
if you see a columnwise (/c
) flag after a matrix identifier you
should take this as a sign of a problem that needs to be corrected
immediately.
The only explicit use of columnwise matrices I can think of as useful (under special circumstances!) is in the case where many transit assignments are to carried out all using the same fixed demand matrix. In this case, the time for converting the matrix to and from columnwise format (which essentially corresponds to a matrix transposition operation) in each assignment can be saved by explicitly converting this matrix to columnwise (using 3.12-4) before the first assignment and converting it back to rowwise again after all transit assignments have been carried out.