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.
- freealg-0.0.1/CHANGELOG.rst +18 -0
- freealg-0.0.1/LICENSE.txt +24 -0
- freealg-0.0.1/MANIFEST.in +29 -0
- freealg-0.0.1/PKG-INFO +145 -0
- freealg-0.0.1/README.rst +81 -0
- freealg-0.0.1/freealg/__init__.py +13 -0
- freealg-0.0.1/freealg/__version__.py +1 -0
- freealg-0.0.1/freealg/_chebyshev.py +201 -0
- freealg-0.0.1/freealg/_damp.py +88 -0
- freealg-0.0.1/freealg/_jacobi.py +188 -0
- freealg-0.0.1/freealg/_pade.py +139 -0
- freealg-0.0.1/freealg/_plot_util.py +499 -0
- freealg-0.0.1/freealg/_util.py +92 -0
- freealg-0.0.1/freealg/distributions/__init__.py +16 -0
- freealg-0.0.1/freealg/distributions/marchenko_pastur.py +512 -0
- freealg-0.0.1/freealg/freeform.py +648 -0
- freealg-0.0.1/freealg.egg-info/PKG-INFO +145 -0
- freealg-0.0.1/freealg.egg-info/SOURCES.txt +25 -0
- freealg-0.0.1/freealg.egg-info/dependency_links.txt +1 -0
- freealg-0.0.1/freealg.egg-info/not-zip-safe +1 -0
- freealg-0.0.1/freealg.egg-info/requires.txt +29 -0
- freealg-0.0.1/freealg.egg-info/top_level.txt +1 -0
- freealg-0.0.1/pyproject.toml +63 -0
- freealg-0.0.1/requirements.txt +5 -0
- freealg-0.0.1/setup.cfg +32 -0
- freealg-0.0.1/setup.py +218 -0
|
@@ -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
|
freealg-0.0.1/README.rst
ADDED
|
@@ -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
|