File: plot_optimal_lhs.py

package info (click to toggle)
openturns 1.24-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 66,204 kB
  • sloc: cpp: 256,662; python: 63,381; ansic: 4,414; javascript: 406; sh: 180; xml: 164; yacc: 123; makefile: 98; lex: 55
file content (151 lines) | stat: -rw-r--r-- 4,858 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
"""
Optimize an LHS design of experiments
=====================================
"""

# %%
# This examples show how to generate optimized LHS experiments according to the different criteria.

# %%
import openturns as ot
import openturns.viewer as viewer
from matplotlib import pylab as plt

ot.Log.Show(ot.Log.NONE)

# %%
# **LHS and space filling**

# %%
N = 100
# Considering independent Uniform distributions of dimension 3
# Bounds are (-1,1), (0,2) and (0, 0.5)
distribution = ot.JointDistribution(
    [ot.Uniform(-1.0, 1.0), ot.Uniform(0.0, 2.0), ot.Uniform(0.0, 0.5)]
)
# Random LHS
lhs = ot.LHSExperiment(distribution, N)
lhs.setAlwaysShuffle(True)  # randomized
design = lhs.generate()
# C2
c2 = ot.SpaceFillingC2().evaluate(design)
# PhiP with default p
phip = ot.SpaceFillingPhiP().evaluate(design)
# mindist
mindist = ot.SpaceFillingMinDist().evaluate(design)
# For p->infinity
phip_inf = ot.SpaceFillingPhiP(100).evaluate(design)
print(phip, mindist, phip_inf)

# %%
# **Optimized LHS using Monte Carlo**

# %%
# As with Monte Carlo, user decides of a fixed number of iterations,
# but this time this number is part of the temperature profile.
#
# Two profiles are currently provided:
# - Linear profile: :math:`T_i = T_0 (1-\frac{1}{n_{iter}})`
# - Geometric profile: :math:`T_i = T_O c^i, 0<c<1`
#
# Starting from an LHS design, a new design is built by permuting a random coordinate of two randomly chosen sample points;
# this new design is also an LHS, but not necessarily a more efficient design.
#
# A comparison of criteria of the two designs is done, and the new LHS is accepted with probability
#
# .. math::
#    min\left(exp{\left[-\frac{\Phi(LHS_{new}) - \Phi(LHS)}{T_i}\right]}, 1\right)
#

# %%
# Considering independent Uniform(0,1) distributions of dimension 3
distribution = ot.JointDistribution([ot.Uniform(0.0, 1.0)] * 3)
# Random LHS
lhs = ot.LHSExperiment(distribution, N)
lhs.setAlwaysShuffle(True)  # randomized
algo = ot.SimulatedAnnealingLHS(lhs)
design = algo.generate()

# %%
# One could also fix the criterion, the temperature profile and get more results.

# Considering independent Uniform distributions of dimension 3
# Bounds are (-1,1), (0,2) and (0, 0.5)
distribution = ot.JointDistribution(
    [ot.Uniform(-1.0, 1.0), ot.Uniform(0.0, 2.0), ot.Uniform(0.0, 0.5)]
)
# Random LHS
lhs = ot.LHSExperiment(distribution, N)
lhs.setAlwaysShuffle(True)  # randomized
# Fixing C2 crit
space_filling = ot.SpaceFillingC2()
# Defining a temperature profile
# A geometric profile seems accurate with default parameters
# e.g. T0=10, c=0.95, iMax=2000
temperatureProfile = ot.GeometricProfile()
algo = ot.SimulatedAnnealingLHS(lhs, space_filling, temperatureProfile)
# optimal design
design = algo.generate()
result = algo.getResult()
# Criteria for the optimal design
crit_c2 = result.getC2()
crit_phip = result.getPhiP()
crit_mindist = result.getMinDist()
# History of the criterion used for optimization
history = result.getAlgoHistory()
criterion_hist = history[:, 0]
# Additional results
temperature_hist = history[:, 1]
probability_hist = history[:, 2]

# %%
# It is also possible to chain several iterations of the whole process with different starting points.
N = 10

# Considering independent Uniform distributions of dimension 3
# Bounds are (-1,1), (0,2) and (0, 0.5)
distribution = ot.JointDistribution(
    [ot.Uniform(-1.0, 1.0), ot.Uniform(0.0, 2.0), ot.Uniform(0.0, 0.5)]
)
# Random LHS
lhs = ot.LHSExperiment(distribution, N)
lhs.setAlwaysShuffle(True)  # randomized
# Fixing PhiP crit
space_filling = ot.SpaceFillingPhiP()
# Defining a temperature profile
# T0=10, iMax=3000
temperatureProfile = ot.LinearProfile(10.0, 3000)
algo = ot.SimulatedAnnealingLHS(lhs, space_filling, temperatureProfile)
restart = 50
design = algo.generateWithRestart(restart)
# Retrieve all optimal designs
result = algo.getResult()
designs = [result.getOptimalDesign(i) for i in range(restart)]

# %%
# Finally, we could start the optimization process of LHS using a precomputed LHS design.

# Considering independent Uniform distributions of dimension 3
# Bounds are (0,1)^3
distribution = ot.JointDistribution([ot.Uniform(0.0, 1.0)] * 3)
# Random LHS
lhs = ot.LHSExperiment(distribution, N)
lhs.setAlwaysShuffle(True)  # randomized
# Fixing C2 crit for example
space_filling = ot.SpaceFillingC2()
# Defining a temperature profile
# T0=10, iMax=3000
temperatureProfile = ot.LinearProfile(10.0, 3000)
algo = ot.SimulatedAnnealingLHS(lhs, space_filling, temperatureProfile)
design = algo.generate()
result = algo.getResult()
# check history ==> draw criterion
graph = result.drawHistoryCriterion()
view = viewer.View(graph)

# %%
# Convergence needs to be performed
# New algo starting from this design
algo = ot.SimulatedAnnealingLHS(design, distribution, space_filling, temperatureProfile)
design = algo.generate()
plt.show()