UQPyL 2.0.10__tar.gz → 2.1.0__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 (180) hide show
  1. {UQPyL-2.0.10 → UQPyL-2.1.0}/PKG-INFO +1 -2
  2. UQPyL-2.1.0/UQPyL/DoE/fast_sequence.py +91 -0
  3. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/DoE/full_fact.py +26 -28
  4. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/DoE/lhs.py +82 -69
  5. UQPyL-2.1.0/UQPyL/DoE/morris_sequence.py +105 -0
  6. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/DoE/random.py +24 -13
  7. UQPyL-2.1.0/UQPyL/DoE/saltelli_sequence.py +113 -0
  8. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/DoE/samplerABC.py +2 -2
  9. UQPyL-2.1.0/UQPyL/DoE/sobol_sequence.py +68 -0
  10. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/__init__.py +1 -1
  11. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/optimization/__init__.py +1 -1
  12. UQPyL-2.1.0/UQPyL/optimization/algorithmABC.py +134 -0
  13. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/optimization/metric/hv.py +31 -18
  14. UQPyL-2.1.0/UQPyL/optimization/multi_objective/moasmo.py +200 -0
  15. UQPyL-2.1.0/UQPyL/optimization/multi_objective/moea_d.py +163 -0
  16. UQPyL-2.1.0/UQPyL/optimization/multi_objective/nsga_ii.py +149 -0
  17. UQPyL-2.1.0/UQPyL/optimization/multi_objective/nsga_iii.py +244 -0
  18. UQPyL-2.1.0/UQPyL/optimization/multi_objective/rvea.py +184 -0
  19. UQPyL-2.1.0/UQPyL/optimization/population.py +230 -0
  20. UQPyL-2.1.0/UQPyL/optimization/result.py +241 -0
  21. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/optimization/single_objective/__init__.py +1 -2
  22. UQPyL-2.1.0/UQPyL/optimization/single_objective/abc.py +279 -0
  23. UQPyL-2.1.0/UQPyL/optimization/single_objective/asmo.py +148 -0
  24. UQPyL-2.1.0/UQPyL/optimization/single_objective/csa.py +201 -0
  25. UQPyL-2.1.0/UQPyL/optimization/single_objective/de.py +147 -0
  26. UQPyL-2.1.0/UQPyL/optimization/single_objective/ego.py +164 -0
  27. UQPyL-2.1.0/UQPyL/optimization/single_objective/ga.py +123 -0
  28. UQPyL-2.1.0/UQPyL/optimization/single_objective/ml_sce_ua.py +192 -0
  29. UQPyL-2.1.0/UQPyL/optimization/single_objective/pso.py +181 -0
  30. UQPyL-2.1.0/UQPyL/optimization/single_objective/sce_ua.py +202 -0
  31. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/optimization/utility_functions/__init__.py +0 -1
  32. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/optimization/utility_functions/crowding_distance.py +3 -3
  33. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/optimization/utility_functions/ndsort.py +7 -6
  34. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/optimization/utility_functions/operation_GA.py +1 -1
  35. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/optimization/utility_functions/tournament_selection.py +12 -7
  36. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/optimization/utility_functions/uniform_point.py +2 -3
  37. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/problems/__init__.py +2 -2
  38. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/problems/multi_objective/DTLZ.py +57 -52
  39. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/problems/multi_objective/ZDT.py +52 -52
  40. UQPyL-2.1.0/UQPyL/problems/problem.py +62 -0
  41. UQPyL-2.1.0/UQPyL/problems/problemABC.py +340 -0
  42. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/problems/single_objective/__init__.py +3 -1
  43. UQPyL-2.1.0/UQPyL/problems/single_objective/single_constraint_problem.py +50 -0
  44. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/problems/single_objective/single_simple_problem.py +171 -121
  45. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/sensibility/__init__.py +1 -1
  46. UQPyL-2.1.0/UQPyL/sensibility/delta_test.py +277 -0
  47. UQPyL-2.1.0/UQPyL/sensibility/fast.py +174 -0
  48. UQPyL-2.1.0/UQPyL/sensibility/mars_sa.py +127 -0
  49. UQPyL-2.1.0/UQPyL/sensibility/morris.py +188 -0
  50. UQPyL-2.1.0/UQPyL/sensibility/rbd_fast.py +150 -0
  51. UQPyL-2.1.0/UQPyL/sensibility/rsa.py +172 -0
  52. UQPyL-2.1.0/UQPyL/sensibility/saABC.py +242 -0
  53. UQPyL-2.1.0/UQPyL/sensibility/sobol.py +297 -0
  54. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/__init__.py +2 -2
  55. UQPyL-2.1.0/UQPyL/surrogates/auto_tuner.py +145 -0
  56. UQPyL-2.1.0/UQPyL/surrogates/gp/gaussian_process.py +192 -0
  57. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/gp/kernel/base_kernel.py +28 -21
  58. UQPyL-2.1.0/UQPyL/surrogates/gp/kernel/c_kernel_.py +28 -0
  59. UQPyL-2.1.0/UQPyL/surrogates/gp/kernel/dot_kernel_.py +28 -0
  60. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/gp/kernel/matern_kernel.py +13 -15
  61. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/gp/kernel/rbf_kernel.py +5 -4
  62. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/gp/kernel/rq_kernel.py +8 -7
  63. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/kriging/kernel/base_kernel.py +29 -20
  64. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/kriging/kernel/cubic_kernel.py +3 -3
  65. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/kriging/kernel/exp_kernel.py +3 -3
  66. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/kriging/kernel/guass_kernel.py +3 -4
  67. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/kriging/kriging.py +42 -112
  68. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/mars/core/_basis.c +49 -49
  69. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/mars/core/_forward.c +80 -80
  70. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/mars/core/_knot_search.c +61 -61
  71. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/mars/core/_pruning.c +67 -67
  72. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/mars/core/_qr.c +48 -48
  73. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/mars/core/_record.c +59 -59
  74. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/mars/core/_types.c +39 -39
  75. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/mars/core/_util.c +40 -40
  76. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/mars/mars.py +204 -519
  77. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/rbf/kernel/base_kernel.py +7 -4
  78. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/rbf/kernel/cubic_kernel.py +6 -3
  79. UQPyL-2.1.0/UQPyL/surrogates/rbf/kernel/gaussian_kernel.py +19 -0
  80. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/rbf/kernel/linear_kernel.py +4 -3
  81. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/rbf/kernel/multiquadric_kernel.py +5 -3
  82. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/rbf/kernel/thin_plate_spline_kernel.py +7 -5
  83. UQPyL-2.1.0/UQPyL/surrogates/rbf/radial_basis_function.py +144 -0
  84. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/regression/lasso/lasso_fast.c +58 -58
  85. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/regression/linear_regression.py +64 -62
  86. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/regression/polynomial_regression.py +34 -35
  87. UQPyL-2.1.0/UQPyL/surrogates/setting.py +207 -0
  88. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/surrogateABC.py +57 -13
  89. UQPyL-2.1.0/UQPyL/surrogates/svr/support_vector_machine.py +145 -0
  90. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/util/boxmin.py +3 -6
  91. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/utility/__init__.py +5 -4
  92. UQPyL-2.1.0/UQPyL/utility/data_selections.py +64 -0
  93. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/utility/metrics.py +16 -10
  94. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/utility/polynomial_features.py +14 -14
  95. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/utility/scalers.py +23 -23
  96. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/utility/verbose.py +141 -153
  97. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL.egg-info/PKG-INFO +1 -2
  98. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL.egg-info/SOURCES.txt +4 -9
  99. {UQPyL-2.0.10 → UQPyL-2.1.0}/pyproject.toml +4 -1
  100. {UQPyL-2.0.10 → UQPyL-2.1.0}/setup.py +1 -1
  101. UQPyL-2.0.10/LICENSE.md +0 -21
  102. UQPyL-2.0.10/UQPyL/DoE/fast_sequence.py +0 -89
  103. UQPyL-2.0.10/UQPyL/DoE/morris_sequence.py +0 -99
  104. UQPyL-2.0.10/UQPyL/DoE/saltelli_sequence.py +0 -90
  105. UQPyL-2.0.10/UQPyL/DoE/sobol_sequence.py +0 -69
  106. UQPyL-2.0.10/UQPyL/optimization/algorithmABC.py +0 -130
  107. UQPyL-2.0.10/UQPyL/optimization/mathematics/__init__.py +0 -2
  108. UQPyL-2.0.10/UQPyL/optimization/mathematics/boxmin.py +0 -108
  109. UQPyL-2.0.10/UQPyL/optimization/multi_objective/moasmo.py +0 -185
  110. UQPyL-2.0.10/UQPyL/optimization/multi_objective/moea_d.py +0 -133
  111. UQPyL-2.0.10/UQPyL/optimization/multi_objective/nsga_ii.py +0 -123
  112. UQPyL-2.0.10/UQPyL/optimization/multi_objective/nsga_iii.py +0 -163
  113. UQPyL-2.0.10/UQPyL/optimization/multi_objective/rvea.py +0 -113
  114. UQPyL-2.0.10/UQPyL/optimization/population.py +0 -173
  115. UQPyL-2.0.10/UQPyL/optimization/result.py +0 -137
  116. UQPyL-2.0.10/UQPyL/optimization/single_objective/abc.py +0 -177
  117. UQPyL-2.0.10/UQPyL/optimization/single_objective/asmo.py +0 -108
  118. UQPyL-2.0.10/UQPyL/optimization/single_objective/csa.py +0 -156
  119. UQPyL-2.0.10/UQPyL/optimization/single_objective/de.py +0 -90
  120. UQPyL-2.0.10/UQPyL/optimization/single_objective/ego.py +0 -93
  121. UQPyL-2.0.10/UQPyL/optimization/single_objective/ga.py +0 -179
  122. UQPyL-2.0.10/UQPyL/optimization/single_objective/ml_sce_ua.py +0 -134
  123. UQPyL-2.0.10/UQPyL/optimization/single_objective/pso.py +0 -143
  124. UQPyL-2.0.10/UQPyL/optimization/single_objective/sce_ua.py +0 -175
  125. UQPyL-2.0.10/UQPyL/problems/pratical_problem.py +0 -34
  126. UQPyL-2.0.10/UQPyL/problems/problemABC.py +0 -131
  127. UQPyL-2.0.10/UQPyL/sensibility/delta_test.py +0 -146
  128. UQPyL-2.0.10/UQPyL/sensibility/fast.py +0 -162
  129. UQPyL-2.0.10/UQPyL/sensibility/mars_sa.py +0 -124
  130. UQPyL-2.0.10/UQPyL/sensibility/morris.py +0 -214
  131. UQPyL-2.0.10/UQPyL/sensibility/rbd_fast.py +0 -141
  132. UQPyL-2.0.10/UQPyL/sensibility/rsa.py +0 -144
  133. UQPyL-2.0.10/UQPyL/sensibility/saABC.py +0 -151
  134. UQPyL-2.0.10/UQPyL/sensibility/sobol.py +0 -252
  135. UQPyL-2.0.10/UQPyL/sensibility/util/_binary_ga.py +0 -70
  136. UQPyL-2.0.10/UQPyL/surrogates/auto_tuner.py +0 -100
  137. UQPyL-2.0.10/UQPyL/surrogates/gp/gaussian_process.py +0 -266
  138. UQPyL-2.0.10/UQPyL/surrogates/gp/kernel/c_kernel_.py +0 -25
  139. UQPyL-2.0.10/UQPyL/surrogates/gp/kernel/dot_kernel_.py +0 -27
  140. UQPyL-2.0.10/UQPyL/surrogates/rbf/kernel/gaussian_kernel.py +0 -17
  141. UQPyL-2.0.10/UQPyL/surrogates/rbf/radial_basis_function.py +0 -142
  142. UQPyL-2.0.10/UQPyL/surrogates/setting.py +0 -94
  143. UQPyL-2.0.10/UQPyL/surrogates/svr/support_vector_machine.py +0 -86
  144. UQPyL-2.0.10/UQPyL/surrogates/util/__init__.py +0 -9
  145. UQPyL-2.0.10/UQPyL/utility/grid_search.py +0 -84
  146. UQPyL-2.0.10/UQPyL/utility/model_selections.py +0 -64
  147. {UQPyL-2.0.10 → UQPyL-2.1.0}/README.md +0 -0
  148. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/DoE/__init__.py +0 -0
  149. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/optimization/metric/__init__.py +0 -0
  150. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/optimization/metric/gd.py +0 -0
  151. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/optimization/metric/igd.py +0 -0
  152. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/optimization/multi_objective/__init__.py +0 -0
  153. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/problems/multi_objective/__init__.py +0 -0
  154. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/problems/utility_functions/NDsort.py +0 -0
  155. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/problems/utility_functions/__init__.py +0 -0
  156. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/problems/utility_functions/uniformPoint.py +0 -0
  157. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/fnn/__init__.py +0 -0
  158. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/fnn/_activation_funcs.py +0 -0
  159. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/fnn/base.py +0 -0
  160. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/fnn/fully_connect_neural_network.py +0 -0
  161. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/gp/__init__.py +0 -0
  162. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/gp/kernel/__init__.py +0 -0
  163. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/kriging/__init__.py +0 -0
  164. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/kriging/kernel/__init__.py +0 -0
  165. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/mars/__init__.py +0 -0
  166. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/mars/core/__init__.py +0 -0
  167. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/rbf/__init__.py +0 -0
  168. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/rbf/kernel/__init__.py +0 -0
  169. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/regression/__init__.py +0 -0
  170. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/regression/lasso/__init__.py +0 -0
  171. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/svr/__init__.py +0 -0
  172. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/svr/core/__init__.py +0 -0
  173. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/svr/core/libsvm_interface.cpp +0 -0
  174. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL/surrogates/svr/core/svm.cpp +0 -0
  175. {UQPyL-2.0.10/UQPyL/sensibility → UQPyL-2.1.0/UQPyL/surrogates}/util/__init__.py +0 -0
  176. {UQPyL-2.0.10/UQPyL/optimization/mathematics → UQPyL-2.1.0/UQPyL/surrogates/util}/adam.py +0 -0
  177. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL.egg-info/dependency_links.txt +0 -0
  178. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL.egg-info/requires.txt +0 -0
  179. {UQPyL-2.0.10 → UQPyL-2.1.0}/UQPyL.egg-info/top_level.txt +0 -0
  180. {UQPyL-2.0.10 → UQPyL-2.1.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: UQPyL
3
- Version: 2.0.10
3
+ Version: 2.1.0
4
4
  Summary: A python package for parameter uncertainty quantification and optimization
5
5
  Author: wmtSky
6
6
  Author-email: wmtSky <wmtsky@hhu.edu.cn>
@@ -13,7 +13,6 @@ Classifier: Programming Language :: Python :: 3.12
13
13
  Classifier: License :: OSI Approved :: MIT License
14
14
  Classifier: Operating System :: OS Independent
15
15
  Description-Content-Type: text/markdown
16
- License-File: LICENSE.md
17
16
 
18
17
 
19
18
  # Uncertainty Quantification Python Laboratory (UQPyL)
@@ -0,0 +1,91 @@
1
+ import numpy as np
2
+ from typing import Union, Optional
3
+
4
+ from .samplerABC import Sampler, decoratorRescale
5
+ from ..problems import ProblemABC as Problem
6
+
7
+ class FAST_Sequence(Sampler):
8
+ """
9
+ The sample technique for FAST (Fourier Amplitude Sensitivity Test) method.
10
+
11
+ This class generates samples for the FAST method, which is used for sensitivity analysis
12
+ by decomposing the output variance into contributions from each input variable.
13
+
14
+ Methods:
15
+ sample: Generate a sample for the FAST method.
16
+ """
17
+
18
+ def __init__(self, M: int = 4):
19
+ """
20
+ Initialize the FAST Sequence sampler with a specified interference parameter.
21
+
22
+ :param M: The interference parameter for the Fourier series decomposition.
23
+ """
24
+ super().__init__()
25
+
26
+ self.M = M
27
+
28
+ def _generate(self, nt: int, nx: int):
29
+ """
30
+ Generate a sample for the FAST method.
31
+
32
+ :param nt: Number of sample points.
33
+ :param nx: Input dimensions of sampled points.
34
+ :return: A 2D array of samples, normalized so factor values are uniformly spaced between zero and one.
35
+ """
36
+ if nt <= 4 * self.M**2:
37
+ raise ValueError("The number of samples must be greater than 4 * M^2!")
38
+
39
+ w = np.zeros(nx)
40
+ w[0] = np.floor((nt - 1) / (2 * self.M))
41
+ max_wi = np.floor(w[0] / (2 * self.M)) # Saltelli's method
42
+
43
+ if max_wi >= nx - 1:
44
+ w[1:] = np.floor(np.linspace(1, max_wi, nx - 1))
45
+ else:
46
+ w[1:] = np.arange(nx - 1) % max_wi + 1
47
+
48
+ s = (2 * np.pi / nt) * np.arange(nt)
49
+
50
+ xInit = np.zeros((nt * nx, nx))
51
+ w_tmp = np.zeros(nx)
52
+
53
+ for i in range(nx):
54
+ w_tmp[i] = w[0]
55
+ idx = list(range(i)) + list(range(i + 1, nx))
56
+ w_tmp[idx] = w[1:]
57
+ idx = range(i * nt, (i + 1) * nt)
58
+ phi = 2 * np.pi * np.random.rand()
59
+ sin_result = np.sin(w_tmp[:, None] * s + phi)
60
+ arsin_result = (1 / np.pi) * np.arcsin(sin_result) # Saltelli's formula
61
+ xInit[idx, :] = 0.5 + arsin_result.transpose()
62
+
63
+ return xInit
64
+
65
+ @decoratorRescale
66
+ def sample(self, nt: int, nx: Optional[int] = None, problem: Optional[Problem] = None, random_seed: Optional[int] = None):
67
+ """
68
+ Generate a sample for the FAST method.
69
+
70
+ :param nt: Number of sample points.
71
+ :param nx: Input dimensions of sampled points.
72
+ :param problem: Problem instance to use bounds for sampling.
73
+ :param random_seed: Random seed for reproducibility.
74
+ :return: A 2D array of FAST samples.
75
+ """
76
+ if random_seed is not None:
77
+ self.random_state = np.random.RandomState(random_seed)
78
+ else:
79
+ self.random_state = np.random.RandomState()
80
+
81
+ if problem is not None and nx is not None:
82
+ if problem.nInput != nx:
83
+ raise ValueError('The input dimensions of the problem and the samples must be the same')
84
+ elif problem is None and nx is None:
85
+ raise ValueError('Either the problem or the input dimensions must be provided')
86
+
87
+ nx = problem.nInput if problem is not None else nx
88
+
89
+ return self._generate(nt, nx)
90
+
91
+
@@ -6,31 +6,33 @@ from .samplerABC import Sampler, decoratorRescale
6
6
  from ..problems import ProblemABC as Problem
7
7
 
8
8
  class FFD(Sampler):
9
- '''
10
- Full Factorial Design
9
+ """
10
+ Full Factorial Design (FFD) for experimental design.
11
11
 
12
- Methods:
13
- __call__ or sample: Generate a Latin-hypercube design
14
-
15
- '''
12
+ This class generates a full factorial design, which is a systematic way to explore
13
+ all possible combinations of factors at different levels.
16
14
 
17
- #Abandon
18
- # def __call__(self, nx: int, levels: Union[np.ndarray, int, list]) -> np.ndarray:
19
-
20
- # return self._generate(nx, levels)
15
+ Methods:
16
+ sample: Generate a full factorial design.
17
+ """
21
18
 
22
19
  def _generate(self, levels: Union[np.ndarray, int, list], nx: int):
23
-
20
+ """
21
+ Internal method to generate the full factorial design.
22
+
23
+ :param levels: Levels for each input dimension. Can be an integer, list, or ndarray.
24
+ :param nx: Number of input dimensions.
25
+ :return: A 2D array of full factorial design samples.
26
+ """
24
27
  if isinstance(levels, int):
25
- levels = [levels]*nx
28
+ levels = [levels] * nx
26
29
  elif isinstance(levels, np.ndarray):
27
30
  levels = levels.ravel().tolist()
28
31
 
29
- if len(levels)!=nx:
32
+ if len(levels) != nx:
30
33
  raise ValueError('The length of levels should be equal to nx or 1')
31
34
 
32
35
  factor_levels = [np.linspace(0, 1, num=level)[:level] for level in levels]
33
-
34
36
  factor_combinations = list(product(*factor_levels))
35
37
 
36
38
  H = np.array(factor_combinations)
@@ -39,30 +41,26 @@ class FFD(Sampler):
39
41
 
40
42
  @decoratorRescale
41
43
  def sample(self, levels: Union[np.ndarray, int, list], nx: Optional[int] = None, problem: Optional[Problem] = None, random_seed: Optional[int] = None):
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
- '''
44
+ """
45
+ Generate a full factorial design sample.
54
46
 
47
+ :param levels: Levels for each input dimension. Can be an integer, list, or ndarray.
48
+ :param nx: Number of input dimensions.
49
+ :param problem: Problem instance to use bounds for sampling.
50
+ :param random_seed: Random seed for reproducibility.
51
+ :return: A 2D array of full factorial design samples.
52
+ """
55
53
  if random_seed is not None:
56
54
  self.random_state = np.random.RandomState(random_seed)
57
55
  else:
58
56
  self.random_state = np.random.RandomState()
59
57
 
60
58
  if problem is not None and nx is not None:
61
- if(problem.nInput!=nx):
59
+ if problem.nInput != nx:
62
60
  raise ValueError('The input dimensions of the problem and the samples must be the same')
63
61
  elif problem is None and nx is None:
64
62
  raise ValueError('Either the problem or the input dimensions must be provided')
65
63
 
66
- nx=problem.nInput if problem is not None else nx
64
+ nx = problem.nInput if problem is not None else nx
67
65
 
68
66
  return self._generate(levels, nx)
@@ -1,20 +1,24 @@
1
- import numpy as np
2
1
  from typing import Literal, Optional
2
+ import numpy as np
3
3
  from scipy.spatial.distance import pdist
4
4
 
5
- from ..problems import ProblemABC as Problem
6
-
7
5
  from .samplerABC import Sampler, decoratorRescale
8
-
9
- # from ._lhs import _lhs_classic, _lhs_centered, _lhs_correlate, _lhs_maximin, _lhs_centered_maximin
10
-
11
-
6
+ from ..problems import ProblemABC as Problem
12
7
 
13
8
  def _lhs_classic(nt: int, nx: int, random_state=None) -> np.ndarray:
14
- # Generate the intervals
9
+ """
10
+ Generate a classic Latin Hypercube Sampling (LHS) design.
11
+
12
+ :param nt: Number of samples.
13
+ :param nx: Number of dimensions.
14
+ :param random_state: Random state for reproducibility.
15
+ :return: A 2D array of LHS samples.
16
+ """
15
17
  if random_state is None:
16
- random_state=np.random.RandomState()
17
- cut = np.linspace(0, 1, nt + 1)
18
+ random_state = np.random.RandomState()
19
+
20
+ # Generate the intervals
21
+ cut = np.linspace(0, 1, nt + 1)
18
22
 
19
23
  # Fill points uniformly in each interval
20
24
  u = random_state.rand(nt, nx)
@@ -22,7 +26,7 @@ def _lhs_classic(nt: int, nx: int, random_state=None) -> np.ndarray:
22
26
  b = cut[1:nt + 1]
23
27
  rdpoints = np.zeros_like(u)
24
28
  for j in range(nx):
25
- rdpoints[:, j] = u[:, j]*(b-a) + a
29
+ rdpoints[:, j] = u[:, j] * (b - a) + a
26
30
 
27
31
  # Make the random pairings
28
32
  H = np.zeros_like(rdpoints)
@@ -35,9 +39,16 @@ def _lhs_classic(nt: int, nx: int, random_state=None) -> np.ndarray:
35
39
  ################################################################################
36
40
 
37
41
  def _lhs_centered(nt: int, nx: int, random_state=None) -> np.ndarray:
38
-
42
+ """
43
+ Generate a centered Latin Hypercube Sampling (LHS) design.
44
+
45
+ :param nt: Number of samples.
46
+ :param nx: Number of dimensions.
47
+ :param random_state: Random state for reproducibility.
48
+ :return: A 2D array of centered LHS samples.
49
+ """
39
50
  if random_state is None:
40
- random_state=np.random.RandomState()
51
+ random_state = np.random.RandomState()
41
52
 
42
53
  # Generate the intervals
43
54
  cut = np.linspace(0, 1, nt + 1)
@@ -58,7 +69,15 @@ def _lhs_centered(nt: int, nx: int, random_state=None) -> np.ndarray:
58
69
  ################################################################################
59
70
 
60
71
  def _lhs_maximin(nt: int, nx: int, iterations: int, random_state=None)-> np.ndarray:
61
-
72
+ """
73
+ Generate a maximin Latin Hypercube Sampling (LHS) design.
74
+
75
+ :param nt: Number of samples.
76
+ :param nx: Number of dimensions.
77
+ :param iterations: Number of iterations to maximize the minimum distance.
78
+ :param random_state: Random state for reproducibility.
79
+ :return: A 2D array of maximin LHS samples.
80
+ """
62
81
  if random_state is None:
63
82
  random_state=np.random.RandomState()
64
83
 
@@ -77,7 +96,15 @@ def _lhs_maximin(nt: int, nx: int, iterations: int, random_state=None)-> np.ndar
77
96
  return H
78
97
 
79
98
  def _lhs_centered_maximin(nt: int, nx: int, iterations: int, random_state=None)-> np.ndarray:
80
-
99
+ """
100
+ Generate a centered maximin Latin Hypercube Sampling (LHS) design.
101
+
102
+ :param nt: Number of samples.
103
+ :param nx: Number of dimensions.
104
+ :param iterations: Number of iterations to maximize the minimum distance.
105
+ :param random_state: Random state for reproducibility.
106
+ :return: A 2D array of centered maximin LHS samples.
107
+ """
81
108
  if random_state is None:
82
109
  random_state=np.random.RandomState()
83
110
 
@@ -96,7 +123,15 @@ def _lhs_centered_maximin(nt: int, nx: int, iterations: int, random_state=None)-
96
123
  ################################################################################
97
124
 
98
125
  def _lhs_correlate(nt: int, nx: int, iterations: int, random_state=None) -> np.ndarray:
99
-
126
+ """
127
+ Generate a correlation-optimized Latin Hypercube Sampling (LHS) design.
128
+
129
+ :param nt: Number of samples.
130
+ :param nx: Number of dimensions.
131
+ :param iterations: Number of iterations to minimize correlation.
132
+ :param random_state: Random state for reproducibility.
133
+ :return: A 2D array of correlation-optimized LHS samples.
134
+ """
100
135
  if random_state is None:
101
136
  random_state=np.random.RandomState()
102
137
 
@@ -119,81 +154,59 @@ LHS_METHOD={'classic': _lhs_classic, 'center': _lhs_centered, 'maximin': _lhs_ma
119
154
  'center_maximin': _lhs_centered_maximin, 'correlation': _lhs_correlate}
120
155
 
121
156
  class LHS(Sampler):
122
- '''
123
- Latin-hypercube design
124
-
125
- Parameters:
126
- criterion : str
127
- Allowable values are "classic", "center", "maximin", "center_maximin",
128
- and "correlation". (Default: classic)
129
-
130
- iterations : int
131
- The number of iterations in the maximin, center_maximin and correlations methods
132
- (Default: 5).
133
-
134
- problem : problem
135
- if the problem is provided, the bounds of the problem will be used to generate the samples
157
+ """
158
+ Latin-hypercube design class for generating samples.
136
159
 
137
160
  Methods:
138
- __call__ or sample: Generate a Latin-hypercube design
161
+ sample: Generate a Latin-hypercube design
162
+
139
163
 
140
- '''
164
+ """
141
165
  def __init__(self, criterion: Criterion ='classic', iterations: int=5):
166
+ """
167
+ Initialize the LHS sampler with a specified criterion and number of iterations.
142
168
 
169
+ :param criterion: The LHS criterion to use.
170
+ :param iterations: Number of iterations for optimization methods.
171
+ """
143
172
  self.criterion=criterion
144
173
  self.iterations=iterations
145
174
 
146
175
  #initial random state
147
176
  super().__init__()
148
177
 
149
- def _generate(self, nt: int, nx:int=None):
150
- '''
151
- Generate a Latin-hypercube design
178
+ def _generate(self, nt: int, nx: int = None):
179
+ """
180
+ Generate a Latin-hypercube design.
152
181
 
153
- Parameters
154
- nt: int
155
- the number of sampled points
156
- nx: int
157
- the input dimensions of sampled points
158
-
159
- Returns:
160
- H: 2d-array
161
- An n-by-samples design matrix that has been normalized so factor values
162
- are uniformly spaced between zero and one.
163
- '''
182
+ :param nt: Number of sampled points.
183
+ :param nx: Input dimensions of sampled points.
184
+ :return: A 2D array of LHS samples.
185
+ """
164
186
 
165
187
  if self.criterion not in LHS_METHOD:
166
188
  raise ValueError('The criterion must be one of {}'.format(LHS_METHOD.keys()))
167
189
 
168
- Sampling_method=LHS_METHOD[self.criterion]
190
+ Sampling_method = LHS_METHOD[self.criterion]
169
191
 
170
192
  if self.criterion in ['maximin', 'center_maximin', 'correlation']:
171
- xInit=Sampling_method(nt, nx, self.iterations, self.random_state)
193
+ xInit = Sampling_method(nt, nx, self.iterations, self.random_state)
172
194
  else:
173
- xInit=Sampling_method(nt, nx, self.random_state)
195
+ xInit = Sampling_method(nt, nx, self.random_state)
174
196
 
175
197
  return xInit
176
198
 
177
199
  @decoratorRescale
178
- def sample(self, nt: int, nx:int = None, problem: Problem = None, random_seed: Optional[int] = None) -> np.ndarray:
179
- '''
180
- Generate a Latin-hypercube design
200
+ def sample(self, nt: int, nx: int = None, problem: Problem = None, random_seed: Optional[int] = None) -> np.ndarray:
201
+ """
202
+ Generate a Latin-hypercube design.
181
203
 
182
- Parameters
183
- nt: int
184
- the number of sampled points
185
-
186
- nx: int
187
- the input dimensions of sampled points
188
-
189
- random_seed: int
190
- the random seed for the random number generator
191
-
192
- Returns:
193
- H: 2d-array
194
- An n-by-samples design matrix that has been normalized so factor values
195
- are uniformly spaced between zero and one.
196
- '''
204
+ :param nt: Number of sampled points.
205
+ :param nx: Input dimensions of sampled points.
206
+ :param problem: Problem instance to use bounds for sampling.
207
+ :param random_seed: Random seed for reproducibility.
208
+ :return: A 2D array of LHS samples.
209
+ """
197
210
 
198
211
  if random_seed is not None:
199
212
  self.random_state = np.random.RandomState(random_seed)
@@ -201,11 +214,11 @@ class LHS(Sampler):
201
214
  self.random_state = np.random.RandomState()
202
215
 
203
216
  if problem is not None and nx is not None:
204
- if(problem.nInput!=nx):
217
+ if problem.nInput != nx:
205
218
  raise ValueError('The input dimensions of the problem and the samples must be the same')
206
219
  elif problem is None and nx is None:
207
220
  raise ValueError('Either the problem or the input dimensions must be provided')
208
221
 
209
- nx=problem.nInput if problem is not None else nx
222
+ nx = problem.nInput if problem is not None else nx
210
223
 
211
224
  return self._generate(nt, nx)
@@ -0,0 +1,105 @@
1
+ import numpy as np
2
+ from typing import Optional
3
+
4
+ from .samplerABC import Sampler, decoratorRescale
5
+ from ..problems import ProblemABC as Problem
6
+
7
+ class Morris_Sequence(Sampler):
8
+ """
9
+ The sample technique for Morris analysis.
10
+
11
+ Methods:
12
+ sample: Generate a sample for the Morris method.
13
+
14
+ Examples:
15
+ >>> mor_seq = Morris_Sequence(numLevels=4)
16
+ >>> mor_seq.sample(100, 4) or mor_seq(100, 4)
17
+
18
+ Reference:
19
+ [1] Max D. Morris (1991) Factorial Sampling Plans for Preliminary Computational Experiments, Technometrics, 33:2, 161-174
20
+ """
21
+ def __init__(self, numLevels: int = 4):
22
+ """
23
+ Initialize the Morris Sequence sampler with a specified number of levels.
24
+
25
+ :param numLevels: Number of levels for the Morris method.
26
+ """
27
+ super().__init__()
28
+ self.numLevels = numLevels
29
+
30
+ def _generate(self, nt: int, nx: int):
31
+ """
32
+ Generate a sample for the Morris method.
33
+
34
+ :param nt: Number of trajectories.
35
+ :param nx: Input dimensions of sampled points.
36
+ :return: A 2D array of samples, normalized so factor values are uniformly spaced between zero and one.
37
+ """
38
+ xInit = np.zeros((nt * (nx + 1), nx))
39
+
40
+ for i in range(nt):
41
+ xInit[i * (nx + 1):(i + 1) * (nx + 1), :] = self._generate_trajectory(nx)
42
+
43
+ return xInit
44
+
45
+ @decoratorRescale
46
+ def sample(self, nt: int, nx: Optional[int] = None, problem: Optional[Problem] = None, random_seed: Optional[int] = None):
47
+ """
48
+ Generate a sample for the Morris method.
49
+
50
+ :param nt: Number of trajectories.
51
+ :param nx: Input dimensions of sampled points.
52
+ :param problem: Problem instance to use bounds for sampling.
53
+ :param random_seed: Random seed for reproducibility.
54
+ :return: A 2D array of samples.
55
+ """
56
+ if random_seed is not None:
57
+ self.random_state = np.random.RandomState(random_seed)
58
+ else:
59
+ self.random_state = np.random.RandomState()
60
+
61
+ if problem is not None and nx is not None:
62
+ if problem.nInput != nx:
63
+ raise ValueError('The input dimensions of the problem and the samples must be the same')
64
+ elif problem is None and nx is None:
65
+ raise ValueError('Either the problem or the input dimensions must be provided')
66
+
67
+ nx = problem.nInput if problem is not None else nx
68
+
69
+ return self._generate(nt, nx)
70
+
71
+ def _generate_trajectory(self, nx: int):
72
+ """
73
+ Generate a single trajectory for the Morris method.
74
+
75
+ :param nx: Input dimensions of sampled points.
76
+ :return: A 2D array representing a single trajectory.
77
+ """
78
+ delta = self.numLevels / (2 * (self.numLevels - 1))
79
+
80
+ B = np.tril(np.ones([nx + 1, nx], dtype=int), -1)
81
+
82
+ # From paper[1] page 164
83
+ D_star = np.diag(np.random.choice([-1, 1], nx)) # Step 1
84
+ J = np.ones((nx + 1, nx))
85
+
86
+ levels_grids = np.linspace(0, 1 - delta, int(self.numLevels / 2))
87
+ x_star = np.random.choice(levels_grids, nx).reshape(1, -1) # Step 2
88
+
89
+ P_star = np.zeros((nx, nx))
90
+ cols = np.random.choice(nx, nx, replace=False)
91
+ P_star[np.arange(nx), cols] = 1 # Step 3
92
+
93
+ element_a = J[0, :] * x_star
94
+ element_b = P_star.T
95
+ element_c = np.matmul(2.0 * B, element_b)
96
+ element_d = np.matmul((element_c - J), D_star)
97
+
98
+ B_star = element_a + (delta / 2.0) * (element_d + J)
99
+
100
+ return B_star
101
+
102
+
103
+
104
+
105
+
@@ -5,39 +5,50 @@ from .samplerABC import Sampler, decoratorRescale
5
5
  from ..problems import ProblemABC as Problem
6
6
 
7
7
  class Random(Sampler):
8
- '''
8
+ """
9
9
  Random Design
10
10
 
11
- Method:
12
- __call__ or sample: Generate a random design
11
+ Methods:
12
+ sample: Generate a random design.
13
13
 
14
14
  Examples:
15
- >>> random=RANDOM()
16
- >>> random(10,10) or random.sample(10,10)
17
- '''
18
- def _generate(self,nt: int, nx: int):
15
+ >>> random = Random()
16
+ >>> random.sample(10, 10) or random(10, 10)
17
+ """
18
+ def _generate(self, nt: int, nx: int):
19
+ """
20
+ Generate a random sample.
19
21
 
20
- H=np.random.random((nt,nx))
22
+ :param nt: Number of sampled points.
23
+ :param nx: Input dimensions of sampled points.
24
+ :return: A 2D array of random samples.
25
+ """
26
+ H = np.random.random((nt, nx))
21
27
 
22
28
  return H
23
29
 
24
30
  @decoratorRescale
25
31
  def sample(self, nt: int, nx: Optional[int] = None, problem: Optional[Problem] = None, random_seed: Optional[int] = None):
26
- '''
27
- Generate a sample with random values between zero and one
28
- '''
32
+ """
33
+ Generate a sample with random values between zero and one.
29
34
 
35
+ :param nt: Number of sampled points.
36
+ :param nx: Input dimensions of sampled points.
37
+ :param problem: Problem instance to use bounds for sampling.
38
+ :param random_seed: Random seed for reproducibility.
39
+ :return: A 2D array of random samples.
40
+ """
30
41
  if random_seed is not None:
31
42
  self.random_state = np.random.RandomState(random_seed)
32
43
  else:
33
44
  self.random_state = np.random.RandomState()
34
45
 
35
46
  if problem is not None and nx is not None:
36
- if(problem.nInput!=nx):
47
+ if problem.nInput != nx:
37
48
  raise ValueError('The input dimensions of the problem and the samples must be the same')
38
49
  elif problem is None and nx is None:
39
50
  raise ValueError('Either the problem or the input dimensions must be provided')
40
51
 
41
- nx=problem.nInput if problem is not None else nx
52
+ nx = problem.nInput if problem is not None else nx
42
53
 
43
54
  return self._generate(nt, nx)