99from popt .misc_tools import optim_tools as ot
1010from pipt .misc_tools import analysis_tools as at
1111from ensemble .ensemble import Ensemble as PETEnsemble
12+ from simulator .simple_models import noSimulation
1213
13- class EnsembleOptimizationBase (PETEnsemble ):
14+ class EnsembleOptimizationBaseClass (PETEnsemble ):
1415 '''
1516 Base class for the popt ensemble
1617 '''
17- def __init__ (self , kwargs_ens , sim , obj_func ):
18+ def __init__ (self , options , simulator , objective ):
1819 '''
1920 Parameters
2021 ----------
21- kwargs_ens : dict
22+ options : dict
2223 Options for the ensemble class
2324
24- sim : callable
25- The forward simulator (e.g. flow)
25+ simulator : callable
26+ The forward simulator (e.g. flow). If None, no simulation is performed.
2627
27- obj_func : callable
28+ objective : callable
2829 The objective function (e.g. npv)
2930 '''
31+ if simulator is None :
32+ sim = noSimulation ()
33+ else :
34+ sim = simulator
3035
3136 # Initialize PETEnsemble
32- super ().__init__ (kwargs_ens , sim )
33-
34- self .save_prediction = kwargs_ens .get ('save_prediction' , None )
35- self .num_models = kwargs_ens .get ('num_models' , 1 )
36- self .transform = kwargs_ens .get ('transform' , False )
37- self .num_samples = self .ne
37+ super ().__init__ (options , sim )
3838
39- # Get bounds and varaince
40- self .upper_bound = []
41- self .lower_bound = []
39+ # Unpack some options
40+ self .save_prediction = options .get ('save_prediction' , None )
41+ self .num_models = options .get ('num_models' , 1 )
42+ self .transform = options .get ('transform' , False )
43+ self .num_samples = self .ne
44+
45+ # Define some variables
46+ self .lb = []
47+ self .ub = []
4248 self .bounds = []
4349 self .cov = np .array ([])
44- for name in self .prior_info .keys ():
45- self .state [name ] = np .asarray (self .prior_info [name ]['mean' ])
46- num_state_var = len (self .state [name ])
47- value_cov = self .prior_info [name ]['variance' ] * np .ones ((num_state_var ,))
48- if 'limits' in self .prior_info [name ].keys ():
49- lb = self .prior_info [name ]['limits' ][0 ]
50- ub = self .prior_info [name ]['limits' ][1 ]
51- self .lower_bound .append (lb )
52- self .upper_bound .append (ub )
50+
51+ # Get bounds and varaince, and initialize state
52+ for key in self .prior_info .keys ():
53+ variable = self .prior_info [key ]
54+
55+ # mean
56+ self .state [key ] = np .asarray (variable ['mean' ])
57+
58+ # Covariance
59+ dim = self .state [key ].size
60+ cov = variable ['variance' ]* np .ones (dim )
61+
62+ if 'limits' in variable .keys ():
63+ lb , ub = variable ['limits' ]
64+ self .lb (lb )
65+ self .ub (ub )
66+
67+ # transform cov to [0, 1] if transform is True
5368 if self .transform :
54- value_cov = value_cov / (ub - lb )** 2
55- np .clip (value_cov , 0 , 1 , out = value_cov )
56- self .bounds += num_state_var * [(0 , 1 )]
69+ cov = np .clip (cov / (ub - lb )** 2 , 0 , 1 , out = cov )
70+ self .bounds += dim * [(0 , 1 )]
5771 else :
58- self .bounds += num_state_var * [(lb , ub )]
59- self .cov = np .append (self .cov , value_cov )
72+ self .bounds += dim * [(lb , ub )]
6073 else :
61- self .bounds += num_state_var * [(None , None )]
74+ self .bounds += dim * [(None , None )]
75+
76+ # Add to covariance
77+ self .cov = np .append (self .cov , cov )
6278
63-
64- self ._scale_state ()
79+ # Make cov full covariance matrix
6580 self .cov = np .diag (self .cov )
6681
82+ # Scale the state to [0, 1] if transform is True
83+ self ._scale_state ()
84+
6785 # Set objective function (callable)
68- self .obj_func = obj_func
86+ self .obj_func = objective
6987
7088 # Objective function values
7189 self .state_func_values = None
@@ -78,8 +96,13 @@ def get_state(self):
7896 x : numpy.ndarray
7997 Control vector as ndarray, shape (number of controls, number of perturbations)
8098 """
81- x = ot .aug_optim_state (self .state , list (self .state .keys ()))
82- return x
99+ return ot .aug_optim_state (self .state , list (self .state .keys ()))
100+
101+ def vec_to_state (self , x ):
102+ """
103+ Converts a control vector to the internal state representation.
104+ """
105+ return ot .update_optim_state (x , self .state , list (self .state .keys ()))
83106
84107 def get_bounds (self ):
85108 """
@@ -112,7 +135,10 @@ def function(self, x, *args):
112135 else :
113136 self .ne = x .shape [1 ]
114137
115- self .state = ot .update_optim_state (x , self .state , list (self .state .keys ())) # go from nparray to dict
138+ # convert x to state
139+ self .state = self .vec_to_state (x ) # go from nparray to dict
140+
141+ # run the simulation
116142 self ._invert_scale_state () # ensure that state is in [lb,ub]
117143 run_success = self .calc_prediction (save_prediction = self .save_prediction ) # calculate flow data
118144 self ._scale_state () # scale back to [0, 1]
@@ -147,17 +173,17 @@ def _scale_state(self):
147173 """
148174 Transform the internal state from [lb, ub] to [0, 1]
149175 """
150- if self .transform and (self .upper_bound and self .lower_bound ):
176+ if self .transform and (self .lb and self .ub ):
151177 for i , key in enumerate (self .state ):
152- self .state [key ] = (self .state [key ] - self .lower_bound [i ])/ (self .upper_bound [i ] - self .lower_bound [i ])
178+ self .state [key ] = (self .state [key ] - self .lb [i ])/ (self .ub [i ] - self .lb [i ])
153179 np .clip (self .state [key ], 0 , 1 , out = self .state [key ])
154180
155181 def _invert_scale_state (self ):
156182 """
157183 Transform the internal state from [0, 1] to [lb, ub]
158184 """
159- if self .transform and (self .upper_bound and self .lower_bound ):
185+ if self .transform and (self .lb and self .ub ):
160186 for i , key in enumerate (self .state ):
161187 if self .transform :
162- self .state [key ] = self .lower_bound [i ] + self .state [key ]* (self .upper_bound [i ] - self .lower_bound [i ])
163- np .clip (self .state [key ], self .lower_bound [i ], self .upper_bound [i ], out = self .state [key ])
188+ self .state [key ] = self .lb [i ] + self .state [key ]* (self .ub [i ] - self .lb [i ])
189+ np .clip (self .state [key ], self .lb [i ], self .ub [i ], out = self .state [key ])
0 commit comments