freealg 0.0.1__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,18 @@
1
+ Changelog
2
+ =========
3
+
4
+ All notable changes to this project will be documented in this file.
5
+
6
+ The format is based on `Keep a Changelog <https://keepachangelog.com/en/1.0.0/>`_,
7
+ and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`_.
8
+
9
+ [Unreleased]
10
+ ------------
11
+
12
+ [0.0.1] - 2024-09-04
13
+ --------------------
14
+
15
+ Changed
16
+ ~~~~~~~
17
+
18
+ packaging
@@ -0,0 +1,24 @@
1
+ Redistribution and use in source and binary forms, with or without
2
+ modification, are permitted provided that the following conditions are met:
3
+
4
+ 1. Redistributions of source code must retain the above copyright notice, this
5
+ list of conditions and the following disclaimer.
6
+
7
+ 2. Redistributions in binary form must reproduce the above copyright notice,
8
+ this list of conditions and the following disclaimer in the documentation
9
+ and/or other materials provided with the distribution.
10
+
11
+ 3. Neither the name of the copyright holder nor the names of its contributors
12
+ may be used to endorse or promote products derived from this software
13
+ without specific prior written permission.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,29 @@
1
+ global-exclude *.py[cod] __pycache__
2
+ global-exclude *.so *.dll *.dylib
3
+ global-exclude *.o
4
+ global-exclude *.swp
5
+
6
+ recursive-include freealg *.rst
7
+ recursive-include freealg/data *.json
8
+
9
+ include CHANGELOG.rst
10
+ include README.rst
11
+ include LICENSE.txt
12
+ include requirements.txt
13
+ include pyproject.toml
14
+
15
+ exclude .gitattributes
16
+ exclude .tokeignore
17
+ exclude .coveragerc
18
+ exclude tox.ini
19
+ exclude TODO.rst
20
+ exclude CONTRIBUTING.rst
21
+ exclude notebook/experimental/clean_battle_20240814_public.json
22
+
23
+ prune docs
24
+ prune archive
25
+ prune benchmark
26
+ prune notebooks
27
+ prune tests
28
+ prune .git
29
+ prune .github
freealg-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,145 @@
1
+ Metadata-Version: 2.4
2
+ Name: freealg
3
+ Version: 0.0.1
4
+ Summary: Free probability for large matrices
5
+ Keywords: leaderboard bot chat
6
+ Platform: Linux
7
+ Platform: OSX
8
+ Platform: Windows
9
+ Classifier: Programming Language :: Python
10
+ Classifier: Programming Language :: Python :: 3.9
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: Implementation :: CPython
15
+ Classifier: License :: OSI Approved :: BSD License
16
+ Classifier: Operating System :: POSIX :: Linux
17
+ Classifier: Operating System :: Microsoft :: Windows
18
+ Classifier: Operating System :: MacOS
19
+ Classifier: Natural Language :: English
20
+ Classifier: Intended Audience :: Science/Research
21
+ Classifier: Intended Audience :: Developers
22
+ Classifier: Topic :: Software Development
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Requires-Python: >=3.9
25
+ Description-Content-Type: text/x-rst
26
+ License-File: LICENSE.txt
27
+ Requires-Dist: numpy
28
+ Requires-Dist: scipy
29
+ Requires-Dist: texplot
30
+ Requires-Dist: matplotlib
31
+ Requires-Dist: colorcet
32
+ Provides-Extra: test
33
+ Requires-Dist: tox; extra == "test"
34
+ Requires-Dist: pytest-cov; extra == "test"
35
+ Requires-Dist: codecov; extra == "test"
36
+ Provides-Extra: docs
37
+ Requires-Dist: sphinx; extra == "docs"
38
+ Requires-Dist: sphinx-math-dollar; extra == "docs"
39
+ Requires-Dist: sphinx-toggleprompt<0.4; extra == "docs"
40
+ Requires-Dist: pydata_sphinx_theme==0.9.0; extra == "docs"
41
+ Requires-Dist: graphviz; extra == "docs"
42
+ Requires-Dist: sphinx-automodapi; extra == "docs"
43
+ Requires-Dist: numpydoc; extra == "docs"
44
+ Requires-Dist: nbsphinx; extra == "docs"
45
+ Requires-Dist: sphinx_design; extra == "docs"
46
+ Requires-Dist: sphinx-multitoc-numbering; extra == "docs"
47
+ Requires-Dist: pandoc; extra == "docs"
48
+ Requires-Dist: sphinx-prompt; extra == "docs"
49
+ Requires-Dist: sphinx-copybutton; extra == "docs"
50
+ Requires-Dist: sphinx-gallery; extra == "docs"
51
+ Requires-Dist: sphinxcontrib-youtube; extra == "docs"
52
+ Requires-Dist: sphinxext-opengraph; extra == "docs"
53
+ Requires-Dist: sphinx-argparse; extra == "docs"
54
+ Dynamic: classifier
55
+ Dynamic: description
56
+ Dynamic: description-content-type
57
+ Dynamic: keywords
58
+ Dynamic: license-file
59
+ Dynamic: platform
60
+ Dynamic: provides-extra
61
+ Dynamic: requires-dist
62
+ Dynamic: requires-python
63
+ Dynamic: summary
64
+
65
+ .. image:: https://raw.githubusercontent.com/ameli/freealg/refs/heads/main/docs/source/_static/images/icons/logo-freealg-light.png
66
+ :align: left
67
+ :width: 240
68
+ :class: custom-dark
69
+
70
+ *freealg* is a python package that employs **free** probability for large matrix **form**\ s.
71
+
72
+ Install
73
+ =======
74
+
75
+ Install with ``pip``:
76
+
77
+ .. code-block::
78
+
79
+ pip install freealg
80
+
81
+ Alternatively, clone the source code and install with
82
+
83
+ .. code-block::
84
+
85
+ cd source_dir
86
+ pip install .
87
+
88
+ Documentation
89
+ =============
90
+
91
+ Documentation is available at `ameli.github.io/freealg <https://ameli.github.io/freealg>`__.
92
+
93
+ Quick Usage
94
+ ===========
95
+
96
+ Create and Train a Model
97
+ ------------------------
98
+
99
+ .. code-block:: python
100
+
101
+ >>> import freealg as fa
102
+
103
+ Test
104
+ ====
105
+
106
+ You may test the package with `tox <https://tox.wiki/>`__:
107
+
108
+ .. code-block::
109
+
110
+ cd source_dir
111
+ tox
112
+
113
+ Alternatively, test with `pytest <https://pytest.org>`__:
114
+
115
+ .. code-block::
116
+
117
+ cd source_dir
118
+ pytest
119
+
120
+ How to Contribute
121
+ =================
122
+
123
+ We welcome contributions via GitHub's pull request. Developers should review
124
+ our [Contributing Guidelines](CONTRIBUTING.rst) before submitting their code.
125
+ If you do not feel comfortable modifying the code, we also welcome feature
126
+ requests and bug reports.
127
+
128
+ How to Cite
129
+ ===========
130
+
131
+ * TBD
132
+
133
+ .. code::
134
+
135
+ @inproceedings{
136
+ TBD
137
+ }
138
+
139
+ License
140
+ =======
141
+
142
+ |license|
143
+
144
+ .. |license| image:: https://img.shields.io/github/license/ameli/freealg
145
+ :target: https://opensource.org/licenses/BSD-3-Clause
@@ -0,0 +1,81 @@
1
+ .. image:: https://raw.githubusercontent.com/ameli/freealg/refs/heads/main/docs/source/_static/images/icons/logo-freealg-light.png
2
+ :align: left
3
+ :width: 240
4
+ :class: custom-dark
5
+
6
+ *freealg* is a python package that employs **free** probability for large matrix **form**\ s.
7
+
8
+ Install
9
+ =======
10
+
11
+ Install with ``pip``:
12
+
13
+ .. code-block::
14
+
15
+ pip install freealg
16
+
17
+ Alternatively, clone the source code and install with
18
+
19
+ .. code-block::
20
+
21
+ cd source_dir
22
+ pip install .
23
+
24
+ Documentation
25
+ =============
26
+
27
+ Documentation is available at `ameli.github.io/freealg <https://ameli.github.io/freealg>`__.
28
+
29
+ Quick Usage
30
+ ===========
31
+
32
+ Create and Train a Model
33
+ ------------------------
34
+
35
+ .. code-block:: python
36
+
37
+ >>> import freealg as fa
38
+
39
+ Test
40
+ ====
41
+
42
+ You may test the package with `tox <https://tox.wiki/>`__:
43
+
44
+ .. code-block::
45
+
46
+ cd source_dir
47
+ tox
48
+
49
+ Alternatively, test with `pytest <https://pytest.org>`__:
50
+
51
+ .. code-block::
52
+
53
+ cd source_dir
54
+ pytest
55
+
56
+ How to Contribute
57
+ =================
58
+
59
+ We welcome contributions via GitHub's pull request. Developers should review
60
+ our [Contributing Guidelines](CONTRIBUTING.rst) before submitting their code.
61
+ If you do not feel comfortable modifying the code, we also welcome feature
62
+ requests and bug reports.
63
+
64
+ How to Cite
65
+ ===========
66
+
67
+ * TBD
68
+
69
+ .. code::
70
+
71
+ @inproceedings{
72
+ TBD
73
+ }
74
+
75
+ License
76
+ =======
77
+
78
+ |license|
79
+
80
+ .. |license| image:: https://img.shields.io/github/license/ameli/freealg
81
+ :target: https://opensource.org/licenses/BSD-3-Clause
@@ -0,0 +1,13 @@
1
+ # SPDX-FileCopyrightText: Copyright 2025, Siavash Ameli <sameli@berkeley.edu>
2
+ # SPDX-License-Identifier: BSD-3-Clause
3
+ # SPDX-FileType: SOURCE
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify it
6
+ # under the terms of the license found in the LICENSE.txt file in the root
7
+ # directory of this source tree.
8
+
9
+ from .freeform import FreeForm
10
+
11
+ __all__ = ['FreeForm']
12
+
13
+ from .__version__ import __version__ # noqa: F401 E402
@@ -0,0 +1 @@
1
+ __version__ = "0.0.1"
@@ -0,0 +1,201 @@
1
+ # SPDX-FileCopyrightText: Copyright 2025, Siavash Ameli <sameli@berkeley.edu>
2
+ # SPDX-License-Identifier: BSD-3-Clause
3
+ # SPDX-FileType: SOURCE
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify it under
6
+ # the terms of the license found in the LICENSE.txt file in the root directory
7
+ # of this source tree.
8
+
9
+
10
+ # =======
11
+ # Imports
12
+ # =======
13
+
14
+ import numpy
15
+ from scipy.special import eval_chebyu
16
+
17
+ __all__ = ['chebyshev_proj', 'chebyshev_approx', 'chebyshev_stieltjes']
18
+
19
+
20
+ # ==============
21
+ # chebyshev proj
22
+ # ==============
23
+
24
+ def chebyshev_proj(eig, support, K=10, reg=0.0):
25
+ """
26
+ Estimate the coefficients \\psi_k in
27
+
28
+ \\rho(x) = w(t) \\sum_{k=0}^K \\psi_k U_k(t),
29
+
30
+ where t = (2x–(\\lambda_{-} + \\lambda_{+}))/ (\\lambda_{+} - \\lambda_{-})
31
+ in [-1, 1] and w(t) = \\sqrt{(1 - t^2}.
32
+
33
+ Parameters
34
+ ----------
35
+
36
+ eig : array_like, shape (N,)
37
+ The raw eigenvalues x_i.
38
+
39
+ support : tuple
40
+ The assumed compact support of rho.
41
+
42
+ K : int
43
+ Highest Chebyshev‐II order.
44
+
45
+ reg : float
46
+ Tikhonov‐style ridge on each coefficient (defaults to 0).
47
+
48
+ Returns
49
+ -------
50
+
51
+ psi : ndarray, shape (K+1,)
52
+ The projected coefficients \\psi_k.
53
+ """
54
+
55
+ lam_m, lam_p = support
56
+
57
+ # Map to [–1,1] interval
58
+ t = (2 * eig - (lam_m + lam_p)) / (lam_p - lam_m)
59
+ N = eig.size
60
+
61
+ # Inner‐product norm of each U_k under w(t) = sqrt{1–t^2} is \\pi/2
62
+ norm = numpy.pi / 2
63
+
64
+ psi = numpy.empty(K+1)
65
+ for k in range(K+1):
66
+
67
+ # empirical moment M_k = (1/N) \\sum U_k(t_i)
68
+ M_k = numpy.sum(eval_chebyu(k, t)) / N
69
+
70
+ # Regularization
71
+ if k == 0:
72
+ # Do not penalize at k=0, as this keeps unit mass.
73
+ # k=0 has unit mass, while k>0 has zero mass by orthogonality.
74
+ penalty = 0
75
+ else:
76
+ penalty = reg * (k / (K + 1))**2
77
+
78
+ # Add regularization on the diagonal
79
+ psi[k] = M_k / (norm + penalty)
80
+
81
+ return psi
82
+
83
+
84
+ # ================
85
+ # chebyshev approx
86
+ # ================
87
+
88
+ def chebyshev_approx(x, psi, support):
89
+ """
90
+ Given \\psi_k, evaluate the approximate density \\rho(x).
91
+
92
+ Parameters
93
+ ----------
94
+
95
+ x : array_like
96
+ Points at which to evaluate \\rho.
97
+
98
+ psi : array_like, shape (K+1,)
99
+ Coefficients from chebyshev_proj.
100
+
101
+ support : tuple
102
+ Same support used for projection.
103
+
104
+ Returns
105
+ -------
106
+
107
+ rho_x : ndarray, same shape as x
108
+ Approximated spectral density on the original x‐axis.
109
+ """
110
+
111
+ lam_m, lam_p = support
112
+
113
+ # Map to [–1,1] interval
114
+ t = (2 * numpy.asarray(x) - (lam_m + lam_p)) / (lam_p - lam_m)
115
+
116
+ # Weight sqrt{1–t^2} (clip for numerical safety)
117
+ w = numpy.sqrt(numpy.clip(1 - t**2, a_min=0, a_max=None))
118
+
119
+ # Summation approximation
120
+ U = numpy.vstack([eval_chebyu(k, t) for k in range(len(psi))]).T
121
+ rho_t = w * (U @ psi)
122
+
123
+ # Adjust for dt to dx transformation
124
+ rho_x = rho_t * (2.0 / (lam_p - lam_m))
125
+
126
+ return rho_x
127
+
128
+
129
+ # ===================
130
+ # chebushev stieltjes
131
+ # ===================
132
+
133
+ def chebyshev_stieltjes(z, psi, support):
134
+ """
135
+ Compute the Stieltjes transform m(z) for a Chebyshev‐II expansion
136
+
137
+ rho(x) = (2/(lam_p - lam_m)) * sqrt(1−t(x)^2) * sum_{k=0}^K psi_k U_k(t(x))
138
+
139
+ via the closed‐form
140
+
141
+ \\int_{-1}^1 U_k(t) sqrt(1−t^2)/(u - t) dt = \\pi J(u)^(k+1),
142
+
143
+ where
144
+
145
+ u = (2(z−center))/span,
146
+ center = (lam_p + lam_m)/2,
147
+ span = lam_p - lam_m,
148
+ J(u) = u − sqrt(u^2−1)
149
+
150
+ and then
151
+
152
+ m(z) = - (2/ span) * \\sum{k=0}^K \\psi_k * [ \\pi J(u)^(k+1) ].
153
+
154
+ Parameters
155
+ ----------
156
+
157
+ z : complex or array_like of complex
158
+ Points in the complex plane.
159
+
160
+ psi : array_like, shape (K+1,)
161
+ Chebyshev‐II coefficients \\psi.
162
+
163
+ support : tuple
164
+ The support interval of the original density.
165
+
166
+ Returns
167
+ -------
168
+
169
+ m_z : ndarray of complex
170
+ The Stieltjes transform m(z) on the same shape as z.
171
+ """
172
+
173
+ z = numpy.asarray(z, dtype=numpy.complex128)
174
+ lam_m, lam_p = support
175
+ span = lam_p - lam_m
176
+ center = 0.5 * (lam_m + lam_p)
177
+
178
+ # map z -> u in the standard [-1,1] domain
179
+ u = (2.0 * (z - center)) / span
180
+
181
+ # inverse-Joukowski: pick branch sqrt with +Im
182
+ root = numpy.sqrt(u*u - 1)
183
+ Jm = u - root
184
+ Jp = u + root
185
+
186
+ # Make sure J is Herglotz
187
+ J = numpy.zeros_like(Jp)
188
+ J = numpy.where(Jp.imag > 0, Jm, Jp)
189
+
190
+ # build powers J^(k+1) for k=0..K
191
+ K = len(psi) - 1
192
+ # shape: (..., K+1)
193
+ Jpow = J[..., None] ** numpy.arange(1, K+2)
194
+
195
+ # sum psi_k * J^(k+1)
196
+ S = numpy.sum(psi * Jpow, axis=-1)
197
+
198
+ # assemble m(z)
199
+ m_z = - (2.0 / span) * numpy.pi * S
200
+
201
+ return m_z
@@ -0,0 +1,88 @@
1
+ # SPDX-FileCopyrightText: Copyright 2025, Siavash Ameli <sameli@berkeley.edu>
2
+ # SPDX-License-Identifier: BSD-3-Clause
3
+ # SPDX-FileType: SOURCE
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify it under
6
+ # the terms of the license found in the LICENSE.txt file in the root directory
7
+ # of this source tree.
8
+
9
+
10
+ # =======
11
+ # Imports
12
+ # =======
13
+
14
+ import numpy
15
+
16
+ __all__ = ['jackson_damping', 'lanczos_damping', 'fejer_damping',
17
+ 'exponential_damping', 'parzen_damping']
18
+
19
+
20
+ # ===============
21
+ # jackson damping
22
+ # ===============
23
+
24
+ def jackson_damping(K):
25
+ """
26
+ Compute Jackson damping coefficients for orders k = 0, 1, ..., K-1.
27
+ """
28
+
29
+ k = numpy.arange(K)
30
+ g = ((K - k + 1) * numpy.cos(numpy.pi * k / (K + 1)) +
31
+ numpy.sin(numpy.pi * k / (K + 1)) / numpy.tan(numpy.pi / (K + 1))) \
32
+ / (K + 1)
33
+
34
+ return g
35
+
36
+
37
+ # ===============
38
+ # lanczos damping
39
+ # ===============
40
+
41
+ def lanczos_damping(K):
42
+ """
43
+ Compute Lanczos damping coefficients for orders k = 0, 1, ..., K-1.
44
+ """
45
+
46
+ k = numpy.arange(K)
47
+ sigma = numpy.sinc(k / K)
48
+
49
+ return sigma
50
+
51
+
52
+ # =============
53
+ # fejer damping
54
+ # =============
55
+
56
+ def fejer_damping(K):
57
+ """
58
+ Compute Fejer damping coefficients for orders k = 0, 1, ..., K-1.
59
+ """
60
+
61
+ k = numpy.arange(K)
62
+ return 1 - k / K
63
+
64
+
65
+ # ===================
66
+ # exponential damping
67
+ # ===================
68
+
69
+ def exponential_damping(K, alpha=6):
70
+ """
71
+ Compute exponential damping coefficients for orders k = 0, 1, ..., K-1.
72
+ """
73
+
74
+ k = numpy.arange(K)
75
+ return numpy.exp(-alpha * (k / K)**2)
76
+
77
+
78
+ # ==============
79
+ # parzen damping
80
+ # ==============
81
+
82
+ def parzen_damping(K):
83
+ """
84
+ Compute Parzen damping coefficients for orders k = 0, 1, ..., K-1.
85
+ """
86
+
87
+ k = numpy.arange(K)
88
+ return 1 - numpy.abs((k - K/2) / (K/2))**3