# Tabular Matrix Problems via Pseudoinverse Estimation
The **Tabular Matrix Problems via Pseudoinverse Estimation (TMPinv)** is a two-stage estimation method that reformulates structured table-based systems — such as allocation problems, transaction matrices, and input–output tables — as structured least-squares problems. Based on the [Convex Least Squares Programming (CLSP)](https://pypi.org/project/pyclsp/ "Convex Least Squares Programming") framework, TMPinv solves systems with row and column constraints, block structure, and optionally reduced dimensionality by (1) constructing a canonical constraint form and applying a pseudoinverse-based projection, followed by (2) a convex-programming refinement stage to improve fit, coherence, and regularization (e.g., via Lasso, Ridge, or Elastic Net). All calculations are performed in numpy.float64 precision.
## Installation
```bash
pip install tmpinv
```
## Quick Example
```python
import numpy as np
from tmpinv import tmpinv
import matplotlib.pyplot as plt
# AP (TM), based on a symmetric input-output table, with 10% of known values
seed = 123456789
rng = np.random.default_rng(seed)
# sample (dataset)
m, p = 20, 20 # matrix dimensions (m x p)
X_true = np.abs(rng.normal(size=(m, p))) # symmetric non-negative X_true
X_true = (X_true + X_true.T) / 2.0
idx = rng.choice(m * p, size=max(1, int(0.1 * (m * p))), # random numbers from
replace=False) # [0,(m * p) - 1], 10% of total
# model
M = np.eye(m * p)[idx,:] # unit matrix
b_row = X_true.sum(axis=1) # row sums (length m)
b_col = X_true.sum(axis=0) # column sums (length p)
b_val = X_true.reshape(-1, 1)[idx] # column vector
bounds = (0, None) # non-negativity
result = tmpinv(
M=M, b_row=b_row, b_col=b_col, b_val=b_val,
m=m, p=p, bounds=bounds, symmetric=True,
r=1, # a solution without refinement
alpha=1.0 # a unique MNBLUE estimator
)
# helpers
def fmt(v):
v = float(v)
return f"{v:.4e}" if abs(v) >= 1e6 or (v != 0 and abs(v) < 1e-4) else f"{v:.6f}"
# results
print("true X:")
print(np.round(np.asarray(X_true), 4))
print("X_hat:")
print(np.round(result.x, 4))
print("\nNumerical stability:")
print(" kappaC :", fmt(result.model.kappaC))
print(" kappaB :", fmt(result.model.kappaB))
print(" kappaA :", fmt(result.model.kappaA))
corr = result.model.corr()
plt.figure(figsize=(8, 4))
plt.grid(True, linestyle="--", alpha=0.6)
plt.bar(range(len(corr["rmsa_i"])), corr["rmsa_i"])
plt.xlabel("Constraint index")
plt.ylabel("dRMSA (row deletion effect)")
plt.title(f"CLSP Correlogram (Total RMSA = {result.model.rmsa:.2f})")
plt.tight_layout()
plt.show()
print("\nGoodness-of-fit:")
x_true = X_true.flatten()
x_hat = result.x.flatten()
ss_res = np.sum((x_true - x_hat) ** 2)
ss_tot = np.sum((x_true - np.mean(x_true)) ** 2)
print(" R2_user_defined :", fmt(1 - ss_res / ss_tot))
print(" NRMSE :", fmt(result.model.nrmse))
print(" Diagnostic band (min):", fmt(np.min(result.model.x_lower)))
print(" Diagnostic band (max):", fmt(np.max(result.model.x_upper)))
print(" Monte Carlo t-test:")
for kw, val in result.model.ttest(sample_size=30, # NRMSE sample
seed=seed, distribution="normal", # seed and distribution
partial=True).items():
print(f" {kw}: {float(val):.6f}")
# AP (TM), based on a trade matrix, with a zero diagonal and 20% of known values
seed = 123456789
rng = np.random.default_rng(seed)
# sample (dataset)
m, p = 40, 40 # matrix dimensions (m x p)
X_true = np.abs(rng.normal(size=(m, p))) # non-negative X_true
X_true = X_true * (1 - np.eye(m, p)) # zero diagonal
idx = rng.choice(m * p, size=max(1, int(0.2 * (m * p))), # random numbers from
replace=False) # [0,(m * p) - 1], 20% of total
# model
M = np.eye(m * p)[idx,:] # unit matrix
b_row = X_true.sum(axis=1) # row sums (length m)
b_col = X_true.sum(axis=0) # column sums (length p)
b_val = X_true.reshape(-1, 1)[idx] # column vector
bounds = (0, None) # non-negativity
result = tmpinv(
M=M, b_row=b_row, b_col=b_col, b_val=b_val,
m=m, p=p, zero_diagonal=True, reduced=(20,20), # reduced models of (20, 20)
bounds=bounds,
r=1, # a solution without refinement
alpha=1.0 # a unique MNBLUE estimator
)
# helpers
def fmt(v):
v = float(v)
return f"{v:.4e}" if abs(v) >= 1e6 or (v != 0 and abs(v) < 1e-4) else f"{v:.6f}"
# results
print("true X:")
print(np.round(np.asarray(X_true), 4))
print("X_hat:")
print(np.round(result.x, 4))
print("\nNumerical stability (min-max across models):")
kappaC = np.array([CLSP.kappaC for CLSP in result.model])
kappaB = np.array([CLSP.kappaB for CLSP in result.model])
kappaA = np.array([CLSP.kappaA for CLSP in result.model])
print(" kappaC :", fmt(np.min(kappaC)), "-", fmt(np.max(kappaC)))
print(" kappaB :", fmt(np.min(kappaB)), "-", fmt(np.max(kappaB)))
print(" kappaA :", fmt(np.min(kappaA)), "-", fmt(np.max(kappaA)))
print("\nGoodness-of-fit (min-max across models):")
x_true = X_true.flatten()
x_hat = result.x.flatten()
mask = np.isfinite(x_true) & np.isfinite(x_hat)
if mask.any():
ss_res = np.sum((x_true[mask] - x_hat[mask])**2)
ss_tot = np.sum((x_true[mask] - np.mean(x_true[mask]))**2)
nrmse = np.array( [CLSP.nrmse for CLSP in result.model])
x_lower = np.concatenate([np.array(CLSP.x_lower).reshape(-1) for CLSP in result.model])
x_upper = np.concatenate([np.array(CLSP.x_upper).reshape(-1) for CLSP in result.model])
print(" R2_user_defined :", fmt(1 - ss_res / ss_tot ))
print(" NRMSE :", fmt(np.min(nrmse)), "-", fmt(np.max(nrmse) ))
print(" Diagnostic band (min):", fmt(np.min(x_lower)), "-", fmt(np.max(x_lower) ))
print(" Diagnostic band (max):", fmt(np.min(x_upper)), "-", fmt(np.max(x_upper) ))
print(" Monte Carlo t-test:")
ttests = [CLSP.ttest(sample_size=30, seed=seed,
distribution="normal") for CLSP in result.model]
keys = ttests[0].keys()
for kw in keys:
val = np.array([t[kw] for t in ttests], dtype=float)
print(f" {kw}: {fmt(np.min(val))} - {fmt(np.max(val))}")
```
## User Reference
For comprehensive information on the estimator's capabilities, advanced configuration options, and implementation details, please refer to the [pyclsp module](https://pypi.org/project/pyclsp/ "Convex Least Squares Programming"), on which TMPinv is based.
**TMPINV Parameters:**
`S` : *array_like* of shape *(m + p, m + p)*, optional
A diagonal sign slack (surplus) matrix with entries in *{0, ±1}*.
- *0* enforces equality (== `b_row` or `b_col`),
- *1* enforces a lower-than-or-equal (≤) condition,
- *–1* enforces a greater-than-or-equal (≥) condition.
The first `m` diagonal entries correspond to row constraints, and the remaining `p` to column constraints. Please note that, in the reduced model, `S` is ignored: slack behavior is derived implicitly from block-wise marginal totals.
`M` : *array_like* of shape *(k, m * p)*, optional
A model matrix with entries in *{0, 1}*. Each row defines a linear restriction on the flattened solution matrix. The corresponding right-hand side values must be provided in `b_val`. This block is used to encode known cell values. Please note that, in the reduced model, `M` must be a unique row subset of an identity matrix (i.e., diagonal-only). Arbitrary or non-diagonal model matrices cannot be mapped to reduced blocks, making the model infeasible.
`b_row` : *array_like* of shape *(m,)*
Right-hand side vector of row totals. Please note that both `b_row` and `b_col` must be provided.
`b_col` : *array_like* of shape *(p,)*
Right-hand side vector of column totals. Please note that both `b_row` and `b_col` must be provided.
`b_val` : *array_like* of shape *(k,)*
Right-hand side vector of known cell values.
`i` : *int*, default = *1*
Number of row groups.
`j` : *int*, default = *1*
Number of column groups.
`zero_diagonal` : *bool*, default = *False*
If *True*, enforces the zero diagonal.
`reduced` : *tuple* of *(int, int)*, optional
Dimensions of the reduced problem. If specified, the problem is estimated as a set of reduced problems constructed from contiguous submatrices of the original table. For example, `reduced` = *(6, 6)* implies *5×5* data blocks with *1* slack row and *1* slack column each (edge blocks may be smaller).
`symmetric` : *bool*, default = *False*
If True, enforces symmetry of the estimated solution matrix as: x = 0.5 * (x + x.T)
Applies to TMPinvResult.x only. For TMPinvResult.model symmetry, add explicit symmetry constraints to M in a full-model solve instead of using this flag.
`bounds` : *sequence* of *(low, high)*, optional
Bounds on cell values. If a single tuple *(low, high)* is given, it is applied to all `m` * `p` cells. Example: *(0, None)*.
`replace_value` : *float* or *None*, default = *np.nan*
Final replacement value for any cell in the solution matrix that violates the specified bounds by more than the given tolerance.
`tolerance` : *float*, default = *square root of machine epsilon*
Convergence tolerance for bounds.
`iteration_limit` : *int*, default = *50*
Maximum number of iterations allowed in the refinement loop.
**CLSP Parameters:**
`r` : *int*, default = *1*
Number of refinement iterations for the pseudoinverse-based estimator.
`Z` : *np.ndarray* or *None*
A symmetric idempotent matrix (projector) defining the subspace for Bott–Duffin pseudoinversion. If *None*, the identity matrix is used, reducing the Bott–Duffin inverse to the Moore–Penrose case.
`final` : *bool*, default = *True*
If *True*, a convex programming problem is solved to refine `zhat`. The resulting solution `z` minimizes a weighted L1/L2 norm around `zhat` subject to `Az = b`.
`alpha` : *float*, *list[float]* or *None*, default = *None*
Regularization parameter (weight) in the final convex program:
- `α = 0`: Lasso (L1 norm)
- `α = 1`: Tikhonov Regularization/Ridge (L2 norm)
- `0 < α < 1`: Elastic Net
If a scalar float is provided, that value is used after clipping to [0, 1].
If a list/iterable of floats is provided, each candidate is evaluated via a full solve, and the α with the smallest NRMSE is selected.
If None, α is chosen, based on an error rule: α = min(1.0, NRMSE_{α = 0} / (NRMSE_{α = 0} + NRMSE_{α = 1} + tolerance))
`*args`, `**kwargs` : optional
CVXPY arguments passed to the CVXPY solver.
**Returns:**
*TMPinvResult*
`TMPinvResult.full` : *bool*
Indicates if this result comes from the full (non-reduced) model.
`TMPinvResult.model` : *CLSP* or *list* of *CLSP*
A single CLSP object in the full model, or a list of CLSP objects for each reduced block in the reduced model.
`TMPinvResult.x` : *np.ndarray*
Final estimated solution matrix of shape *(m, p)*.
## Bibliography
To be added.
## License
MIT License — see the [LICENSE](LICENSE) file.
Raw data
{
"_id": null,
"home_page": null,
"name": "pytmpinv",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "tabular-matrix-problems, convex-optimization, least-squares, generalized-inverse, regularization",
"author": null,
"author_email": "The Economist <29724411+econcz@users.noreply.github.com>",
"download_url": "https://files.pythonhosted.org/packages/70/bd/59278986d461966ea6595751df6fce18422ef0305ce7356d1bc7e0358577/pytmpinv-1.2.0.tar.gz",
"platform": null,
"description": "# Tabular Matrix Problems via Pseudoinverse Estimation\n\nThe **Tabular Matrix Problems via Pseudoinverse Estimation (TMPinv)** is a two-stage estimation method that reformulates structured table-based systems \u2014 such as allocation problems, transaction matrices, and input\u2013output tables \u2014 as structured least-squares problems. Based on the [Convex Least Squares Programming (CLSP)](https://pypi.org/project/pyclsp/ \"Convex Least Squares Programming\") framework, TMPinv solves systems with row and column constraints, block structure, and optionally reduced dimensionality by (1) constructing a canonical constraint form and applying a pseudoinverse-based projection, followed by (2) a convex-programming refinement stage to improve fit, coherence, and regularization (e.g., via Lasso, Ridge, or Elastic Net). All calculations are performed in numpy.float64 precision.\n\n## Installation\n\n```bash\npip install tmpinv\n```\n\n## Quick Example\n\n```python\nimport numpy as np\nfrom tmpinv import tmpinv\nimport matplotlib.pyplot as plt\n\n# AP (TM), based on a symmetric input-output table, with 10% of known values\n\nseed = 123456789\nrng = np.random.default_rng(seed)\n\n# sample (dataset)\nm, p = 20, 20 # matrix dimensions (m x p)\nX_true = np.abs(rng.normal(size=(m, p))) # symmetric non-negative X_true\nX_true = (X_true + X_true.T) / 2.0\nidx = rng.choice(m * p, size=max(1, int(0.1 * (m * p))), # random numbers from\n replace=False) # [0,(m * p) - 1], 10% of total\n\n# model\nM = np.eye(m * p)[idx,:] # unit matrix\nb_row = X_true.sum(axis=1) # row sums (length m)\nb_col = X_true.sum(axis=0) # column sums (length p)\nb_val = X_true.reshape(-1, 1)[idx] # column vector\nbounds = (0, None) # non-negativity\nresult = tmpinv(\n M=M, b_row=b_row, b_col=b_col, b_val=b_val,\n m=m, p=p, bounds=bounds, symmetric=True,\n r=1, # a solution without refinement\n alpha=1.0 # a unique MNBLUE estimator\n )\n\n# helpers\ndef fmt(v):\n v = float(v)\n return f\"{v:.4e}\" if abs(v) >= 1e6 or (v != 0 and abs(v) < 1e-4) else f\"{v:.6f}\"\n\n# results\nprint(\"true X:\")\nprint(np.round(np.asarray(X_true), 4))\nprint(\"X_hat:\")\nprint(np.round(result.x, 4))\n\nprint(\"\\nNumerical stability:\")\nprint(\" kappaC :\", fmt(result.model.kappaC))\nprint(\" kappaB :\", fmt(result.model.kappaB))\nprint(\" kappaA :\", fmt(result.model.kappaA))\ncorr = result.model.corr()\nplt.figure(figsize=(8, 4))\nplt.grid(True, linestyle=\"--\", alpha=0.6)\nplt.bar(range(len(corr[\"rmsa_i\"])), corr[\"rmsa_i\"])\nplt.xlabel(\"Constraint index\")\nplt.ylabel(\"dRMSA (row deletion effect)\")\nplt.title(f\"CLSP Correlogram (Total RMSA = {result.model.rmsa:.2f})\")\nplt.tight_layout()\nplt.show()\n\nprint(\"\\nGoodness-of-fit:\")\nx_true = X_true.flatten()\nx_hat = result.x.flatten()\nss_res = np.sum((x_true - x_hat) ** 2)\nss_tot = np.sum((x_true - np.mean(x_true)) ** 2)\nprint(\" R2_user_defined :\", fmt(1 - ss_res / ss_tot))\nprint(\" NRMSE :\", fmt(result.model.nrmse))\nprint(\" Diagnostic band (min):\", fmt(np.min(result.model.x_lower)))\nprint(\" Diagnostic band (max):\", fmt(np.max(result.model.x_upper)))\nprint(\" Monte Carlo t-test:\")\nfor kw, val in result.model.ttest(sample_size=30, # NRMSE sample\n seed=seed, distribution=\"normal\", # seed and distribution\n partial=True).items():\n print(f\" {kw}: {float(val):.6f}\")\n\n# AP (TM), based on a trade matrix, with a zero diagonal and 20% of known values\n\nseed = 123456789\nrng = np.random.default_rng(seed)\n\n# sample (dataset)\nm, p = 40, 40 # matrix dimensions (m x p)\nX_true = np.abs(rng.normal(size=(m, p))) # non-negative X_true\nX_true = X_true * (1 - np.eye(m, p)) # zero diagonal\nidx = rng.choice(m * p, size=max(1, int(0.2 * (m * p))), # random numbers from\n replace=False) # [0,(m * p) - 1], 20% of total\n\n# model\nM = np.eye(m * p)[idx,:] # unit matrix\nb_row = X_true.sum(axis=1) # row sums (length m)\nb_col = X_true.sum(axis=0) # column sums (length p)\nb_val = X_true.reshape(-1, 1)[idx] # column vector\nbounds = (0, None) # non-negativity\nresult = tmpinv(\n M=M, b_row=b_row, b_col=b_col, b_val=b_val,\n m=m, p=p, zero_diagonal=True, reduced=(20,20), # reduced models of (20, 20)\n bounds=bounds,\n r=1, # a solution without refinement\n alpha=1.0 # a unique MNBLUE estimator\n )\n\n# helpers\ndef fmt(v):\n v = float(v)\n return f\"{v:.4e}\" if abs(v) >= 1e6 or (v != 0 and abs(v) < 1e-4) else f\"{v:.6f}\"\n\n# results\nprint(\"true X:\")\nprint(np.round(np.asarray(X_true), 4))\nprint(\"X_hat:\")\nprint(np.round(result.x, 4))\n\nprint(\"\\nNumerical stability (min-max across models):\")\nkappaC = np.array([CLSP.kappaC for CLSP in result.model])\nkappaB = np.array([CLSP.kappaB for CLSP in result.model])\nkappaA = np.array([CLSP.kappaA for CLSP in result.model])\nprint(\" kappaC :\", fmt(np.min(kappaC)), \"-\", fmt(np.max(kappaC)))\nprint(\" kappaB :\", fmt(np.min(kappaB)), \"-\", fmt(np.max(kappaB)))\nprint(\" kappaA :\", fmt(np.min(kappaA)), \"-\", fmt(np.max(kappaA)))\n\nprint(\"\\nGoodness-of-fit (min-max across models):\")\nx_true = X_true.flatten()\nx_hat = result.x.flatten()\nmask = np.isfinite(x_true) & np.isfinite(x_hat)\nif mask.any():\n ss_res = np.sum((x_true[mask] - x_hat[mask])**2)\n ss_tot = np.sum((x_true[mask] - np.mean(x_true[mask]))**2)\nnrmse = np.array( [CLSP.nrmse for CLSP in result.model])\nx_lower = np.concatenate([np.array(CLSP.x_lower).reshape(-1) for CLSP in result.model])\nx_upper = np.concatenate([np.array(CLSP.x_upper).reshape(-1) for CLSP in result.model])\nprint(\" R2_user_defined :\", fmt(1 - ss_res / ss_tot ))\nprint(\" NRMSE :\", fmt(np.min(nrmse)), \"-\", fmt(np.max(nrmse) ))\nprint(\" Diagnostic band (min):\", fmt(np.min(x_lower)), \"-\", fmt(np.max(x_lower) ))\nprint(\" Diagnostic band (max):\", fmt(np.min(x_upper)), \"-\", fmt(np.max(x_upper) ))\nprint(\" Monte Carlo t-test:\")\nttests = [CLSP.ttest(sample_size=30, seed=seed,\n distribution=\"normal\") for CLSP in result.model]\nkeys = ttests[0].keys()\nfor kw in keys:\n val = np.array([t[kw] for t in ttests], dtype=float)\n print(f\" {kw}: {fmt(np.min(val))} - {fmt(np.max(val))}\")\n```\n\n## User Reference\n\nFor comprehensive information on the estimator's capabilities, advanced configuration options, and implementation details, please refer to the [pyclsp module](https://pypi.org/project/pyclsp/ \"Convex Least Squares Programming\"), on which TMPinv is based.\n\n**TMPINV Parameters:**\n\n`S` : *array_like* of shape *(m + p, m + p)*, optional\nA diagonal sign slack (surplus) matrix with entries in *{0, \u00b11}*.\n- *0* enforces equality (== `b_row` or `b_col`),\n- *1* enforces a lower-than-or-equal (\u2264) condition,\n- *\u20131* enforces a greater-than-or-equal (\u2265) condition.\n\nThe first `m` diagonal entries correspond to row constraints, and the remaining `p` to column constraints. Please note that, in the reduced model, `S` is ignored: slack behavior is derived implicitly from block-wise marginal totals.\n\n`M` : *array_like* of shape *(k, m * p)*, optional\nA model matrix with entries in *{0, 1}*. Each row defines a linear restriction on the flattened solution matrix. The corresponding right-hand side values must be provided in `b_val`. This block is used to encode known cell values. Please note that, in the reduced model, `M` must be a unique row subset of an identity matrix (i.e., diagonal-only). Arbitrary or non-diagonal model matrices cannot be mapped to reduced blocks, making the model infeasible.\n\n`b_row` : *array_like* of shape *(m,)*\nRight-hand side vector of row totals. Please note that both `b_row` and `b_col` must be provided.\n\n`b_col` : *array_like* of shape *(p,)*\nRight-hand side vector of column totals. Please note that both `b_row` and `b_col` must be provided.\n\n`b_val` : *array_like* of shape *(k,)*\nRight-hand side vector of known cell values.\n\n`i` : *int*, default = *1*\nNumber of row groups.\n\n`j` : *int*, default = *1*\nNumber of column groups.\n\n`zero_diagonal` : *bool*, default = *False*\nIf *True*, enforces the zero diagonal.\n\n`reduced` : *tuple* of *(int, int)*, optional\nDimensions of the reduced problem. If specified, the problem is estimated as a set of reduced problems constructed from contiguous submatrices of the original table. For example, `reduced` = *(6, 6)* implies *5\u00d75* data blocks with *1* slack row and *1* slack column each (edge blocks may be smaller).\n\n`symmetric` : *bool*, default = *False*\nIf True, enforces symmetry of the estimated solution matrix as: x = 0.5 * (x + x.T)\nApplies to TMPinvResult.x only. For TMPinvResult.model symmetry, add explicit symmetry constraints to M in a full-model solve instead of using this flag.\n\n`bounds` : *sequence* of *(low, high)*, optional\nBounds on cell values. If a single tuple *(low, high)* is given, it is applied to all `m` * `p` cells. Example: *(0, None)*.\n\n`replace_value` : *float* or *None*, default = *np.nan*\nFinal replacement value for any cell in the solution matrix that violates the specified bounds by more than the given tolerance.\n\n`tolerance` : *float*, default = *square root of machine epsilon*\nConvergence tolerance for bounds.\n\n`iteration_limit` : *int*, default = *50*\nMaximum number of iterations allowed in the refinement loop.\n\n**CLSP Parameters:**\n\n`r` : *int*, default = *1*\nNumber of refinement iterations for the pseudoinverse-based estimator.\n\n`Z` : *np.ndarray* or *None*\nA symmetric idempotent matrix (projector) defining the subspace for Bott\u2013Duffin pseudoinversion. If *None*, the identity matrix is used, reducing the Bott\u2013Duffin inverse to the Moore\u2013Penrose case.\n\n`final` : *bool*, default = *True*\nIf *True*, a convex programming problem is solved to refine `zhat`. The resulting solution `z` minimizes a weighted L1/L2 norm around `zhat` subject to `Az = b`.\n\n`alpha` : *float*, *list[float]* or *None*, default = *None*\n Regularization parameter (weight) in the final convex program:\n - `\u03b1 = 0`: Lasso (L1 norm)\n - `\u03b1 = 1`: Tikhonov Regularization/Ridge (L2 norm)\n - `0 < \u03b1 < 1`: Elastic Net\n If a scalar float is provided, that value is used after clipping to [0, 1].\n If a list/iterable of floats is provided, each candidate is evaluated via a full solve, and the \u03b1 with the smallest NRMSE is selected.\n If None, \u03b1 is chosen, based on an error rule: \u03b1 = min(1.0, NRMSE_{\u03b1 = 0} / (NRMSE_{\u03b1 = 0} + NRMSE_{\u03b1 = 1} + tolerance))\n\n`*args`, `**kwargs` : optional\nCVXPY arguments passed to the CVXPY solver.\n\n**Returns:**\n*TMPinvResult*\n\n`TMPinvResult.full` : *bool*\nIndicates if this result comes from the full (non-reduced) model.\n\n`TMPinvResult.model` : *CLSP* or *list* of *CLSP*\nA single CLSP object in the full model, or a list of CLSP objects for each reduced block in the reduced model.\n\n`TMPinvResult.x` : *np.ndarray*\nFinal estimated solution matrix of shape *(m, p)*.\n\n## Bibliography\n\nTo be added.\n\n## License\n\nMIT License \u2014 see the [LICENSE](LICENSE) file.\n",
"bugtrack_url": null,
"license": null,
"summary": "Tabular Matrix Problems via Pseudoinverse Estimation",
"version": "1.2.0",
"project_urls": {
"Bug Tracker": "https://github.com/econcz/pytmpinv/issues",
"Homepage": "https://github.com/econcz/pytmpinv"
},
"split_keywords": [
"tabular-matrix-problems",
" convex-optimization",
" least-squares",
" generalized-inverse",
" regularization"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "d0ece592a2643f44c5dc6e75ab13baea0bb0cfec5c664efccdef6626e326c09d",
"md5": "9038a492d84f964fafccaa81424e5081",
"sha256": "ec1d82f4dfdec0e11b8ca25625f4899ffdf5672b71fcd0e5d1085cfa832f8054"
},
"downloads": -1,
"filename": "pytmpinv-1.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "9038a492d84f964fafccaa81424e5081",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 11176,
"upload_time": "2025-09-19T05:40:07",
"upload_time_iso_8601": "2025-09-19T05:40:07.390781Z",
"url": "https://files.pythonhosted.org/packages/d0/ec/e592a2643f44c5dc6e75ab13baea0bb0cfec5c664efccdef6626e326c09d/pytmpinv-1.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "70bd59278986d461966ea6595751df6fce18422ef0305ce7356d1bc7e0358577",
"md5": "31d2837e0f4b593aaec4bd250b7344e6",
"sha256": "9ce676893e1d2d7f49d2093a756caa583aa7a9db071996acae239fd1256ed5f5"
},
"downloads": -1,
"filename": "pytmpinv-1.2.0.tar.gz",
"has_sig": false,
"md5_digest": "31d2837e0f4b593aaec4bd250b7344e6",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 10643,
"upload_time": "2025-09-19T05:40:08",
"upload_time_iso_8601": "2025-09-19T05:40:08.785268Z",
"url": "https://files.pythonhosted.org/packages/70/bd/59278986d461966ea6595751df6fce18422ef0305ce7356d1bc7e0358577/pytmpinv-1.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-19 05:40:08",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "econcz",
"github_project": "pytmpinv",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "pytmpinv"
}