Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

class method as model function and class method as optimization function for scipy.optimize

I am using python to solve an optimization problem. I would like to define a class to do the job. In the class I would like to use a model function as a method of a class like :

class MyClass(object):
      def f(self,x,parameters):

but I would also like to define another method in that same class that do the optimization on the function f on x, for example:

     def Optim_Funtion(self):
         scipy.optimize.minimize(f,x0,'method='Nelder-Mead')

My question is how to do that? do I have to pass the function f as a self.f in the Optim_Funtion method ? I found a question related to that but they take the optimization problem out of the class definition: class method as a model function for scipy.optimize.curve_fit and it is not what I would like to do.

Here the code I am using:

class LaserGating:
# Given laser pulse energy and min photon number to be received at a detector, calculate the max distance  


def __init__(self, alpha, PhotonNumber, EnergyMin, EnergyMax, Wavelength,TargetReflection,d):

    self.alpha = alpha
    self.PhotonNumber = PhotonNumber # photon number @detector
    self.EnergyMax = EnergyMax # laser pulse energy max
    self.EnergyMin = EnergyMin # laser pulse energy Min
    self.Wavelength = Wavelength # laser wavelengh
    self.TargetReflection = TargetReflection # target reflection 
    self.d = d # detector size
    self.PhotonEnergy = 1.054e-34*2*np.pi*3.e8/self.Wavelength # energy of a photon at wavelength "Wavelength"
    self.PulseEnergy = self.EnergyMin 
    self.PulseEnergyRange = np.linspace(self.EnergyMin,self.EnergyMax,1000) # array of energy pulse values

    return


def fMin(self,x,PulseEnergy):
    # laser range model: x is the argument (distance) that the function is to be minimized on

    f = self.PhotonNumber - PulseEnergy*self.TargetReflection * ((self.d/x)**2)*np.exp(-self.alpha*x)/self.PhotonEnergy
    return f


def FindDistance(self):
    #find maximale distance given energy and photon number@ detector
    #print self.PulseEnergyRange
    rangeEnergy = self.PulseEnergyRange
    #print rangeEnergy
    testrange = []
    #for testeleements in rangeEnergy:
        #print testeleements

    for elements in rangeEnergy:

        #initial guess. Fixed for the moment but should depend on elements
        x0 = 10.
        #print elements
        # optimisation on x, using elements as arg
        test = scp.optimize.newton(self.fMin,x0,args = (elements,),tol= 1e-3)

        # append answer
        testrange.append(test)

    return testrange

When I run it, using for example:

DistanceRange = LaserGating(0.001,1000,1.e-9,1.e-6,532.e-9,0.2,0.001)
DistanceRange.FindDistance()

I got the following error message:

enter ---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-199-597c7ff1bb69> in <module>()
 ----> 1 DistanceRange.FindDistance()

 <ipython-input-194-b1c115d544c0> in FindDistance(self)
 32             x0 = 1000.
 33 
 ---> 34             test = scp.optimize.minimize(self.fMin,x0,args =        (elements),method='Nelder-Mead',tol= 1e-2)
 35             testrange.append(test)
 36             print elements

 C:\Users\spinchip\AppData\Local\Continuum\Anaconda\lib\site-    packages\scipy\optimize\_minimize.pyc in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
411                       callback=callback, **options)
412     elif meth == 'nelder-mead':
--> 413         return _minimize_neldermead(fun, x0, args, callback, **options)
414     elif meth == 'powell':
415         return _minimize_powell(fun, x0, args, callback, **options)

C:\Users\spinchip\AppData\Local\Continuum\Anaconda\lib\site-  packages\scipy\optimize\optimize.pyc in _minimize_neldermead(func, x0, args, callback,   xtol, ftol, maxiter, maxfev, disp, return_all, **unknown_options)
436     if retall:
437         allvecs = [sim[0]]
--> 438     fsim[0] = func(x0)
439     nonzdelt = 0.05
440     zdelt = 0.00025

C:\Users\spinchip\AppData\Local\Continuum\Anaconda\lib\site-  packages\scipy\optimize\optimize.pyc in function_wrapper(*wrapper_args)
279     def function_wrapper(*wrapper_args):
280         ncalls[0] += 1
--> 281         return function(*(wrapper_args + args))
282 
283     return ncalls, function_wrapper

TypeError: fMin() takes exactly 3 arguments (2 given)code here

So the problems lies on the additional parameters that are not recognized when calling the methods.

Thanks in advance for any suggestions,

Grégory

like image 909
gregory Avatar asked Oct 21 '22 02:10

gregory


1 Answers

Passing args = (elements) is equivalent to args = elements, i.e. no tuple is created.

To pass a 1-element tuple, either do args = (elements,), or args = tuple([elements]).

like image 153
shx2 Avatar answered Oct 22 '22 15:10

shx2