UQPyL 2.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.
- UQPyL-2.0.1/LICENSE.md +21 -0
- UQPyL-2.0.1/PKG-INFO +64 -0
- UQPyL-2.0.1/README.md +46 -0
- UQPyL-2.0.1/UQPyL/DoE/__init__.py +8 -0
- UQPyL-2.0.1/UQPyL/DoE/_lhs.py +90 -0
- UQPyL-2.0.1/UQPyL/DoE/fast_sampler.py +77 -0
- UQPyL-2.0.1/UQPyL/DoE/full_fact.py +57 -0
- UQPyL-2.0.1/UQPyL/DoE/lhs.py +73 -0
- UQPyL-2.0.1/UQPyL/DoE/random.py +28 -0
- UQPyL-2.0.1/UQPyL/DoE/sampler_ABC.py +26 -0
- UQPyL-2.0.1/UQPyL/DoE/sobol_sequence.py +47 -0
- UQPyL-2.0.1/UQPyL/__init__.py +13 -0
- UQPyL-2.0.1/UQPyL/optimization/__init__.py +21 -0
- UQPyL-2.0.1/UQPyL/optimization/_binary_ga.py +61 -0
- UQPyL-2.0.1/UQPyL/optimization/_ga.py +120 -0
- UQPyL-2.0.1/UQPyL/optimization/adam.py +81 -0
- UQPyL-2.0.1/UQPyL/optimization/asmo.py +86 -0
- UQPyL-2.0.1/UQPyL/optimization/boxmin.py +95 -0
- UQPyL-2.0.1/UQPyL/optimization/ga.py +122 -0
- UQPyL-2.0.1/UQPyL/optimization/mo_asmo.py +115 -0
- UQPyL-2.0.1/UQPyL/optimization/nsga_ii.py +219 -0
- UQPyL-2.0.1/UQPyL/optimization/sce_ua.py +182 -0
- UQPyL-2.0.1/UQPyL/problems/__init__.py +22 -0
- UQPyL-2.0.1/UQPyL/problems/multi_DTLZ.py +577 -0
- UQPyL-2.0.1/UQPyL/problems/multi_ZDT.py +224 -0
- UQPyL-2.0.1/UQPyL/problems/pratical_problem.py +31 -0
- UQPyL-2.0.1/UQPyL/problems/problem_ABC.py +42 -0
- UQPyL-2.0.1/UQPyL/problems/single_Benchmarks.py +475 -0
- UQPyL-2.0.1/UQPyL/problems/utility_functions/_NDsort.py +34 -0
- UQPyL-2.0.1/UQPyL/problems/utility_functions/__init__.py +0 -0
- UQPyL-2.0.1/UQPyL/problems/utility_functions/_uniformPoint.py +47 -0
- UQPyL-2.0.1/UQPyL/sensibility/__init__.py +15 -0
- UQPyL-2.0.1/UQPyL/sensibility/delta_test.py +78 -0
- UQPyL-2.0.1/UQPyL/sensibility/fast.py +74 -0
- UQPyL-2.0.1/UQPyL/sensibility/mars_sa.py +60 -0
- UQPyL-2.0.1/UQPyL/sensibility/morris.py +88 -0
- UQPyL-2.0.1/UQPyL/sensibility/rbd_fast.py +59 -0
- UQPyL-2.0.1/UQPyL/sensibility/rsa.py +51 -0
- UQPyL-2.0.1/UQPyL/sensibility/sa_ABC.py +133 -0
- UQPyL-2.0.1/UQPyL/sensibility/sobol.py +141 -0
- UQPyL-2.0.1/UQPyL/surrogates/BaggingEnsemble.py +1 -0
- UQPyL-2.0.1/UQPyL/surrogates/BootstrapEnsemble.py +1 -0
- UQPyL-2.0.1/UQPyL/surrogates/__init__.py +23 -0
- UQPyL-2.0.1/UQPyL/surrogates/fully_connect_neural_network.py +415 -0
- UQPyL-2.0.1/UQPyL/surrogates/gaussian_process.py +191 -0
- UQPyL-2.0.1/UQPyL/surrogates/gp_kernels/Kernel.py +459 -0
- UQPyL-2.0.1/UQPyL/surrogates/gp_kernels/__init__.py +9 -0
- UQPyL-2.0.1/UQPyL/surrogates/kriging.py +315 -0
- UQPyL-2.0.1/UQPyL/surrogates/lasso_/__init__.py +8 -0
- UQPyL-2.0.1/UQPyL/surrogates/lasso_/lasso_fast.c +53419 -0
- UQPyL-2.0.1/UQPyL/surrogates/linear_regression.py +225 -0
- UQPyL-2.0.1/UQPyL/surrogates/mars.py +1233 -0
- UQPyL-2.0.1/UQPyL/surrogates/mars_/__init__.py +4 -0
- UQPyL-2.0.1/UQPyL/surrogates/mars_/_basis.c +55538 -0
- UQPyL-2.0.1/UQPyL/surrogates/mars_/_forward.c +44565 -0
- UQPyL-2.0.1/UQPyL/surrogates/mars_/_knot_search.c +56654 -0
- UQPyL-2.0.1/UQPyL/surrogates/mars_/_pruning.c +20134 -0
- UQPyL-2.0.1/UQPyL/surrogates/mars_/_qr.c +39824 -0
- UQPyL-2.0.1/UQPyL/surrogates/mars_/_record.c +28565 -0
- UQPyL-2.0.1/UQPyL/surrogates/mars_/_types.c +7104 -0
- UQPyL-2.0.1/UQPyL/surrogates/mars_/_util.c +14073 -0
- UQPyL-2.0.1/UQPyL/surrogates/mars_/pyearth/__init__.py +4 -0
- UQPyL-2.0.1/UQPyL/surrogates/mlp_utility/__init__.py +9 -0
- UQPyL-2.0.1/UQPyL/surrogates/mlp_utility/_activation_funcs.py +63 -0
- UQPyL-2.0.1/UQPyL/surrogates/mlp_utility/base.py +281 -0
- UQPyL-2.0.1/UQPyL/surrogates/mo_surrogates.py +35 -0
- UQPyL-2.0.1/UQPyL/surrogates/polynomial_regression.py +113 -0
- UQPyL-2.0.1/UQPyL/surrogates/radial_basis_function.py +93 -0
- UQPyL-2.0.1/UQPyL/surrogates/rbf_kernels/__init__.py +14 -0
- UQPyL-2.0.1/UQPyL/surrogates/rbf_kernels/base_kernel.py +447 -0
- UQPyL-2.0.1/UQPyL/surrogates/rbf_kernels/cubic_kernel.py +14 -0
- UQPyL-2.0.1/UQPyL/surrogates/rbf_kernels/gaussian_kernel.py +9 -0
- UQPyL-2.0.1/UQPyL/surrogates/rbf_kernels/linear_kernel.py +15 -0
- UQPyL-2.0.1/UQPyL/surrogates/rbf_kernels/multiquadric_kernel.py +18 -0
- UQPyL-2.0.1/UQPyL/surrogates/rbf_kernels/thin_plate_spline_kernel.py +20 -0
- UQPyL-2.0.1/UQPyL/surrogates/support_vector_machine.py +106 -0
- UQPyL-2.0.1/UQPyL/surrogates/surrogate_ABC.py +111 -0
- UQPyL-2.0.1/UQPyL/surrogates/svr_/__init__.py +7 -0
- UQPyL-2.0.1/UQPyL/surrogates/svr_/libsvm_interface.cpp +106 -0
- UQPyL-2.0.1/UQPyL/surrogates/svr_/svm.cpp +3313 -0
- UQPyL-2.0.1/UQPyL/utility/__init__.py +17 -0
- UQPyL-2.0.1/UQPyL/utility/grid_search.py +85 -0
- UQPyL-2.0.1/UQPyL/utility/metrics.py +52 -0
- UQPyL-2.0.1/UQPyL/utility/model_selections.py +62 -0
- UQPyL-2.0.1/UQPyL/utility/polynomial_features.py +61 -0
- UQPyL-2.0.1/UQPyL/utility/scalers.py +87 -0
- UQPyL-2.0.1/UQPyL.egg-info/PKG-INFO +64 -0
- UQPyL-2.0.1/UQPyL.egg-info/SOURCES.txt +92 -0
- UQPyL-2.0.1/UQPyL.egg-info/dependency_links.txt +1 -0
- UQPyL-2.0.1/UQPyL.egg-info/requires.txt +2 -0
- UQPyL-2.0.1/UQPyL.egg-info/top_level.txt +1 -0
- UQPyL-2.0.1/pyproject.toml +35 -0
- UQPyL-2.0.1/setup.cfg +4 -0
- UQPyL-2.0.1/setup.py +64 -0
UQPyL-2.0.1/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) [2024] [wmtSky]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
UQPyL-2.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: UQPyL
|
|
3
|
+
Version: 2.0.1
|
|
4
|
+
Summary: A python package for parameter uncertainty quantification and optimization
|
|
5
|
+
Author: wmtSky
|
|
6
|
+
Author-email: wmtSky <wmtsky@hhu.edu.cn>
|
|
7
|
+
Classifier: Programming Language :: Python :: 3.6
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
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: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE.md
|
|
18
|
+
|
|
19
|
+
# Uncertainty Quantification Python Laboratory <br> (UQPyL)
|
|
20
|
+
|
|
21
|
+
**UQPyL:** The **Uncertainty Quantification Python Laboratory** provide a comprehensive workflow for parameter **uncertainty quantification** and **optimization** in computational numerical simulations. **UQPyL** offers an extensive suite of advanced methodologies(Sobol', Delta Test, EFAST, et al.) and algorithms (NSGA-II, ASMO, MO-ASMO, et al.). In summary, UQPyL consists of four core modules:
|
|
22
|
+
- Design of Experiments (DoE)
|
|
23
|
+
- Sensibility Analysis
|
|
24
|
+
- Optimization
|
|
25
|
+
- Surrogate models
|
|
26
|
+
|
|
27
|
+
The surrogate models Module can help to solve computational expensive problems caused by intensive numerical simulations.**
|
|
28
|
+
|
|
29
|
+
Once you have clearly defined the problem you aim to address, you can employ all pre-prepared methods and algorithms to complete following task:
|
|
30
|
+
* Uncertainty Quantification (UQ)
|
|
31
|
+
* Parameter Optimization
|
|
32
|
+
|
|
33
|
+
Moreover, the versatility of UQPyL allows researchers to craft their own methods or algorithms by incorporating its diverse range of surrogate models. Consequently, users can:
|
|
34
|
+
- Evaluate the effectiveness of their custom-designed algorithms
|
|
35
|
+
- Compare different methods and algorithms under specific problem scenarios
|
|
36
|
+
|
|
37
|
+
**Website:** http://www.uq-pyl.com/ (**#TODO** it need to update now.) <br>
|
|
38
|
+
**Source Code:** https://github.com/smasky/UQPyL/ <br>
|
|
39
|
+
**Documentation:** **#TODO** <br>
|
|
40
|
+
**Citing in your work:** **#TODO** <br>
|
|
41
|
+
|
|
42
|
+
# Installation
|
|
43
|
+
|
|
44
|
+
` pip install UQPyL ` (Recommend)
|
|
45
|
+
|
|
46
|
+
or
|
|
47
|
+
|
|
48
|
+
` git clone https://github.com/smasky/UQPyL.git `
|
|
49
|
+
|
|
50
|
+
` cd UQPyL` and ` pip install . `
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# Call for Contributions
|
|
54
|
+
We appreciate and welcome contributions. Because, we only set up standard workflows here. More advanced quantification methods and optimization algorithms are waited for pulling to this project.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
# Contact:
|
|
58
|
+
|
|
59
|
+
wmtSky, <wmtsky@hhu.edu.cn>
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
UQPyL-2.0.1/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Uncertainty Quantification Python Laboratory <br> (UQPyL)
|
|
2
|
+
|
|
3
|
+
**UQPyL:** The **Uncertainty Quantification Python Laboratory** provide a comprehensive workflow for parameter **uncertainty quantification** and **optimization** in computational numerical simulations. **UQPyL** offers an extensive suite of advanced methodologies(Sobol', Delta Test, EFAST, et al.) and algorithms (NSGA-II, ASMO, MO-ASMO, et al.). In summary, UQPyL consists of four core modules:
|
|
4
|
+
- Design of Experiments (DoE)
|
|
5
|
+
- Sensibility Analysis
|
|
6
|
+
- Optimization
|
|
7
|
+
- Surrogate models
|
|
8
|
+
|
|
9
|
+
The surrogate models Module can help to solve computational expensive problems caused by intensive numerical simulations.**
|
|
10
|
+
|
|
11
|
+
Once you have clearly defined the problem you aim to address, you can employ all pre-prepared methods and algorithms to complete following task:
|
|
12
|
+
* Uncertainty Quantification (UQ)
|
|
13
|
+
* Parameter Optimization
|
|
14
|
+
|
|
15
|
+
Moreover, the versatility of UQPyL allows researchers to craft their own methods or algorithms by incorporating its diverse range of surrogate models. Consequently, users can:
|
|
16
|
+
- Evaluate the effectiveness of their custom-designed algorithms
|
|
17
|
+
- Compare different methods and algorithms under specific problem scenarios
|
|
18
|
+
|
|
19
|
+
**Website:** http://www.uq-pyl.com/ (**#TODO** it need to update now.) <br>
|
|
20
|
+
**Source Code:** https://github.com/smasky/UQPyL/ <br>
|
|
21
|
+
**Documentation:** **#TODO** <br>
|
|
22
|
+
**Citing in your work:** **#TODO** <br>
|
|
23
|
+
|
|
24
|
+
# Installation
|
|
25
|
+
|
|
26
|
+
` pip install UQPyL ` (Recommend)
|
|
27
|
+
|
|
28
|
+
or
|
|
29
|
+
|
|
30
|
+
` git clone https://github.com/smasky/UQPyL.git `
|
|
31
|
+
|
|
32
|
+
` cd UQPyL` and ` pip install . `
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# Call for Contributions
|
|
36
|
+
We appreciate and welcome contributions. Because, we only set up standard workflows here. More advanced quantification methods and optimization algorithms are waited for pulling to this project.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
# Contact:
|
|
40
|
+
|
|
41
|
+
wmtSky, <wmtsky@hhu.edu.cn>
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from .lhs import LHS
|
|
2
|
+
from .full_fact import FFD
|
|
3
|
+
from .random import RANDOM
|
|
4
|
+
from .sampler_ABC import Sampler
|
|
5
|
+
from .sobol_sequence import Sobol_Sequence
|
|
6
|
+
from .fast_sampler import FAST_Sampler
|
|
7
|
+
|
|
8
|
+
__all__=['LHS', 'FFD', 'RANDOM','Sobol_Sequence', 'FAST_Sampler','Sampler']
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from scipy.spatial.distance import pdist,squareform
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def _lhs_classic(nt: int, nx: int) -> np.ndarray:
|
|
6
|
+
# Generate the intervals
|
|
7
|
+
cut = np.linspace(0, 1, nt + 1)
|
|
8
|
+
|
|
9
|
+
# Fill points uniformly in each interval
|
|
10
|
+
u = np.random.rand(nt, nx)
|
|
11
|
+
a = cut[:nt]
|
|
12
|
+
b = cut[1:nt + 1]
|
|
13
|
+
rdpoints = np.zeros_like(u)
|
|
14
|
+
for j in range(nx):
|
|
15
|
+
rdpoints[:, j] = u[:, j]*(b-a) + a
|
|
16
|
+
|
|
17
|
+
# Make the random pairings
|
|
18
|
+
H = np.zeros_like(rdpoints)
|
|
19
|
+
for j in range(nx):
|
|
20
|
+
order = np.random.permutation(range(nt))
|
|
21
|
+
H[:, j] = rdpoints[order, j]
|
|
22
|
+
|
|
23
|
+
return H
|
|
24
|
+
|
|
25
|
+
################################################################################
|
|
26
|
+
|
|
27
|
+
def _lhs_centered(nt: int, nx: int) -> np.ndarray:
|
|
28
|
+
# Generate the intervals
|
|
29
|
+
cut = np.linspace(0, 1, nt + 1)
|
|
30
|
+
|
|
31
|
+
# Fill points uniformly in each interval
|
|
32
|
+
u = np.random.rand(nt, nx)
|
|
33
|
+
a = cut[:nt]
|
|
34
|
+
b = cut[1:nt + 1]
|
|
35
|
+
_center = (a + b)/2
|
|
36
|
+
|
|
37
|
+
# Make the random pairings
|
|
38
|
+
H = np.zeros_like(u)
|
|
39
|
+
for j in range(nx):
|
|
40
|
+
H[:, j] = np.random.permutation(_center)
|
|
41
|
+
|
|
42
|
+
return H
|
|
43
|
+
|
|
44
|
+
################################################################################
|
|
45
|
+
|
|
46
|
+
def _lhs_maximin(nt: int, nx: int, iterations: int)-> np.ndarray:
|
|
47
|
+
|
|
48
|
+
maxdist = 0
|
|
49
|
+
|
|
50
|
+
# Maximize the minimum distance between points
|
|
51
|
+
for i in range(iterations):
|
|
52
|
+
|
|
53
|
+
H_candidate = _lhs_classic(nt, nx)
|
|
54
|
+
|
|
55
|
+
d = pdist(H_candidate,'euclidean')
|
|
56
|
+
if maxdist<np.min(d):
|
|
57
|
+
maxdist = np.min(d)
|
|
58
|
+
H = H_candidate.copy()
|
|
59
|
+
|
|
60
|
+
return H
|
|
61
|
+
|
|
62
|
+
def _lhs_centered_maximin(nt: int, nx: int, iterations: int)-> np.ndarray:
|
|
63
|
+
maxdist = 0
|
|
64
|
+
|
|
65
|
+
# Maximize the minimum distance between points
|
|
66
|
+
for i in range(iterations):
|
|
67
|
+
|
|
68
|
+
H_candidate = _lhs_centered(nt, nx)
|
|
69
|
+
d = pdist(H_candidate,'euclidean')
|
|
70
|
+
if maxdist<np.min(d):
|
|
71
|
+
maxdist = np.min(d)
|
|
72
|
+
H = H_candidate.copy()
|
|
73
|
+
|
|
74
|
+
return H
|
|
75
|
+
################################################################################
|
|
76
|
+
|
|
77
|
+
def _lhs_correlate(nt: int, nx: int, iterations: int) -> np.ndarray:
|
|
78
|
+
mincorr = np.inf
|
|
79
|
+
|
|
80
|
+
# Minimize the components correlation coefficients
|
|
81
|
+
for i in range(iterations):
|
|
82
|
+
# Generate a random LHS
|
|
83
|
+
H_candidate = _lhs_classic(nt, nx)
|
|
84
|
+
R = np.corrcoef(H_candidate)
|
|
85
|
+
if np.max(np.abs(R[R!=1]))<mincorr:
|
|
86
|
+
mincorr = np.max(np.abs(R-np.eye(R.shape[0])))
|
|
87
|
+
print('new candidate solution found with max,abs corrcoef = {}'.format(mincorr))
|
|
88
|
+
H = H_candidate.copy()
|
|
89
|
+
|
|
90
|
+
return H
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from .sampler_ABC import Sampler
|
|
4
|
+
|
|
5
|
+
class FAST_Sampler(Sampler):
|
|
6
|
+
'''
|
|
7
|
+
The sample technique for FAST(Fourier Amplitude Sensitivity Test) method
|
|
8
|
+
|
|
9
|
+
Parameters:
|
|
10
|
+
M: int
|
|
11
|
+
The interference parameter, i.e., the number of harmonics to sum in the
|
|
12
|
+
Fourier series decomposition (defalut 4).
|
|
13
|
+
But, the number of sample must be greater than 4*M**2!
|
|
14
|
+
|
|
15
|
+
Methods:
|
|
16
|
+
__call__ or sample: Generate a sample for FAST method
|
|
17
|
+
|
|
18
|
+
Examples:
|
|
19
|
+
>>> fast=FAST_Sampler()
|
|
20
|
+
>>> samples=fast(5, 4) or fast.sample(5,4)
|
|
21
|
+
|
|
22
|
+
'''
|
|
23
|
+
def __init__(self, M: int=4):
|
|
24
|
+
|
|
25
|
+
super().__init__()
|
|
26
|
+
self.M=M
|
|
27
|
+
|
|
28
|
+
def _generate(self, nt: int, nx: int) -> np.ndarray:
|
|
29
|
+
'''
|
|
30
|
+
Generate a shape of (nt*nx, nx) sample for FAST
|
|
31
|
+
|
|
32
|
+
parameters:
|
|
33
|
+
nt: int
|
|
34
|
+
the number of sample points
|
|
35
|
+
nx: int
|
|
36
|
+
the input dimensions of sampled points
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
H: 2d-array
|
|
40
|
+
An n-by-samples design matrix that has been normalized so factor values
|
|
41
|
+
are uniformly spaced between zero and one.
|
|
42
|
+
'''
|
|
43
|
+
|
|
44
|
+
if nt<=4*self.M**2:
|
|
45
|
+
raise ValueError("the number of sample must be greater than 4*M**2!")
|
|
46
|
+
|
|
47
|
+
w=np.zeros(nx)
|
|
48
|
+
w[0]=np.floor((nt-1)/(2*self.M))
|
|
49
|
+
max_wi=np.floor(w[0]/(2*self.M)) #Saltelli
|
|
50
|
+
|
|
51
|
+
if max_wi>=nx-1:
|
|
52
|
+
w[1:]=np.floor(np.linspace(1,max_wi, nx-1))
|
|
53
|
+
else:
|
|
54
|
+
w[1:]=np.arange(nx-1)%max_wi+1
|
|
55
|
+
|
|
56
|
+
s=(2*np.pi/nt)*np.arange(nt)
|
|
57
|
+
|
|
58
|
+
X_sa=np.zeros((nt*nx, nx))
|
|
59
|
+
w_tmp=np.zeros(nx)
|
|
60
|
+
|
|
61
|
+
for i in range(nx):
|
|
62
|
+
w_tmp[i]=w[0]
|
|
63
|
+
idx=list(range(i))+list(range(i+1,nx))
|
|
64
|
+
w_tmp[idx]=w[1:]
|
|
65
|
+
idx=range(i*nt, (i+1)*nt)
|
|
66
|
+
phi=2*np.pi*np.random.rand()
|
|
67
|
+
sin_result=np.sin(w_tmp[:,None]*s+phi)
|
|
68
|
+
arsin_result=(1/np.pi)*np.arcsin(sin_result) #saltelli formula
|
|
69
|
+
X_sa[idx, :]=0.5+arsin_result.transpose()
|
|
70
|
+
|
|
71
|
+
return X_sa
|
|
72
|
+
|
|
73
|
+
def sample(self, nt: int, nx: int) -> np.ndarray:
|
|
74
|
+
|
|
75
|
+
return self._generate(nt, nx)
|
|
76
|
+
|
|
77
|
+
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from typing import Union
|
|
3
|
+
from itertools import product
|
|
4
|
+
|
|
5
|
+
from .sampler_ABC import Sampler
|
|
6
|
+
|
|
7
|
+
class FFD(Sampler):
|
|
8
|
+
'''
|
|
9
|
+
Full Factorial Design
|
|
10
|
+
|
|
11
|
+
Methods:
|
|
12
|
+
__call__ or sample: Generate a Latin-hypercube design
|
|
13
|
+
|
|
14
|
+
Examples:
|
|
15
|
+
>>> ffd=FFD()
|
|
16
|
+
>>> samples=ffd(3, [2,3,4]) or samples=ffd.sample(3, [2,3,4])
|
|
17
|
+
'''
|
|
18
|
+
|
|
19
|
+
def __call__(self, nx: int, levels: Union[np.ndarray, int, list]) -> np.ndarray:
|
|
20
|
+
|
|
21
|
+
return self._generate(nx, levels)
|
|
22
|
+
|
|
23
|
+
def _generate(self, nx: int, levels: Union[np.ndarray, int, list]) -> np.ndarray:
|
|
24
|
+
|
|
25
|
+
if isinstance(levels, int):
|
|
26
|
+
levels = [levels]*nx
|
|
27
|
+
elif isinstance(levels, np.ndarray):
|
|
28
|
+
levels = levels.ravel().tolist()
|
|
29
|
+
|
|
30
|
+
if len(levels)!=nx:
|
|
31
|
+
raise ValueError('The length of levels should be equal to nx or 1')
|
|
32
|
+
|
|
33
|
+
factor_levels = [np.linspace(0, 1, num=level + 1)[:level] for level in levels]
|
|
34
|
+
|
|
35
|
+
factor_combinations = list(product(*factor_levels))
|
|
36
|
+
|
|
37
|
+
H = np.array(factor_combinations)
|
|
38
|
+
|
|
39
|
+
return H
|
|
40
|
+
|
|
41
|
+
def sample(self, nx: int, levels: Union[np.ndarray, int, list]) -> np.ndarray:
|
|
42
|
+
'''
|
|
43
|
+
Parameters:
|
|
44
|
+
nx: int
|
|
45
|
+
The number of input dimensions
|
|
46
|
+
|
|
47
|
+
levels: Union[np.ndarray, int, list]
|
|
48
|
+
The levels for each input dimension
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
H: 2d-array
|
|
52
|
+
An n-by-samples design matrix between zero and one.
|
|
53
|
+
'''
|
|
54
|
+
|
|
55
|
+
return self._generate(nx, levels)
|
|
56
|
+
|
|
57
|
+
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from typing import Literal
|
|
3
|
+
|
|
4
|
+
from .sampler_ABC import Sampler
|
|
5
|
+
from ._lhs import _lhs_classic, _lhs_centered, _lhs_correlate, _lhs_maximin, _lhs_centered_maximin
|
|
6
|
+
|
|
7
|
+
Criterion=Literal['classic','center','maximin','center_maximin','correlation']
|
|
8
|
+
LHS_METHOD={'classic': _lhs_classic, 'center': _lhs_centered, 'maximin': _lhs_maximin,
|
|
9
|
+
'center_maximin': _lhs_centered_maximin, 'correlation': _lhs_correlate}
|
|
10
|
+
|
|
11
|
+
class LHS(Sampler):
|
|
12
|
+
'''
|
|
13
|
+
Latin-hypercube design
|
|
14
|
+
|
|
15
|
+
Parameters:
|
|
16
|
+
criterion : str
|
|
17
|
+
Allowable values are "classic", "center", "maximin", "center_maximin",
|
|
18
|
+
and "correlation". (Default: classic)
|
|
19
|
+
|
|
20
|
+
iterations : int
|
|
21
|
+
The number of iterations in the maximin, center_maximin and correlations methods
|
|
22
|
+
(Default: 5).
|
|
23
|
+
|
|
24
|
+
Methods:
|
|
25
|
+
__call__ or sample: Generate a Latin-hypercube design
|
|
26
|
+
|
|
27
|
+
Examples:
|
|
28
|
+
>>>lhs=LHS('classic')
|
|
29
|
+
>>>samples=lhs(5,10) or samples=lhs.sample(5,10)
|
|
30
|
+
|
|
31
|
+
'''
|
|
32
|
+
def __init__(self, criterion: Criterion='classic', iterations: int=5)-> None:
|
|
33
|
+
self.criterion=criterion
|
|
34
|
+
self.iterations=iterations
|
|
35
|
+
|
|
36
|
+
def _generate(self, nt: int, nx: int) -> np.ndarray:
|
|
37
|
+
'''
|
|
38
|
+
Generate a Latin-hypercube design
|
|
39
|
+
|
|
40
|
+
Parameters
|
|
41
|
+
nt: int
|
|
42
|
+
the number of sampled points
|
|
43
|
+
nx: int
|
|
44
|
+
the input dimensions of sampled points
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
H: 2d-array
|
|
48
|
+
An n-by-samples design matrix that has been normalized so factor values
|
|
49
|
+
are uniformly spaced between zero and one.
|
|
50
|
+
'''
|
|
51
|
+
Sampling_method=LHS_METHOD[self.criterion]
|
|
52
|
+
if self.criterion in ['maximin', 'center_maximin', 'correlation']:
|
|
53
|
+
return Sampling_method(nt, nx, self.iterations)
|
|
54
|
+
else:
|
|
55
|
+
return Sampling_method(nt, nx)
|
|
56
|
+
|
|
57
|
+
def sample(self, nt: int, nx:int) -> np.ndarray:
|
|
58
|
+
'''
|
|
59
|
+
Generate a Latin-hypercube design
|
|
60
|
+
|
|
61
|
+
Parameters
|
|
62
|
+
nt: int
|
|
63
|
+
the number of sampled points
|
|
64
|
+
nx: int
|
|
65
|
+
the input dimensions of sampled points
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
H: 2d-array
|
|
69
|
+
An n-by-samples design matrix that has been normalized so factor values
|
|
70
|
+
are uniformly spaced between zero and one.
|
|
71
|
+
'''
|
|
72
|
+
|
|
73
|
+
return self._generate(nt, nx)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from .sampler_ABC import Sampler
|
|
4
|
+
|
|
5
|
+
class RANDOM(Sampler):
|
|
6
|
+
'''
|
|
7
|
+
Random Design
|
|
8
|
+
|
|
9
|
+
Method:
|
|
10
|
+
__call__ or sample: Generate a random design
|
|
11
|
+
|
|
12
|
+
Examples:
|
|
13
|
+
>>> random=RANDOM()
|
|
14
|
+
>>> random(10,10) or random.sample(10,10)
|
|
15
|
+
'''
|
|
16
|
+
|
|
17
|
+
def _generate(self,nt: int, nx: int) -> np.ndarray:
|
|
18
|
+
|
|
19
|
+
H=np.random.random((nt,nx))
|
|
20
|
+
|
|
21
|
+
return H
|
|
22
|
+
|
|
23
|
+
def sample(self, nt: int, nx: int) -> np.ndarray:
|
|
24
|
+
'''
|
|
25
|
+
Generate a sample with random values between zero and one
|
|
26
|
+
'''
|
|
27
|
+
|
|
28
|
+
return self._generate(nt, nx)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
class Sampler(metaclass=abc.ABCMeta):
|
|
5
|
+
def __init__(self):
|
|
6
|
+
pass
|
|
7
|
+
|
|
8
|
+
def __call__(self, nt:int, nx: int) -> np.ndarray:
|
|
9
|
+
return self._generate(nt, nx)
|
|
10
|
+
|
|
11
|
+
def sample(self, nt:int, nx:int) -> np.ndarray:
|
|
12
|
+
return self._generate(nt, nx)
|
|
13
|
+
|
|
14
|
+
@abc.abstractmethod
|
|
15
|
+
def _generate(self, nt: int, nx: int) -> np.ndarray:
|
|
16
|
+
'''
|
|
17
|
+
nt: the number of sampled points
|
|
18
|
+
nx: the dimensions of decision variables
|
|
19
|
+
|
|
20
|
+
return:
|
|
21
|
+
ndarry[nt,nx]
|
|
22
|
+
|
|
23
|
+
'''
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from scipy.stats.qmc import Sobol
|
|
3
|
+
|
|
4
|
+
from .sampler_ABC import Sampler
|
|
5
|
+
|
|
6
|
+
class Sobol_Sequence(Sampler):
|
|
7
|
+
'''
|
|
8
|
+
Sobol Sequence
|
|
9
|
+
|
|
10
|
+
Methods:
|
|
11
|
+
__call__ or sample: generate the shape of (nt*nx, nx) and numpy array Sobol sequence.
|
|
12
|
+
|
|
13
|
+
'''
|
|
14
|
+
def __init__(self):
|
|
15
|
+
|
|
16
|
+
super().__init__()
|
|
17
|
+
|
|
18
|
+
def _generate(self, nt: int, nx: int) -> np.ndarray:
|
|
19
|
+
'''
|
|
20
|
+
generate the shape of (nt*nx, nx) and numpy array Sobol sequence.
|
|
21
|
+
'''
|
|
22
|
+
|
|
23
|
+
return Sobol(d=nx).random(nt)
|
|
24
|
+
|
|
25
|
+
def sample(self, nt: int, nx: int) -> np.ndarray:
|
|
26
|
+
'''
|
|
27
|
+
generate the shape of (nt, nx) and numpy array Sobol sequence.
|
|
28
|
+
|
|
29
|
+
Parameters
|
|
30
|
+
nt: int
|
|
31
|
+
the number of sampled points
|
|
32
|
+
nx: int
|
|
33
|
+
the input dimensions of sampled points
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
H: 2d-array
|
|
37
|
+
An n-by-samples design matrix that has been normalized so factor values
|
|
38
|
+
are uniformly spaced between zero and one.
|
|
39
|
+
'''
|
|
40
|
+
return self._generate(nt, nx)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from .ga import GA
|
|
2
|
+
from .boxmin import Boxmin
|
|
3
|
+
from .adam import Adam
|
|
4
|
+
from .sce_ua import SCE_UA
|
|
5
|
+
from .asmo import ASMO
|
|
6
|
+
from .nsga_ii import NSGAII
|
|
7
|
+
from .mo_asmo import MOASMO
|
|
8
|
+
from ._binary_ga import Binary_GA
|
|
9
|
+
__all__=[
|
|
10
|
+
'GA',
|
|
11
|
+
'Boxmin',
|
|
12
|
+
'Adam',
|
|
13
|
+
'SCE_UA',
|
|
14
|
+
'ASMO',
|
|
15
|
+
'NSGAII',
|
|
16
|
+
'MOASMO',
|
|
17
|
+
'Binary_GA'
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
MP_List=['Boxmin']
|
|
21
|
+
EA_List=['GA']
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
class Binary_GA():
|
|
4
|
+
def __init__(self, evaluate, n_features, population_size=50, n_generations=100, crossover_rate=0.7, mutation_rate=0.01):
|
|
5
|
+
self.population_size = population_size
|
|
6
|
+
self.n_generations = n_generations
|
|
7
|
+
self.crossover_rate = crossover_rate
|
|
8
|
+
self.mutation_rate = mutation_rate
|
|
9
|
+
self.n_features = n_features
|
|
10
|
+
self.evaluate = evaluate
|
|
11
|
+
def initialize_population(self):
|
|
12
|
+
return np.random.randint(2, size=(self.population_size, self.n_features))
|
|
13
|
+
|
|
14
|
+
def select(self, fitnesses):
|
|
15
|
+
inverse_fitnesses = [1.0/f for f in fitnesses]
|
|
16
|
+
total_fitness = sum(inverse_fitnesses)
|
|
17
|
+
selection_probs = [f/total_fitness for f in inverse_fitnesses]
|
|
18
|
+
return np.random.choice(range(self.population_size), size=self.population_size, replace=True, p=selection_probs)
|
|
19
|
+
|
|
20
|
+
def crossover(self, parent1, parent2):
|
|
21
|
+
if np.random.rand() < self.crossover_rate:
|
|
22
|
+
point = np.random.randint(1, self.n_features)
|
|
23
|
+
child1 = np.concatenate([parent1[:point], parent2[point:]])
|
|
24
|
+
child2 = np.concatenate([parent2[:point], parent1[point:]])
|
|
25
|
+
return child1, child2
|
|
26
|
+
return parent1, parent2
|
|
27
|
+
|
|
28
|
+
def mutate(self, individual):
|
|
29
|
+
for i in range(self.n_features):
|
|
30
|
+
if np.random.rand() < self.mutation_rate:
|
|
31
|
+
individual[i] = 1 - individual[i]
|
|
32
|
+
return individual
|
|
33
|
+
|
|
34
|
+
def run(self):
|
|
35
|
+
population = self.initialize_population()
|
|
36
|
+
best_individual = None
|
|
37
|
+
best_fitness = float('inf')
|
|
38
|
+
history_individuals = []
|
|
39
|
+
history_values=[]
|
|
40
|
+
for generation in range(self.n_generations):
|
|
41
|
+
fitnesses = [self.evaluate(individual) for individual in population]
|
|
42
|
+
if min(fitnesses) < best_fitness:
|
|
43
|
+
best_fitness = min(fitnesses)
|
|
44
|
+
best_individual = population[np.argmin(fitnesses)]
|
|
45
|
+
|
|
46
|
+
history_individuals.append(best_individual)
|
|
47
|
+
history_values.append(best_fitness)
|
|
48
|
+
|
|
49
|
+
selected_indices = self.select(fitnesses)
|
|
50
|
+
selected_population = population[selected_indices]
|
|
51
|
+
offspring_population = []
|
|
52
|
+
for i in range(0, self.population_size, 2):
|
|
53
|
+
parent1, parent2 = selected_population[i], selected_population[i+1]
|
|
54
|
+
child1, child2 = self.crossover(parent1, parent2)
|
|
55
|
+
offspring_population.append(self.mutate(child1))
|
|
56
|
+
offspring_population.append(self.mutate(child2))
|
|
57
|
+
population = np.array(offspring_population)
|
|
58
|
+
# 精英保留
|
|
59
|
+
if best_individual is not None:
|
|
60
|
+
population[0] = best_individual
|
|
61
|
+
return best_individual, best_fitness, history_individuals, history_values
|