예제 #1
0
    def solve_via_data(self, data, warm_start, verbose, solver_opts, solver_cache=None):
        from naginterfaces.library import opt
        from naginterfaces.base import utils

        bigbnd = 1.0e20
        c = data[s.C]
        G = data[s.G]
        h = data[s.H]
        dims = data[s.DIMS]
        nvar = data['nvar']
        soc_dim = nvar - len(c)
        nleq = dims[s.LEQ_DIM]
        neq = dims[s.EQ_DIM]
        m = len(h)

        # declare the NAG problem handle
        handle = opt.handle_init(nvar)

        # define the linear objective
        cvec = np.concatenate((c, np.zeros(soc_dim)))
        opt.handle_set_linobj(handle, cvec)

        # define linear constraints
        rows, cols, vals = sp.sparse.find(G)
        lb = np.zeros(m)
        ub = np.zeros(m)
        lb[0:nleq] = -bigbnd
        lb[nleq:m] = h[nleq:m]
        ub = h
        if nvar > len(c):
            isoc_idx = nleq + neq
            jsoc_idx = len(c)
            rows = np.concatenate((rows, np.arange(isoc_idx, isoc_idx + soc_dim)))
            cols = np.concatenate((cols, np.arange(jsoc_idx, jsoc_idx + soc_dim)))
            vals = np.concatenate((vals, np.ones(soc_dim)))
        rows = rows + 1
        cols = cols + 1
        opt.handle_set_linconstr(handle, lb, ub, rows, cols, vals)

        # define the cones
        idx = len(c)
        size_cdvars = 0
        if soc_dim > 0:
            for size_cone in dims[s.SOC_DIM]:
                opt.handle_set_group(handle, gtype='Q',
                                     group=np.arange(idx+1, idx+size_cone+1),
                                     idgroup=0)
                idx += size_cone
                size_cdvars += size_cone

        # deactivate printing by default
        opt.handle_opt_set(handle, "Print File = -1")
        if verbose:
            opt.handle_opt_set(handle, "Monitoring File = 6")
            opt.handle_opt_set(handle, "Monitoring Level = 2")

        # Set the optional parameters
        kwargs = sorted(solver_opts.keys())
        if "nag_params" in kwargs:
            for option, value in solver_opts["nag_params"].items():
                optstr = option + '=' + str(value)
                opt.handle_opt_set(handle, optstr)
            kwargs.remove("nag_params")
        if kwargs:
            raise ValueError("invalid keyword-argument '{0}'".format(kwargs[0]))

        # Use an explicit I/O manager for abbreviated iteration output:
        iom = utils.FileObjManager(locus_in_output=False)

        # Call SOCP interior point solver
        x = np.zeros(nvar)
        status = 0
        u = np.zeros(2*m)
        uc = np.zeros(size_cdvars)
        try:
            if soc_dim > 0:
                sln = opt.handle_solve_socp_ipm(handle, x=x, u=u, uc=uc, io_manager=iom)
            elif soc_dim == 0:
                sln = opt.handle_solve_lp_ipm(handle, x=x, u=u, io_manager=iom)
        except (utils.NagValueError, utils.NagAlgorithmicWarning,
                utils.NagAlgorithmicMajorWarning) as exc:
            status = exc.errno
            sln = exc.return_data

        # Destroy the handle:
        opt.handle_free(handle)

        return {'status': status, 'sln': sln}
