def ieqconsfn(Ab, *args):
     """Optimiser inequality constraint function."""
     initcs = args[0]
     A = r_[eye(initcs.nd), -eye(initcs.nd)]
     b = array([Ab]).T
     # get vertices for constraint set iteration
     V = tryvol(A, b, initcs)[1]
     iterset = ConSet(V)
     #constraint checking for vertices
     ineqs = iterset.allinside(initcs)[1]
     return array([-linalg.norm(ineqs)])
 def ieqconsfn(Ab, *args):
     """Optimiser inequality constraint function."""
     initcs = args[0]
     A, b = splitAb(Ab, initcs.nd)
     # get vertices
     V = tryvol(A, b, initcs)[1]
     iterset = ConSet(V)
     # constraint checking
     if iterset.allinside(initcs):
         return 0
     else:
         return -1
 def objfn2(Ab, *args):
     """Volume objective function for fmin (Simplex)."""
     initcs = args[0]
     A = r_[eye(initcs.nd), -eye(initcs.nd)]
     b = array([Ab]).T
     vol, V = tryvol(A, b, initcs)
     Pv = 200.
     #Penalties
     # points outside of init space
     iterset = ConSet(V)
     outnorm = linalg.norm(iterset.allinside(initcs)[1])
     # open shape
     cl = con2vert(A, b)[1]
     if cl:
         closed = 1
     else:
         closed = -1
     vol = tryvol(A, b, initcs)[0]
     return (-vol*closed) + Pv*(outnorm**3)
 def objfn(Ab, *args):
     """Volume objective function for fmin (Simplex)."""
     initcs = args[0]
     A, b = splitAb(Ab, initcs.nd)
     vol, V = tryvol(A, b, initcs)
     Pv = 200.
     Pn = 100.
     #Penalties
     # large b norm
     bnorm = abs(linalg.norm(b) - 1)
     # points outside of init space
     iterset = ConSet(V)
     outnorm = linalg.norm(iterset.allinside(initcs)[1])
     #outnorm = iterset.allinside(initcs)[2]
     # open shape
     cl = con2vert(A, b)[1]
     if cl:
         closed = 1
     else:
         closed = -1
     vol = tryvol(A, b, initcs)[0]
     return (-vol*closed) + Pn*(bnorm**initcs.nd) + Pv*(outnorm**(initcs.nd+3))
from conclasses import ConSet
from scipy import array, linalg
from auxfuns import mat2ab
from fitting import fitset, fitmaxbox

#MAIN START =================================================================

# define AIS and DOS (equations : Ax<b)
# equations in the form Ax<b, matrix = [A s b] 
# with s the sign vector [1:>, -1:<]
AISA, AISs, AISb = mat2ab(array([[1., 0., 1.,  4],
                                 [1., 0., -1., 20],
                                 [0., 1.,  1., 4],
                                 [0., 1., -1., 20.]]))
AIS = ConSet(AISA, AISs, AISb) 

DOSA, DOSs, DOSb = mat2ab(array([[1., 0.,  1., 1.2],
                                 [1., 0., -1., 1.5],
                                 [0., 1.,  1., 15.],
                                 [0., 1., -1., 18.]]))
DOS = ConSet(DOSA, DOSs, DOSb)

POS = ConSet(*mat2ab(array([[1., 0.,  1., 0],
                            [1., 0., -1., 1.9],
                            [0., 1.,  1., 6.],
                            [0., 1., -1., 25.]])))

# define G (steady-state model)
G = array([[-0.0476, -0.0498],
           [ 0.0111, -0.0604]])
from conclasses import ConSet
from scipy import array, linalg
from auxfuns import mat2ab
from fitting import fitset
from convertfuns import con2pscon

#MAIN START =================================================================

# define AIS and DOS (equations : Ax<b)
# equations in the form Ax<b, matrix = [A s b] 
# with s the sign vector [1:>, -1:<]
AISA, AISs, AISb = mat2ab(array([[1., 0., 1.,  11],
                                 [1., 0., -1., 15],
                                 [0., 1.,  1., 25],
                                 [0., 1., -1., 90.]]))
AIS = ConSet(AISA, AISs, AISb) 

