Example #1
0
File: TRF.py Project: astaid/pyomo
def TRF(m, eflist, config):
    """The main function of the Trust Region Filter algorithm

    m is a PyomoModel containing ExternalFunction() objects Model
    requirements: m is a nonlinear program, with exactly one active
    objective function.

    eflist is a list of ExternalFunction objects that should be
    treated with the trust region

    config is the persistent set of variables defined 
    in the ConfigBlock class object

    Return: 
    model is solved, variables are at optimal solution or
    other exit condition.  model is left in reformulated form, with
    some new variables introduced in a block named "tR" TODO: reverse
    the transformation.
    """

    logger = Logger()
    filteR = Filter()
    problem = PyomoInterface(m, eflist)
    x, y, z = problem.getInitialValue()

    iteration = -1

    romParam, yr = problem.buildROM(x, config.sample_radius)
    #y = yr
    rebuildROM = False
    xk, yk, zk = cloneXYZ(x, y, z)
    chik = 1e8
    thetak = norm(yr - yk, 1)

    objk = problem.evaluateObj(x, y, z)

    while True:
        if iteration >= 0:
            logger.printIteration(iteration)
            #print(xk)
        # increment iteration counter
        iteration = iteration + 1
        if iteration > config.max_it:
            print("EXIT: Maxmium iterations\n")
            break

        ######  Why is this here ###########
        if iteration == 1:
            config.sample_region = False
        ################################

        # Keep Sample Region within Trust Region
        if config.trust_radius < config.sample_radius:
            config.sample_radius = max(
                config.sample_radius_adjust * config.trust_radius,
                config.delta_min)
            rebuildROM = True

        #Generate a RM r_k (x) that is kappa-fully linear on sigma k
        if (rebuildROM):
            #TODO: Ask Jonathan what variable 1e-3 should be
            if config.trust_radius < 1e-3:
                problem.romtype = ROMType.linear
            else:
                problem.romtype = config.reduced_model_type

            romParam, yr = problem.buildROM(x, config.sample_radius)
            #print(romParam)
            #print(config.sample_radius)

        # Criticality Check
        if iteration > 0:
            flag, chik = problem.criticalityCheck(x, y, z, romParam)
            if (not flag):
                raise Exception("Criticality Check fails!\n")

        # Save the iteration information to the logger
        logger.newIter(iteration, xk, yk, zk, thetak, objk, chik,
                       config.print_variables)

        # Check for Termination
        if (thetak < config.ep_i and chik < config.ep_chi
                and config.sample_radius < config.ep_delta):
            print("EXIT: OPTIMAL SOLUTION FOUND")
            break

        # If trust region very small and no progress is being made,
        # terminate. The following condition must hold for two
        # consecutive iterations.
        if (config.trust_radius <= config.delta_min and thetak < config.ep_i):
            if subopt_flag:
                print("EXIT: FEASIBLE SOLUTION FOUND ")
                break
            else:
                subopt_flag = True
        else:
            # This condition holds for iteration 0, which will declare
            # the boolean subopt_flag
            subopt_flag = False

        # New criticality phase
        if not config.sample_region:
            config.sample_radius = config.trust_radius / 2.0
            if config.sample_radius > chik * config.criticality_check:
                config.sample_radius = config.sample_radius / 10.0
            config.trust_radius = config.sample_radius * 2
        else:
            config.sample_radius = max(
                min(config.sample_radius, chik * config.criticality_check),
                config.delta_min)

        logger.setCurIter(trustRadius=config.trust_radius,
                          sampleRadius=config.sample_radius)

        # Compatibility Check (Definition 2)
        # radius=max(kappa_delta*config.trust_radius*min(1,kappa_mu*config.trust_radius**mu),
        #            delta_min)
        radius = max(
            config.kappa_delta * config.trust_radius *
            min(1, config.kappa_mu * pow(config.trust_radius, config.mu)),
            config.delta_min)

        try:
            flag, obj = problem.compatibilityCheck(
                x, y, z, xk, yk, zk, romParam, radius,
                config.compatibility_penalty)
        except:
            print("Compatibility check failed, unknown error")
            raise

        if not flag:
            raise Exception("Compatibility check fails!\n")

        theNorm = norm(x - xk, 2)**2 + norm(z - zk, 2)**2
        if (obj - config.compatibility_penalty * theNorm >
                config.ep_compatibility):
            # Restoration stepNorm
            yr = problem.evaluateDx(x)
            theta = norm(yr - y, 1)

            logger.iterlog.restoration = True

            fe = FilterElement(objk - config.gamma_f * thetak,
                               (1 - config.gamma_theta) * thetak)
            filteR.addToFilter(fe)

            rhok = 1 - ((theta - config.ep_i) / max(thetak, config.ep_i))
            if rhok < config.eta1:
                config.trust_radius = max(config.gamma_c * config.trust_radius,
                                          config.delta_min)
            elif rhok >= config.eta2:
                config.trust_radius = min(config.gamma_e * config.trust_radius,
                                          config.radius_max)

            obj = problem.evaluateObj(x, y, z)

            stepNorm = norm(packXYZ(x - xk, y - yk, z - zk), inf)
            logger.setCurIter(stepNorm=stepNorm)

        else:

            # Solve TRSP_k
            flag, obj = problem.TRSPk(x, y, z, xk, yk, zk, romParam,
                                      config.trust_radius)
            if not flag:
                raise Exception("TRSPk fails!\n")

            # Filter
            yr = problem.evaluateDx(x)

            stepNorm = norm(packXYZ(x - xk, y - yk, z - zk), inf)
            logger.setCurIter(stepNorm=stepNorm)

            theta = norm(yr - y, 1)
            fe = FilterElement(obj, theta)

            if not filteR.checkAcceptable(fe,
                                          config.theta_max) and iteration > 0:
                logger.iterlog.rejected = True
                config.trust_radius = max(config.gamma_c * stepNorm,
                                          config.delta_min)
                rebuildROM = False
                x, y, z = cloneXYZ(xk, yk, zk)
                continue

            # Switching Condition and Trust Region update
            if (((objk - obj) >=
                 config.kappa_theta * pow(thetak, config.gamma_s))
                    and (thetak < config.theta_min)):
                logger.iterlog.fStep = True

                config.trust_radius = min(
                    max(config.gamma_e * stepNorm, config.trust_radius),
                    config.radius_max)

            else:
                logger.iterlog.thetaStep = True

                fe = FilterElement(obj - config.gamma_f * theta,
                                   (1 - config.gamma_theta) * theta)
                filteR.addToFilter(fe)

                # Calculate rho for theta step trust region update
                rhok = 1 - ((theta - config.ep_i) / max(thetak, config.ep_i))
                if rhok < config.eta1:
                    config.trust_radius = max(config.gamma_c * stepNorm,
                                              config.delta_min)
                elif rhok >= config.eta2:
                    config.trust_radius = min(
                        max(config.gamma_e * stepNorm, config.trust_radius),
                        config.radius_max)

        # Accept step
        rebuildROM = True
        xk, yk, zk = cloneXYZ(x, y, z)
        thetak = theta
        objk = obj

    logger.printVectors()
