from mynumpy import *

def opt1(fun,w,max=False,method='BFGS'):
    if max:
        obj = value_and_grad(lambda z : -fun(z))
        #obj = lambda z : -fun(z)
    else:
        obj = value_and_grad(fun)
        #obj = fun
    #from IPython import embed
    #embed()        
    
    #options = {'pgtol' : 1e-10}
    options = {}
    rez=scipy.optimize.minimize(obj,w,jac=True,method=method,options=options)
    w = rez.x
    #print(rez.message)
    #print(rez)
    assert(rez.success)
    return rez.x

def opt(fun,args,max=False,method='BFGS'):
    w,unflatten = flatten(args)
    def fun2(w):
        args = unflatten(w)
        print('args',args)
        if type(args) is tuple:
            print('tuple land')
            return fun(*args)
        else:
            print('non tuple land')
            return fun(args)
    w = opt1(fun2,w,max,method)
    args = unflatten(w)
    return args