DOSA, DOSs, DOSb = mat2ab(array([[1., 0.,  1., 66.],
                                 [1., 0., -1., 68.],
                                 [0., 1.,  1., 78.],
                                 [0., 1., -1., 82.]]))
DOS = ConSet(DOSA, DOSs, DOSb)

# define G (steady-state model)
#              R     T10sp
G = array([[-0.0575, 0.96],    # T1
           [ -0.146, 0.518]])  # T8
Gi = linalg.inv(G)

# calc AOS (from G and AIS)
lss = array([[68., 78.]]) # nominal operating point (used for model generation)
def fitshape(cset, spset, solver):
    """
    Fit a constraint set (specified by the number of constraints) within an existing
    constraint set.
     cset - [ConSet] existing constraint set
     ncon - [int] number of constraints to fit
    """
    #### State problem
    # ncongiven > ncon >= nD+1
    # Constraints are bounding
    # All vertices within constraint set
    #### Define parameters
    snorm = linalg.norm(spset.b)
    sp = c_[spset.A, spset.b]/snorm # starting point - combined Ab matrix to optimise
    
    #### Objective fn (FMIN)
    def objfn(Ab, *args):
        """Volume objective function for fmin (Simplex)."""
        initcs = args[0]
        A, b = splitAb(Ab, initcs.nd)
        vol, V = tryvol(A, b, initcs)
        Pv = 200.
        Pn = 100.
        #Penalties
        # large b norm
        bnorm = abs(linalg.norm(b) - 1)
        # points outside of init space
        iterset = ConSet(V)
        outnorm = linalg.norm(iterset.allinside(initcs)[1])
        #outnorm = iterset.allinside(initcs)[2]
        # open shape
        cl = con2vert(A, b)[1]
        if cl:
            closed = 1
        else:
            closed = -1
        vol = tryvol(A, b, initcs)[0]
        return (-vol*closed) + Pn*(bnorm**initcs.nd) + Pv*(outnorm**(initcs.nd+3))
       
    #### Objective fn (SLSQP)
    def objfn2(Ab, *args):
        """Volume objective function for SLSQP."""
        initcs = args[0]
        A, b = splitAb(Ab, initcs.nd)
        cl = con2vert(A, b)[1]
        if cl:
            closed = 1
        else:
            closed = -1
        vol = tryvol(A, b, initcs)[0]
        return closed * -vol
    def eqconsfn(Ab, *args):
        """Optimiser equality constraint function."""
        initcs = args[0]
        b = splitAb(Ab, initcs.nd)[1]
        # get vertices
        bn = linalg.norm(b) - 1
        return array([bn])
    def ieqconsfn(Ab, *args):
        """Optimiser inequality constraint function."""
        initcs = args[0]
        A, b = splitAb(Ab, initcs.nd)
        # get vertices
        V = tryvol(A, b, initcs)[1]
        iterset = ConSet(V)
        # constraint checking
        if iterset.allinside(initcs):
            return 0
        else:
            return -1
    
    #### Maximise volume
    if solver in 'aA':
        optAb = optimize.fmin_slsqp(objfn2, sp, f_eqcons=eqconsfn,
                                    f_ieqcons=ieqconsfn, args=[cset], iprint=0)
    elif solver in 'bB':
        optAb = optimize.fmin(objfn, sp, args=[cset], maxiter=20000, disp=False)
    elif solver in 'cC':
        optAb = optimize.fmin_cobyla(objfn2, sp, ieqconsfn, args=[cset], iprint=0)
        optAb = optAb.ravel()
    tA, tb = splitAb(optAb, cset.nd)
    ts = -ones(tb.shape)
    optsol = ConSet(tA, ts, tb)
    if solver in 'bB':
        optcent = sum(optsol.vert, axis=0)/len(optsol.vert)
        itersol = ConSet(optsol.vert)
        while not itersol.allinside(cset)[0]:
            vi = (itersol.vert - optcent)*0.9999 + optcent
            itersol = ConSet(vi)
        optsol = itersol
    return optsol
