UQPyL 2.0.1__cp39-cp39-win_amd64.whl
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/DoE/__init__.py +8 -0
- UQPyL/DoE/_lhs.py +90 -0
- UQPyL/DoE/fast_sampler.py +77 -0
- UQPyL/DoE/full_fact.py +57 -0
- UQPyL/DoE/lhs.py +73 -0
- UQPyL/DoE/random.py +28 -0
- UQPyL/DoE/sampler_ABC.py +26 -0
- UQPyL/DoE/sobol_sequence.py +47 -0
- UQPyL/__init__.py +13 -0
- UQPyL/optimization/__init__.py +21 -0
- UQPyL/optimization/_binary_ga.py +61 -0
- UQPyL/optimization/_ga.py +120 -0
- UQPyL/optimization/adam.py +81 -0
- UQPyL/optimization/asmo.py +86 -0
- UQPyL/optimization/boxmin.py +95 -0
- UQPyL/optimization/ga.py +122 -0
- UQPyL/optimization/mo_asmo.py +115 -0
- UQPyL/optimization/nsga_ii.py +219 -0
- UQPyL/optimization/sce_ua.py +182 -0
- UQPyL/problems/__init__.py +22 -0
- UQPyL/problems/multi_DTLZ.py +577 -0
- UQPyL/problems/multi_ZDT.py +224 -0
- UQPyL/problems/pratical_problem.py +31 -0
- UQPyL/problems/problem_ABC.py +42 -0
- UQPyL/problems/single_Benchmarks.py +475 -0
- UQPyL/problems/utility_functions/_NDsort.py +34 -0
- UQPyL/problems/utility_functions/__init__.py +0 -0
- UQPyL/problems/utility_functions/_uniformPoint.py +47 -0
- UQPyL/sensibility/__init__.py +15 -0
- UQPyL/sensibility/delta_test.py +78 -0
- UQPyL/sensibility/fast.py +74 -0
- UQPyL/sensibility/mars_sa.py +60 -0
- UQPyL/sensibility/morris.py +88 -0
- UQPyL/sensibility/rbd_fast.py +59 -0
- UQPyL/sensibility/rsa.py +51 -0
- UQPyL/sensibility/sa_ABC.py +133 -0
- UQPyL/sensibility/sobol.py +141 -0
- UQPyL/surrogates/BaggingEnsemble.py +1 -0
- UQPyL/surrogates/BootstrapEnsemble.py +1 -0
- UQPyL/surrogates/__init__.py +23 -0
- UQPyL/surrogates/fully_connect_neural_network.py +415 -0
- UQPyL/surrogates/gaussian_process.py +191 -0
- UQPyL/surrogates/gp_kernels/Kernel.py +459 -0
- UQPyL/surrogates/gp_kernels/__init__.py +9 -0
- UQPyL/surrogates/kriging.py +315 -0
- UQPyL/surrogates/lasso_/__init__.py +8 -0
- UQPyL/surrogates/lasso_/lasso_fast.c +53419 -0
- UQPyL/surrogates/lasso_/lasso_fast.cp39-win_amd64.pyd +0 -0
- UQPyL/surrogates/linear_regression.py +225 -0
- UQPyL/surrogates/mars.py +1233 -0
- UQPyL/surrogates/mars_/__init__.py +4 -0
- UQPyL/surrogates/mars_/_basis.c +55538 -0
- UQPyL/surrogates/mars_/_basis.cp39-win_amd64.pyd +0 -0
- UQPyL/surrogates/mars_/_forward.c +44565 -0
- UQPyL/surrogates/mars_/_forward.cp39-win_amd64.pyd +0 -0
- UQPyL/surrogates/mars_/_knot_search.c +56654 -0
- UQPyL/surrogates/mars_/_knot_search.cp39-win_amd64.pyd +0 -0
- UQPyL/surrogates/mars_/_pruning.c +20134 -0
- UQPyL/surrogates/mars_/_pruning.cp39-win_amd64.pyd +0 -0
- UQPyL/surrogates/mars_/_qr.c +39824 -0
- UQPyL/surrogates/mars_/_qr.cp39-win_amd64.pyd +0 -0
- UQPyL/surrogates/mars_/_record.c +28565 -0
- UQPyL/surrogates/mars_/_record.cp39-win_amd64.pyd +0 -0
- UQPyL/surrogates/mars_/_types.c +7104 -0
- UQPyL/surrogates/mars_/_types.cp39-win_amd64.pyd +0 -0
- UQPyL/surrogates/mars_/_util.c +14073 -0
- UQPyL/surrogates/mars_/_util.cp39-win_amd64.pyd +0 -0
- UQPyL/surrogates/mars_/pyearth/__init__.py +4 -0
- UQPyL/surrogates/mlp_utility/__init__.py +9 -0
- UQPyL/surrogates/mlp_utility/_activation_funcs.py +63 -0
- UQPyL/surrogates/mlp_utility/base.py +281 -0
- UQPyL/surrogates/mo_surrogates.py +35 -0
- UQPyL/surrogates/polynomial_regression.py +113 -0
- UQPyL/surrogates/radial_basis_function.py +93 -0
- UQPyL/surrogates/rbf_kernels/__init__.py +14 -0
- UQPyL/surrogates/rbf_kernels/base_kernel.py +447 -0
- UQPyL/surrogates/rbf_kernels/cubic_kernel.py +14 -0
- UQPyL/surrogates/rbf_kernels/gaussian_kernel.py +9 -0
- UQPyL/surrogates/rbf_kernels/linear_kernel.py +15 -0
- UQPyL/surrogates/rbf_kernels/multiquadric_kernel.py +18 -0
- UQPyL/surrogates/rbf_kernels/thin_plate_spline_kernel.py +20 -0
- UQPyL/surrogates/support_vector_machine.py +106 -0
- UQPyL/surrogates/surrogate_ABC.py +111 -0
- UQPyL/surrogates/svr_/__init__.py +7 -0
- UQPyL/surrogates/svr_/libsvm_interface.cp39-win_amd64.pyd +0 -0
- UQPyL/surrogates/svr_/libsvm_interface.cpp +106 -0
- UQPyL/surrogates/svr_/svm.cpp +3313 -0
- UQPyL/utility/__init__.py +17 -0
- UQPyL/utility/grid_search.py +85 -0
- UQPyL/utility/metrics.py +52 -0
- UQPyL/utility/model_selections.py +62 -0
- UQPyL/utility/polynomial_features.py +61 -0
- UQPyL/utility/scalers.py +87 -0
- UQPyL-2.0.1.dist-info/LICENSE.md +21 -0
- UQPyL-2.0.1.dist-info/METADATA +66 -0
- UQPyL-2.0.1.dist-info/RECORD +98 -0
- UQPyL-2.0.1.dist-info/WHEEL +5 -0
- UQPyL-2.0.1.dist-info/top_level.txt +1 -0
UQPyL/DoE/__init__.py
ADDED
|
@@ -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']
|
UQPyL/DoE/_lhs.py
ADDED
|
@@ -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
|
+
|
UQPyL/DoE/full_fact.py
ADDED
|
@@ -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
|
+
|
UQPyL/DoE/lhs.py
ADDED
|
@@ -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)
|
UQPyL/DoE/random.py
ADDED
|
@@ -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)
|
UQPyL/DoE/sampler_ABC.py
ADDED
|
@@ -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
|
+
|
UQPyL/__init__.py
ADDED
|
@@ -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
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import warnings
|
|
3
|
+
import math
|
|
4
|
+
from typing import Callable
|
|
5
|
+
|
|
6
|
+
class GA():
|
|
7
|
+
type="EA" #Evolutionary Algorithm
|
|
8
|
+
proC=None
|
|
9
|
+
disC=None
|
|
10
|
+
proM=None
|
|
11
|
+
disM=None
|
|
12
|
+
tolerate=1e-6
|
|
13
|
+
def __init__(self, dim: int, ub: np.ndarray, lb: np.ndarray, n_samples: int,
|
|
14
|
+
proC: float=1, disC: float=20, proM: float=1, disM: float=20,
|
|
15
|
+
tolerate_times: int=1000):
|
|
16
|
+
self.__check__(dim,ub,lb)
|
|
17
|
+
self.dim=dim;self.ub=ub.reshape(1,-1);self.lb=lb.reshape(1,-1)
|
|
18
|
+
|
|
19
|
+
self.proC=proC;self.disC=disC
|
|
20
|
+
self.proM=proM;self.disM=disM
|
|
21
|
+
self.tolerate=1e-6; self.tolerate_times=tolerate_times
|
|
22
|
+
self.n_samples=n_samples
|
|
23
|
+
self.iterTimes=4000
|
|
24
|
+
def _tournamentSelection(self,decs: np.ndarray, objs: np.ndarray, K: int=2):
|
|
25
|
+
'''
|
|
26
|
+
K-tournament selection
|
|
27
|
+
'''
|
|
28
|
+
rankIndex=np.argsort(objs,axis=0)
|
|
29
|
+
rank=np.argsort(rankIndex,axis=0)
|
|
30
|
+
|
|
31
|
+
tourSelection=np.random.randint(0,high=objs.shape[0],size=(objs.shape[0],K))
|
|
32
|
+
winner=np.min(rank[tourSelection,:].ravel().reshape(objs.shape[0],2),axis=1)
|
|
33
|
+
winIndex=rankIndex[winner]
|
|
34
|
+
|
|
35
|
+
return decs[winIndex.ravel(),:]
|
|
36
|
+
|
|
37
|
+
def _operationGA(self,decs: np.ndarray):
|
|
38
|
+
'''
|
|
39
|
+
GA Operation
|
|
40
|
+
'''
|
|
41
|
+
n_samples=decs.shape[0]
|
|
42
|
+
Parent1=decs[:math.floor(n_samples/2),:]
|
|
43
|
+
Parent2=decs[math.floor(n_samples/2):math.floor(n_samples/2)*2,:]
|
|
44
|
+
|
|
45
|
+
N,D=Parent1.shape
|
|
46
|
+
|
|
47
|
+
beta=np.zeros((N,D))
|
|
48
|
+
mu=np.random.random((N,D))
|
|
49
|
+
|
|
50
|
+
beta[mu<=0.5]=np.power(2*mu[mu<=0.5],1/(self.disC+1))
|
|
51
|
+
beta[mu>0.5]=np.power(2-2*mu[mu>0.5],-1/(self.disC+1))
|
|
52
|
+
beta=beta*np.power(-1,np.random.randint(0,high=2,size=(N,D)))
|
|
53
|
+
beta[np.random.random((N,D))<0.5]=1
|
|
54
|
+
beta[np.repeat(np.random.random((N,1))>self.proC,D,axis=1)]=1
|
|
55
|
+
|
|
56
|
+
off1=(Parent1+Parent2)/2+beta*(Parent1-Parent2)/2
|
|
57
|
+
off2=(Parent1+Parent2)/2-beta*(Parent1-Parent2)/2
|
|
58
|
+
Offspring=np.vstack((off1,off2))
|
|
59
|
+
|
|
60
|
+
Lower=np.repeat(self.lb,2*N,axis=0)
|
|
61
|
+
Upper=np.repeat(self.ub,2*N,axis=0)
|
|
62
|
+
Site=np.random.random((2*N,D))<self.proM/D
|
|
63
|
+
mu=np.random.random((2*N,D))
|
|
64
|
+
temp=np.zeros((2*N,D),dtype=np.bool_)
|
|
65
|
+
temp[Site * mu<=0.5]=1
|
|
66
|
+
Offspring=np.minimum(np.maximum(Offspring,Lower),Upper)
|
|
67
|
+
|
|
68
|
+
t1=(1-2*mu[temp])*np.power(1-(Offspring[temp]-Lower[temp])/(Upper[temp]-Lower[temp]),self.disM+1)
|
|
69
|
+
Offspring[temp]=Offspring[temp]+(Upper[temp]-Lower[temp])*(np.power(2*mu[temp]+t1,1/(self.disM+1))-1)
|
|
70
|
+
|
|
71
|
+
temp=np.zeros((2*N,D),dtype=np.bool_);temp[Site * mu>0.5]=1
|
|
72
|
+
t2=2*(mu[temp]-0.5)*np.power(1-(Upper[temp]-Offspring[temp])/(Upper[temp]-Lower[temp]),self.disM+1)
|
|
73
|
+
|
|
74
|
+
Offspring[temp]=Offspring[temp]+(Upper[temp]-Lower[temp])*(1-np.power(2*(1-mu[temp])+t2,1/(self.disM+1)))
|
|
75
|
+
|
|
76
|
+
return Offspring
|
|
77
|
+
|
|
78
|
+
def run(self, func: Callable):
|
|
79
|
+
|
|
80
|
+
best_objs=np.inf
|
|
81
|
+
best_decs=None
|
|
82
|
+
time=1
|
|
83
|
+
iter=0
|
|
84
|
+
|
|
85
|
+
decs=np.random.random((self.n_samples,self.dim))*(self.ub-self.lb)+self.lb
|
|
86
|
+
objs=func(decs)
|
|
87
|
+
|
|
88
|
+
while iter<self.iterTimes:
|
|
89
|
+
|
|
90
|
+
matingPool=self._tournamentSelection(decs,objs,2)
|
|
91
|
+
matingDecs=self._operationGA(matingPool)
|
|
92
|
+
matingObjs=func(matingDecs)
|
|
93
|
+
|
|
94
|
+
tempObjs=np.vstack((objs,matingObjs))
|
|
95
|
+
tempDecs=np.vstack((decs,matingDecs))
|
|
96
|
+
rank=np.argsort(tempObjs,axis=0)
|
|
97
|
+
decs=tempDecs[rank[:self.n_samples,0],:]
|
|
98
|
+
objs=tempObjs[rank[:self.n_samples,0],:]
|
|
99
|
+
|
|
100
|
+
if(abs(best_objs-np.min(objs))>self.tolerate):
|
|
101
|
+
best_objs=np.min(objs)
|
|
102
|
+
best_decs=decs[np.argmin(objs,axis=0),:]
|
|
103
|
+
time=0
|
|
104
|
+
else:
|
|
105
|
+
time+=1
|
|
106
|
+
|
|
107
|
+
if(time>self.tolerate_times):
|
|
108
|
+
break
|
|
109
|
+
|
|
110
|
+
iter+=1
|
|
111
|
+
|
|
112
|
+
return best_decs,best_objs
|
|
113
|
+
|
|
114
|
+
def __check__(self,dim: int, ub: np.ndarray, lb: np.ndarray):
|
|
115
|
+
if(ub.size==lb.size and dim==ub.size):
|
|
116
|
+
pass
|
|
117
|
+
else:
|
|
118
|
+
raise ValueError("The dimensions should be consistent among dim, ub and lb")
|
|
119
|
+
|
|
120
|
+
|