Python Forum
How to use scipy.optimization.brute for multivariable function
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to use scipy.optimization.brute for multivariable function
#1
I want to find the global minima of a two-variables function, say V(x,y,T), where (x,y) are the independent variables and `T' is the parameter. My target is to find the global minimum/ minima (minima of the function which has two variables is determined by https://en.wikipedia.org/wiki/Second_par...ative_test) of the function V(x,y,T) for a fixed value of the parameter T. I want to use the package 'scipy.optimization.brute'. At first, please confirm whether I am right or wrong.

I am pasting a sample example from (https://scipy-lectures.org/intro/scipy/a...mple2.html)

[python]
from scipy import optimize

# Global optimization
grid = (-10, 10, 0.1)
xmin_global = optimize.brute(f, (grid, ))
print("Global minima found %s" % xmin_global)
[/python]
This example is for single-variable-function. I have no idea how to put the input for the two-variables case.
Reply
#2
You need to define ranges where brute will search for an optimum, e.g.

grid = ((-1, 1, 0.1), (-1, 1, 0.1)) 
# Also, you can use slice objects for this:
# grid = (slice(-1, 1, 0.1), slice(-1, 1, 0.1))
Further, you need to define a function to be optimized:

def f(x, T):
    return (x[0] - T) ** 2 + (x[1] - T) ** 2
And, finally, use brute to find the minimum:

from scipy.optimize import brute
brute(f, grid, (1,))
Shiladitya likes this post
Reply
#3
(Oct-19-2020, 10:08 PM)scidam Wrote: You need to define ranges where brute will search for an optimum, e.g.

grid = ((-1, 1, 0.1), (-1, 1, 0.1)) 
# Also, you can use slice objects for this:
# grid = (slice(-1, 1, 0.1), slice(-1, 1, 0.1))
Further, you need to define a function to be optimized:

def f(x, T):
    return (x[0] - T) ** 2 + (x[1] - T) ** 2
And, finally, use brute to find the minimum:

from scipy.optimize import brute
brute(f, grid, (1,))

Thanks a lot for your kind reply.


And I have a question-
brute(f, grid, (1,))
What does "(1,)" stand for? Is it the value of parameter 'T'?

And when defined the function, you used x[0] and x[1]; why?
Mathematically the function is 'f(x,y,T)=(x - T)^2 + (y - T)^2.
Am I right?
Reply
#4
You are right. (1, ) is a value assigned to T (parameter). Note, that brute expects that the first argument of a function responsive for optimization domain. However, this first argument can be a vector. So, if you want to optimize your function in 2D space, you need to pass 2D vector as a first argument. Other arguments are function's parameters.

You unpack x and y, as follows:

def f(X, T):
    x = X[0]
    y = X[1]
    return (x-T)**2 + (y-T)**2
Shiladitya likes this post
Reply
#5
(Oct-20-2020, 10:27 AM)scidam Wrote: You are right. (1, ) is a value assigned to T (parameter). Note, that brute expects that the first argument of a function responsive for optimization domain. However, this first argument can be a vector. So, if you want to optimize your function in 2D space, you need to pass 2D vector as a first argument. Other arguments are function's parameters.

You unpack x and y, as follows:

def f(X, T):
    x = X[0]
    y = X[1]
    return (x-T)**2 + (y-T)**2

Thanks.

I am getting an error for my function f(x,y,T).
At first, I defined the function f(x,y,T). Then I typed
def fT(X,T):
  x=X[0]
  y=X[1]
  return f(x,y,T)


grid = ((1, 400, 10), (1, 400, 10))
xmin_globalT =optimize.brute(fT, grid, (132,) )
print(xmin_globalT)
I am getting an error message in output
[ 9.89129495e+18 -1.31404261e+18]
/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:249: RuntimeWarning: overflow encountered in double_scalars
/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:247: RuntimeWarning: overflow encountered in double_scalars
Could you kindly help me here, please?
Reply
#6
It seems that f(x, y) returns too large values. Could you provide implementation of f(x, y) here? Actually, this is not an error, just a warning.
Shiladitya likes this post
Reply
#7
(Oct-21-2020, 11:44 PM)scidam Wrote: It seems that f(x, y) returns too large values. Could you provide implementation of f(x, y) here? Actually, this is not an error, just a warning.

Sorry for the late reply. I got stuck with some other businesses.
Here is a simplified form of my function. If you will compile, you will see two errors.
import math
import numpy as np
from scipy import optimize

def fT(X,T):
  p=X[0]
  q=X[1]
  r=pow(p,2) + pow(p,4) 
  Vtest = (( -(r**4)*(math.log((r**2)/(T**2))) ))
  return Vtest


grid = ((10, 40, 1), (10, 40, 1))
xmin_globalT =optimize.brute(fT, grid, (567,) )
print(xmin_globalT)
The errors are
/usr/..:RuntimeWarning: overflow encountered in double_scalars
  if __name__ == '__main__':
/usr/../scipy/optimize/optimize.py:597: RuntimeWarning: invalid value encountered in subtract
  numpy.max(numpy.abs(fsim[0] - fsim[1:])) <= fatol):
Thanks in advance.
Reply
#8
This is because brute use int32 dtype for X. Just append dots to grid definition, e.g. grid = ((10.0, 40.0, 1.0), (10.0, 40.0, 1.0)). However, there are still large values occur when evaluating fT. Also, q variable is not used at all.
Reply
#9
(Oct-25-2020, 11:12 PM)scidam Wrote: This is because brute use int32 dtype for X. Just append dots to grid definition, e.g. grid = ((10.0, 40.0, 1.0), (10.0, 40.0, 1.0)). However, there are still large values occur when evaluating fT. Also, q variable is not used at all.

I am a little bit confused now. Instead of executing 'brute', if I only try to find the value of 'fT', it is not blowing up.

(I changed the fT now)

import math
import numpy as np
from scipy import optimize
 
def fT(X,T):
  p=X[0]
  q=X[1]
  r=pow(p,2) + pow(q,4)
  Vtest = (( -(r**4)*(math.log((r**2)/(T**2))) ))
  return Vtest
 
 
grid = ((5.0, 10.0, 1.0), (5.0, 10.0, 1.0))
#xmin_globalT =optimize.brute(fT, grid, (3,) )
#print(xmin_globalT)


z1=pow(1.0,2) + pow(40.0,4) 
A1=(( -(z1**4)*(math.log((z1**2)/(270**2))) ))
print(A1)

z2=pow(40.0,2) + pow(40.0,4) 
A2=(( -(z2**4)*(math.log((z2**2)/(270**2))) ))
print(A2)
And I. am getting the result without any warning -
-7.865898072821287e+26
-7.886106650018259e+26
Whenever, I run the 'brute', even for a smaller range, I am getting that error.
Reply
#10
Your function seems to be quite simple and you can probably try to find out extreme points by differentiating it.
If the function is monotonic within the area of interest, it reaches its extremal value on the edge of the area.
Try to find derivative of the function and equal it to zero. You can also simplify math.log(x ** 2) to 2*math.log(x) etc. In this case you will not need to compute powers (which can lead to very large values).
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  I need advise with developing a brute forcing script fatjuicypython 11 1,573 Aug-21-2020, 09:20 PM
Last Post: Marbelous
  ModuleNotFoundError: No module named 'scipy.optimize'; 'scipy' is not a package AaronKR 1 4,001 Jul-09-2020, 02:36 AM
Last Post: bowlofred
  Password Brute Force 2skywalkers 9 2,639 Oct-18-2018, 02:35 PM
Last Post: buran
  Brute Force Password Guesser 2skywalkers 1 1,732 Oct-05-2018, 08:04 PM
Last Post: ichabod801
  Brute Force Pad Lock Guesser RedSkeleton007 4 2,093 Mar-03-2018, 07:42 AM
Last Post: RedSkeleton007
  Speeding up Brute force password guesser Gamervote 5 4,221 Jul-20-2017, 02:52 PM
Last Post: nilamo
  brute force password from list petru 10 7,251 Apr-04-2017, 02:08 PM
Last Post: buran

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020