def fitcube(cset, spset, solver):
    """
    Fit a rectangle (high/low limits on outputs) within an existing
    constraint set.
     cset - [ConSet] existing constraint set
    """
    #### State problem
    # nvar = cset.nd
    # Constraints are bounding
    # All vertices within constraint set
    #### Define parameters
    sp = spset.b.ravel() # starting point - b matrix to optimise
    #### Objective fn (SLSQP)
    def objfn(Ab, *args):
        """Volume objective function for SLSQP."""
        initcs = args[0]
        A = r_[eye(initcs.nd), -eye(initcs.nd)]
        b = array([Ab]).T
        cl = con2vert(A, b)[1]
        if cl:
            closed = 1
        else:
            closed = -1
        vol = tryvol(A, b, initcs)[0]
        return closed * -vol
    #### Constraints
    def ieqconsfn(Ab, *args):
        """Optimiser inequality constraint function."""
        initcs = args[0]
        A = r_[eye(initcs.nd), -eye(initcs.nd)]
        b = array([Ab]).T
        # get vertices for constraint set iteration
        V = tryvol(A, b, initcs)[1]
        iterset = ConSet(V)
        #constraint checking for vertices
        ineqs = iterset.allinside(initcs)[1]
        return array([-linalg.norm(ineqs)])
    
    #### Objective fn (FMIN)
    def objfn2(Ab, *args):
        """Volume objective function for fmin (Simplex)."""
        initcs = args[0]
        A = r_[eye(initcs.nd), -eye(initcs.nd)]
        b = array([Ab]).T
        vol, V = tryvol(A, b, initcs)
        Pv = 200.
        #Penalties
        # points outside of init space
        iterset = ConSet(V)
        outnorm = linalg.norm(iterset.allinside(initcs)[1])
        # open shape
        cl = con2vert(A, b)[1]
        if cl:
            closed = 1
        else:
            closed = -1
        vol = tryvol(A, b, initcs)[0]
        return (-vol*closed) + Pv*(outnorm**3)
    
    #### Maximise volume
    if solver in 'aA':
        optAb = optimize.fmin_slsqp(objfn, sp, f_ieqcons=ieqconsfn, args=[cset], 
                                iprint=0)
    elif solver in 'bB':
        optAb = optimize.fmin(objfn2, sp, args=[cset], maxiter=50000, disp=False)
    if solver in 'cC':
        optAb = optimize.fmin_cobyla(objfn, sp, ieqconsfn, args=[cset], 
                                iprint=0)
    tA = r_[eye(cset.nd), -eye(cset.nd)]
    tb = array([optAb]).T
    ts = -ones(tb.shape)
    optsol = ConSet(tA, ts, tb)
    if solver in 'bBcC':
        optcent = sum(optsol.vert, axis=0)/len(optsol.vert)
        itersol = ConSet(optsol.vert)
        while not itersol.allinside(cset)[0]:
            vi = (itersol.vert - optcent)*0.9999 + optcent
            itersol = ConSet(vi)
        optsol = itersol
    return optsol
#               - conclasses

from conclasses import ConSet
from scipy import array
from auxfuns import mat2ab

#MAIN START =================================================================

# define AIS and DOS (equations : Ax<b)
# equations in the form Ax<b, matrix = [A s b] 
# with s the sign vector [1:>, -1:<]
AISA, AISs, AISb = mat2ab(array([[1., 0., 1.,  -0.0525],
                                 [1., 0., -1., 0.125],
                                 [0., 1.,  1., -10],
                                 [0., 1., -1., 10.]]))
AIS = ConSet(AISA, AISs, AISb) 

DOSA, DOSs, DOSb = mat2ab(array([[1., 0.,  1., -1.],
                                 [1., 0., -1.,  1.],
                                 [0., 1.,  1., -1.],
                                 [0., 1., -1.,  1.]]))
DOS = ConSet(DOSA, DOSs, DOSb)

# define G (steady-state model)
lss = array([[50., 50.]]) # nominal operating point (used for model generation)
G = array([[1, 0.0025],
           [2, 0.0025]])  # gain matrix - atm linear steady state matrix

# calc AOS (from G and AIS)
AOSA, AOSs, AOSb = AIS.outconlin(G, AIS.cscent, lss)  
AOS = ConSet(AOSA, AOSs, AOSb)