mfa-estimator 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2023, benediktfesl
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,371 @@
1
+ Metadata-Version: 2.4
2
+ Name: mfa-estimator
3
+ Version: 0.1.0
4
+ Summary: MFA-based estimator for linear inverse problems with complex-valued priors.
5
+ License-Expression: BSD-3-Clause
6
+ Project-URL: Homepage, https://github.com/benediktfesl/MFA_estimator
7
+ Project-URL: Repository, https://github.com/benediktfesl/MFA_estimator
8
+ Project-URL: Issues, https://github.com/benediktfesl/MFA_estimator/issues
9
+ Keywords: complex-valued,mixture of factor analyzers,MFA,linear inverse problems,MMSE,low-rank,signal processing
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Intended Audience :: Science/Research
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: Topic :: Scientific/Engineering
19
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: numpy>=1.23
24
+ Requires-Dist: cplx-mfa>=0.1.0
25
+ Dynamic: license-file
26
+
27
+ # mfa-estimator
28
+
29
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)
30
+ [![License: BSD-3-Clause](https://img.shields.io/badge/License-BSD--3--Clause-blue.svg)](LICENSE)
31
+ [![Package](https://img.shields.io/badge/package-PyPI-informational.svg)](https://pypi.org/project/mfa-estimator/)
32
+
33
+ MFA-based estimator for complex-valued linear inverse problems.
34
+
35
+ `mfa-estimator` provides an estimator for noisy linear observation models using a complex-valued mixture of factor analyzers (MFA) prior. The package builds on [cplx-mfa](https://pypi.org/project/cplx-mfa/) for fitting the complex-valued MFA prior and adds an estimation layer for inverse problems of the form
36
+
37
+ ```text
38
+ y = A h + n
39
+ ```
40
+
41
+ where `h` is the unknown complex-valued vector, `A` is a known linear observation matrix, and `n` is complex Gaussian observation noise.
42
+
43
+ The estimator is domain-independent and can be used for linear inverse problems in signal processing, communications, and related applications. Channel estimation is one motivating application and is discussed in the research background section.
44
+
45
+ ## ✨ Highlights
46
+
47
+ - MFA-based estimator for complex-valued linear inverse problems
48
+ - Supports general linear observation models of the form `y = A h + n`
49
+ - Uses complex-valued MFA priors fitted with [`cplx-mfa`](https://pypi.org/project/cplx-mfa/)
50
+ - Component-wise LMMSE estimation under the fitted mixture prior
51
+ - Posterior component weighting in the observation domain
52
+ - Supports identity and rectangular observation matrices
53
+ - Supports full posterior mixture estimates or truncated component sums
54
+ - scikit-learn-like workflow via inherited `fit(...)` and added `estimate(...)`
55
+ - Modern Python packaging with `pyproject.toml`, `uv`, `pytest`, and `ruff`
56
+
57
+ ## 📌 Citation
58
+
59
+ If you use `mfa-estimator` in academic work, please cite the package directly:
60
+
61
+ ```bibtex
62
+ @software{fesl_mfa_estimator,
63
+ author = {Fesl, Benedikt},
64
+ title = {{mfa-estimator}: MFA-based estimator for complex-valued linear inverse problems},
65
+ year = {2026},
66
+ url = {https://github.com/benediktfesl/MFA_estimator},
67
+ version = {0.1.0}
68
+ }
69
+ ```
70
+
71
+ Plain-text citation:
72
+
73
+ > B. Fesl, `mfa-estimator`: MFA-based estimator for complex-valued linear inverse problems, version 0.1.0. Available: https://github.com/benediktfesl/MFA_estimator
74
+
75
+ If you use the estimator in the context of channel estimation, please also consider citing the related papers listed in the research background section.
76
+
77
+ ## 📦 Installation
78
+
79
+ Install from PyPI:
80
+
81
+ ```bash
82
+ pip install mfa-estimator
83
+ ```
84
+
85
+ or with `uv`:
86
+
87
+ ```bash
88
+ uv add mfa-estimator
89
+ ```
90
+
91
+ For development, clone the repository and install the development environment:
92
+
93
+ ```bash
94
+ git clone https://github.com/benediktfesl/MFA_estimator.git
95
+ cd MFA_estimator
96
+ uv sync --group dev
97
+ ```
98
+
99
+ ## 🚀 Quick Start
100
+
101
+ ```python
102
+ import numpy as np
103
+
104
+ from mfa_estimator import MfaEstimator
105
+
106
+ rng = np.random.default_rng(0)
107
+
108
+ h_train = (
109
+ rng.normal(size=(1_000, 8))
110
+ + 1j * rng.normal(size=(1_000, 8))
111
+ ) / np.sqrt(2.0)
112
+
113
+ h_val = (
114
+ rng.normal(size=(100, 8))
115
+ + 1j * rng.normal(size=(100, 8))
116
+ ) / np.sqrt(2.0)
117
+
118
+ noise = (
119
+ rng.normal(size=(100, 8))
120
+ + 1j * rng.normal(size=(100, 8))
121
+ ) / np.sqrt(2.0)
122
+
123
+ # Identity observation model: y = h + n
124
+ noise_covariance = np.eye(8)
125
+ y = h_val + noise
126
+
127
+ estimator = MfaEstimator(
128
+ n_components=4,
129
+ latent_dim=2,
130
+ random_state=0,
131
+ max_iter=100,
132
+ verbose=False,
133
+ )
134
+
135
+ # Fit the complex-valued MFA prior p(h).
136
+ estimator.fit(h_train)
137
+
138
+ # Estimate h from noisy observations y.
139
+ h_est = estimator.estimate(
140
+ y=y,
141
+ Cn=noise_covariance,
142
+ A=None,
143
+ n_summands_or_proba=1.0,
144
+ )
145
+ ```
146
+
147
+ The estimator follows a two-step pattern:
148
+
149
+ 1. `fit(h_train)` fits the complex-valued MFA prior using the inherited `cplx-mfa` implementation.
150
+ 2. `estimate(y, Cn, A)` estimates the unknown vector from noisy linear observations.
151
+
152
+ ## 🧩 Estimation Model
153
+
154
+ The package assumes a linear observation model
155
+
156
+ ```text
157
+ y = A h + n
158
+ ```
159
+
160
+ where:
161
+
162
+ | Symbol | Description |
163
+ |---|---|
164
+ | `h` | Unknown complex-valued vector to be estimated. |
165
+ | `y` | Noisy complex-valued observation. |
166
+ | `A` | Known linear observation matrix. |
167
+ | `n` | Zero-mean complex Gaussian noise with covariance `Cn`. |
168
+
169
+ The unknown vector `h` is modeled with a fitted complex-valued MFA prior:
170
+
171
+ ```text
172
+ p(h) = Σ_k π_k CN(h; μ_k, C_k)
173
+ ```
174
+
175
+ For each mixture component, the observation-domain model is
176
+
177
+ ```text
178
+ y | k ~ CN(A μ_k, A C_k Aᴴ + Cn)
179
+ ```
180
+
181
+ The estimator computes posterior component probabilities in the observation domain and combines component-wise LMMSE estimates.
182
+
183
+ ## 🧠 Estimator API
184
+
185
+ The main class is:
186
+
187
+ ```python
188
+ from mfa_estimator import MfaEstimator
189
+ ```
190
+
191
+ `MfaEstimator` inherits from [`cplx_mfa.ComplexMFA`](https://pypi.org/project/cplx-mfa/) and therefore supports the same prior-fitting API.
192
+
193
+ Core methods:
194
+
195
+ | Method | Description |
196
+ |---|---|
197
+ | `fit(X)` | Fit the complex-valued MFA prior. Inherited from `cplx-mfa`. |
198
+ | `predict(X)` | Predict the most likely MFA prior component. Inherited from `cplx-mfa`. |
199
+ | `predict_proba(X)` | Return prior-domain component probabilities. Inherited from `cplx-mfa`. |
200
+ | `sample(n_samples=1, rng=None)` | Draw samples from the fitted MFA prior. Inherited from `cplx-mfa`. |
201
+ | `estimate(y, Cn, A=None, n_summands_or_proba=1)` | Estimate unknown vectors from noisy linear observations. |
202
+
203
+ Constructor parameters are inherited from `ComplexMFA`:
204
+
205
+ | Parameter | Description |
206
+ |---|---|
207
+ | `n_components` | Number of mixture components. |
208
+ | `latent_dim` | Latent dimensionality of each factor analyzer. |
209
+ | `ppca` | If `True`, use one isotropic noise variance per component. |
210
+ | `lock_psis` | If `True`, use shared diagonal noise variances across components. |
211
+ | `rs_clip` | Lower clipping value for responsibilities during EM. |
212
+ | `max_condition_number` | Scaling factor used for random loading initialization. |
213
+ | `max_iter` | Maximum number of EM iterations. |
214
+ | `tol` | Relative convergence tolerance. |
215
+ | `random_state` | Integer seed or NumPy random generator used for initialization. |
216
+ | `verbose` | If `True`, print EM progress. |
217
+
218
+ The fitted prior parameters are exposed using the trailing-underscore attributes from `cplx-mfa`:
219
+
220
+ | Attribute | Description |
221
+ |---|---|
222
+ | `weights_` | Mixture weights of shape `(n_components,)`. |
223
+ | `means_` | Component means of shape `(n_components, n_features)`. |
224
+ | `loadings_` | Factor loading matrices of shape `(n_components, n_features, latent_dim)`. |
225
+ | `covariances_` | Full implied covariance matrices of shape `(n_components, n_features, n_features)`. |
226
+ | `precisions_` | Inverse covariance matrices of shape `(n_components, n_features, n_features)`. |
227
+ | `noise_variances_` | Diagonal noise variances of shape `(n_components, n_features)`. |
228
+ | `lower_bound_history_` | EM lower-bound values collected during fitting. |
229
+
230
+ ## 🔎 Estimation
231
+
232
+ The main method added by this package is `estimate(...)`:
233
+
234
+ ```python
235
+ h_est = estimator.estimate(
236
+ y=y,
237
+ Cn=noise_covariance,
238
+ A=observation_matrix,
239
+ n_summands_or_proba=1.0,
240
+ )
241
+ ```
242
+
243
+ Arguments:
244
+
245
+ | Argument | Description |
246
+ |---|---|
247
+ | `y` | Observations of shape `(n_samples, n_observations)`. |
248
+ | `Cn` | Observation noise covariance of shape `(n_observations, n_observations)`. |
249
+ | `A` | Observation matrix of shape `(n_observations, n_features)`. If `None`, the identity matrix is used. |
250
+ | `n_summands_or_proba` | Component-selection rule for the posterior mixture estimate. |
251
+
252
+ The component-selection parameter can be used in two ways:
253
+
254
+ | Value | Behavior |
255
+ |---|---|
256
+ | Integer, e.g. `1` or `5` | Use the corresponding number of most likely posterior components. |
257
+ | Float in `(0, 1]`, e.g. `0.9` | Use the fewest most likely components whose cumulative posterior probability reaches the threshold. |
258
+ | `1.0` | Use all components. |
259
+
260
+ ## 🧪 Examples
261
+
262
+ Run the example script:
263
+
264
+ ```bash
265
+ uv run python examples/mfa_estimator_example.py --nr 1
266
+ ```
267
+
268
+ Available examples:
269
+
270
+ | Number | Description |
271
+ |---|---|
272
+ | `1` | Identity observation model with component-wise diagonal noise variances. |
273
+ | `2` | Selection observation model with component-wise diagonal noise variances. |
274
+ | `3` | Identity observation model with shared diagonal noise variances. |
275
+ | `4` | Identity observation model with shared isotropic PPCA-style noise variances. |
276
+
277
+ Run all examples back to back:
278
+
279
+ ```bash
280
+ for nr in 1 2 3 4; do
281
+ uv run python examples/mfa_estimator_example.py --nr "$nr"
282
+ done
283
+ ```
284
+
285
+ Use `--help` to inspect the script interface:
286
+
287
+ ```bash
288
+ uv run python examples/mfa_estimator_example.py --help
289
+ ```
290
+
291
+ ## 📚 Research Background
292
+
293
+ This package was originally developed in the context of low-rank structured MMSE estimation with mixture models. The implementation is domain-independent, but the motivating application is channel estimation in communication systems.
294
+
295
+ Related publications:
296
+
297
+ - B. Fesl, N. Turan, and W. Utschick, “Low-Rank Structured MMSE Channel Estimation with Mixtures of Factor Analyzers,” *57th Asilomar Conference on Signals, Systems, and Computers*, 2023.
298
+ [[IEEE](https://ieeexplore.ieee.org/document/10477088)] [[arXiv](https://arxiv.org/abs/2304.14809)]
299
+
300
+ - B. Fesl, N. Turan, B. Böck, and W. Utschick, “Channel Estimation for Quantized Systems based on Conditionally Gaussian Latent Models,” *IEEE Transactions on Signal Processing*, 2024.
301
+ [[IEEE](https://ieeexplore.ieee.org/document/10454252)] [[arXiv](https://arxiv.org/abs/2309.04014)]
302
+
303
+ - B. Fesl, “Generative Model-Aided Channel Estimation Design and Optimality Analysis,” *Ph.D. dissertation, Technical University of Munich*, 2025.
304
+ [[Link](https://mediatum.ub.tum.de/?id=1748775)]
305
+
306
+ ## 🧪 Development
307
+
308
+ Install the development environment with `uv`:
309
+
310
+ ```bash
311
+ uv sync --group dev
312
+ ```
313
+
314
+ Run tests:
315
+
316
+ ```bash
317
+ uv run pytest
318
+ ```
319
+
320
+ Run linting:
321
+
322
+ ```bash
323
+ uv run ruff check .
324
+ ```
325
+
326
+ Format code:
327
+
328
+ ```bash
329
+ uv run ruff format .
330
+ ```
331
+
332
+ Run an example:
333
+
334
+ ```bash
335
+ uv run python examples/mfa_estimator_example.py --nr 1
336
+ ```
337
+
338
+ Build the package:
339
+
340
+ ```bash
341
+ uv run python -m build
342
+ ```
343
+
344
+ Check the package distribution:
345
+
346
+ ```bash
347
+ uv run twine check dist/*
348
+ ```
349
+
350
+ ## ✅ Test Coverage
351
+
352
+ The test suite covers:
353
+
354
+ - package imports
355
+ - integration with the `cplx-mfa` package
356
+ - estimation with identity observation matrices
357
+ - estimation with rectangular observation matrices
358
+ - estimation with complex-valued observation matrices
359
+ - real-valued input handling
360
+ - posterior probability normalization
361
+ - component-count selection
362
+ - cumulative-probability selection
363
+ - unfitted-estimator behavior
364
+ - invalid input validation
365
+ - non-finite input validation
366
+ - preservation of fitted prior parameters during estimation
367
+ - example script execution
368
+
369
+ ## 📄 License
370
+
371
+ This project is licensed under the [BSD 3-Clause License](LICENSE).