Skip to content

Commit 8c018eb

Browse files
authored
Upgraded and corrected version
Added inner_bounding and changed the code to use Ordered Dictionnaries to prevent random ordering of keys and values, making the function more stable and prevent some potential issues.
1 parent 53c185a commit 8c018eb

File tree

1 file changed

+81
-32
lines changed

1 file changed

+81
-32
lines changed

ipython/Kwarg optimization wrapper.ipynb

Lines changed: 81 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"from randon import randint, uniform\n",
3737
"\n",
3838
"\n",
39-
"def adpt_distr(boundict, Method=True, Size=1, out='df', hardfloat=True):\n",
39+
"def adpt_distr(boundict, Method: bool=True, Size=1, out='df', hardfloat=True):\n",
4040
" \"\"\"\n",
4141
" Takes input with bounds, check bounds, if bounds are (float) sample from uniform 0,1\n",
4242
" otherwise if bounds are (bool) sample from randint 0,1 and otherwise sample from randint bound to bound\n",
@@ -152,15 +152,20 @@
152152
},
153153
"outputs": [],
154154
"source": [
155+
"from collections import OrderedDict as OD\n",
156+
"import numpy as np\n",
157+
"\n",
158+
"\n",
155159
"def dicwrap(funck,\n",
156-
" dicti,\n",
157-
" lenit=1,\n",
158-
" inpt='',\n",
159-
" i_as_meth_arg=False,\n",
160-
" factory=True,\n",
161-
" Cmeth=\"RUN\",\n",
162-
" staticD:=dict(),\n",
163-
" hardfloat=False):\n",
160+
" boundings,\n",
161+
" lenit: int=1,\n",
162+
" inpt=None,\n",
163+
" i_as_meth_arg: bool=False,\n",
164+
" factory: bool=True,\n",
165+
" Cmeth: str=\"RUN\",\n",
166+
" staticD: dict=dict(),\n",
167+
" hardfloat=False,\n",
168+
" inner_bounding=False):\n",
164169
" \"\"\"take in function and dict and return:\n",
165170
" if factory is True :\n",
166171
" the primed function is returned, this function is the one given to minimize\n",
@@ -174,8 +179,10 @@
174179
" args:\n",
175180
" funck:\n",
176181
" function to optimize\n",
177-
" dicti:\n",
178-
" dictionnary with kwargs, and bounds as tuple ex: {'lenght':(0,12),'height':(4,6),'condition':(bool),'size':(float)}\n",
182+
" boundings:\n",
183+
" list or ordered dictionnary, if a list is passed is should be composed of tuples,\n",
184+
" the first level of tuples contains the key and another tuple with a type or the bounds\n",
185+
" i.e.:[('a',(1,100)),('b',(float)),('c',(1,100)),('d',(bool)),('e',(1,100)),('f',(1,100))]\n",
179186
" lenit:\n",
180187
" lenght(row not cols) of the first innit distribution\n",
181188
" inpt:\n",
@@ -194,15 +201,32 @@
194201
" if hardfloat is true, floats will be returned in the initial guess and bounds,\n",
195202
" this is not recomended to use with minimize,\n",
196203
" if floats are needed in the function it is recommended to do a type check and to convert from int to float and divide\n",
204+
" inner_bounding:\n",
205+
" if True, bounds will be enforced inside the generated function and not with scipy,\n",
206+
" otherwise bounds are assumed to be useless or enforced by the optimizer\n",
197207
" \"\"\"\n",
198-
" dicf = {}\n",
208+
" if isinstance(boundings, list):\n",
209+
" dicti = OD(boundings)\n",
210+
" elif isinstance(boundings, OD):\n",
211+
" print('good type of input')\n",
212+
" elif isinstance(boundings, dict):\n",
213+
" print(\n",
214+
" \"kwargs will be in a random order, use ordered dictionnary instead\"\n",
215+
" )\n",
216+
" else:\n",
217+
" print(\"invalid input for boundings, quitting\")\n",
218+
" exit(1)\n",
219+
"\n",
220+
" dicf = OD()\n",
199221
" args = []\n",
200222
" bounds = []\n",
201223
" initg = []\n",
202-
" if factory and (inpt == '' or inpt == None):\n",
224+
" if factory and (\n",
225+
" inpt == None\n",
226+
" ): # set inpt as '' when creating the function to ignore it\n",
203227
" inpt = input(\n",
204228
" 'please input the arg that will be executed by the function')\n",
205-
" for ke, va in dicti.items():\n",
229+
" for ke, va in boundings.items():\n",
206230
" if va == bool:\n",
207231
" dicf[ke] = (0, 1)\n",
208232
" elif va == float:\n",
@@ -223,30 +247,49 @@
223247
" if lenit > 0:\n",
224248
" initguess = adpt_distr(\n",
225249
" dicf, out='array', Size=lenit, hardfloat=hardfloat)\n",
226-
" for kk, vv in dicti.items():\n",
227-
" args.append(kk)\n",
250+
" for kk, vv in dicf.items():\n",
228251
" bounds.append(vv)\n",
252+
" args.append(kk)\n",
229253
" if factory:\n",
230254
"\n",
231-
" def kwargsf(initvs):\n",
255+
" def kwargsf(initvs): # inner funct\n",
232256
" dictos = {}\n",
233257
" if not (len(initvs) == len(args)):\n",
234-
" print(\n",
235-
" \"\"\"initial values provided are not the same lenght as keywords provided,\n",
236-
" something went wrong, aborting\"\"\")\n",
237-
" exit(1)\n",
238-
" else:\n",
239-
" dictos = dicti(zip(args, initvs))\n",
240-
" if i_as_meth_arg:\n",
258+
" if isinstance(initvs,\n",
259+
" (np.ndarray,\n",
260+
" np.array)) and len(initvs[0]) == len(args):\n",
261+
" initvs = initvs[0]\n",
262+
" else:\n",
263+
" print(initvs)\n",
264+
" print(len(initvs), len(args))\n",
265+
" print(initvs.type)\n",
266+
" print(\n",
267+
" \"\"\"initial values provided are not the same lenght as keywords provided,\n",
268+
" something went wrong, aborting\"\"\")\n",
269+
" exit(1)\n",
270+
" if inner_bounding:\n",
271+
" for i in range(len(bounds)):\n",
272+
" maxx = max(bounds[i])\n",
273+
" minn = min(bounds[i])\n",
274+
" if initvs[i] > maxx:\n",
275+
" initvs[i] = maxx\n",
276+
" elif initvs[i] < minn:\n",
277+
" initvs[i] = minn\n",
278+
" dictos = dict(zip(args, initvs))\n",
279+
" if len(inpt) == 0 or len(\n",
280+
" inpt) == 1: # no static input, only values to optimize\n",
281+
" instt = funck(**staticD, **dictos)\n",
282+
" elif i_as_meth_arg:\n",
241283
" # an alternative may be instt=funck(inpt,**staticD,**dictos)\n",
242284
" instt = funck(**staticD, **dictos)\n",
243285
" else:\n",
244286
" instt = funck(inpt, **staticD, **dictos)\n",
245287
" # if an element is present in both dictos and staticD, dictos will overwrite it\n",
246288
" # if you want the element in staticD to never change, place it after dictos\n",
247289
" # check if executing the function return an output\n",
248-
" if not (isinstance(instt,\n",
249-
" (tuple, array, ndarray, int, float, list))):\n",
290+
" if not (isinstance(instt, (tuple, int, float, list))\n",
291+
" or isinstance(instt,\n",
292+
" (np.array, np.ndarray, pd.DataFrame))):\n",
250293
" # if no value output is returned then it is assumed that the function is a class instance\n",
251294
" if i_as_meth_arg:\n",
252295
" outa = getattr(instt, Cmeth)(inpt)\n",
@@ -257,10 +300,16 @@
257300
" return (instt)\n",
258301
"\n",
259302
" if lenit > 0:\n",
303+
" if inner_bounding:\n",
304+
" return (kwargsf, initguess, args)\n",
260305
" return (kwargsf, initguess, bounds, args)\n",
261306
" else:\n",
307+
" if inner_bounding:\n",
308+
" return (kwargsf, args)\n",
262309
" return (kwargsf, bounds, args)\n",
263310
" else:\n",
311+
" if inner_bounding:\n",
312+
" return (initguess, args)\n",
264313
" return (initguess, bounds, args)"
265314
]
266315
},
@@ -293,10 +342,10 @@
293342
"\n",
294343
"\n",
295344
"# our dinctionnary with our bounds and variable to optimize\n",
296-
"kwarg = {'first_V': (0, 23), 'second_V': (bool), 'third_V': (float)}\n",
345+
"kwarg = [('first_V', (0, 23)), ('second_V', (bool)), ('third_V', (float))]\n",
297346
"\n",
298347
"Function, Vector_init, Bounds, Args = dicwrap(\n",
299-
" foo, dicti=kwarg, lenit=1, inpt=data)\n",
348+
" foo, dicti=kwarg, lenit=1, inpt='')\n",
300349
"optimized = minimize(fun=Function, x0=Vector_init, bounds=Bounds)\n",
301350
"optimize_kwargs = zip(Args, optimized)"
302351
]
@@ -337,14 +386,14 @@
337386
" self.fourth = fourth_V\n",
338387
"\n",
339388
" def EXEC(self, data):\n",
340-
" # do something using the instance variables set by init\n",
389+
" # do something using the instance variables set by init and some data\n",
341390
" pass\n",
342391
"\n",
343392
"\n",
344393
"# our dinctionnary with our bounds and variable to optimize\n",
345-
"kwarg1 = {'first_V': (0, 23), 'second_V': (float)}\n",
346-
"kwarg2 = {'third_V': (13, 38), 'fourth_V': (bool)}\n",
347-
"optimized_kwargs = dict() # create empty dict to ensure everything goes well\n",
394+
"kwarg1 = [('first_V', (0, 23)), ('second_V', (float))]\n",
395+
"kwarg2 = [('third_V', (13, 38)), ('fourth_V', (bool))]\n",
396+
"optimized_kwargs = OD() # create empty dict to ensure everything goes well\n",
348397
"\n",
349398
"for dicto in [kwarg1, kwarg2]:\n",
350399
" Function, Vector_init, Bounds, Args = dicwrap(\n",

0 commit comments

Comments
 (0)