pyANOVAapprox 2.0.2__tar.gz → 2.0.4__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.
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/.github/workflows/documentation.yml +12 -4
- pyanovaapprox-2.0.4/.github/workflows/format.yml +42 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/.gitignore +4 -1
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/PKG-INFO +1 -1
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/docs/source/conf.py +16 -2
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/docs/source/index.rst +2 -3
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/pyproject.toml +1 -1
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/simpleTest/exampleNonPeriodic.py +3 -1
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/simpleTest/exampleWavelet.py +13 -7
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/src/pyANOVAapprox/analysis.py +16 -29
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/src/pyANOVAapprox/approx.py +85 -57
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/src/pyANOVAapprox/bandwidth.py +36 -22
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/src/pyANOVAapprox/errors.py +11 -23
- pyanovaapprox-2.0.2/.github/workflows/format.yml +0 -27
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/.github/workflows/ci.yml +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/.github/workflows/release.yml +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/LICENSE +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/README.md +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/docs/Makefile +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/docs/source/Analysis.rst +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/docs/source/Approximation.rst +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/docs/source/Errors.rst +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/simpleTest/TestFunctionPeriodic.py +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/simpleTest/exampleAutoapproximate.py +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/simpleTest/exampleCheb.py +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/simpleTest/exampleClassification.py +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/simpleTest/examplePeriodic.py +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/src/pyANOVAapprox/__init__.py +2 -2
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/src/pyANOVAapprox/fista.py +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/src/pyANOVAapprox/trafos.py +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/tests/TestFunctionCheb.py +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/tests/TestFunctionPeriodic.py +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/tests/cheb_fista.py +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/tests/cheb_lsqr.py +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/tests/per_fista.py +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/tests/per_lsqr.py +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/tests/run_tests.py +0 -0
- {pyanovaapprox-2.0.2 → pyanovaapprox-2.0.4}/tests/wav_lsqr.py +0 -0
|
@@ -10,20 +10,28 @@ jobs:
|
|
|
10
10
|
runs-on: ubuntu-latest
|
|
11
11
|
steps:
|
|
12
12
|
- uses: actions/checkout@v4
|
|
13
|
+
|
|
13
14
|
- uses: actions/setup-python@v5
|
|
15
|
+
with:
|
|
16
|
+
python-version: "3.12"
|
|
17
|
+
|
|
14
18
|
- name: Install dependencies
|
|
15
19
|
run: |
|
|
16
20
|
pip install sphinx sphinx_rtd_theme myst_parser
|
|
21
|
+
# WICHTIG: Wenn dein Code Abhängigkeiten hat (z.B. numpy, scipy),
|
|
22
|
+
# installiere sie hier, sonst kann 'autodoc' den Code nicht importieren!
|
|
23
|
+
# pip install -e .
|
|
24
|
+
|
|
17
25
|
- name: Sphinx build
|
|
18
26
|
run: |
|
|
19
27
|
cd docs
|
|
20
28
|
sphinx-apidoc -o ./source ../src -f
|
|
21
29
|
make html
|
|
30
|
+
|
|
22
31
|
- name: Deploy to GitHub Pages
|
|
23
|
-
uses: peaceiris/actions-gh-pages@
|
|
32
|
+
uses: peaceiris/actions-gh-pages@v4
|
|
24
33
|
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
|
25
34
|
with:
|
|
26
|
-
publish_branch: gh-pages
|
|
27
35
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
28
|
-
publish_dir: docs/build/html
|
|
29
|
-
force_orphan: true
|
|
36
|
+
publish_dir: docs/build/html
|
|
37
|
+
force_orphan: true
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: Format Python Code
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- '**' # Läuft bei jedem Push auf absolut jeden Branch...
|
|
7
|
+
tags-ignore:
|
|
8
|
+
- '**' # ...ABER ignoriert jeden Push, der ein Tag (Release) ist.
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
python-code-format:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
permissions:
|
|
14
|
+
contents: write
|
|
15
|
+
pull-requests: write
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
- uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.12"
|
|
22
|
+
architecture: "x64"
|
|
23
|
+
|
|
24
|
+
- name: Display Python version
|
|
25
|
+
run: python --version
|
|
26
|
+
|
|
27
|
+
- name: Install packages
|
|
28
|
+
run: pip install black isort
|
|
29
|
+
|
|
30
|
+
- name: Formatter
|
|
31
|
+
run: |
|
|
32
|
+
black .
|
|
33
|
+
isort .
|
|
34
|
+
- name: Create Pull Request
|
|
35
|
+
uses: peter-evans/create-pull-request@v6
|
|
36
|
+
with:
|
|
37
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
38
|
+
commit-message: "style: auto code format"
|
|
39
|
+
title: "Fixes by format action"
|
|
40
|
+
body: "This is an auto-generated PR with code formatting fixes."
|
|
41
|
+
labels: automated pr
|
|
42
|
+
branch: python-code-format-patches
|
|
@@ -7,6 +7,7 @@ dist/
|
|
|
7
7
|
__pycache__/
|
|
8
8
|
venv/
|
|
9
9
|
venv2/
|
|
10
|
+
.venv/
|
|
10
11
|
|
|
11
12
|
bin/
|
|
12
13
|
/lib64/
|
|
@@ -17,4 +18,6 @@ src/pyNFFT3/lib/AVX2/libgomp-1.dll
|
|
|
17
18
|
src/pyNFFT3/lib/AVX2/libgcc_s_seh-1.dll
|
|
18
19
|
src/pyNFFT3/lib/AVX2/libwinpthread-1.dll
|
|
19
20
|
simpleTest/venv/
|
|
20
|
-
bandwidth_detection
|
|
21
|
+
bandwidth_detection*
|
|
22
|
+
cross_validation*
|
|
23
|
+
/src/pyANOVAapprox/.ipynb_checkpoints/
|
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
# For the full list of built-in configuration values, see the documentation:
|
|
4
4
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
|
5
5
|
|
|
6
|
+
import os
|
|
7
|
+
import sys
|
|
8
|
+
|
|
9
|
+
# -- Path setup --------------------------------------------------------------
|
|
10
|
+
# Macht den src-Ordner für Sphinx und autodoc auffindbar
|
|
11
|
+
sys.path.insert(0, os.path.abspath("../../src"))
|
|
12
|
+
|
|
6
13
|
# -- Project information -----------------------------------------------------
|
|
7
14
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
|
8
15
|
|
|
@@ -14,7 +21,13 @@ release = "29.07.2025"
|
|
|
14
21
|
# -- General configuration ---------------------------------------------------
|
|
15
22
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
|
16
23
|
|
|
17
|
-
|
|
24
|
+
# Erweiterungen hinzugefügt, damit automodule, Mathe und Markdown funktionieren
|
|
25
|
+
extensions = [
|
|
26
|
+
"sphinx.ext.autodoc",
|
|
27
|
+
"sphinx.ext.napoleon", # Unterstützt Google/NumPy-Style Docstrings
|
|
28
|
+
"sphinx.ext.mathjax",
|
|
29
|
+
"myst_parser",
|
|
30
|
+
]
|
|
18
31
|
|
|
19
32
|
templates_path = ["_templates"]
|
|
20
33
|
exclude_patterns = []
|
|
@@ -23,5 +36,6 @@ exclude_patterns = []
|
|
|
23
36
|
# -- Options for HTML output -------------------------------------------------
|
|
24
37
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
|
25
38
|
|
|
26
|
-
|
|
39
|
+
# Auf das im Workflow genutzte Theme umgestellt
|
|
40
|
+
html_theme = "sphinx_rtd_theme"
|
|
27
41
|
html_static_path = ["_static"]
|
|
@@ -150,7 +150,9 @@ print(
|
|
|
150
150
|
################################################
|
|
151
151
|
|
|
152
152
|
Umask = np.append(np.array([True]), gsis > 1e-2)
|
|
153
|
-
U = [
|
|
153
|
+
U = [
|
|
154
|
+
ads.getSetting().U[i] for i in np.arange(0, len(Umask))[Umask]
|
|
155
|
+
] # get important subsets
|
|
154
156
|
bws = M / (math.log10(M) * (len(U) - 1)) # calculate frequencies per subset
|
|
155
157
|
N = [
|
|
156
158
|
math.floor(bws ** (1 / max(1, len(u))) / 2) * 2 for u in U
|
|
@@ -74,20 +74,23 @@ anova_model = ANOVAapprox.approx(X, y, ds=q, basis=basis, N=N)
|
|
|
74
74
|
|
|
75
75
|
#### Do approximation by least-squares ###
|
|
76
76
|
anova_model.approximate(lam=lambdas, solver="lsqr")
|
|
77
|
-
print(
|
|
77
|
+
print(
|
|
78
|
+
"Total number of used parameters = "
|
|
79
|
+
+ str(len(anova_model.getFc()[lambdas[0]].vec()))
|
|
80
|
+
)
|
|
78
81
|
|
|
79
82
|
#######################
|
|
80
83
|
## Analyze the model ##
|
|
81
84
|
#######################
|
|
82
85
|
|
|
83
86
|
### Do sensitivity analysis ####
|
|
84
|
-
anova_model.get_GSI(
|
|
85
|
-
|
|
86
|
-
) # calculates indices for importance of terms (gsis is vector, with indices belonging to terms in anova_model.U)
|
|
87
|
-
anova_model.get_GSI(lam=0.0, Dict=
|
|
87
|
+
gsis = anova_model.get_GSI(
|
|
88
|
+
lam=0.0
|
|
89
|
+
) # calculates indices for importance of terms (gsis is vector, with indices belonging to terms in anova_model.getSetting().U)
|
|
90
|
+
anova_model.get_GSI(lam=0.0, Dict=True)
|
|
88
91
|
|
|
89
92
|
y_min_calc = 10 ** (np.min(np.log10(gsis)) - 0.5)
|
|
90
|
-
label = list(anova_model.U[1:])
|
|
93
|
+
label = list(anova_model.getSetting().U[1:])
|
|
91
94
|
l = len(label)
|
|
92
95
|
plt.figure()
|
|
93
96
|
x_values = np.arange(1, l + 1)
|
|
@@ -128,7 +131,10 @@ anova_model = anova_model.approx(
|
|
|
128
131
|
X=X, y=y, U=U, N=[i + 2 for i in N], basis=basis
|
|
129
132
|
) # increase number of paramers in N for the important terms
|
|
130
133
|
anova_model.approximate(lam=lambdas)
|
|
131
|
-
print(
|
|
134
|
+
print(
|
|
135
|
+
"Total number of used parameters = "
|
|
136
|
+
+ str(len(anova_model.getFc()[lambdas[0]].vec()))
|
|
137
|
+
)
|
|
132
138
|
mse_train = anova_model.get_mse(lam=0.0)
|
|
133
139
|
mse_test = anova_model.get_mse(X=X_test, y=y_test, lam=0.0)
|
|
134
140
|
print("MSE on test points after ANOVA truncation: " + str(mse_test))
|
|
@@ -3,22 +3,22 @@ import numpy as np
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
def _variances(self, settingnr, lam, Dict): # helpfunction for get_variances
|
|
6
|
-
setting = self.getSetting(settingnr)
|
|
6
|
+
setting = self.getSetting(settingnr, lam)
|
|
7
7
|
if setting.basis.startswith("chui"):
|
|
8
|
-
variances = self.getFc(settingnr)[lam].norms(
|
|
8
|
+
variances = self.getFc(settingnr, lam)[lam].norms(
|
|
9
9
|
Dict=False, m=int(setting.basis[-1])
|
|
10
10
|
)
|
|
11
11
|
else:
|
|
12
|
-
variances = self.getFc(settingnr)[lam].norms()
|
|
12
|
+
variances = self.getFc(settingnr, lam)[lam].norms()
|
|
13
13
|
|
|
14
14
|
variances = variances[1:]
|
|
15
15
|
if Dict:
|
|
16
16
|
if a.basis.startswith("chui"):
|
|
17
|
-
variances = self.getFc(settingnr)[lam].norms(
|
|
17
|
+
variances = self.getFc(settingnr, lam)[lam].norms(
|
|
18
18
|
Dict=True, m=int(setting.basis[-1])
|
|
19
19
|
)
|
|
20
20
|
else:
|
|
21
|
-
variances = self.getFc(settingnr)[lam].norms(Dict=True)
|
|
21
|
+
variances = self.getFc(settingnr, lam)[lam].norms(Dict=True)
|
|
22
22
|
|
|
23
23
|
return {u: variances[u] for u in list(variances)}
|
|
24
24
|
else:
|
|
@@ -37,31 +37,28 @@ def get_variances(self, settingnr=None, lam=None, Dict=False):
|
|
|
37
37
|
elif (
|
|
38
38
|
lam == None
|
|
39
39
|
): # get_variances( a::approx; dict::Bool = false )::Dict{Float64,Union{Vector{Float64},Dict{Vector{Int},Float64}}}
|
|
40
|
-
return {
|
|
41
|
-
l: self._variances(settingnr, l, Dict)
|
|
42
|
-
for l in self.getSetting(settingnr).lam
|
|
43
|
-
}
|
|
40
|
+
return {l: self._variances(settingnr, l, Dict) for l in self.lam.keys()}
|
|
44
41
|
|
|
45
42
|
|
|
46
43
|
def _GSI(self, settingnr, lam, Dict): # helpfunction for get_GSI
|
|
47
|
-
setting = self.getSetting(settingnr)
|
|
44
|
+
setting = self.getSetting(settingnr, lam)
|
|
48
45
|
if setting.basis.startswith("chui"):
|
|
49
46
|
variances = np.square(
|
|
50
|
-
self.getFc(settingnr)[lam].norms(Dict=False, m=int(setting.basis[-1]))
|
|
47
|
+
self.getFc(settingnr, lam)[lam].norms(Dict=False, m=int(setting.basis[-1]))
|
|
51
48
|
)
|
|
52
49
|
else:
|
|
53
|
-
variances = np.square(self.getFc(settingnr)[lam].norms())
|
|
50
|
+
variances = np.square(self.getFc(settingnr, lam)[lam].norms())
|
|
54
51
|
|
|
55
52
|
variances = variances[1:]
|
|
56
53
|
variance_f = sum(variances)
|
|
57
54
|
|
|
58
55
|
if Dict:
|
|
59
56
|
if setting.basis.startswith("chui"):
|
|
60
|
-
variances = self.getFc(settingnr)[lam].norms(
|
|
57
|
+
variances = self.getFc(settingnr, lam)[lam].norms(
|
|
61
58
|
Dict=True, m=int(setting.basis[-1])
|
|
62
59
|
)
|
|
63
60
|
else:
|
|
64
|
-
variances = self.getFc(settingnr)[lam].norms(Dict=True)
|
|
61
|
+
variances = self.getFc(settingnr, lam)[lam].norms(Dict=True)
|
|
65
62
|
return {u: (variances[u] ** 2) / variance_f for u in list(variances)}
|
|
66
63
|
|
|
67
64
|
else:
|
|
@@ -78,9 +75,7 @@ def get_GSI(self, settingnr=None, lam=None, Dict=False):
|
|
|
78
75
|
): # get_GSI(a::approx, λ::Float64; dict::Bool = false,)::Union{Vector{Float64},Dict{Vector{Int},Float64}}
|
|
79
76
|
return self._GSI(settingnr, lam, Dict)
|
|
80
77
|
else: # get_GSI( a::approx; dict::Bool = false )::Dict{Float64,Union{Vector{Float64},Dict{Vector{Int},Float64}}}
|
|
81
|
-
return {
|
|
82
|
-
l: self._GSI(settingnr, l, Dict) for l in self.getSetting(settingnr).lam
|
|
83
|
-
}
|
|
78
|
+
return {l: self._GSI(settingnr, l, Dict) for l in self.lam.keys()}
|
|
84
79
|
|
|
85
80
|
|
|
86
81
|
def _AttributeRanking(self, settingnr, lam): # helpfunction for get_AttributeRanking
|
|
@@ -120,17 +115,14 @@ def get_AttributeRanking(self, settingnr=None, lam=None):
|
|
|
120
115
|
if (
|
|
121
116
|
lam is None
|
|
122
117
|
): # get_AttributeRanking( a::approx, λ::Float64 )::Dict{Float64,Vector{Float64}}
|
|
123
|
-
return {
|
|
124
|
-
l: self._AttributeRanking(settingnr, l)
|
|
125
|
-
for l in self.getSetting(settingnr).lam
|
|
126
|
-
}
|
|
118
|
+
return {l: self._AttributeRanking(settingnr, l) for l in self.lam.keys()}
|
|
127
119
|
else: # get_AttributeRanking( a::approx, λ::Float64 )::Vector{Float64}
|
|
128
120
|
return self._AttributeRanking(settingnr, lam)
|
|
129
121
|
|
|
130
122
|
|
|
131
123
|
def _ActiveSet(self, eps, settingnr, lam): # helpfunction for get_ActiveSet
|
|
132
124
|
|
|
133
|
-
U = self.getSetting(settingnr).U[1:]
|
|
125
|
+
U = self.getSetting(settingnr, lam).U[1:]
|
|
134
126
|
lengths = [len(u) for u in U]
|
|
135
127
|
ds = max(lengths)
|
|
136
128
|
|
|
@@ -162,10 +154,7 @@ def get_ActiveSet(self, eps, settingnr=None, lam=None):
|
|
|
162
154
|
if (
|
|
163
155
|
lam is None
|
|
164
156
|
): # get_ActiveSet(a::approx, eps::Vector{Float64})::Dict{Float64,Vector{Vector{Int}}}
|
|
165
|
-
return {
|
|
166
|
-
l: self._ActiveSet(eps, settingnr, l)
|
|
167
|
-
for l in self.getSetting(settingnr).lam
|
|
168
|
-
}
|
|
157
|
+
return {l: self._ActiveSet(eps, settingnr, l) for l in self.lam.keys()}
|
|
169
158
|
else: # get_ActiveSet(a::approx, eps::Vector{Float64}, λ::Float64)::Vector{Vector{Int}}
|
|
170
159
|
return self._ActiveSet(eps, settingnr, lam)
|
|
171
160
|
|
|
@@ -190,9 +179,7 @@ def get_ShapleyValues(self, settingnr=None, lam=None):
|
|
|
190
179
|
This function returns the Shapley values of the approximation for all reg. parameters ``\lambda``, if lam == None, as a dictionary of vectors of length `a.d`. Otherwise for the provided lam as a vector of length `a.d`.
|
|
191
180
|
"""
|
|
192
181
|
if lam is None: # get_ShapleyValues(a::approx)::Dict{Float64,Vector{Float64}}
|
|
193
|
-
return {
|
|
194
|
-
l: self._ShapleyValues(settingnr, l) for l in self.getSetting(settingnr).lam
|
|
195
|
-
}
|
|
182
|
+
return {l: self._ShapleyValues(settingnr, l) for l in self.lam.keys()}
|
|
196
183
|
else: # get_ShapleyValues(a::approx, λ::Float64)::Vector{Float64}
|
|
197
184
|
return self._ShapleyValues(settingnr, lam)
|
|
198
185
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import copy
|
|
2
|
+
import warnings
|
|
2
3
|
|
|
3
4
|
import pyANOVAapprox.analysis as ANOVAanalysis
|
|
4
5
|
import pyANOVAapprox.bandwidth as ANOVAbandwidth
|
|
@@ -186,8 +187,13 @@ class approx:
|
|
|
186
187
|
lam={0.0},
|
|
187
188
|
):
|
|
188
189
|
|
|
190
|
+
if type(lam) is np.ndarray:
|
|
191
|
+
lam = {float(i) for i in lam}
|
|
192
|
+
if type(lam) is list:
|
|
193
|
+
lam = set(lam)
|
|
194
|
+
|
|
189
195
|
self.X = X
|
|
190
|
-
|
|
196
|
+
|
|
191
197
|
if X.shape[0] != y.shape[0]:
|
|
192
198
|
raise ValueError("X and y have different lengths.")
|
|
193
199
|
|
|
@@ -222,6 +228,9 @@ class approx:
|
|
|
222
228
|
self.trafo = [None]
|
|
223
229
|
self.fc = [{}]
|
|
224
230
|
self.aktsetting = 0
|
|
231
|
+
self.lam = {}
|
|
232
|
+
for i in lam:
|
|
233
|
+
self.lam[i] = [0]
|
|
225
234
|
|
|
226
235
|
if setting.N is not None:
|
|
227
236
|
self.addTrafo()
|
|
@@ -233,17 +242,24 @@ class approx:
|
|
|
233
242
|
self.trafo.append(None)
|
|
234
243
|
self.fc.append({})
|
|
235
244
|
|
|
236
|
-
def getSettingNr(self, settingnr=None):
|
|
237
|
-
|
|
245
|
+
def getSettingNr(self, settingnr=None, lam=None, warn=True):
|
|
246
|
+
if lam is None:
|
|
247
|
+
return self.aktsetting if settingnr is None else settingnr
|
|
248
|
+
else:
|
|
249
|
+
if lam in self.lam.keys():
|
|
250
|
+
return self.lam[lam][-1] if settingnr is None else settingnr
|
|
251
|
+
else:
|
|
252
|
+
warnings.warn("Not yet approximated for this lambda")
|
|
253
|
+
return self.aktsetting if settingnr is None else settingnr
|
|
238
254
|
|
|
239
|
-
def getSetting(self, settingnr=None):
|
|
240
|
-
return self.setting[self.getSettingNr(settingnr)]
|
|
255
|
+
def getSetting(self, settingnr=None, lam=None):
|
|
256
|
+
return self.setting[self.getSettingNr(settingnr, lam)]
|
|
241
257
|
|
|
242
|
-
def getTrafo(self, settingnr=None):
|
|
243
|
-
return self.trafo[self.getSettingNr(settingnr)]
|
|
258
|
+
def getTrafo(self, settingnr=None, lam=None):
|
|
259
|
+
return self.trafo[self.getSettingNr(settingnr, lam)]
|
|
244
260
|
|
|
245
|
-
def getFc(self, settingnr=None):
|
|
246
|
-
return self.fc[self.getSettingNr(settingnr)]
|
|
261
|
+
def getFc(self, settingnr=None, lam=None):
|
|
262
|
+
return self.fc[self.getSettingNr(settingnr, lam)]
|
|
247
263
|
|
|
248
264
|
def addTrafo(self, settingnr=None):
|
|
249
265
|
setting = self.getSetting(settingnr)
|
|
@@ -356,6 +372,7 @@ class approx:
|
|
|
356
372
|
If lam is a np.ndarray of dtype float, this function computes the approximation for the regularization parameters contained in lam.
|
|
357
373
|
If lam is a float, this function computes the approximation for the regularization parameter lam.
|
|
358
374
|
"""
|
|
375
|
+
|
|
359
376
|
setting = self.getSetting(settingnr)
|
|
360
377
|
|
|
361
378
|
if lam is None:
|
|
@@ -393,6 +410,7 @@ class approx:
|
|
|
393
410
|
solver_verbose,
|
|
394
411
|
solver_tol,
|
|
395
412
|
):
|
|
413
|
+
settingnrs = []
|
|
396
414
|
setting = self.getSetting(settingnr)
|
|
397
415
|
|
|
398
416
|
n = len(self.y)
|
|
@@ -401,13 +419,14 @@ class approx:
|
|
|
401
419
|
|
|
402
420
|
D = dict([(u, tuple([1.0] * len(u))) for u in setting.U])
|
|
403
421
|
t = dict([(u, tuple([1.0] * len(u))) for u in setting.U])
|
|
404
|
-
|
|
405
|
-
if verbosity>3:
|
|
422
|
+
|
|
423
|
+
if verbosity > 3:
|
|
406
424
|
if not os.path.exists("log"):
|
|
407
425
|
os.mkdir("log")
|
|
408
|
-
with open(
|
|
409
|
-
csv.writer(csvfile, delimiter=
|
|
410
|
-
|
|
426
|
+
with open("log/log.csv", "w", newline="") as csvfile:
|
|
427
|
+
csv.writer(csvfile, delimiter=",").writerow(["it"] + setting.U)
|
|
428
|
+
if verbosity > 2:
|
|
429
|
+
print("B =", B)
|
|
411
430
|
for idx in range(maxiter):
|
|
412
431
|
if verbosity > 0:
|
|
413
432
|
print("===== Iteration ", str(idx + 1), " =====")
|
|
@@ -415,6 +434,7 @@ class approx:
|
|
|
415
434
|
if setting.N is not None:
|
|
416
435
|
self.addSetting(setting)
|
|
417
436
|
settingnr = self.aktsetting
|
|
437
|
+
settingnrs = settingnrs + [settingnr]
|
|
418
438
|
setting = self.getSetting(settingnr)
|
|
419
439
|
|
|
420
440
|
setting.N = [bw[i] for i in setting.U]
|
|
@@ -423,11 +443,13 @@ class approx:
|
|
|
423
443
|
if verbosity > 0:
|
|
424
444
|
for i in setting.U:
|
|
425
445
|
print("bw in", str(i), ":", bw[i])
|
|
426
|
-
#print("bw in iteration", str(idx + 1), "are", str(bw))
|
|
446
|
+
# print("bw in iteration", str(idx + 1), "are", str(bw))
|
|
427
447
|
print()
|
|
428
448
|
if verbosity > 3:
|
|
429
|
-
with open(
|
|
430
|
-
csv.writer(csvfile, delimiter=
|
|
449
|
+
with open("log/log.csv", "a", newline="") as csvfile:
|
|
450
|
+
csv.writer(csvfile, delimiter=",").writerow(
|
|
451
|
+
["bw in it" + str(idx + 1)] + [str(bw[i]) for i in setting.U]
|
|
452
|
+
)
|
|
431
453
|
self.approximate(
|
|
432
454
|
lam=lam,
|
|
433
455
|
solver=solver,
|
|
@@ -440,23 +462,39 @@ class approx:
|
|
|
440
462
|
D, t = self.estimate_rates(lam=lam, verbosity=verbosity)
|
|
441
463
|
if verbosity > 1:
|
|
442
464
|
for i in setting.U:
|
|
443
|
-
print(
|
|
465
|
+
print(
|
|
466
|
+
"estimated rates for",
|
|
467
|
+
str(i),
|
|
468
|
+
": D = ",
|
|
469
|
+
str(D[i]),
|
|
470
|
+
"and t = ",
|
|
471
|
+
str(t[i]),
|
|
472
|
+
)
|
|
444
473
|
print()
|
|
445
|
-
|
|
446
|
-
#print(
|
|
474
|
+
|
|
475
|
+
# print(
|
|
447
476
|
# "estimated rates in iteration",
|
|
448
477
|
# str(idx + 1),
|
|
449
478
|
# "are D =",
|
|
450
479
|
# str(D),
|
|
451
480
|
# "and t =",
|
|
452
481
|
# str(t),
|
|
453
|
-
#)
|
|
482
|
+
# )
|
|
454
483
|
if verbosity > 3:
|
|
455
|
-
with open(
|
|
456
|
-
wr = csv.writer(csvfile, delimiter=
|
|
457
|
-
wr.writerow(
|
|
458
|
-
|
|
459
|
-
|
|
484
|
+
with open("log/log.csv", "a", newline="") as csvfile:
|
|
485
|
+
wr = csv.writer(csvfile, delimiter=",")
|
|
486
|
+
wr.writerow(
|
|
487
|
+
["D in it" + str(idx + 1)] + [str(D[i]) for i in setting.U]
|
|
488
|
+
)
|
|
489
|
+
wr.writerow(
|
|
490
|
+
["t in it" + str(idx + 1)] + [str(t[i]) for i in setting.U]
|
|
491
|
+
)
|
|
492
|
+
|
|
493
|
+
if all([math.isnan(j) for j in sum([D[i] for i in D], [])]) and all(
|
|
494
|
+
[math.isnan(j) for j in sum([t[i] for i in D], [])]
|
|
495
|
+
):
|
|
496
|
+
break
|
|
497
|
+
return settingnrs
|
|
460
498
|
|
|
461
499
|
def autoapproximate(
|
|
462
500
|
self,
|
|
@@ -471,18 +509,21 @@ class approx:
|
|
|
471
509
|
solver_verbose=False,
|
|
472
510
|
solver_tol=1e-8,
|
|
473
511
|
):
|
|
512
|
+
settingnr = self.getSettingNr(settingnr)
|
|
474
513
|
setting = self.getSetting(settingnr)
|
|
475
514
|
|
|
476
515
|
if lam is None:
|
|
477
516
|
lam = setting.lam
|
|
478
517
|
else:
|
|
518
|
+
if isinstance(lam, np.ndarray):
|
|
519
|
+
lam = {float(l) for l in lam}
|
|
479
520
|
if not isinstance(lam, set):
|
|
480
521
|
lam = {lam}
|
|
481
522
|
setting.lam = lam
|
|
482
523
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
524
|
+
for l in lam:
|
|
525
|
+
settingnrs = self._autoapproximate(
|
|
526
|
+
l,
|
|
486
527
|
settingnr=settingnr,
|
|
487
528
|
B=B,
|
|
488
529
|
maxiter=maxiter,
|
|
@@ -493,22 +534,7 @@ class approx:
|
|
|
493
534
|
solver_verbose=solver_verbose,
|
|
494
535
|
solver_tol=solver_tol,
|
|
495
536
|
)
|
|
496
|
-
|
|
497
|
-
return {
|
|
498
|
-
l: self._autoapproximate(
|
|
499
|
-
l,
|
|
500
|
-
settingnr=settingnr,
|
|
501
|
-
B=B,
|
|
502
|
-
maxiter=maxiter,
|
|
503
|
-
solver=solver,
|
|
504
|
-
verbosity=verbosity,
|
|
505
|
-
solver_max_iter=solver_max_iter,
|
|
506
|
-
solver_weights=solver_weights,
|
|
507
|
-
solver_verbose=solver_verbose,
|
|
508
|
-
solver_tol=solver_tol,
|
|
509
|
-
)
|
|
510
|
-
for l in lam
|
|
511
|
-
}
|
|
537
|
+
self.lam[l] = self.lam[l] + settingnrs
|
|
512
538
|
|
|
513
539
|
def evaluate(self, settingnr=None, lam=None, X=None):
|
|
514
540
|
"""
|
|
@@ -519,7 +545,7 @@ class approx:
|
|
|
519
545
|
- If only lam is given: evaluate at self.X for specific lam.
|
|
520
546
|
- If neither are given: evaluate at self.X for all lam.
|
|
521
547
|
"""
|
|
522
|
-
setting = self.getSetting(settingnr)
|
|
548
|
+
setting = self.getSetting(settingnr, lam)
|
|
523
549
|
|
|
524
550
|
if X is not None:
|
|
525
551
|
if setting.basis == "per" and (np.min(X) < -0.5 or np.max(X) >= 0.5):
|
|
@@ -537,14 +563,14 @@ class approx:
|
|
|
537
563
|
basis_vect=setting.basis_vect,
|
|
538
564
|
)
|
|
539
565
|
else:
|
|
540
|
-
trafo = self.getTrafo(settingnr)
|
|
566
|
+
trafo = self.getTrafo(settingnr, lam)
|
|
541
567
|
|
|
542
568
|
if (
|
|
543
569
|
lam is not None
|
|
544
570
|
): # evaluate( a::approx; X::Matrix{Float64}, λ::Float64 )::Union{Vector{ComplexF64},Vector{Float64}}
|
|
545
|
-
return trafo @ self.getFc(settingnr)[lam]
|
|
571
|
+
return trafo @ self.getFc(settingnr, lam)[lam]
|
|
546
572
|
else: # evaluate( a::approx; X::Matrix{Float64} )::Dict{Float64,Union{Vector{ComplexF64},Vector{Float64}}}
|
|
547
|
-
return {λ: trafo @ self.getFc(settingnr)[λ] for λ in
|
|
573
|
+
return {λ: trafo @ self.getFc(settingnr, lam)[λ] for λ in self.lam.keys()}
|
|
548
574
|
|
|
549
575
|
def evaluateANOVAterms(self, settingnr=None, X=None, lam=None):
|
|
550
576
|
"""
|
|
@@ -553,7 +579,7 @@ class approx:
|
|
|
553
579
|
- If lam is given: evaluate at X for specific lam.
|
|
554
580
|
- If lam is not given: evaluate at X for all lam.
|
|
555
581
|
"""
|
|
556
|
-
setting = self.getSetting(settingnr)
|
|
582
|
+
setting = self.getSetting(settingnr, lam)
|
|
557
583
|
if X is None:
|
|
558
584
|
X = self.X
|
|
559
585
|
|
|
@@ -567,9 +593,11 @@ class approx:
|
|
|
567
593
|
Xt = transformX(X, setting.basis)
|
|
568
594
|
|
|
569
595
|
if self.getSetting(settingnr).basis == "per":
|
|
570
|
-
values = np.zeros(
|
|
596
|
+
values = np.zeros(
|
|
597
|
+
(Xt.shape[0], len(self.getSetting(settingnr).U)), "complex"
|
|
598
|
+
)
|
|
571
599
|
else:
|
|
572
|
-
values = np.zeros((Xt.shape[0], len(self.
|
|
600
|
+
values = np.zeros((Xt.shape[0], len(self.getSetting(settingnr).U)), "float")
|
|
573
601
|
|
|
574
602
|
trafo = GroupedTransform(
|
|
575
603
|
system=gt_systems[setting.basis],
|
|
@@ -583,14 +611,14 @@ class approx:
|
|
|
583
611
|
lam is not None
|
|
584
612
|
): # evaluateANOVAterms( a::approx; X::Matrix{Float64}, λ::Float64 )::Union{Matrix{ComplexF64},Matrix{Float64}}
|
|
585
613
|
for j, u in enumerate(setting.U):
|
|
586
|
-
values[:, j] = trafo[u] @ self.getFc(settingnr)[lam][u]
|
|
614
|
+
values[:, j] = trafo[u] @ self.getFc(settingnr, lam)[lam][u]
|
|
587
615
|
return values
|
|
588
616
|
else: # evaluateANOVAterms( a::approx; X::Matrix{Float64} )::Dict{Float64,Union{Matrix{ComplexF64},Matrix{Float64}}}
|
|
589
617
|
results = {}
|
|
590
|
-
for λ in
|
|
618
|
+
for λ in self.lam.keys():
|
|
591
619
|
vals = np.zeros_like(values)
|
|
592
620
|
for j, u in enumerate(setting.U):
|
|
593
|
-
vals[:, j] = trafo[u] @ self.getFc(settingnr)[λ][u]
|
|
621
|
+
vals[:, j] = trafo[u] @ self.getFc(settingnr, lam)[λ][u]
|
|
594
622
|
results[λ] = vals
|
|
595
623
|
return results
|
|
596
624
|
|
|
@@ -601,7 +629,7 @@ class approx:
|
|
|
601
629
|
- If lam is given: evaluate at X for specific lam.
|
|
602
630
|
- If lam is not given: evaluate at X for all lam.
|
|
603
631
|
"""
|
|
604
|
-
setting = self.getSetting(settingnr)
|
|
632
|
+
setting = self.getSetting(settingnr, lam)
|
|
605
633
|
|
|
606
634
|
if X is None:
|
|
607
635
|
X = self.X
|
|
@@ -631,7 +659,7 @@ class approx:
|
|
|
631
659
|
|
|
632
660
|
else: # evaluateSHAPterms( a::approx; X::Matrix{Float64} )::Dict{Float64,Union{Matrix{ComplexF64},Matrix{Float64}}}
|
|
633
661
|
results = {}
|
|
634
|
-
for l in
|
|
662
|
+
for l in self.lam.keys():
|
|
635
663
|
terms = self.evaluateANOVAterms(X, l)
|
|
636
664
|
|
|
637
665
|
Dtype = np.complex128 if setting.basis == "per" else np.float64
|
|
@@ -5,11 +5,11 @@ def getfcu(ghat, u):
|
|
|
5
5
|
idx = [s.u for s in ghat.settings].index(u)
|
|
6
6
|
bws = ghat.settings[idx].bandwidths
|
|
7
7
|
|
|
8
|
-
#fcu = ghat[u].reshape(bws[::-1] - 1)
|
|
9
|
-
#fcu = np.permute_dims(fcu, range(len(bws))[::-1])
|
|
8
|
+
# fcu = ghat[u].reshape(bws[::-1] - 1)
|
|
9
|
+
# fcu = np.permute_dims(fcu, range(len(bws))[::-1])
|
|
10
10
|
fcu = ghat[u].reshape(bws - 1)
|
|
11
11
|
fcu = np.permute_dims(fcu, range(len(bws)))
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
return fcu
|
|
14
14
|
|
|
15
15
|
|
|
@@ -30,6 +30,9 @@ def getaxissum(ghat, u, j, system):
|
|
|
30
30
|
else:
|
|
31
31
|
raise ValueError("For this basis is estimate rates not implemented")
|
|
32
32
|
# fcuj = np.concatenate(fcuj[math.ceil(bws[j]/2):] + [fcuj[0]]) + fcuj[math.ceil(bws[j]/2)-1::-1]
|
|
33
|
+
|
|
34
|
+
fcuj = np.cumsum(fcuj[::-1])[::-1]
|
|
35
|
+
|
|
33
36
|
return fcuj
|
|
34
37
|
|
|
35
38
|
|
|
@@ -37,13 +40,14 @@ def compute_bandwidth(B, D, t):
|
|
|
37
40
|
us = set(D.keys()) - {()}
|
|
38
41
|
bw = {u: [6] * len(u) for u in us}
|
|
39
42
|
bw[()] = []
|
|
40
|
-
|
|
43
|
+
|
|
41
44
|
minfreqs = sum(math.prod((bw[u][j] - 1) for j in range(len(u))) for u in us)
|
|
42
45
|
if B < minfreqs:
|
|
43
46
|
raise ValueError(f"Budget too small: {B} < {minfreqs}")
|
|
44
47
|
|
|
45
48
|
def fun_lmbda_u(lmbda, u):
|
|
46
|
-
p1 = math.prod((bw[u][j] - 1) for j in range(len(u)) if math.isnan(t[u][j]))
|
|
49
|
+
p1 = math.prod((bw[u][j] - 1) for j in range(len(u)) if not math.isnan(t[u][j]))
|
|
50
|
+
|
|
47
51
|
p2 = math.prod(
|
|
48
52
|
((2 * t[u][j] * D[u][j]) / lmbda) ** (0.5 / t[u][j])
|
|
49
53
|
for j in range(len(u))
|
|
@@ -69,7 +73,7 @@ def compute_bandwidth(B, D, t):
|
|
|
69
73
|
bwuj = ((2 * t[u][j] * D[u][j]) / (lmbda * sizeIu)) ** (
|
|
70
74
|
0.5 / t[u][j]
|
|
71
75
|
) + 1
|
|
72
|
-
bw[u][j] = 2 * round(0.5 * bwuj)
|
|
76
|
+
bw[u][j] = max(6, 2 * round(0.5 * bwuj))
|
|
73
77
|
|
|
74
78
|
return bw
|
|
75
79
|
|
|
@@ -123,19 +127,19 @@ def estimate_rates(self, lam, settingnr=None, verbosity=0):
|
|
|
123
127
|
|
|
124
128
|
mcl = np.exp(most_common_value(np.log(abs(self.getFc(settingnr)[lam].data))))
|
|
125
129
|
threshold = 100 * mcl**2
|
|
126
|
-
|
|
127
|
-
if verbosity>5:
|
|
128
|
-
if not os.path.exists(os.path.join("log","figures")):
|
|
129
|
-
os.mkdir(os.path.join("log","figures"))
|
|
130
|
+
|
|
131
|
+
if verbosity > 5:
|
|
132
|
+
if not os.path.exists(os.path.join("log", "figures")):
|
|
133
|
+
os.mkdir(os.path.join("log", "figures"))
|
|
130
134
|
num = 0
|
|
131
|
-
|
|
135
|
+
|
|
132
136
|
system = self.getTrafo(settingnr).system
|
|
133
137
|
|
|
134
138
|
for u in us:
|
|
135
139
|
if len(u) == 0:
|
|
136
140
|
continue
|
|
137
141
|
|
|
138
|
-
if verbosity>5:
|
|
142
|
+
if verbosity > 5:
|
|
139
143
|
fig, ax = plt.subplots()
|
|
140
144
|
ax.set_xscale("log")
|
|
141
145
|
ax.set_yscale("log")
|
|
@@ -154,17 +158,16 @@ def estimate_rates(self, lam, settingnr=None, verbosity=0):
|
|
|
154
158
|
None,
|
|
155
159
|
)
|
|
156
160
|
|
|
157
|
-
if verbosity>5:
|
|
161
|
+
if verbosity > 5:
|
|
158
162
|
|
|
159
163
|
y = np.cumsum(axissum[::-1])[::-1]
|
|
160
164
|
ax.plot(
|
|
161
|
-
|
|
162
|
-
|
|
165
|
+
axissumnum,
|
|
166
|
+
axissum,
|
|
163
167
|
label=u[j],
|
|
164
168
|
marker="o",
|
|
165
169
|
# color=j
|
|
166
170
|
)
|
|
167
|
-
|
|
168
171
|
if (idx is None) or idx >= len(axissum):
|
|
169
172
|
D[u][j] = math.nan
|
|
170
173
|
t[u][j] = math.nan
|
|
@@ -174,7 +177,7 @@ def estimate_rates(self, lam, settingnr=None, verbosity=0):
|
|
|
174
177
|
D[u][j] = Duj
|
|
175
178
|
t[u][j] = -tuj / 2
|
|
176
179
|
|
|
177
|
-
if verbosity>5:
|
|
180
|
+
if verbosity > 5:
|
|
178
181
|
x = np.arange(1, idx + 1)
|
|
179
182
|
ax.plot(
|
|
180
183
|
x,
|
|
@@ -182,12 +185,23 @@ def estimate_rates(self, lam, settingnr=None, verbosity=0):
|
|
|
182
185
|
linewidth=2,
|
|
183
186
|
# color=j
|
|
184
187
|
)
|
|
185
|
-
if verbosity>5:
|
|
186
|
-
#plt.figure(figsize=(12, 9))
|
|
187
|
-
#for ax in ps:
|
|
188
|
+
if verbosity > 5:
|
|
189
|
+
# plt.figure(figsize=(12, 9))
|
|
190
|
+
# for ax in ps:
|
|
188
191
|
# plt.sca(ax)
|
|
189
|
-
|
|
192
|
+
time = ""
|
|
193
|
+
if verbosity > 8:
|
|
194
|
+
from datetime import datetime
|
|
195
|
+
|
|
196
|
+
time = str(round(datetime.timestamp(datetime.now())))
|
|
197
|
+
fig.savefig(
|
|
198
|
+
os.path.join(
|
|
199
|
+
"log",
|
|
200
|
+
"figures",
|
|
201
|
+
time + "_" + str(num).strip() + "_rates_" + str(u).strip() + ".png",
|
|
202
|
+
)
|
|
203
|
+
)
|
|
190
204
|
num = num + 1
|
|
191
|
-
plt.close(fig)
|
|
205
|
+
plt.close(fig)
|
|
192
206
|
|
|
193
207
|
return D, t
|
|
@@ -37,10 +37,7 @@ def get_l2_error(self, settingnr=None, X=None, y=None, lam=None):
|
|
|
37
37
|
if lam is not None:
|
|
38
38
|
return self._l2_error(settingnr, lam, X, y)
|
|
39
39
|
else:
|
|
40
|
-
return {
|
|
41
|
-
l: self._l2_error(settingnr, l, X, y)
|
|
42
|
-
for l in self.getSetting(settingnr).lam
|
|
43
|
-
}
|
|
40
|
+
return {l: self._l2_error(settingnr, l, X, y) for l in self.lam.keys()}
|
|
44
41
|
|
|
45
42
|
|
|
46
43
|
def _mse(self, settingnr, lam, X, y): # helpfunction for get_mse
|
|
@@ -77,9 +74,7 @@ def get_mse(self, settingnr=None, X=None, y=None, lam=None):
|
|
|
77
74
|
if lam is not None:
|
|
78
75
|
return self._mse(settingnr, lam, X, y)
|
|
79
76
|
else:
|
|
80
|
-
return {
|
|
81
|
-
l: self._mse(settingnr, l, X, y) for l in self.getSetting(settingnr).lam
|
|
82
|
-
}
|
|
77
|
+
return {l: self._mse(settingnr, l, X, y) for l in self.lam.keys()}
|
|
83
78
|
|
|
84
79
|
|
|
85
80
|
def _mad(self, settingnr, lam, X, y): # helpfunction for get_mad
|
|
@@ -116,21 +111,21 @@ def get_mad(self, settingnr=None, X=None, y=None, lam=None):
|
|
|
116
111
|
if lam is not None:
|
|
117
112
|
return self._mad(settingnr, lam, X, y)
|
|
118
113
|
else:
|
|
119
|
-
return {
|
|
120
|
-
l: self._mad(settingnr, l, X, y) for l in self.getSetting(settingnr).lam
|
|
121
|
-
}
|
|
114
|
+
return {l: self._mad(settingnr, l, X, y) for l in self.lam.keys()}
|
|
122
115
|
|
|
123
116
|
|
|
124
117
|
def _L2_error(self, norm, bc_fun, settingnr, lam):
|
|
125
118
|
# print(settingnr)
|
|
126
|
-
if self.getSetting(settingnr).basis in {"per", "cos", "cheb", "std", "mixed"}:
|
|
119
|
+
if self.getSetting(settingnr, lam).basis in {"per", "cos", "cheb", "std", "mixed"}:
|
|
127
120
|
error = norm**2
|
|
128
|
-
index_set = gt.get_IndexSet(
|
|
121
|
+
index_set = gt.get_IndexSet(
|
|
122
|
+
self.getTrafo(settingnr, lam).settings, self.X.shape[1]
|
|
123
|
+
)
|
|
129
124
|
|
|
130
125
|
for i in range(index_set.shape[1]):
|
|
131
126
|
k = index_set[:, i]
|
|
132
127
|
error += (
|
|
133
|
-
abs(bc_fun(k) - self.getFc(settingnr)[lam][i]) ** 2
|
|
128
|
+
abs(bc_fun(k) - self.getFc(settingnr, lam)[lam][i]) ** 2
|
|
134
129
|
- abs(bc_fun(k)) ** 2
|
|
135
130
|
)
|
|
136
131
|
|
|
@@ -153,10 +148,7 @@ def get_L2_error(self, norm, bc_fun, settingnr=None, lam=None):
|
|
|
153
148
|
if lam is not None:
|
|
154
149
|
return self._L2_error(norm, bc_fun, settingnr, lam)
|
|
155
150
|
else:
|
|
156
|
-
return {
|
|
157
|
-
l: self._L2_error(norm, bc_fun, settingnr, l)
|
|
158
|
-
for l in self.getSetting(settingnr).lam
|
|
159
|
-
}
|
|
151
|
+
return {l: self._L2_error(norm, bc_fun, settingnr, l) for l in self.lam.keys()}
|
|
160
152
|
|
|
161
153
|
|
|
162
154
|
def _acc(self, settingnr, lam, X, y): # helpfunction for get_acc
|
|
@@ -176,9 +168,7 @@ def get_acc(self, settingnr=None, X=None, y=None, lam=None):
|
|
|
176
168
|
if lam is not None:
|
|
177
169
|
return self._acc(settingnr, lam, X, y)
|
|
178
170
|
else:
|
|
179
|
-
return {
|
|
180
|
-
l: self._acc(settingnr, l, X, y) for l in self.getSetting(settingnr).lam
|
|
181
|
-
}
|
|
171
|
+
return {l: self._acc(settingnr, l, X, y) for l in self.lam.keys()}
|
|
182
172
|
|
|
183
173
|
|
|
184
174
|
def auc_score(y_true, y_pred_proba):
|
|
@@ -240,9 +230,7 @@ def get_auc(self, settingnr=None, X=None, y=None, lam=None):
|
|
|
240
230
|
if lam is not None:
|
|
241
231
|
return self._auc(settingnr, lam, X, y)
|
|
242
232
|
else:
|
|
243
|
-
return {
|
|
244
|
-
l: self._auc(settingnr, l, X, y) for l in self.getSetting(settingnr).lam
|
|
245
|
-
}
|
|
233
|
+
return {l: self._auc(settingnr, l, X, y) for l in self.lam.keys()}
|
|
246
234
|
|
|
247
235
|
|
|
248
236
|
__all__ = [
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
name: Format Python Code
|
|
2
|
-
on: push
|
|
3
|
-
jobs:
|
|
4
|
-
python-code-format:
|
|
5
|
-
runs-on: ubuntu-latest
|
|
6
|
-
steps:
|
|
7
|
-
- uses: actions/checkout@v2
|
|
8
|
-
- uses: actions/setup-python@v4
|
|
9
|
-
with:
|
|
10
|
-
python-version: "3.12"
|
|
11
|
-
architecture: "x64"
|
|
12
|
-
- name: Display Python version
|
|
13
|
-
run: python --version
|
|
14
|
-
- name: Install packages
|
|
15
|
-
run: pip install black isort
|
|
16
|
-
- name: Formatter
|
|
17
|
-
run: |
|
|
18
|
-
black .
|
|
19
|
-
isort .
|
|
20
|
-
- name: Create Pull Request
|
|
21
|
-
uses: peter-evans/create-pull-request@v3
|
|
22
|
-
with:
|
|
23
|
-
commit-message: Auto code format
|
|
24
|
-
title: Fixes by format action
|
|
25
|
-
body: This is an auto-generated PR with fixes.
|
|
26
|
-
labels: automated pr
|
|
27
|
-
branch: python-code-format-patches
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import csv
|
|
1
2
|
import math
|
|
3
|
+
import os
|
|
2
4
|
import threading
|
|
3
5
|
from math import acos, isnan
|
|
4
6
|
|
|
@@ -8,8 +10,6 @@ from pyGroupedTransforms import *
|
|
|
8
10
|
from scipy.optimize import bisect
|
|
9
11
|
from scipy.sparse.linalg import lsqr
|
|
10
12
|
from scipy.special import erf
|
|
11
|
-
import csv
|
|
12
|
-
import os
|
|
13
13
|
|
|
14
14
|
# from sklearn.metrics import roc_auc_score
|
|
15
15
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|