diff --git a/ipython/Kwarg optimization wrapper.ipynb b/ipython/Kwarg optimization wrapper.ipynb index 0b27b03..dfa74a3 100644 --- a/ipython/Kwarg optimization wrapper.ipynb +++ b/ipython/Kwarg optimization wrapper.ipynb @@ -36,7 +36,7 @@ "from randon import randint, uniform\n", "\n", "\n", - "def adpt_distr(boundict, Method=True, Size=1, out='df', hardfloat=True):\n", + "def adpt_distr(boundict, Method: bool=True, Size=1, out='df', hardfloat=True):\n", " \"\"\"\n", " Takes input with bounds, check bounds, if bounds are (float) sample from uniform 0,1\n", " otherwise if bounds are (bool) sample from randint 0,1 and otherwise sample from randint bound to bound\n", @@ -152,15 +152,20 @@ }, "outputs": [], "source": [ + "from collections import OrderedDict as OD\n", + "import numpy as np\n", + "\n", + "\n", "def dicwrap(funck,\n", - " dicti,\n", - " lenit=1,\n", - " inpt='',\n", - " i_as_meth_arg=False,\n", - " factory=True,\n", - " Cmeth=\"RUN\",\n", - " staticD:=dict(),\n", - " hardfloat=False):\n", + " boundings,\n", + " lenit: int=1,\n", + " inpt=None,\n", + " i_as_meth_arg: bool=False,\n", + " factory: bool=True,\n", + " Cmeth: str=\"RUN\",\n", + " staticD=dict(),\n", + " hardfloat=False,\n", + " inner_bounding=False):\n", " \"\"\"take in function and dict and return:\n", " if factory is True :\n", " the primed function is returned, this function is the one given to minimize\n", @@ -174,8 +179,10 @@ " args:\n", " funck:\n", " function to optimize\n", - " dicti:\n", - " dictionnary with kwargs, and bounds as tuple ex: {'lenght':(0,12),'height':(4,6),'condition':(bool),'size':(float)}\n", + " boundings:\n", + " list or ordered dictionnary, if a list is passed is should be composed of tuples,\n", + " the first level of tuples contains the key and another tuple with a type or the bounds\n", + " i.e.:[('a',(1,100)),('b',(float)),('c',(1,100)),('d',(bool)),('e',(1,100)),('f',(1,100))]\n", " lenit:\n", " lenght(row not cols) of the first innit distribution\n", " inpt:\n", @@ -194,15 +201,32 @@ " if hardfloat is true, floats will be returned in the initial guess and bounds,\n", " this is not recomended to use with minimize,\n", " 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", + " inner_bounding:\n", + " if True, bounds will be enforced inside the generated function and not with scipy,\n", + " otherwise bounds are assumed to be useless or enforced by the optimizer\n", " \"\"\"\n", - " dicf = {}\n", + " if isinstance(boundings, list):\n", + " dicti = OD(boundings)\n", + " elif isinstance(boundings, OD):\n", + " print('good type of input')\n", + " elif isinstance(boundings, dict):\n", + " print(\n", + " \"kwargs will be in a random order, use ordered dictionnary instead\"\n", + " )\n", + " else:\n", + " print(\"invalid input for boundings, quitting\")\n", + " exit(1)\n", + "\n", + " dicf = OD()\n", " args = []\n", " bounds = []\n", " initg = []\n", - " if factory and (inpt == '' or inpt == None):\n", + " if factory and (\n", + " inpt == None\n", + " ): # set inpt as '' when creating the function to ignore it\n", " inpt = input(\n", " 'please input the arg that will be executed by the function')\n", - " for ke, va in dicti.items():\n", + " for ke, va in boundings.items():\n", " if va == bool:\n", " dicf[ke] = (0, 1)\n", " elif va == float:\n", @@ -223,21 +247,38 @@ " if lenit > 0:\n", " initguess = adpt_distr(\n", " dicf, out='array', Size=lenit, hardfloat=hardfloat)\n", - " for kk, vv in dicti.items():\n", - " args.append(kk)\n", + " for kk, vv in dicf.items():\n", " bounds.append(vv)\n", + " args.append(kk)\n", " if factory:\n", "\n", - " def kwargsf(initvs):\n", - " dictos = {}\n", + " def kwargsf(initvs): # inner funct\n", " if not (len(initvs) == len(args)):\n", - " print(\n", - " \"\"\"initial values provided are not the same lenght as keywords provided,\n", - " something went wrong, aborting\"\"\")\n", - " exit(1)\n", - " else:\n", - " dictos = dicti(zip(args, initvs))\n", - " if i_as_meth_arg:\n", + " if isinstance(initvs,\n", + " (np.ndarray,\n", + " np.array)) and len(initvs[0]) == len(args):\n", + " initvs = initvs[0]\n", + " else:\n", + " print(initvs)\n", + " print(len(initvs), len(args))\n", + " print(initvs.type)\n", + " print(\n", + " \"\"\"initial values provided are not the same lenght as keywords provided,\n", + " something went wrong, aborting\"\"\")\n", + " exit(1)\n", + " if inner_bounding:\n", + " for i in range(len(bounds)):\n", + " maxx = max(bounds[i])\n", + " minn = min(bounds[i])\n", + " if initvs[i] > maxx:\n", + " initvs[i] = maxx\n", + " elif initvs[i] < minn:\n", + " initvs[i] = minn\n", + " dictos = dict(zip(args, initvs))\n", + " if len(inpt) == 0 or len(\n", + " inpt) == 1: # no static input, only values to optimize\n", + " instt = funck(**staticD, **dictos)\n", + " elif i_as_meth_arg:\n", " # an alternative may be instt=funck(inpt,**staticD,**dictos)\n", " instt = funck(**staticD, **dictos)\n", " else:\n", @@ -245,8 +286,9 @@ " # if an element is present in both dictos and staticD, dictos will overwrite it\n", " # if you want the element in staticD to never change, place it after dictos\n", " # check if executing the function return an output\n", - " if not (isinstance(instt,\n", - " (tuple, array, ndarray, int, float, list))):\n", + " if not (isinstance(instt, (tuple, int, float, list))\n", + " or isinstance(instt,\n", + " (np.array, np.ndarray, pd.DataFrame))):\n", " # if no value output is returned then it is assumed that the function is a class instance\n", " if i_as_meth_arg:\n", " outa = getattr(instt, Cmeth)(inpt)\n", @@ -257,10 +299,16 @@ " return (instt)\n", "\n", " if lenit > 0:\n", + " if inner_bounding:\n", + " return (kwargsf, initguess, args)\n", " return (kwargsf, initguess, bounds, args)\n", " else:\n", + " if inner_bounding:\n", + " return (kwargsf, args)\n", " return (kwargsf, bounds, args)\n", " else:\n", + " if inner_bounding:\n", + " return (initguess, args)\n", " return (initguess, bounds, args)" ] }, @@ -293,10 +341,10 @@ "\n", "\n", "# our dinctionnary with our bounds and variable to optimize\n", - "kwarg = {'first_V': (0, 23), 'second_V': (bool), 'third_V': (float)}\n", + "kwarg = [('first_V', (0, 23)), ('second_V', (bool)), ('third_V', (float))]\n", "\n", "Function, Vector_init, Bounds, Args = dicwrap(\n", - " foo, dicti=kwarg, lenit=1, inpt=data)\n", + " foo, dicti=kwarg, lenit=1, inpt='')\n", "optimized = minimize(fun=Function, x0=Vector_init, bounds=Bounds)\n", "optimize_kwargs = zip(Args, optimized)" ] @@ -337,14 +385,14 @@ " self.fourth = fourth_V\n", "\n", " def EXEC(self, data):\n", - " # do something using the instance variables set by init\n", + " # do something using the instance variables set by init and some data\n", " pass\n", "\n", "\n", "# our dinctionnary with our bounds and variable to optimize\n", - "kwarg1 = {'first_V': (0, 23), 'second_V': (float)}\n", - "kwarg2 = {'third_V': (13, 38), 'fourth_V': (bool)}\n", - "optimized_kwargs = dict() # create empty dict to ensure everything goes well\n", + "kwarg1 = [('first_V', (0, 23)), ('second_V', (float))]\n", + "kwarg2 = [('third_V', (13, 38)), ('fourth_V', (bool))]\n", + "optimized_kwargs = OD() # create empty dict to ensure everything goes well\n", "\n", "for dicto in [kwarg1, kwarg2]:\n", " Function, Vector_init, Bounds, Args = dicwrap(\n",