pyANOVAapprox 0.2.1__tar.gz → 0.2.3__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.
Files changed (35) hide show
  1. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/PKG-INFO +1 -1
  2. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/pyproject.toml +1 -1
  3. pyanovaapprox-0.2.3/simpleTest/exampleCheb.py +202 -0
  4. pyanovaapprox-0.2.3/simpleTest/exampleClassification.py +190 -0
  5. pyanovaapprox-0.2.3/simpleTest/exampleNonPeriodic.py +200 -0
  6. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/simpleTest/examplePeriodic.py +3 -2
  7. pyanovaapprox-0.2.3/simpleTest/exampleWavelet.py +134 -0
  8. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/src/pyANOVAapprox/__init__.py +0 -21
  9. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/src/pyANOVAapprox/analysis.py +2 -2
  10. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/src/pyANOVAapprox/approx.py +3 -2
  11. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/src/pyANOVAapprox/fista.py +0 -2
  12. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/tests/run_tests.py +1 -1
  13. pyanovaapprox-0.2.3/tests/wav_lsqr.py +50 -0
  14. pyanovaapprox-0.2.1/tests/wav_lsqr.py +0 -1
  15. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/.github/workflows/ci.yml +0 -0
  16. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/.github/workflows/documentation.yml +0 -0
  17. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/.github/workflows/format.yml +0 -0
  18. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/.github/workflows/release.yml +0 -0
  19. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/.gitignore +0 -0
  20. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/LICENSE +0 -0
  21. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/README.md +0 -0
  22. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/docs/Makefile +0 -0
  23. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/docs/source/Analysis.rst +0 -0
  24. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/docs/source/Approximation.rst +0 -0
  25. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/docs/source/Errors.rst +0 -0
  26. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/docs/source/conf.py +0 -0
  27. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/docs/source/index.rst +0 -0
  28. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/src/pyANOVAapprox/errors.py +0 -0
  29. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/src/pyANOVAapprox/trafos.py +0 -0
  30. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/tests/TestFunctionCheb.py +0 -0
  31. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/tests/TestFunctionPeriodic.py +0 -0
  32. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/tests/cheb_fista.py +0 -0
  33. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/tests/cheb_lsqr.py +0 -0
  34. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/tests/per_fista.py +0 -0
  35. {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/tests/per_lsqr.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyANOVAapprox
3
- Version: 0.2.1
3
+ Version: 0.2.3
4
4
  Summary: Approximation Package for High-Dimensional Functions
5
5
  Project-URL: Homepage, https://github.com/NFFT/pyGroupedTransforms
6
6
  Author-email: Felix Wirth <fwi012001@gmail.com>
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "pyANOVAapprox"
7
- version = "0.2.1"
7
+ version = "0.2.3"
8
8
  authors = [
9
9
  { name="Felix Wirth", email="fwi012001@gmail.com" },
10
10
  ]
@@ -0,0 +1,202 @@
1
+ # pip install pyANOVAapprox
2
+
3
+ # Example for approximating an non periodic function
4
+
5
+ import math
6
+
7
+ import matplotlib.pyplot as plt
8
+ import numpy as np
9
+
10
+ import pyANOVAapprox as ANOVAapprox
11
+
12
+
13
+ def TestFunction(x):
14
+ return x[0] * x[4] + 2 - np.exp(x[3]) + np.sqrt(x[5] + 3 + x[1])
15
+
16
+
17
+ rng = np.random.default_rng(1234)
18
+
19
+ ##################################
20
+ ## Definition of the parameters ##
21
+ ##################################
22
+
23
+ d = 6 # dimension
24
+
25
+ M = 10000 # number of used evaluation points to train the model
26
+ M_test = 100000 # number of used evaluation points to test the accuracity the model
27
+
28
+ max_iter = 50 # maximum number of iterations
29
+
30
+ # there are 3 possibilities with varying degree of freedom to define the number of used frequencies
31
+ ########### Variant 1:
32
+ ds = 2 # superposition dimension
33
+ num = np.sum([math.comb(6, k) for k in np.arange(1, 2 + 1)]) # number of used subsets
34
+ b = M / (
35
+ math.log10(M) * num
36
+ ) # number for the number of frequencies if we use logarithmic oversampling and distribute it evenly to all subsets
37
+ bw = [
38
+ math.floor(b / 2) * 2,
39
+ math.floor(math.sqrt(b) / 2) * 2,
40
+ ] # bandwidths (use even numbers)
41
+ # Use all subsets up to ds and use bw[1] many frequences in the the subsets with one element, b[2]^2 many for subsets with two elements and so on
42
+ #
43
+ ########### Variant 2:
44
+ # used subsets:
45
+ # U = [(), (0,), (1,), (2,), (3,), (4,), (5,),
46
+ # (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
47
+ # Bandwidths for these subsets:
48
+ # N = [0 , 100, 100, 100, 100, 100, 100,
49
+ # 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
50
+ # Use the subsets U with the bandwiths N. The bandwith N[i] corresponds to the subset U[i]. For subsets with more then one direction is the same bandwidth in all directions used
51
+ #
52
+ ########### Variant 3:
53
+ # used subsets:
54
+ # U = [(), (0,), (1,), (2,), (3,), (4,), (5,),
55
+ # (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
56
+ # Bandwidths for these subsets:
57
+ # N = [(), (100,), (100,), (100,), (100,), (100,), (100,),
58
+ # (10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,)]
59
+ # Use the subsets U with the bandwiths N. The bandwith N[i] corresponds to the subset U[i]. The bandwidth N[i][j] corresponds to the direction U[i][j]
60
+
61
+ lambdas = np.array([0.0, 1.0]) # used regularisation parameters λ
62
+
63
+ ############################
64
+ ## Generation of the data ##
65
+ ############################
66
+
67
+ X = 2 * rng.random((M, d)) - 1 # construct the evaluation points for training
68
+ X = np.sin(np.pi * (X - 0.5))
69
+ y = np.array(
70
+ [TestFunction(X[i, :].T) for i in range(M)]
71
+ ) # evaluate the function at these points
72
+ X_test = 2 * rng.random((M_test, d)) - 1 #
73
+ X_test = np.sin(np.pi * (X_test - 0.5))
74
+ y_test = np.array(
75
+ [TestFunction(X_test[i, :].T) for i in range(M_test)]
76
+ ) # the same for the test points
77
+
78
+ ##########################
79
+ ## Do the approximation ##
80
+ ##########################
81
+
82
+ ads = ANOVAapprox.approx(X, y, ds=ds, basis="cheb", N=bw)
83
+ ads.approximate(lam=lambdas, max_iter=max_iter, solver="lsqr")
84
+
85
+ ################################
86
+ ## get approximation accuracy ##
87
+ ################################
88
+
89
+ # mse = ANOVAapprox.get_mse(ads) # get mse error at the given training points
90
+ mse = ANOVAapprox.get_mse(ads, X_test, y_test) # get mse error at the test points
91
+ λ_min = min(
92
+ mse, key=mse.get
93
+ ) # get the regularisation parameter which leads to the minimal error
94
+ mse_min = mse[λ_min]
95
+
96
+ print("mse = " + str(mse_min))
97
+
98
+ ###############################################
99
+ ## Analyze the model to improve the accuracy ##
100
+ ###############################################
101
+
102
+
103
+ ar = ANOVAapprox.get_AttributeRanking(ads, λ_min) # get the attrbute ranking
104
+
105
+ plt.figure()
106
+ (markers, stemlines, baseline) = plt.stem(
107
+ np.arange(1, d + 1), # x-Werte (1:d)
108
+ ar, # y-Werte (ar)
109
+ linefmt="C0-", # Stil der Stiele
110
+ markerfmt="C0^", # Stil der Markierung (C0 = erste Farbe, ^ = up-triangle)
111
+ basefmt="k:", # Stil der Basislinie (optional)
112
+ )
113
+ plt.setp(markers, markersize=8)
114
+ plt.yscale("log")
115
+ y_min_calc = 10 ** (np.min(np.log10(ar)) - 0.5)
116
+ plt.ylim(y_min_calc, 1)
117
+ plt.title("Attribute Ranking")
118
+ plt.xlabel("Attribut-Index")
119
+ plt.xlim(0.5, d + 0.5)
120
+ plt.grid(True, which="both", ls="--", linewidth=0.5)
121
+ plt.show() # plot the arrtibute ranking in an logplot
122
+ print("active dimensions: " + str(ar[ar > 1e-2]))
123
+
124
+ gsis = ANOVAapprox.get_GSI(ads, λ_min)
125
+ label = list(ads.U[1:])
126
+ l = len(label)
127
+ plt.figure()
128
+ x_values = np.arange(1, l + 1)
129
+ (markers, stemlines, baseline) = plt.stem(
130
+ x_values, # X-Werte: 1 bis l
131
+ gsis, # Y-Werte: gsis
132
+ linefmt="C0-", # Stil der Stiele
133
+ markerfmt="C0^", # Stil der Markierung (^ = up-triangle)
134
+ basefmt="k:", # Stil der Basislinie
135
+ )
136
+ plt.setp(markers, markersize=8)
137
+ plt.xticks(x_values, label, rotation=45, ha="right")
138
+ plt.xlabel("Input Dimension")
139
+ plt.yscale("log")
140
+ plt.ylim(y_min_calc, 1)
141
+ plt.title("Global sensitivity indices")
142
+ plt.grid(True, which="both", ls="--", linewidth=0.5)
143
+ plt.tight_layout() # Stellt sicher, dass die Labels sichtbar sind
144
+ plt.show()
145
+ print(
146
+ "important dimensional interactions: : "
147
+ + str([label[i] for i in np.arange(0, l)[gsis > 1e-2]])
148
+ )
149
+
150
+ ################################################
151
+ ## Approximation with better suited index set ##
152
+ ################################################
153
+
154
+ Umask = np.append(np.array([True]), gsis > 1e-2)
155
+ U = [ads.U[i] for i in np.arange(0, len(Umask))[Umask]] # get important subsets
156
+ bws = M / (math.log10(M) * (len(U) - 1)) # calculate frequencies per subset
157
+ N = [
158
+ math.floor(bws ** (1 / max(1, len(u))) / 2) * 2 for u in U
159
+ ] # distribute the frequencies evenly and make them even
160
+ N[0] = 0
161
+
162
+ a = ANOVAapprox.approx(
163
+ X, y, U, N, "cheb"
164
+ ) # generate the data structure for the approximation
165
+ a.approximate(
166
+ lam=lambdas, max_iter=max_iter, solver="lsqr"
167
+ ) # do the approximation for all specified regularisation parameters
168
+
169
+ mse = ANOVAapprox.get_mse(a, X_test, y_test) # get mse error at the test points
170
+ λ_min = min(
171
+ mse, key=mse.get
172
+ ) # get the regularisation parameter which leads to the minimal error
173
+ mse_min = mse[λ_min]
174
+ print("mse = " + str(mse_min))
175
+
176
+ ########################
177
+ ## Evaluate the model ##
178
+ ########################
179
+
180
+ # y_approx = a.evaluate(lam=λ_min) # evaluate the approximation at the training points for the regularisation λ_min
181
+ # y_approx = a.evaluate(X=X_test, lam=λ_min) # evaluate the approximation at the points X_test for the regularisation λ_min
182
+
183
+ # In the following we plot the real and the approximated anova term for the subset u=[3]
184
+
185
+ y_eval_anova = a.evaluateANOVAterms(
186
+ X=X_test, lam=λ_min
187
+ ) # evaluate all of the ANOVA terms
188
+ pos = a.U.index((3,)) # find the index for the subset u=[3]
189
+ y_eval_anova_3 = y_eval_anova.T[pos]
190
+
191
+ perm = np.argsort(X_test.T[3])
192
+ X_plot = X_test.T[3][perm]
193
+ y_eval_anova_3_plot = np.real(y_eval_anova_3[perm])
194
+ y_anova_3_plot = -np.exp(X_plot) + 1.2660446775548282
195
+
196
+ plt.figure()
197
+ plt.plot(X_plot, y_eval_anova_3_plot, label="approximation")
198
+ plt.plot(X_plot, y_anova_3_plot, label="ANOVA term") # ... "ANOVA term"]
199
+ plt.title("Approximation of the ANOVA term 4") # title = "..."
200
+ plt.legend() # Zeigt die Labels/Legende an
201
+ plt.grid(True, linestyle="--", alpha=0.7)
202
+ plt.show()
@@ -0,0 +1,190 @@
1
+ # pip install pyANOVAapprox
2
+
3
+ # Example for classification into two sets
4
+
5
+ import math
6
+
7
+ import matplotlib.pyplot as plt
8
+ import numpy as np
9
+
10
+ import pyANOVAapprox as ANOVAapprox
11
+
12
+
13
+ def TestFunction(x):
14
+ e = (
15
+ abs(x[1] + 1.0j * x[2]) + (np.angle(x[1] + 1.0j * x[2]) / (math.pi * 8))
16
+ ) % 0.25 > 0.125
17
+ return e * 2 - 1
18
+
19
+
20
+ rng = np.random.default_rng(1234)
21
+
22
+ ##################################
23
+ ## Definition of the parameters ##
24
+ ##################################
25
+
26
+ d = 3 # dimension
27
+
28
+ M = 10000 # number of used evaluation points to train the model
29
+ M_test = 10000 # number of used evaluation points to test the accuracity the model
30
+
31
+ max_iter = 50 # maximum number of iterations
32
+
33
+ # there are 3 possibilities with varying degree of freedom to define the number of used frequencies
34
+ ########### Variant 1:
35
+ ds = 2 # superposition dimension
36
+ num = np.sum([math.comb(6, k) for k in np.arange(1, 2 + 1)]) # number of used subsets
37
+ b = M / (
38
+ math.log10(M) * num
39
+ ) # number for the number of frequencies if we use logarithmic oversampling and distribute it evenly to all subsets
40
+ bw = [
41
+ math.floor(b / 2) * 2,
42
+ math.floor(math.sqrt(b) / 2) * 2,
43
+ ] # bandwidths (use even numbers)
44
+ # Use all subsets up to ds and use bw[1] many frequences in the the subsets with one element, b[2]^2 many for subsets with two elements and so on
45
+ #
46
+ ########### Variant 2:
47
+ # used subsets:
48
+ # U = [(), (0,), (1,), (2,), (3,), (4,), (5,),
49
+ # (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
50
+ # Bandwidths for these subsets:
51
+ # N = [0 , 100, 100, 100, 100, 100, 100,
52
+ # 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
53
+ # Use the subsets U with the bandwiths N. The bandwith N[i] corresponds to the subset U[i]. For subsets with more then one direction is the same bandwidth in all directions used
54
+ #
55
+ ########### Variant 3:
56
+ # used subsets:
57
+ # U = [(), (0,), (1,), (2,), (3,), (4,), (5,),
58
+ # (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
59
+ # Bandwidths for these subsets:
60
+ # N = [(), (100,), (100,), (100,), (100,), (100,), (100,),
61
+ # (10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,)]
62
+ # Use the subsets U with the bandwiths N. The bandwith N[i] corresponds to the subset U[i]. The bandwidth N[i][j] corresponds to the direction U[i][j]
63
+
64
+ lambdas = np.array([0.0]) # used regularisation parameters λ
65
+
66
+ ############################
67
+ ## Generation of the data ##
68
+ ############################
69
+
70
+ X = rng.random((M, d)) - 0.5 # construct the evaluation points for training
71
+ y = np.array(
72
+ [TestFunction(X[i, :].T) for i in range(M)], dtype=float
73
+ ) # evaluate the function at these points
74
+ X = X + 0.5
75
+ X_test = rng.random((M_test, d)) - 0.5 #
76
+ y_test = np.array(
77
+ [TestFunction(X_test[i, :].T) for i in range(M_test)], dtype=float
78
+ ) # the same for the test points
79
+ X_test = X_test + 0.5
80
+
81
+ ###########################
82
+ ## Do the classification ##
83
+ ###########################
84
+
85
+ ads = ANOVAapprox.approx(X, y, ds=ds, basis="cos", N=bw, classification=True)
86
+ ads.approximate(max_iter=max_iter, lam=lambdas)
87
+
88
+ #################################
89
+ ## get classification accuracy ##
90
+ #################################
91
+
92
+ y_approx = ads.evaluate(X=X_test, lam=0.0) # evaluate the classification
93
+ acc = sum(np.sign(y_approx) == y_test) / M_test # calculate the accuracity
94
+ print("accuracity = " + str(acc))
95
+
96
+ ###############################################
97
+ ## Analyze the model to improve the accuracy ##
98
+ ###############################################
99
+
100
+ ar = ANOVAapprox.get_AttributeRanking(ads, 0.0) # get the attrbute ranking
101
+
102
+ plt.figure()
103
+ (markers, stemlines, baseline) = plt.stem(
104
+ np.arange(1, d + 1), # x-Werte (1:d)
105
+ ar, # y-Werte (ar)
106
+ linefmt="C0-", # Stil der Stiele
107
+ markerfmt="C0^", # Stil der Markierung (C0 = erste Farbe, ^ = up-triangle)
108
+ basefmt="k:", # Stil der Basislinie (optional)
109
+ )
110
+ plt.setp(markers, markersize=8)
111
+ plt.yscale("log")
112
+ y_min_calc = 10 ** (np.min(np.log10(ar)) - 0.5)
113
+ plt.ylim(y_min_calc, 1)
114
+ plt.title("Attribute Ranking")
115
+ plt.xlabel("Attribut-Index")
116
+ plt.xlim(0.5, d + 0.5)
117
+ plt.grid(True, which="both", ls="--", linewidth=0.5)
118
+ plt.show() # plot the arrtibute ranking in an logplot
119
+ print("active dimensions: " + str(ar[ar > 1e-2]))
120
+
121
+ gsis = ANOVAapprox.get_GSI(ads, 0.0)
122
+ label = list(ads.U[1:])
123
+ l = len(label)
124
+ plt.figure()
125
+ x_values = np.arange(1, l + 1)
126
+ (markers, stemlines, baseline) = plt.stem(
127
+ x_values, # X-Werte: 1 bis l
128
+ gsis, # Y-Werte: gsis
129
+ linefmt="C0-", # Stil der Stiele
130
+ markerfmt="C0^", # Stil der Markierung (^ = up-triangle)
131
+ basefmt="k:", # Stil der Basislinie
132
+ )
133
+ plt.setp(markers, markersize=8)
134
+ plt.xticks(x_values, label, rotation=45, ha="right")
135
+ plt.xlabel("Input Dimension")
136
+ plt.yscale("log")
137
+ plt.ylim(y_min_calc, 1)
138
+ plt.title("Global sensitivity indices")
139
+ plt.grid(True, which="both", ls="--", linewidth=0.5)
140
+ plt.tight_layout() # Stellt sicher, dass die Labels sichtbar sind
141
+ plt.show()
142
+ print(
143
+ "important dimensional interactions: : "
144
+ + str([label[i] for i in np.arange(0, l)[gsis > 1e-2]])
145
+ )
146
+
147
+ #################################################
148
+ ## Classification with better suited index set ##
149
+ #################################################
150
+
151
+ Umask = np.append(np.array([True]), gsis > 1e-2)
152
+ U = [ads.U[i] for i in np.arange(0, len(Umask))[Umask]] # get important subsets
153
+ bws = M / (math.log10(M) * (len(U) - 1)) # calculate frequencies per subset
154
+ N = [
155
+ math.floor(bws ** (1 / max(1, len(u))) / 2) * 2 for u in U
156
+ ] # distribute the frequencies evenly and make them even
157
+ N[0] = 0
158
+
159
+ a = ANOVAapprox.approx(
160
+ X, y, U, N, "cos", classification=True
161
+ ) # generate the data structure for the classification
162
+ a.approximate(
163
+ lam=lambdas, max_iter=max_iter
164
+ ) # do the approximation for all specified regularisation parameters
165
+
166
+ y_approx = a.evaluate(X=X_test, lam=0.0) # evaluate the classification
167
+ acc = sum(np.sign(y_approx) == y_test) / M_test # calculate the accuracity
168
+ print("accuracity = " + str(acc))
169
+
170
+ ########################
171
+ ## Evaluate the model ##
172
+ ########################
173
+
174
+ # y_approx = a.evaluate(X=X_test) # evaluate the classification at the training points for the regularisation λ_min
175
+ y_approx = a.evaluate(
176
+ X=X_test, lam=0.0
177
+ ) # evaluate the classification at the points X_test for the regularisation λ_min
178
+
179
+ plt.figure()
180
+ scatter = plt.scatter(
181
+ X_test[:, 1],
182
+ X_test[:, 2],
183
+ c=np.sign(y_approx),
184
+ cmap="winter",
185
+ s=100,
186
+ alpha=0.8,
187
+ edgecolors="black",
188
+ linewidths=0.5,
189
+ )
190
+ plt.show()
@@ -0,0 +1,200 @@
1
+ # pip install pyANOVAapprox
2
+
3
+ # Example for approximating an non periodic function
4
+
5
+ import math
6
+
7
+ import matplotlib.pyplot as plt
8
+ import numpy as np
9
+
10
+ import pyANOVAapprox as ANOVAapprox
11
+
12
+
13
+ def TestFunction(x):
14
+ return x[0] * x[4] + 2 - np.exp(x[3]) + np.sqrt(x[5] + 3 + x[1])
15
+
16
+
17
+ rng = np.random.default_rng(1234)
18
+
19
+ ##################################
20
+ ## Definition of the parameters ##
21
+ ##################################
22
+
23
+ d = 6 # dimension
24
+
25
+ M = 10000 # number of used evaluation points to train the model
26
+ M_test = 100000 # number of used evaluation points to test the accuracity the model
27
+
28
+ max_iter = 50 # maximum number of iterations
29
+
30
+ # there are 3 possibilities with varying degree of freedom to define the number of used frequencies
31
+ ########### Variant 1:
32
+ ds = 2 # superposition dimension
33
+ num = np.sum([math.comb(6, k) for k in np.arange(1, 2 + 1)]) # number of used subsets
34
+ b = M / (
35
+ math.log10(M) * num
36
+ ) # number for the number of frequencies if we use logarithmic oversampling and distribute it evenly to all subsets
37
+ bw = [
38
+ math.floor(b / 2) * 2,
39
+ math.floor(math.sqrt(b) / 2) * 2,
40
+ ] # bandwidths (use even numbers)
41
+ # Use all subsets up to ds and use bw[1] many frequences in the the subsets with one element, b[2]^2 many for subsets with two elements and so on
42
+ #
43
+ ########### Variant 2:
44
+ # used subsets:
45
+ # U = [(), (0,), (1,), (2,), (3,), (4,), (5,),
46
+ # (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
47
+ # Bandwidths for these subsets:
48
+ # N = [0 , 100, 100, 100, 100, 100, 100,
49
+ # 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
50
+ # Use the subsets U with the bandwiths N. The bandwith N[i] corresponds to the subset U[i]. For subsets with more then one direction is the same bandwidth in all directions used
51
+ #
52
+ ########### Variant 3:
53
+ # used subsets:
54
+ # U = [(), (0,), (1,), (2,), (3,), (4,), (5,),
55
+ # (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
56
+ # Bandwidths for these subsets:
57
+ # N = [(), (100,), (100,), (100,), (100,), (100,), (100,),
58
+ # (10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,)]
59
+ # Use the subsets U with the bandwiths N. The bandwith N[i] corresponds to the subset U[i]. The bandwidth N[i][j] corresponds to the direction U[i][j]
60
+
61
+ lambdas = np.array([0.0, 1.0]) # used regularisation parameters λ
62
+
63
+ ############################
64
+ ## Generation of the data ##
65
+ ############################
66
+
67
+ X = rng.random((M, d)) # construct the evaluation points for training
68
+ y = np.array(
69
+ [TestFunction(X[i, :].T) for i in range(M)]
70
+ ) # evaluate the function at these points
71
+ X_test = rng.random((M_test, d)) #
72
+ y_test = np.array(
73
+ [TestFunction(X_test[i, :].T) for i in range(M_test)]
74
+ ) # the same for the test points
75
+
76
+ ##########################
77
+ ## Do the approximation ##
78
+ ##########################
79
+
80
+ ads = ANOVAapprox.approx(X, y, ds=ds, basis="cos", N=bw)
81
+ ads.approximate(lam=lambdas, max_iter=max_iter, solver="lsqr")
82
+
83
+ ################################
84
+ ## get approximation accuracy ##
85
+ ################################
86
+
87
+ # mse = ANOVAapprox.get_mse(ads) # get mse error at the given training points
88
+ mse = ANOVAapprox.get_mse(ads, X_test, y_test) # get mse error at the test points
89
+ λ_min = min(
90
+ mse, key=mse.get
91
+ ) # get the regularisation parameter which leads to the minimal error
92
+ mse_min = mse[λ_min]
93
+
94
+ print("mse = " + str(mse_min))
95
+
96
+ ###############################################
97
+ ## Analyze the model to improve the accuracy ##
98
+ ###############################################
99
+
100
+
101
+ ar = ANOVAapprox.get_AttributeRanking(ads, λ_min) # get the attrbute ranking
102
+
103
+ plt.figure()
104
+ (markers, stemlines, baseline) = plt.stem(
105
+ np.arange(1, d + 1), # x-Werte (1:d)
106
+ ar, # y-Werte (ar)
107
+ linefmt="C0-", # Stil der Stiele
108
+ markerfmt="C0^", # Stil der Markierung (C0 = erste Farbe, ^ = up-triangle)
109
+ basefmt="k:", # Stil der Basislinie (optional)
110
+ )
111
+ plt.setp(markers, markersize=8)
112
+ plt.yscale("log")
113
+ y_min_calc = 10 ** (np.min(np.log10(ar)) - 0.5)
114
+ plt.ylim(y_min_calc, 1)
115
+ plt.title("Attribute Ranking")
116
+ plt.xlabel("Attribut-Index")
117
+ plt.xlim(0.5, d + 0.5)
118
+ plt.grid(True, which="both", ls="--", linewidth=0.5)
119
+ plt.show() # plot the arrtibute ranking in an logplot
120
+ print("active dimensions: " + str(ar[ar > 1e-2]))
121
+
122
+ gsis = ANOVAapprox.get_GSI(ads, λ_min)
123
+ label = list(ads.U[1:])
124
+ l = len(label)
125
+ plt.figure()
126
+ x_values = np.arange(1, l + 1)
127
+ (markers, stemlines, baseline) = plt.stem(
128
+ x_values, # X-Werte: 1 bis l
129
+ gsis, # Y-Werte: gsis
130
+ linefmt="C0-", # Stil der Stiele
131
+ markerfmt="C0^", # Stil der Markierung (^ = up-triangle)
132
+ basefmt="k:", # Stil der Basislinie
133
+ )
134
+ plt.setp(markers, markersize=8)
135
+ plt.xticks(x_values, label, rotation=45, ha="right")
136
+ plt.xlabel("Input Dimension")
137
+ plt.yscale("log")
138
+ plt.ylim(y_min_calc, 1)
139
+ plt.title("Global sensitivity indices")
140
+ plt.grid(True, which="both", ls="--", linewidth=0.5)
141
+ plt.tight_layout() # Stellt sicher, dass die Labels sichtbar sind
142
+ plt.show()
143
+ print(
144
+ "important dimensional interactions: : "
145
+ + str([label[i] for i in np.arange(0, l)[gsis > 1e-2]])
146
+ )
147
+
148
+ ################################################
149
+ ## Approximation with better suited index set ##
150
+ ################################################
151
+
152
+ Umask = np.append(np.array([True]), gsis > 1e-2)
153
+ U = [ads.U[i] for i in np.arange(0, len(Umask))[Umask]] # get important subsets
154
+ bws = M / (math.log10(M) * (len(U) - 1)) # calculate frequencies per subset
155
+ N = [
156
+ math.floor(bws ** (1 / max(1, len(u))) / 2) * 2 for u in U
157
+ ] # distribute the frequencies evenly and make them even
158
+ N[0] = 0
159
+
160
+ a = ANOVAapprox.approx(
161
+ X, y, U, N, "cos"
162
+ ) # generate the data structure for the approximation
163
+ a.approximate(
164
+ lam=lambdas, max_iter=max_iter, solver="lsqr"
165
+ ) # do the approximation for all specified regularisation parameters
166
+
167
+ mse = ANOVAapprox.get_mse(a, X_test, y_test) # get mse error at the test points
168
+ λ_min = min(
169
+ mse, key=mse.get
170
+ ) # get the regularisation parameter which leads to the minimal error
171
+ mse_min = mse[λ_min]
172
+ print("mse = " + str(mse_min))
173
+
174
+ ########################
175
+ ## Evaluate the model ##
176
+ ########################
177
+
178
+ # y_approx = a.evaluate(lam=λ_min) # evaluate the approximation at the training points for the regularisation λ_min
179
+ # y_approx = a.evaluate(X=X_test, lam=λ_min) # evaluate the approximation at the points X_test for the regularisation λ_min
180
+
181
+ # In the following we plot the real and the approximated anova term for the subset u=[3]
182
+
183
+ y_eval_anova = a.evaluateANOVAterms(
184
+ X=X_test, lam=λ_min
185
+ ) # evaluate all of the ANOVA terms
186
+ pos = a.U.index((3,)) # find the index for the subset u=[3]
187
+ y_eval_anova_3 = y_eval_anova.T[pos]
188
+
189
+ perm = np.argsort(X_test.T[3])
190
+ X_plot = X_test.T[3][perm]
191
+ y_eval_anova_3_plot = np.real(y_eval_anova_3[perm])
192
+ y_anova_3_plot = -np.exp(X_plot) + np.exp(1) - 1
193
+
194
+ plt.figure()
195
+ plt.plot(X_plot, y_eval_anova_3_plot, label="approximation")
196
+ plt.plot(X_plot, y_anova_3_plot, label="ANOVA term") # ... "ANOVA term"]
197
+ plt.title("Approximation of the ANOVA term 4") # title = "..."
198
+ plt.legend() # Zeigt die Labels/Legende an
199
+ plt.grid(True, linestyle="--", alpha=0.7)
200
+ plt.show()
@@ -68,6 +68,7 @@ lambdas = np.array([0.0, 1.0]) # used regularisation parameters λ
68
68
  ############################
69
69
  ## Generation of the data ##
70
70
  ############################
71
+
71
72
  X = rng.random((M, d)) - 0.5 # construct the evaluation points for training
72
73
  y = np.array(
73
74
  [TestFunction(X[i, :].T) for i in range(M)], dtype=complex
@@ -82,7 +83,7 @@ y_test = np.array(
82
83
  ##########################
83
84
 
84
85
  ads = ANOVAapprox.approx(X, y, ds=ds, basis="per", N=bw)
85
- ads.approximate(lam=lambdas, solver="lsqr")
86
+ ads.approximate(lam=lambdas, max_iter=max_iter, solver="lsqr")
86
87
 
87
88
  ################################
88
89
  ## get approximation accuracy ##
@@ -165,7 +166,7 @@ a = ANOVAapprox.approx(
165
166
  X, y, U, N, "per"
166
167
  ) # generate the data structure for the approximation
167
168
  a.approximate(
168
- lam=lambdas, solver="lsqr"
169
+ lam=lambdas, max_iter=max_iter, solver="lsqr"
169
170
  ) # do the approximation for all specified regularisation parameters
170
171
 
171
172
  mse = ANOVAapprox.get_mse(a, X_test, y_test) # get mse error at the test points
@@ -0,0 +1,134 @@
1
+ # pip install pyANOVAapprox
2
+
3
+ # Example for approximating an non periodic function
4
+
5
+ import math
6
+
7
+ import matplotlib.pyplot as plt
8
+ import numpy as np
9
+
10
+ import pyANOVAapprox as ANOVAapprox
11
+
12
+ basis = "chui3"
13
+ # for 'cos' the samples have to be in [0,1]^d
14
+ # for a periodic function use 'per' or wavelets 'chui2', 'chui3', 'chui4' (samples have to be in [-0.5,0.5]^d here, 'chuim' are the Chui-Wang wavelets of order m)
15
+
16
+
17
+ def TestFunction(x): # this function is of the form f_0 + f_1 + f_2 + f_3 + f_4 + f_2,3
18
+ return 2 * abs(x[0]) + abs(math.sin(math.pi * x[1] * x[2])) + np.cos(3 + x[3])
19
+
20
+
21
+ rng = np.random.default_rng(1234)
22
+
23
+ ##################################
24
+ ## Definition of the parameters ##
25
+ ##################################
26
+
27
+ d = 8 # dimension
28
+ q = 2 # superposition dimension
29
+ M = 10000 # number of used evaluation points to train the model
30
+ M_test = 10000 # number of used evaluation points to test the accuracity the model
31
+ N = [5, 2] # number of parameters, should be vector of length q:
32
+ # for wavelets the total number of parameters scales exponentially, i.e.:
33
+ # for q = 1 and N = [N1] the total number of parameters scales like ~O(d*2^N1)
34
+ # for q = 2 and N = [N1 , N2] the total number of parameters scales like ~O(d*2^N1) + O(d^2 * N2*2^N2)
35
+
36
+ lambdas = np.array([0.0]) # used regularisation parameters λ
37
+
38
+ ############################
39
+ ## Generation of the data ##
40
+ ############################
41
+
42
+ if basis == "chui2" or basis == "chui3" or basis == "chui4" or basis == "per":
43
+ X = (
44
+ rng.random((M, d)) - 0.5
45
+ ) # for perioidic approximation samples have to be in [-0.5,0.5]^d
46
+ elif basis == "cos":
47
+ X = rng.random((M, d))
48
+ y = np.array(
49
+ [TestFunction(X[i, :].T) for i in range(M)]
50
+ ) # evaluate the function at these points
51
+
52
+ if (
53
+ basis == "chui1"
54
+ or basis == "chui2"
55
+ or basis == "chui3"
56
+ or basis == "chui4"
57
+ or basis == "per"
58
+ ):
59
+ X_test = (
60
+ rng.random((M_test, d)) - 0.5
61
+ ) # for perioidic approximation samples have to be in [-0.5,0.5]^d
62
+ elif basis == "cos":
63
+ X_test = rng.random((M_test, d))
64
+ y_test = np.array(
65
+ [TestFunction(X_test[i, :].T) for i in range(M_test)]
66
+ ) # the same for the test points
67
+
68
+ ##########################
69
+ ## Do the approximation ##
70
+ ##########################
71
+
72
+ #### construct model for ANOVAapprox ####
73
+ anova_model = ANOVAapprox.approx(X, y, ds=q, basis=basis, N=N)
74
+
75
+ #### Do approximation by least-squares ###
76
+ anova_model.approximate(lam=lambdas, solver="lsqr")
77
+ print("Total number of used parameters = " + str(len(anova_model.fc[lambdas[0]].vec())))
78
+
79
+ #######################
80
+ ## Analyze the model ##
81
+ #######################
82
+
83
+ ### Do sensitivity analysis ####
84
+ gsis = ANOVAapprox.get_GSI(
85
+ anova_model, 0.0
86
+ ) # calculates indices for importance of terms (gsis is vector, with indices belonging to terms in anova_model.U)
87
+ gsis_as_dict = ANOVAapprox.get_GSI(anova_model,0.0,dict=true)
88
+
89
+ y_min_calc = 10 ** (np.min(np.log10(gsis)) - 0.5)
90
+ label = list(anova_model.U[1:])
91
+ l = len(label)
92
+ plt.figure()
93
+ x_values = np.arange(1, l + 1)
94
+ (markers, stemlines, baseline) = plt.stem(
95
+ x_values, # X-Werte: 1 bis l
96
+ gsis, # Y-Werte: gsis
97
+ linefmt="C0-", # Stil der Stiele
98
+ markerfmt="C0^", # Stil der Markierung (^ = up-triangle)
99
+ basefmt="k:", # Stil der Basislinie
100
+ )
101
+ plt.setp(markers, markersize=8)
102
+ plt.xticks(x_values, label, rotation=45, ha="right")
103
+ plt.xlabel("Input Dimension")
104
+ plt.yscale("log")
105
+ plt.ylim(y_min_calc, 1)
106
+ plt.title("Global sensitivity indices")
107
+ plt.grid(True, which="both", ls="--", linewidth=0.5)
108
+ plt.tight_layout() # Stellt sicher, dass die Labels sichtbar sind
109
+ plt.show()
110
+
111
+ ################################
112
+ ## get approximation accuracy ##
113
+ ################################
114
+
115
+ ### error analysis ###
116
+ mse_train = ANOVAapprox.get_mse(anova_model, lam=0.0)
117
+ mse_test = ANOVAapprox.get_mse(anova_model, X_test, y_test, lam=0.0)
118
+
119
+ print("MSE on test points: " + str(mse_test))
120
+
121
+ ################################################
122
+ ## Approximation with better suited index set ##
123
+ ################################################
124
+
125
+ U = ANOVAapprox.get_ActiveSet(anova_model, [0.01, 0.01], lam=0.0)
126
+ print("Found index-set U: " + str(U))
127
+ anova_model = ANOVAapprox.approx(
128
+ X, y, U=U, N=[i + 2 for i in N], basis=basis
129
+ ) # increase number of paramers in N for the important terms
130
+ anova_model.approximate(lam=lambdas)
131
+ print("Total number of used parameters = " + str(len(anova_model.fc[lambdas[0]].vec())))
132
+ mse_train = ANOVAapprox.get_mse(anova_model, lam=0.0)
133
+ mse_test = ANOVAapprox.get_mse(anova_model, X_test, y_test, lam=0.0)
134
+ print("MSE on test points after ANOVA truncation: " + str(mse_test))
@@ -9,27 +9,6 @@ from scipy.special import erf
9
9
 
10
10
  # from sklearn.metrics import roc_auc_score
11
11
 
12
-
13
- def get_superposition_set(d, ds): # TODO: Später funktion aut GT verwenden
14
- """
15
- get_superposition_set( d::Int, ds::Int )::Vector{Vector{Int}}
16
-
17
- This function returns ``U^{(d,ds)} = \{ \pmb u \subset \{1,2,\dots,d\} : |\pmb u| \leq ds \}``.
18
- """
19
- nset = [[j] for j in range(d)]
20
- returnset = [[]] + nset
21
- for i in range(ds - 1):
22
- nextnset = []
23
- for s in nset:
24
- for j in range(d):
25
- if s[-1] < j:
26
- nextnset.append(s + [j])
27
- returnset = returnset + nextnset
28
- nset = nextnset
29
-
30
- return [tuple(item) for item in returnset]
31
-
32
-
33
12
  def bisection(l, r, fun, maxiter=1000):
34
13
  lval = fun(l)
35
14
  rval = fun(r)
@@ -47,7 +47,7 @@ def _GSI(a, lam, Dict): # helpfunction for get_GSI
47
47
 
48
48
  if Dict:
49
49
  if a.basis.startswith("chui"):
50
- variances = np.square(a.fc[lam].norms(Dict=True, m=int(a.basis[-1])))
50
+ variances = a.fc[lam].norms(Dict=True, m=int(a.basis[-1]))
51
51
  else:
52
52
  variances = a.fc[lam].norms(Dict=True)
53
53
  return {u: (variances[u] ** 2) / variance_f for u in list(variances)}
@@ -129,7 +129,7 @@ def lam_ActiveSet(a, eps, lam): # helpfunction for get_ActiveSet
129
129
  n += 1
130
130
 
131
131
  U_active = [None] * (n + 1)
132
- U_active[0] = []
132
+ U_active[0] = ()
133
133
 
134
134
  idx = 1
135
135
  for i in range(len(gsi)):
@@ -1,5 +1,3 @@
1
- from pyGroupedTransforms.GroupedTransform import * # TODO: Kann wahrscheinlich weg sobald in pyGroupedTransform GreoupedTransform exportiert wird
2
-
3
1
  from pyANOVAapprox import *
4
2
  from pyANOVAapprox.fista import *
5
3
 
@@ -83,6 +81,7 @@ class approx:
83
81
  classification=False,
84
82
  basis_vect=[],
85
83
  fastmult=None,
84
+ parallel=True,
86
85
  ds=None,
87
86
  ):
88
87
 
@@ -185,6 +184,7 @@ class approx:
185
184
  N=N,
186
185
  X=Xt,
187
186
  fastmult=fastmult,
187
+ parallel=parallel,
188
188
  basis_vect=basis_vect,
189
189
  )
190
190
 
@@ -198,6 +198,7 @@ class approx:
198
198
  self.classification = classification
199
199
  self.basis_vect = basis_vect
200
200
  self.fastmult = fastmult
201
+ self.parallel = parallel
201
202
 
202
203
  def Approximate(
203
204
  self, lam, max_iter=50, weights=None, verbose=False, solver=None, tol=1e-8
@@ -1,5 +1,3 @@
1
- from pyGroupedTransforms.GroupedCoefficients import * # TODO: Kann wahrscheinlich weg sobald in pyGroupedTransform GreoupedTransform exportiert wird
2
-
3
1
  from pyANOVAapprox import *
4
2
 
5
3
 
@@ -12,7 +12,7 @@ import sys
12
12
  # Script to run all tests and return any failures
13
13
  def run_tests():
14
14
  test_files = [
15
- # "tests/wav_lsqr.py",
15
+ "tests/wav_lsqr.py",
16
16
  "tests/cheb_fista.py",
17
17
  "tests/cheb_lsqr.py",
18
18
  "tests/per_fista.py",
@@ -0,0 +1,50 @@
1
+ import os
2
+ import sys
3
+
4
+ src_aa = os.path.abspath(os.path.join(os.getcwd(), "src"))
5
+ sys.path.insert(0, src_aa)
6
+
7
+ import numpy as np
8
+ from pyGroupedTransforms import *
9
+ from TestFunctionPeriodic import *
10
+
11
+ import pyANOVAapprox as ANOVAapprox
12
+
13
+ d = 6
14
+ ds = 2
15
+ M = 10000
16
+ max_iter = 50
17
+ bw = [4, 4]
18
+ lambdas = np.array([0.0, 1.0])
19
+
20
+ rng = np.random.default_rng()
21
+ X = rng.random((M, d)) - 0.5
22
+ y = np.array([f(X[i, :].T) for i in range(M)])
23
+ X_test = rng.random((M, d)) - 0.5
24
+ y_test = np.array([f(X_test[i, :].T) for i in range(M)])
25
+
26
+ ads = ANOVAapprox.approx(X, y, ds=ds, N=bw, basis="chui2")
27
+ ads.approximate(lam=lambdas, solver="lsqr")
28
+
29
+ print("AR: " + str(sum(ANOVAapprox.get_AttributeRanking(ads, 0.0))))
30
+ assert abs(sum(ANOVAapprox.get_AttributeRanking(ads, 0.0)) - 1) < 0.0001
31
+
32
+ bw = ANOVAapprox.get_orderDependentBW(AS, [4, 4])
33
+ aU = ANOVAapprox.approx(X, y, U=AS, N=bw, basis="chui2")
34
+ aU.approximate(lam=lambdas, solver="lsqr")
35
+
36
+ err_l2_ds = ANOVAapprox.get_l2_error(ads)[0.0]
37
+ err_l2_U = ANOVAapprox.get_l2_error(aU)[0.0]
38
+ err_l2_rand_ds = ANOVAapprox.get_l2_error(ads, X_test, y_test)[0.0]
39
+ err_l2_rand_U = ANOVAapprox.get_l2_error(aU, X_test, y_test)[0.0]
40
+
41
+ print("== WAVELET LSQR ==")
42
+ print("l2 ds: ", err_l2_ds)
43
+ print("l2 U: ", err_l2_U)
44
+ print("l2 rand ds: ", err_l2_rand_ds)
45
+ print("l2 rand U: ", err_l2_rand_U)
46
+
47
+ assert err_l2_ds < 0.01
48
+ assert err_l2_U < 0.01 # maybe restrict to 0.005
49
+ assert err_l2_rand_ds < 0.01
50
+ assert err_l2_rand_U < 0.01
@@ -1 +0,0 @@
1
- # hier bin ich unverhofft auf probleme gestoßen, deswegen erstmal ein dummyfile nur...
File without changes
File without changes
File without changes