0
$\begingroup$

I want to minimize $h(x) = \sin(x)-e^{\cos(x^{2})} - x$ on $[0,1]$ as an exercise in writing generic solvers.

Here's what I have done in Python.

I defined my function.

>>> def h(x):
    return numpy.sin(x)-numpy.exp(numpy.cos(x**2)) - x

After importing what's needed, I ran the minimize function with an initial guess of $0.5$

>>> scipy.optimize.minimize(h,[0.5,],bounds=((0,1),))

I obtained the following output

      fun: array([-2.71828183])
 hess_inv: <1x1 LbfgsInvHessProduct with dtype=float64>
      jac: array([ 0.])
  message: b'CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL'
     nfev: 4
      nit: 1
   status: 0
  success: True
        x: array([ 0.])

The minimum looks to be $e$ at $x = 0$. Which seems believable.

Curiously, changing the initial guess to $0.48$ from $0.50$, I obtained the following:

>>> scipy.optimize.minimize(h,[0.48,],bounds=((0,1),))
      fun: array([-2.71831419])
 hess_inv: <1x1 LbfgsInvHessProduct with dtype=float64>
      jac: array([ -3.81916720e-06])
  message: b'CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL'
     nfev: 24
      nit: 3
   status: 0
  success: True
        x: array([ 0.09182462])

Indeed, tossing my function into Wolfram Alpha gives a minimum of roughly $-2.171831$ at $x \approx 0.0919095$.

I'm curious to know if there are some good ways to provide an initial guess when one is blind to where the solution ought to be. I chose an initial guess of $x = 0.5$ because it felt "natural" to choose the midpoint of the domain.

When I provided an initial guess of $x = 0$, I got ...

>>> scipy.optimize.minimize(h,[0],bounds=((0,1),))
      fun: array([-2.71828183])
 hess_inv: <1x1 LbfgsInvHessProduct with dtype=float64<
      jac: array([ 0.])
  message: b'CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL'
     nfev: 2
      nit: 0
   status: 0
  success: True
        x: array([ 0.])

I'm back to having a minimum at $x = 0$ ...

And more hack work with the initial guesses: for an initial guess of $x = 0.01$, scipy.optimize.minimize tells me the minimum is at $x = 0.01004454$ with a value of $-2.71828198$. However, an initial guess of $x = 0.02$ gives $(0.09188086,-2.71831419)$.

Of course, I can graph the function, but I still may dumbly give an initial guess of $x = 0$. image1

Zooming in to $0 \leq x \leq 0.1$ I see this ... enter image description here

Anyway, the question is: what's a good way to provide an initial guess without implicitly solving the problem? I know that optimization algorithms can get stuck on local extrema, but I thought for sure in the case of $h(x)$ there shouldn't be an issue. Changing tolerance and maximum number of iterations didn't help either.

As two aside points: I was a little surprised by the varying results from scipy.optimize.minimize. And for anyone curious, this all came about because I was putting together a genetic algorithm for a course I'm teaching. When I asked it to minimize $h$, it found $x = 0.0946478$, $h(x) = -2.71831401$ which agrees to six places with Wolfram Alpha's solution as well as scipy.optimize.minimize's solution after I gave it a little help. And that got me down this hole.

$\endgroup$
  • $\begingroup$ i think there is no solution in the given interval $\endgroup$ – Dr. Sonnhard Graubner May 6 '17 at 10:49
  • $\begingroup$ Well, according to Taylor, your function is $h(x)=-e-\frac16x^3+O(x^4)$, so $x=0$ is among the first places where one would not expect the minimum to be $\endgroup$ – Hagen von Eitzen May 6 '17 at 10:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.