Calculations
These methods compute matrices, indicators and standalone IOT/SUT formula outputs. For normal database workflows, prefer the database compute API because it understands scenarios, table format and already materialized matrices.
For a compact spreadsheet overview of the nomenclature and worked matrix
calculations on the MARIO test IOT, SUT_IT and SUT_PT examples,
download the nomenclature and formulas workbook.
Reading the formulas#
Each standalone helper below documents its equation, inputs and returned axes.
The same information is available in Python with, for example,
help(mario.calc_fc). Matrix products use ordinary mathematical multiplication
in equations and @ in Python.
\(I\) is the identity matrix and \(\mathbf{1}\) is a vector of ones with the length required by the product.
\(\operatorname{diag}(x)\) puts a vector on the diagonal. \(\mathsf{T}\) denotes transpose.
\(Y\mathbf{1}\) sums final-demand categories and regions for each production node. It is
Y.sum(axis=1)in Python, not the matrixY.Subscripts \(a\) and \(c\) identify activity and commodity nodes in SUT formulas: \(e_a\) is
ea, \(f_c\) isfcand \(w_{aa}\) iswaain the API.
For example, \(F=f\operatorname{diag}(Y\mathbf{1})\) returns accounts by
production nodes. To retain the final-demand category columns, use the separate
matrix product f @ Y instead.
Coefficient helpers use an elementwise inverse of production, assigning zero to inverse entries where production is zero. The notation \(\operatorname{diag}(X)^{-1}\) describes this convention even when the diagonal matrix would be singular.
Database Compute API#
Method |
Use |
|---|---|
Materialize one or more requested matrices in a scenario. |
|
Resolve one matrix and return the materialized block. |
|
Resolve several matrices and return a mapping. |
|
Explain which compute path MARIO would use for one matrix. |
|
Calculate backward and forward linkage indicators. |
|
Build a greenhouse-gas aggregate extension from selected satellite rows. |
|
Aggregate one sector or commodity into a region-by-region trade matrix and optional heatmap. |
|
Calculate embodied trade content and, with |
|
Shortcut for |
|
Enumerate demand-driven structural paths for one indicator and final-demand bundle. |
|
Collapse embodied trade-content matrices into import accounts by destination Region. |
|
Collapse embodied trade-content matrices into export accounts by origin Region. |
|
Calculate embodied net imports as imports minus exports. |
|
Calculate contributor-region concentration of embodied trade content. |
|
Calculate embodied trade-content exposure to selected contributor Regions. |
Runtime Compute Options#
Demand-driven matrices such as the X total production vector, the f
total (direct+indirect) environmental transaction coefficients matrix, the
F total (direct+indirect) environmental transaction flows matrix, the m
total (direct+indirect) value added coefficients matrix, the M total
(direct+indirect) value added transaction matrix and the p price index
vector can be computed either through the explicit w Leontief inverse
matrix or through linear-system solves.
See mario.set_compute_method, mario.set_linear_solver and mario.set_linear_strategy.
The optional UMFPACK backend uses sparse direct LU for solve-based IOT and SUT
targets. Install scikit-umfpack and its SuiteSparse libraries, then select:
mario.set_compute_method("solve")
mario.set_linear_solver("umfpack")
mario.set_linear_strategy("direct")
auto is also supported as the linear strategy and selects direct solves
for UMFPACK. The iterative strategy requires the SciPy backend. Selecting
UMFPACK does not change matrices that are already materialized. It preserves
float64 precision and raises an error for failed solves instead of applying a
pseudo-inverse or least-squares fallback.
Sparse factorization uses 64-bit indices and compares fill-reducing orderings.
Singular diagonal blocks are diagnosed before native factorization, with the
affected node labels in the error message. Selecting a faster solver cannot
make a singular system invertible.
Singular systems raise an error by default. To request only independently determined coefficients, enable the partial policy explicitly:
mario.set_singular_policy("partial")
fc = db.fc
This policy applies to solve-based IOT and SUT targets with either SciPy or
UMFPACK, using a direct or automatic linear strategy. Singular components and
every coefficient depending on them become NaN; the remaining equations
are solved without changing their coefficients or right-hand sides. The
residual check applies to this independent subsystem, not to the full singular
system, which may be inconsistent or have nonunique solutions. Full inverse
requests still raise an error.
A mario.PartialResultWarning
reports the singular node labels and the affected coefficient count whenever
a partial result is computed. The result’s attrs["mario_partial"] records
the singular components and all affected node labels. MARIO compute reductions
and products preserve undefined values; when using pandas directly, pass
skipna=False to reductions such as fc.sum(axis=1, skipna=False).
User-defined pandas operations retain pandas’ usual missing-value behavior.
Use db.resolve("fc", compute_options=mario.ComputeOptions(
backend_override="sparse_direct", singular_policy="partial")) for a
per-call override. See
mario.set_singular_policy.
Changing the policy does not recompute already materialized matrices.
Resolvable Database Blocks#
SUT and IOT results can also be requested as named blocks through
db.resolve(...), db.resolve_many(...),
db.calc_all(...) and dotted access such as db.Xa or db.wcc.
See Resolvable Matrices and Blocks for the authoritative list of built-in block names currently supported by MARIO.
Standalone SUT Use, Supply and Quadrant Helpers#
These functions operate directly on pandas matrices, like calc_X and
calc_z. They return a result without changing a database. Open a function
for its signature, inputs, formula and returned axes.
u = mario.calc_u(U, Xa)
s = mario.calc_s(S, Xc) # Industry-based technology (IT).
s_pt = mario.calc_s(S, Xa=Xa, tech_assumption="PT")
wcc = mario.calc_wcc(u, s)
For scenario-aware calculation and automatic input resolution, the same blocks remain available through the database compute API.
Function |
Formula |
|---|---|
\[u = U\operatorname{diag}(X_a)^{-1}\]
|
|
\[U = u\operatorname{diag}(X_a)\]
|
|
\[\begin{split}s = \begin{cases}
S\operatorname{diag}(X_c)^{-1} & \text{IT},\\
\left(S^{\mathsf{T}}\operatorname{diag}(X_a)^{-1}\right)^{-1}
& \text{PT}.
\end{cases}\end{split}\]
|
|
\[\begin{split}S = \begin{cases}
s\operatorname{diag}(X_c) & \text{IT},\\
\left(c\operatorname{diag}(X_a)\right)^{\mathsf{T}},
\quad c=s^{-1} & \text{PT}.
\end{cases}\end{split}\]
|
|
\[c = S^{\mathsf{T}}\operatorname{diag}(X_a)^{-1}\]
|
|
\[X_a = S\mathbf{1} + Y_a\mathbf{1}\]
|
|
\[X_c = U\mathbf{1} + Y_c\mathbf{1}\]
|
|
\[w_{cc} = (I-us)^{-1}\]
|
|
\[w_{ca} = (I-us)^{-1}u = w_{cc}u\]
|
|
\[w_{ac} = (I-su)^{-1}s = w_{aa}s\]
|
|
\[w_{aa} = (I-su)^{-1}\]
|
|
\[b_u = \operatorname{diag}(X_c)^{-1}U\]
|
|
\[b_s = \operatorname{diag}(X_a)^{-1}S\]
|
|
\[g_{cc} = (I-b_u b_s)^{-1}\]
|
|
\[g_{ca} = g_{cc}b_u\]
|
|
\[g_{ac} = g_{aa}b_s\]
|
|
\[g_{aa} = (I-b_s b_u)^{-1}\]
|
|
\[p_a = w_{aa}^{\mathsf{T}}v_a^{\mathsf{T}}\mathbf{1} + w_{ca}^{\mathsf{T}}v_c^{\mathsf{T}}\mathbf{1}\]
|
|
\[p_c = w_{ac}^{\mathsf{T}}v_a^{\mathsf{T}}\mathbf{1} + w_{cc}^{\mathsf{T}}v_c^{\mathsf{T}}\mathbf{1}\]
|
Standalone IOT Helpers#
The functions below operate on pandas matrices directly. They do not mutate a
Database and they do not infer missing inputs. Select a function for its signature, parameters and returned axes.
Matrix names and descriptions follow the matrix catalogue and the IOT guide.
Function |
Formula |
|---|---|
\(X = Z\mathbf{1} + Y\mathbf{1}\) |
|
\(z = Z\operatorname{diag}(X)^{-1}\) |
|
\(Z = z\operatorname{diag}(X)\) |
|
\(w = (I-z)^{-1}\) |
|
\(X = w(Y\mathbf{1})\) |
|
\((I-z)X = Y\mathbf{1}\) |
|
\(v = V\operatorname{diag}(X)^{-1}\) \(V = v\operatorname{diag}(X)\) |
|
\(e = E\operatorname{diag}(X)^{-1}\) \(E = e\operatorname{diag}(X)\) |
|
\(m = vw = v(I-z)^{-1}\) |
|
\(f = ew = e(I-z)^{-1}\) |
|
\(M = m\operatorname{diag}(Y\mathbf{1})\) |
|
\(F = f\operatorname{diag}(Y\mathbf{1})\) |
|
\(p = w^{\mathsf{T}}v^{\mathsf{T}}\mathbf{1}\) |
|
\(b = \operatorname{diag}(X)^{-1}Z\) \(g = (I-b)^{-1}\) |
|
\(y = Y / (\mathbf{1}^{\mathsf{T}}Y\mathbf{1})\) |
|
\(f_{\mathrm{dis}} = \operatorname{diag}(e_k)w\) |
Standalone SUT Split Helpers#
The functions below operate on split SUT blocks directly. They are useful when
you already have activity-side and commodity-side blocks as pandas matrices and
want one standalone numerical helper instead of resolving through a
Database.
The total multipliers include both activity-side and commodity-side direct
coefficients. In calc_ma / calc_fa, supplying vc / ec also
requires u. Omitting the commodity-side argument sets that term to zero.
Here \(u\) has commodity rows and activity columns; \(s\) has activity
rows and commodity columns. Consequently,
\(w_{aa}=(I-su)^{-1}\) and \(w_{cc}=(I-us)^{-1}\).
Function |
Formula |
|---|---|
\(v_a = V_a\operatorname{diag}(X_a)^{-1}\) \(V_a = v_a\operatorname{diag}(X_a)\) |
|
\(v_c = V_c\operatorname{diag}(X_c)^{-1}\) \(V_c = v_c\operatorname{diag}(X_c)\) |
|
\(e_a = E_a\operatorname{diag}(X_a)^{-1}\) \(E_a = e_a\operatorname{diag}(X_a)\) |
|
\(e_c = E_c\operatorname{diag}(X_c)^{-1}\) \(E_c = e_c\operatorname{diag}(X_c)\) |
|
\(m_a = (v_a+v_cu)w_{aa}\) \(M_a = m_a\operatorname{diag}(s(Y_c\mathbf{1}))\) |
|
\(m_c = (v_as+v_c)w_{cc}\) \(M_c = m_c\operatorname{diag}(Y_c\mathbf{1})\) |
|
\(f_a = (e_a+e_cu)w_{aa}\) \(F_a = f_a\operatorname{diag}(s(Y_c\mathbf{1}))\) |
|
\(f_c = (e_as+e_c)w_{cc}\) \(F_c = f_c\operatorname{diag}(Y_c\mathbf{1})\) |
Exploded Multiplier Matrices#
These methods decompose multiplier (f, m, p) matrices by stacking
scaled transfer matrices. IOT and SUT use separate methods.
The f_ex and m_ex families return a (account/factor, region,
sector) MultiIndex on rows, while the p_ex family returns aggregated
contributions whose rows identify the contributing region-sector.
The _all property variants (e.g. db.f_ex_all) are zero-argument
shorthands that return the full matrix for all accounts/factors at baseline
scenario. Use the method form (e.g. db.f_ex(...)) to filter or select a
different scenario.
In the formulas below, a two-block column means vertical concatenation:
activity contributors first, then commodity contributors.
The subscript k selects one satellite account and h selects one factor.
Summing contributor rows recovers the corresponding total coefficient or price
index. These are multiplier contributions; final demand is not applied.
Method / table |
Formula |
|---|---|
db.f_ex(…) (IOT) |
\(f_{\mathrm{ex}} = \operatorname{diag}(e_k)\,w\) |
db.fa_ex(…) (SUT) |
\(f_{a,\mathrm{ex}} = \begin{bmatrix} \operatorname{diag}(e_{a,k})w_{aa} \\ \operatorname{diag}(e_{c,k})w_{ca} \end{bmatrix}\) |
db.fc_ex(…) (SUT) |
\(f_{c,\mathrm{ex}} = \begin{bmatrix} \operatorname{diag}(e_{a,k})s\,w_{cc} \\ \operatorname{diag}(e_{c,k})w_{cc} \end{bmatrix}\) |
db.m_ex(…) (IOT) |
\(m_{\mathrm{ex}} = \operatorname{diag}(v_h)\,w\) |
db.ma_ex(…) (SUT) |
\(m_{a,\mathrm{ex}} = \begin{bmatrix} \operatorname{diag}(v_{a,h})w_{aa} \\ \operatorname{diag}(v_{c,h})w_{ca} \end{bmatrix}\) |
db.mc_ex(…) (SUT) |
\(m_{c,\mathrm{ex}} = \begin{bmatrix} \operatorname{diag}(v_{a,h})s\,w_{cc} \\ \operatorname{diag}(v_{c,h})w_{cc} \end{bmatrix}\) |
db.p_ex(…) (IOT) |
\(p_{\mathrm{ex}} = \operatorname{diag}(v^{\mathsf{T}}\mathbf{1})\,w\) |
db.pa_ex(…) (SUT) |
\(p_{a,\mathrm{ex}} = \begin{bmatrix} \operatorname{diag}(v_a^{\mathsf{T}}\mathbf{1})w_{aa} \\ \operatorname{diag}(v_c^{\mathsf{T}}\mathbf{1})w_{ca} \end{bmatrix}\) |
db.pc_ex(…) (SUT) |
\(p_{c,\mathrm{ex}} = \begin{bmatrix} \operatorname{diag}(v_a^{\mathsf{T}}\mathbf{1})s\,w_{cc} \\ \operatorname{diag}(v_c^{\mathsf{T}}\mathbf{1})w_{cc} \end{bmatrix}\) |