optimize params

    Input:
    gpr: GP regression class
    params0: dictionary filled with starting hyperparameters
    opts: options for optimizer

def opt_hyper(gpr,Ifilter=None,bounds=None,opts={},*args,**kw_args):
    """
    optimize params

    Input:
    gpr: GP regression class
    params0: dictionary filled with starting hyperparameters
    opts: options for optimizer
    """
    if 'gradcheck' in opts:
        gradcheck = opts['gradcheck']
    else:
        gradcheck = False
    if 'max_iter_opt' in opts:
        max_iter = opts['max_iter_opt']
    else:
        max_iter = 5000
    if 'pgtol' in opts:
        pgtol = opts['pgtol']
    else:
        pgtol = 1e-10

    params0 = gpr.getParams()

    def f(x):
        x_ = X0
        x_[Ifilter_x] = x
        gpr.setParams(param_list_to_dict(x_,param_struct,skeys))
        lml = gpr.LML()
        if SP.isnan(lml):
            lml=1E6
        lml_grad = gpr.LML_grad()
        lml_grad = param_dict_to_list(lml_grad,skeys)
        if (~SP.isfinite(lml_grad)).any():
            idx = (~SP.isfinite(lml_grad))
            lml_grad[idx] = 1E6
        return lml, lml_grad[Ifilter_x]

    skeys = SP.sort(list(params0.keys()))
    param_struct = dict([(name,params0[name].shape) for name in skeys])

    # mask params that should not be optimized
    X0 = param_dict_to_list(params0,skeys)
    if Ifilter is not None:
        Ifilter_x = SP.array(param_dict_to_list(Ifilter,skeys),dtype=bool)
    else:
        Ifilter_x = SP.ones(len(X0),dtype='bool')

    # add bounds if necessary
    if bounds is not None:
        _b = []
        for key in skeys:
            if key in list(bounds.keys()):
                _b.extend(bounds[key])
            else:
                _b.extend([[-SP.inf,+SP.inf]]*params0[key].size)
        bounds = SP.array(_b)
        bounds = bounds[Ifilter_x]

    LG.info('Starting optimization ...')
    t = time.time()

    x = X0.copy()[Ifilter_x]
    RV = optimize(f,x,maxfun=int(max_iter),pgtol=pgtol,bounds=bounds,**kw_args)
    #RVopt = optimize(f,x,messages=True,maxfun=int(max_iter),pgtol=pgtol,bounds=bounds)
    #LG.info('%s'%OPT.tnc.RCSTRINGS[RVopt[2]])
    #LG.info('Optimization is converged at iteration %d'%RVopt[1])
    #LG.info('Total time: %.2fs'%(time.time()-t))

    info = RV[2]
    conv = info['warnflag']==0

    if gradcheck:
        err = OPT.check_grad(f,df,xopt)
        LG.info("check_grad (post): %.2f"%err)

    return conv,info