Search code examples
pythonmatlabscipyfminsearch

Translating Matlab @ into Python code (RuntimeWarning: invalid value encountered in true_divide )


I'm translating a Matlab code to python and I got stuck here. I think that with @ it's creating a local variable right? I tried to traduce the code with nested function but it seems to have a problem in hanfling one of the variable.

#Code's variable:

#LL0 = first tentative value
#Sad and f = returns of psd estimation via welch's method
#Sad = is the psd of discrete time-series
#f = is an array of the sampled frequencies
#u_mean = is a scalar

% Matlab Code
f = @(LL, Sad, n, U_media)sum((Sad - 4 * n * LL / U_media .* (1 + 70.8 * (n * LL / U_media).^2).^(-5/6)).^2);
fun = @(LL)f(LL, Sad, n, U_media);
LL = fminsearch(fun, LL0);
def f1(LL, Sad, n, u_mean):
    a = sum((Sad - 4 * n * LL / u_mean * (1 + 70.8 * (n * LL / u_mean)**2)**(-5/6))**2)
    return(a)
f2 = lambda LL, Sad, u_mean, f: f1(LL, Sad, n, u_mean)
fun = lambda LL: f2(LL, Sad, n, u_mean)
LL = scipy.optimize.fmin(func=fun, x0=LL0, maxfun=100000, xtol=1e-6, maxiter=10000, disp=True)

The code is running but the iterations give me this output

RuntimeWarning: invalid value encountered in true_divide
  sum((S_adim - 4 * f * LL / u_mean * (1 + 70.8 * (f * LL / u_mean**2)**(-5/6)))**2)
RuntimeWarning: invalid value encountered in reduce
  return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
Warning: Maximum number of iterations has been exceeded.

The value I get in return is the same I used as tentative value Can anyone help me? Thanks in advance


Solution

  • finally found the solution; i'm not so sure why now it's working think i was assigning the same variable twice. Anyway this is the solution I've come to:

        def f(LL, Sad, n, u_mean):
            f = sum((Sad - (4 * n * LL / u_mean) *
                     ((1 + 70.8 * ((n * LL / u_mean) ** (2)))**(-5 / 6)))**2)
            return(f)
    
        fun = lambda LL: f(LL, Sad, n, u_mean)
        res = scipy.optimize.minimize(fun=fun, x0=LL0)
        Lux = res.x
    
    

    Btw, spyder idle keeps saying that I shouldn't use lambda function but instead define a function.. can anyone tell me why? I was able to translate the "fun" into a function; I've tried with:

    def fun(LL):
       f(LL, Sad, n, u_mean)
       return(f)
    
    res = scipy.optimize.minimize(fun=fun, x0=LL0)
    
    

    but it doesn't work. Would be nice if anybody can tell me why.

    Thanks for your help