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 matrix Y.

  • Subscripts \(a\) and \(c\) identify activity and commodity nodes in SUT formulas: \(e_a\) is ea, \(f_c\) is fc and \(w_{aa}\) is waa in 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

db.calc_all(…)

Materialize one or more requested matrices in a scenario.

db.resolve(…)

Resolve one matrix and return the materialized block.

db.resolve_many(…)

Resolve several matrices and return a mapping.

db.explain(…)

Explain which compute path MARIO would use for one matrix.

db.calc_linkages(…)

Calculate backward and forward linkage indicators.

db.calc_ghg(…)

Build a greenhouse-gas aggregate extension from selected satellite rows.

db.calc_trades(…)

Aggregate one sector or commodity into a region-by-region trade matrix and optional heatmap.

db.calc_trades_content(…)

Calculate embodied trade content and, with breakdown=True, decompose it by contributor.

db.calc_trades_content_breakdown(…)

Shortcut for db.calc_trades_content(..., breakdown=True).

db.calc_spa(…)

Enumerate demand-driven structural paths for one indicator and final-demand bundle.

db.calc_embodied_imports(…)

Collapse embodied trade-content matrices into import accounts by destination Region.

db.calc_embodied_exports(…)

Collapse embodied trade-content matrices into export accounts by origin Region.

db.calc_embodied_net_imports(…)

Calculate embodied net imports as imports minus exports.

db.calc_trades_concentration(…)

Calculate contributor-region concentration of embodied trade content.

db.calc_trades_exposure(…)

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

calc_u()

\[u = U\operatorname{diag}(X_a)^{-1}\]

calc_U()

\[U = u\operatorname{diag}(X_a)\]

calc_s()

\[\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}\]

calc_S()

\[\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}\]

calc_c()

\[c = S^{\mathsf{T}}\operatorname{diag}(X_a)^{-1}\]

calc_Xa()

\[X_a = S\mathbf{1} + Y_a\mathbf{1}\]

calc_Xc()

\[X_c = U\mathbf{1} + Y_c\mathbf{1}\]

calc_wcc()

\[w_{cc} = (I-us)^{-1}\]

calc_wca()

\[w_{ca} = (I-us)^{-1}u = w_{cc}u\]

calc_wac()

\[w_{ac} = (I-su)^{-1}s = w_{aa}s\]

calc_waa()

\[w_{aa} = (I-su)^{-1}\]

calc_bu()

\[b_u = \operatorname{diag}(X_c)^{-1}U\]

calc_bs()

\[b_s = \operatorname{diag}(X_a)^{-1}S\]

calc_gcc()

\[g_{cc} = (I-b_u b_s)^{-1}\]

calc_gca()

\[g_{ca} = g_{cc}b_u\]

calc_gac()

\[g_{ac} = g_{aa}b_s\]

calc_gaa()

\[g_{aa} = (I-b_s b_u)^{-1}\]

calc_pa()

\[p_a = w_{aa}^{\mathsf{T}}v_a^{\mathsf{T}}\mathbf{1} + w_{ca}^{\mathsf{T}}v_c^{\mathsf{T}}\mathbf{1}\]

calc_pc()

\[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

calc_X()

\(X = Z\mathbf{1} + Y\mathbf{1}\)

calc_z()

\(z = Z\operatorname{diag}(X)^{-1}\)

calc_Z()

\(Z = z\operatorname{diag}(X)\)

calc_w()

\(w = (I-z)^{-1}\)

calc_X_from_w()

\(X = w(Y\mathbf{1})\)

calc_X_from_z()

\((I-z)X = Y\mathbf{1}\)

calc_v() / calc_V()

\(v = V\operatorname{diag}(X)^{-1}\)

\(V = v\operatorname{diag}(X)\)

calc_e() / calc_E()

\(e = E\operatorname{diag}(X)^{-1}\)

\(E = e\operatorname{diag}(X)\)

calc_m() / calc_m_from_z()

\(m = vw = v(I-z)^{-1}\)

calc_f() / calc_f_from_z()

\(f = ew = e(I-z)^{-1}\)

calc_M()

\(M = m\operatorname{diag}(Y\mathbf{1})\)

calc_F()

\(F = f\operatorname{diag}(Y\mathbf{1})\)

calc_p() / calc_p_from_z()

\(p = w^{\mathsf{T}}v^{\mathsf{T}}\mathbf{1}\)

calc_b() / calc_g()

\(b = \operatorname{diag}(X)^{-1}Z\)

\(g = (I-b)^{-1}\)

calc_y()

\(y = Y / (\mathbf{1}^{\mathsf{T}}Y\mathbf{1})\)

calc_f_dis()

\(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

calc_va() / calc_Va()

\(v_a = V_a\operatorname{diag}(X_a)^{-1}\)

\(V_a = v_a\operatorname{diag}(X_a)\)

calc_vc() / calc_Vc()

\(v_c = V_c\operatorname{diag}(X_c)^{-1}\)

\(V_c = v_c\operatorname{diag}(X_c)\)

calc_ea() / calc_Ea()

\(e_a = E_a\operatorname{diag}(X_a)^{-1}\)

\(E_a = e_a\operatorname{diag}(X_a)\)

calc_ec() / calc_Ec()

\(e_c = E_c\operatorname{diag}(X_c)^{-1}\)

\(E_c = e_c\operatorname{diag}(X_c)\)

calc_ma() / calc_Ma()

\(m_a = (v_a+v_cu)w_{aa}\)

\(M_a = m_a\operatorname{diag}(s(Y_c\mathbf{1}))\)

calc_mc() / calc_Mc()

\(m_c = (v_as+v_c)w_{cc}\)

\(M_c = m_c\operatorname{diag}(Y_c\mathbf{1})\)

calc_fa() / calc_Fa()

\(f_a = (e_a+e_cu)w_{aa}\)

\(F_a = f_a\operatorname{diag}(s(Y_c\mathbf{1}))\)

calc_fc() / calc_Fc()

\(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}\)