예제 #2
0
def main():
    """
    Example for :func:`naginterfaces.library.opt.handle_solve_dfls`.

    Derivative-free solver for a nonlinear least squares objective function.

    >>> main()
    naginterfaces.library.opt.handle_solve_dfls Python Example Results.
    Minimizing the Kowalik and Osborne function.
    ...
      Status: Converged, small trust region size
    ...
      Value of the objective                    4.02423E-04
      Number of objective function evaluations           27
      Number of steps                                    10
    ...
     Primal variables:
       idx   Lower bound        Value      Upper bound
         1       -inf       1.81300E-01         inf
         2   2.00000E-01    5.90128E-01    1.00000E+00
         3       -inf       2.56929E-01         inf
         4   3.00000E-01    3.00000E-01         inf
    """

    from naginterfaces.base import utils
    from naginterfaces.library import opt
    from copy import deepcopy

    print(
        'naginterfaces.library.opt.handle_solve_dfls Python Example Results.')
    print('Minimizing the Kowalik and Osborne function.')

    # The initial guess:
    x = [0.25, 0.39, 0.415, 0.39]

    # The Kowalik and Osborne function:
    y = [4., 2., 1., 0.5, 0.25, 0.167, 0.125, 0.1, 0.0833, 0.0714, 0.0625]
    z = [
        0.1957, 0.1947, 0.1735, 0.1600, 0.0844, 0.0627, 0.0456, 0.0342, 0.0323,
        0.0235, 0.0246
    ]
    objfun = lambda x, _nres: z - x[0] * (y * (y + x[1])) / (y *
                                                             (y + x[2]) + x[3])
    fit = lambda x, y: x[0] * (y * (y + x[1])) / (y * (y + x[2]) + x[3])

    steps = []

    def monit(x, rinfo, stats, data=None):
        """The monitor function."""
        pt = deepcopy(x)
        steps.append([pt, rinfo[0]])

    # Create a handle for the problem:
    handle = opt.handle_init(nvar=len(x))

    # Define the residuals structure:
    nres = 11
    opt.handle_set_nlnls(
        handle,
        nres,
        irowrd=None,
        icolrd=None,
    )

    # Define the bounds:
    opt.handle_set_simplebounds(
        handle,
        bl=[-1.e20, 0.2, -1.e20, 0.3],
        bu=[1.e20, 1., 1.e20, 1.e20],
    )

    # Set some algorithmic options.
    # Relax the main convergence criteria slightly:
    opt.handle_opt_set(handle, 'DFLS Trust Region Tolerance = 5.0e-6')
    # Turn off option printing:
    opt.handle_opt_set(handle, 'Print Options = NO')
    # Print the solution:
    opt.handle_opt_set(handle, 'Print Solution = YES')
    # Call Monitor at each step to log progress
    opt.handle_opt_set(handle, 'DFO Monitor Frequency = 1')

    # Use an explicit I/O manager for abbreviated iteration output:
    iom = utils.FileObjManager(locus_in_output=False)

    # Solve the problem:
    ret = opt.handle_solve_dfls(handle,
                                objfun,
                                x,
                                nres,
                                monit=monit,
                                io_manager=iom)

    # Destroy the handle:
    opt.handle_free(handle)

    import numpy as np
    m_y = np.linspace(y[0], y[-1])
    m_z = fit(x, m_y)

    import matplotlib.pyplot as plt
    from matplotlib import cm

    cols = cm.jet(range(0, 240, 20))
    plt.grid(True)
    # plot initial guess (parameters x)
    i = 0
    plt.plot(m_y, m_z, '-', color=cols[i][0:3])

    # plot intermediary fits
    for s in steps:
        i = i + 1
        m_z = fit(s[0], m_y)
        plt.plot(m_y,
                 m_z,
                 '-',
                 color=cols[i][0:3],
                 label=r'LSE: {:.3e}'.format(s[1]))

    # plot optimised/fitted parameters ret.x)
    m_z = fit(ret.x, m_y)
    plt.plot(m_y,
             m_z,
             '-',
             color=cols[-1][0:3],
             linewidth=3,
             label=r'LSE: {:.3e}'.format(ret.rinfo[0]))
    plt.plot(y, z, 'gx', markersize=7, label='Observations')

    plt.xlabel('$y$')
    plt.ylabel('$z=p(y,t=x)$')
    plt.legend(loc='lower right')
    plt.title('DFO NLLS fit for the Kowalik and Osborne function')

    plt.show()
