Question

I have a python program running under Jython (to use a third party Java API), inside which I would like to calculate a constrained minimization of a multivariate function.

Scipy has a module for this that works perfectly (scipy.optimize) but unfortunately you cannot use scipy within Jython. Does anyone know of a good library/any other way to do this in Jython? If I could just run this under Jython, I'd be all set:

def func(x, sign=1.0):
    """ Objective function -- minimize this """
    return sign*(2*x[0]*x[1] + 2*x[0] - x[0]**2 - 2*x[1]**2)

def func_deriv(x, sign=1.0):
    """ Derivative of objective function """
    dfdx0 = sign*(-2*x[0] + 2*x[1] + 2)
    dfdx1 = sign*(2*x[0] - 4*x[1])
    return np.array([ dfdx0, dfdx1 ])

cons = ({'type': 'eq',
         'fun' : lambda x: np.array([x[0]**3 - x[1]]),
         'jac' : lambda x: np.array([3.0*(x[0]**2.0), -1.0])}, #partial derivative of fun
        {'type': 'ineq',
         'fun' : lambda x: np.array([x[1] - 1]),
         'jac' : lambda x: np.array([0.0, 1.0])})   #partial derivative of fun

res = minimize(func, [-1.0,1.0], args=(-1.0,), jac=func_deriv, 
               method='SLSQP', constraints=cons, options={'disp': True})

Thanks! -Michael

Was it helpful?

Solution

This may not be the most optimal solution to your particular use case as you already have your application in Jython but JPype (link) allows a CPython program to talk to a program running on JVM, I haven't tried it my self but found a hello world example here.

Basically you make your Java class, compile it into a jar and then in CPython do

import jpype
import os.path

jarpath = os.path.join(os.path.abspath('.'), 'build/jar')
jpype.startJVM(jpype.getDefaultJVMPath(), "-Djava.ext.dirs=%s" % jarpath)

# get the class
hello_world = jpype.JClass('com.stackoverflow.HelloWorld')
t = hello_world()  # create an instance of the class
t.helloWorld("Say hello")  # try to call one of the class methods
jpype.shutdownJVM()

I realise though that inverts your application logic. The other option would be to use subprocess and serialise the inputs/outputs.

UPDATE

I came across a similar problem recently and decided to give JPype a go and can now say that it's well worth using, although there are some issues installing it at least on OSX, see help here (some of the JVM paths need to be altered in setup.py).

OTHER TIPS

If your project is using Jython, you can use Slsqp4j to perform the solving natively on the JVM and bypass writing SciPy code entirely. Slsqp4j is a Java wrapper around the SLSQP solver included in SciPy. The api is very similar to SciPy's. It's hosted here: https://github.com/skew-opensource/slsqp4j

(disclosure: I am the author)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top