Example #2
0
def TRF(m, eflist):
    """
    The main function of the Trust Region Filter algorithm

    m is a PyomoModel containing ExternalFunction() objects
    Model requirements: m is a nonlinear program, with exactly one active objective function.

    eflist is a list of ExternalFunction objects that should be treated with the
    trust region


    Return:
    model is solved, variables are at optimal solution or other exit condition.
    model is left in reformulated form, with some new variables introduced
    in a block named "tR" TODO: reverse the transformation.
    """

    logger = Logger()
    filteR = Filter()
    problem = PyomoInterface(m, eflist)
    x, y, z = problem.getInitialValue()

    trustRadius = TRUST_RADIUS
    sampleRadius = SAMPLE_RADIUS
    sampleregion_yn = SAMPLEREGION_YN
    iteration = -1

    romParam, yr = problem.buildROM(x, sampleRadius)
    #y = yr
    rebuildROM = False
    xk, yk, zk = cloneXYZ(x, y, z)
    chik = 1e8
    thetak = norm(yr - yk, 1)

    objk = problem.evaluateObj(x, y, z)

    while True:
        if (iteration >= 0):
            logger.printIteration(iteration)
            #print(xk)
        # increment iteration counter
        iteration = iteration + 1
        if (iteration > MAXIT):
            print("EXIT: Maxmium iterations\n")
            break

        ######  Why is this here ###########
        if iteration == 1:
            sampleregion_yn = False
        ################################

        # Keep Sample Region within Trust Region
        if trustRadius < sampleRadius:
            sampleRadius = max(SR_ADJUST * trustRadius, DELTMIN)
            rebuildROM = True

        #Generate a RM r_k (x) that is κ-fully linear on sigma k
        if (rebuildROM):
            if trustRadius < 1e-3:
                problem.romtype = ROMType.linear
            else:
                problem.romtype = DEFAULT_ROMTYPE

            romParam, yr = problem.buildROM(x, sampleRadius)
            #print(romParam)
            #print(sampleRadius)

        # Criticality Check
        if iteration > 0:
            flag, chik = problem.criticalityCheck(x, y, z, romParam)
            if (not flag):
                raise Exception("Criticality Check fails!\n")

        # Save the iteration information to the logger
        logger.newIter(iteration, xk, yk, zk, thetak, objk, chik)

        # Check for Termination
        if thetak < EP_I and chik < EP_CHI and sampleRadius < EP_DELT:
            print("EXIT: OPTIMAL SOLUTION FOUND")
            break

        # If trust region very small and no progress is being made, terminate
        # The following condition must hold for two consecutive iterations.
        if trustRadius <= DELTMIN and thetak < EP_I:
            if subopt_flag:
                print("EXIT: FEASIBLE SOLUTION FOUND ")
                break
            else:
                subopt_flag = True
        else:
            # This condition holds for iteration 0, which will declare the boolean subopt_flag
            subopt_flag = False

        # New criticality phase
        if not sampleregion_yn:
            sampleRadius = trustRadius / 2.0
            if sampleRadius > chik * CRITICALITY_CHECK:
                sampleRadius = sampleRadius / 10.0
            trustRadius = sampleRadius * 2
        else:
            sampleRadius = max(min(sampleRadius, chik * CRITICALITY_CHECK),
                               DELTMIN)

        logger.setCurIter(trustRadius=trustRadius, sampleRadius=sampleRadius)

        # Compatibility Check
        radius = max(KAPPA_DELTA * trustRadius * \
            min(1, KAPPA_MU * pow(trustRadius, MU)),DELTMIN)

        try:
            flag, obj = problem.compatibilityCheck(x, y, z, xk, yk, zk,
                                                   romParam, radius,
                                                   COMPAT_PENALTY)
        except:
            print("Compatibility check failed, unknown error")
            raise

        if not flag:
            raise Exception("Compatibility check fails!\n")

        if (obj - COMPAT_PENALTY *
            (norm(x - xk, 2)**2 + norm(z - zk, 2)**2) > EP_COMPAT):
            # Restoration stepNorm
            yr = problem.evaluateDx(x)
            theta = norm(yr - y, 1)

            logger.iterlog.restoration = True

            fe = FilterElement(objk - GAMMA_F * thetak,
                               (1 - GAMMA_THETA) * thetak)
            filteR.addToFilter(fe)

            rhok = 1 - (theta - EP_I) / max(thetak, EP_I)
            if (rhok < ETA1):
                trustRadius = max(GAMMA_C * trustRadius, DELTMIN)
            elif (rhok >= ETA2):
                trustRadius = min(GAMMA_E * trustRadius, RADIUS_MAX)

            obj = problem.evaluateObj(x, y, z)

            stepNorm = norm(packXYZ(x - xk, y - yk, z - zk), inf)
            logger.setCurIter(stepNorm=stepNorm)

        else:

            # Solve TRSP_k
            flag, obj = problem.TRSPk(x, y, z, xk, yk, zk, romParam,
                                      trustRadius)
            if not flag:
                raise Exception("TRSPk fails!\n")

            # Filter
            yr = problem.evaluateDx(x)

            stepNorm = norm(packXYZ(x - xk, y - yk, z - zk), inf)
            logger.setCurIter(stepNorm=stepNorm)

            theta = norm(yr - y, 1)
            fe = FilterElement(obj, theta)

            if not filteR.checkAcceptable(fe) and iteration > 0:
                logger.iterlog.rejected = True
                trustRadius = max(GAMMA_C * stepNorm, DELTMIN)
                rebuildROM = False
                x, y, z = cloneXYZ(xk, yk, zk)
                continue

            # Switching Condition and Trust Region update
            if ((objk - obj) >= KAPPA_THETA * pow(thetak, GAMMA_S)
                    and thetak < THETA_MIN):
                logger.iterlog.fStep = True

                trustRadius = min(max(GAMMA_E * stepNorm, trustRadius),
                                  RADIUS_MAX)

            else:
                logger.iterlog.thetaStep = True

                fe = FilterElement(obj - GAMMA_F * theta,
                                   (1 - GAMMA_THETA) * theta)
                filteR.addToFilter(fe)

                # Calculate rho for theta step trust region update
                rhok = 1 - (theta - EP_I) / max(thetak, EP_I)
                if (rhok < ETA1):
                    trustRadius = max(GAMMA_C * stepNorm, DELTMIN)
                elif (rhok >= ETA2):
                    trustRadius = min(max(GAMMA_E * stepNorm, trustRadius),
                                      RADIUS_MAX)

        # Accept step
        rebuildROM = True
        xk, yk, zk = cloneXYZ(x, y, z)
        thetak = theta
        objk = obj

    logger.printVectors()