def main():
    """
    Example for :func:`naginterfaces.library.opt.handle_solve_bounds_foas`.

    Large-scale first order active set bound-constrained nonlinear programming.

    >>> main()
    naginterfaces.library.opt.handle_solve_bounds_foas Python Example Results.
    Minimizing a bound-constrained Rosenbrock problem.
     -------------------------------------------------------------------------------
      E04KF, First order method for bound contrained problems
     -------------------------------------------------------------------------------
     Begin of Options
    ...
     End of Options
    <BLANKLINE>
     Status: converged, an optimal solution was found
     Value of the objective             4.00000E-02
    ...
     """

    from naginterfaces.base import utils
    from naginterfaces.library import opt

    print('naginterfaces.library.opt.handle_solve_bounds_foas '
          'Python Example Results.')
    print('Minimizing a bound-constrained Rosenbrock problem.')

    # The initial guess: Interesting scenarios
    # x = [-1.5, 1.9]
    # x = [-1.5, -2.5]
    # x = [-0.5, -2.1]
    # x = [-0.5, 1.0]
    x = [-1.0, -1.5]
    # x = [-0.9, -1.5]
    # x = [-2.0, 1.5]

    # The Rosenbrock objective:
    objfun = lambda x, inform: (
        (1. - x[0])**2 + 100. * (x[1] - x[0]**2)**2,
        inform,
    )

    def objgrd(x, fdx, inform):
        """The objective's gradient."""
        fdx[:] = [
            2. * x[0] - 400. * x[0] * (x[1] - x[0]**2) - 2.,
            200. * (x[1] - x[0]**2),
        ]
        return inform

    steps = []

    def monit(x, inform, rinfo, stats, data=None):
        """The monitor function."""
        steps.append([x[0], x[1], rinfo[0]])
        return inform

    # Create a handle for the problem:
    nvar = len(x)
    handle = opt.handle_init(nvar)

    # Define the bounds:
    bl = [-1., -2.]
    bu = [0.8, 2.]
    opt.handle_set_simplebounds(
        handle,
        bl=bl,
        bu=bu,
    )

    # Define the nonlinear objective:
    opt.handle_set_nlnobj(handle, idxfd=list(range(1, nvar + 1)))

    # Set some algorithmic options.
    for option in [
            'FOAS Print Frequency = 5',
            'Print Solution = yes',
            'FOAS Monitor Frequency = 1',
            'Print Level = 2',
            'Monitoring Level = 3',
    ]:
        opt.handle_opt_set(handle, option)

    # Use an explicit I/O manager for abbreviated iteration output:
    iom = utils.FileObjManager(locus_in_output=False)

    # Solve the problem:
    ret = opt.handle_solve_bounds_foas(handle,
                                       objfun,
                                       objgrd,
                                       x,
                                       monit=monit,
                                       io_manager=iom)

    # Destroy the handle:
    opt.handle_free(handle)

    # Add solution to step list
    steps.append([ret.x[0], ret.x[1], ret.rinfo[0]])

    # Evaluate the funtion over the domain
    import numpy as np
    x_m = np.linspace(bl[0] - 0.5, bu[0] + 0.5, 101)
    y_m = np.linspace(bl[1] - 0.5, bu[1] + 0.5, 101)
    z_m = np.empty((101, 101))
    j = y_m[0]
    for i in range(0, 101):
        for j in range(0, 101):
            z_m[i, j], _inform = objfun([x_m[i], y_m[j]], 1)
    nb = 25
    x_box = np.linspace(bl[0], bu[0], nb)
    y_box = np.linspace(bl[1], bu[1], nb)
    box = np.array([
        np.concatenate(
            [x_box, bu[0] * np.ones(nb), x_box[::-1], bl[0] * np.ones(nb)]),
        np.concatenate(
            [bl[1] * np.ones(nb), y_box, bu[1] * np.ones(nb), y_box[::-1]])
    ])
    z_box = np.empty(box[0].shape)
    for i in range(0, (box[0].size)):
        z_box[i], _inform = objfun([box[0][i], box[1][i]], 1)

    X, Y = np.meshgrid(x_m, y_m, indexing='ij')

    # Plot function and steps taken
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    from matplotlib import cm
    fig = plt.figure()
    ax = Axes3D(fig)
    ax = fig.gca(projection='3d')
    ax.grid(False)
    ax.plot(box[0], box[1], z_box, 'k-', linewidth=1.5)
    ax.plot([bl[0], bu[0], bu[0], bl[0], bl[0]],
            [bl[1], bl[1], bu[1], bu[1], bl[1]], -1.2 * np.ones(5), 'k-')
    ax.contour(X, Y, z_m, 15, offset=-1.2, cmap=cm.jet)
    ax.plot_surface(X, Y, z_m, cmap=cm.jet, alpha=0.5)
    ax.set_title('Rosenbrock Function')
    ax.set_xlabel(r'$\mathit{x}$')
    ax.set_ylabel(r'$\mathit{y}$')
    steps = np.column_stack(steps)
    ax.plot(steps[0], steps[1], steps[2], 'o-', color='magenta', markersize=2)
    ax.azim = 160
    ax.elev = 35
    plt.show()