Ejemplo n.º 1
0
def call_solver(p,quiet):
    """
    Calls solver. 

    :param p: Convex cvxpy_program. 
              Assumed to be expanded.
    :param quiet: Boolean.
    """

    # Set printing format for cvxopt sparse matrices
    opt.spmatrix_str = opt.printing.spmatrix_str_triplet 	
    
    # Expand objects defined via partial minimization
    constr_list = cvxpy_list(pm_expand(p.constraints))
    
    # Get variables
    variables = constr_list.variables
    variables.sort()

    # Count variables
    n = len(variables)

    # Create variable-index map
    var_to_index = {}
    for i in range(0,n,1):
        var_to_index[variables[i]] = i

    # Construct objective vector
    c = construct_c(p.objective,var_to_index,n,p.action)

    # Construct Ax == b
    A,b = construct_Ab(constr_list._get_eq(),var_to_index,n)

    # Construct  Gx <= h
    G,h,dim_l,dim_q,dim_s = construct_Gh(constr_list._get_ineq_in(),
                                         var_to_index,n)
    
    # Construct F
    F = construct_F(constr_list._get_ineq_in(),var_to_index,n)

    # Call cvxopt
    solvers.options['maxiters'] = p.options['maxiters']
    solvers.options['abstol'] = p.options['abstol']
    solvers.options['reltol'] = p.options['reltol']
    solvers.options['feastol'] = p.options['feastol']
    solvers.options['show_progress'] = not quiet
    dims = {'l':dim_l, 'q':dim_q, 's':dim_s}
    if F is None:
        r =  solvers.conelp(c,G,h,dims,A,b)
    else:
        r =  solvers.cpl(c,F,G,h,dims,A,b)

    # Store numerical values
    if r['status'] != PRIMAL_INFEASIBLE:
        for v in variables:
            v.value =  r['x'][var_to_index[v]]

    # Return result
    return r
Ejemplo n.º 2
0
def call_solver(p, quiet):
    """
    Calls solver. 

    :param p: Convex cvxpy_program. 
              Assumed to be expanded.
    :param quiet: Boolean.
    """

    # Set printing format for cvxopt sparse matrices
    opt.spmatrix_str = opt.printing.spmatrix_str_triplet

    # Expand objects defined via partial minimization
    constr_list = cvxpy_list(pm_expand(p.constraints))

    # Get variables
    variables = constr_list.variables
    variables.sort()

    # Count variables
    n = len(variables)

    # Create variable-index map
    var_to_index = {}
    for i in range(0, n, 1):
        var_to_index[variables[i]] = i

    # Construct objective vector
    c = construct_c(p.objective, var_to_index, n, p.action)

    # Construct Ax == b
    A, b = construct_Ab(constr_list._get_eq(), var_to_index, n)

    # Construct  Gx <= h
    G, h, dim_l, dim_q, dim_s = construct_Gh(constr_list._get_ineq_in(),
                                             var_to_index, n)

    # Construct F
    F = construct_F(constr_list._get_ineq_in(), var_to_index, n)

    # Call cvxopt
    solvers.options['maxiters'] = p.options['maxiters']
    solvers.options['abstol'] = p.options['abstol']
    solvers.options['reltol'] = p.options['reltol']
    solvers.options['feastol'] = p.options['feastol']
    solvers.options['show_progress'] = not quiet
    dims = {'l': dim_l, 'q': dim_q, 's': dim_s}
    if F is None:
        r = solvers.conelp(c, G, h, dims, A, b)
    else:
        r = solvers.cpl(c, F, G, h, dims, A, b)

    # Store numerical values
    if r['status'] != PRIMAL_INFEASIBLE:
        for v in variables:
            v.value = r['x'][var_to_index[v]]

    # Return result
    return r
Ejemplo n.º 3
0
def mean_variance_optimization(covariance,
                               mean=None,
                               expected_return=None,
                               expected_variance=None,
                               can_short=False):
    if expected_return is not None and expected_variance is not None:
        raise ValueError('不能同时设定均值与方差!')

    A = np.ones((covariance.shape[0], 1))
    A = matrix(A.T)
    b = np.ones((1, 1))
    b = matrix(b)

    if expected_variance is not None:
        c = -mean.reshape((covariance.shape[0], 1))

        def F(x):
            return x.dot(covariance).dot(x) - expected_variance

        if not can_short:
            G = -np.eye(covariance.shape[0])
            h = np.zeros_like(mean)
        else:
            G, h = None, None
        c = matrix(c)
        G = matrix(G)
        h = matrix(h)
        result = solvers.cpl(c, F, G, h, A, b)
        return np.array(result['x'])

    Q = covariance.values
    Q = matrix(Q)
    p = np.zeros((covariance.shape[0], 1))
    p = matrix(p)

    if not can_short:
        if expected_return is not None:
            G = np.vstack([
                -mean.values.reshape((1, covariance.shape[0])),
                -np.eye(covariance.shape[0])
            ])
            h = np.array([-expected_return].extend([0] * covariance.shape[0]))
        else:
            G = -np.eye(covariance.shape[0])
            h = np.zeros((covariance.shape[0], 1))
    else:
        if expected_return is not None:
            G = -mean.values.reshape((1, covariance.shape[0]))
            h = np.array([-expected_return])
        else:
            G = None
            h = None

    G = matrix(G)
    h = matrix(h)
    result = solvers.qp(Q, p, G, h, A, b)

    return pd.Series(result['x'],
                     index=covariance.index), result['primal objective']
Ejemplo n.º 4
0
    def optimize(self, ret, cov):
        """
        Max return, constrains on risk
        """

        cov = np.matrix(cov)

        # positive definite check
        if not np.all(np.linalg.eigvals(cov) > 0):
            print('Not positive definite.')
            mat = cov * cov.T
            w, v = np.linalg.eig(mat)
            sqrt_w, v = np.diag(np.sqrt(w)), np.matrix(v)
            cov = v * sqrt_w * np.linalg.inv(v)

        # positive definite check may yield a plural value matrix
        # thus use cov.real, note plural part is tiny e^-10
        ret, cov, N = matrix(-ret), matrix(cov.real), len(ret)

        ## nonlinear constraints
        def func(x=None, z=None):
            if x is None:
                return 1, matrix(1 / N, (N, 1))

            # risk constraints and its matrix derivative
            f = x.T * cov * x - 0.0064
            df = x.T * (cov + cov.T)
            if z is None:
                return f, df
            return f, df, z[0, 0] * (cov + cov.T)

        ## linear constrains
        ## note all the constraints are 'less and equal'

        # no shortselling
        g1 = matrix(np.diag(np.ones(N) * -1))
        h1 = matrix(np.zeros(N))

        # weights upperlimits
        g2 = matrix(np.diag(np.ones(N)))
        h2 = matrix(np.ones(N) * 0.05)
        g, h = matrix([g1, g2]), matrix([h1, h2])

        # weights sum equals 1
        a = matrix(np.ones(N)).T
        b = matrix(1.0, (1, 1))

        ## option for solver

        # print convergence table
        solvers.options['show_progress'] = self.show_progress

        # max iteration
        solvers.options['maxiters'] = self.maxiter

        sol = solvers.cpl(ret, func, g, h, A=a, b=b)
        return sol['x']
Ejemplo n.º 5
0
def model2(sigma2):
    r = matrix([-1.0, -1.0, -3.0])
    V = matrix(np.diag([1.0, 1.0, 1.0]))

    G = matrix(np.diag([-1.0, -1.0, -1.0]))
    h = matrix([0.33, 0.33, 0.33])

    A = matrix(np.ones(3)).T
    b = matrix(0.0, (1, 1))

    def F(x=None, z=None):
        if x is None:
            return 1, matrix([0.0, 0.0, 0.0])
        f = x.T * V * x - sigma2
        Df = x.T * (V + V.T)
        if z is None:
            return f, Df
        return f, Df, z[0, 0] * (V + V.T)

    dims = {'l': h.size[0], 'q': [], 's': []}
    sol = solvers.cpl(r, F, G, h, dims, A, b)
    return sol['x']
Ejemplo n.º 6
0
def floorplan(Amin, opts):

    #     minimize    W+H
    #     subject to  Amink / hk <= wk, k = 1,..., 5
    #                 x1 >= 0,  x2 >= 0, x4 >= 0
    #                 x1 + w1 + rho <= x3
    #                 x2 + w2 + rho <= x3
    #                 x3 + w3 + rho <= x5
    #                 x4 + w4 + rho <= x5
    #                 x5 + w5 <= W
    #                 y2 >= 0,  y3 >= 0,  y5 >= 0
    #                 y2 + h2 + rho <= y1
    #                 y1 + h1 + rho <= y4
    #                 y3 + h3 + rho <= y4
    #                 y4 + h4 <= H
    #                 y5 + h5 <= H
    #                 hk/gamma <= wk <= gamma*hk,  k = 1, ..., 5
    #
    # 22 Variables W, H, x (5), y (5), w (5), h (5).
    #
    # W, H:  scalars; bounding box width and height
    # x, y:  5-vectors; coordinates of bottom left corners of blocks
    # w, h:  5-vectors; widths and heigths of the 5 blocks

    rho, gamma = 1.0, 5.0  # min spacing, min aspect ratio

    # The objective is to minimize W + H.  There are five nonlinear
    # constraints
    #
    #     -wk + Amink / hk <= 0,  k = 1, ..., 5

    c = matrix(2 * [1.0] + 20 * [0.0])

    def F(x=None, z=None):
        # F0
        if x is None:
            return 5, matrix(17 * [0.0] + 5 * [1.0])
        if min(x[17:]) <= 0.0:
            return None
        # F1
        f = -x[12:17] + div(Amin, x[17:])
        Df = matrix(0.0, (5, 22))
        Df[:, 12:17] = spmatrix(-1.0, range(5), range(5))
        Df[:, 17:] = spmatrix(-div(Amin, x[17:]**2), range(5), range(5))
        if z is None:
            return f, Df
        # F2
        H = spmatrix(2.0 * mul(z, div(Amin, x[17::]**3)), range(17, 22),
                     range(17, 22))
        return f, Df, H

    G = matrix(0.0, (26, 22))
    h = matrix(0.0, (26, 1))

    # -x1 <= 0
    G[0, 2] = -1.0

    # -x2 <= 0
    G[1, 3] = -1.0

    # -x4 <= 0
    G[2, 5] = -1.0

    # x1 - x3 + w1 <= -rho
    G[3, [2, 4, 12]], h[3] = [1.0, -1.0, 1.0], -rho

    # x2 - x3 + w2 <= -rho
    G[4, [3, 4, 13]], h[4] = [1.0, -1.0, 1.0], -rho

    # x3 - x5 + w3 <= -rho
    G[5, [4, 6, 14]], h[5] = [1.0, -1.0, 1.0], -rho

    # x4 - x5 + w4 <= -rho
    G[6, [5, 6, 15]], h[6] = [1.0, -1.0, 1.0], -rho

    # -W + x5 + w5 <= 0
    G[7, [0, 6, 16]] = -1.0, 1.0, 1.0

    # -y2 <= 0
    G[8, 8] = -1.0

    # -y3 <= 0
    G[9, 9] = -1.0

    # -y5 <= 0
    G[10, 11] = -1.0

    # -y1 + y2 + h2 <= -rho
    G[11, [7, 8, 18]], h[11] = [-1.0, 1.0, 1.0], -rho

    # y1 - y4 + h1 <= -rho
    G[12, [7, 10, 17]], h[12] = [1.0, -1.0, 1.0], -rho

    # y3 - y4 + h3 <= -rho
    G[13, [9, 10, 19]], h[13] = [1.0, -1.0, 1.0], -rho

    # -H + y4 + h4 <= 0
    G[14, [1, 10, 20]] = -1.0, 1.0, 1.0

    # -H + y5 + h5 <= 0
    G[15, [1, 11, 21]] = -1.0, 1.0, 1.0

    # -w1 + h1/gamma <= 0
    G[16, [12, 17]] = -1.0, 1.0 / gamma

    # w1 - gamma * h1 <= 0
    G[17, [12, 17]] = 1.0, -gamma

    # -w2 + h2/gamma <= 0
    G[18, [13, 18]] = -1.0, 1.0 / gamma

    #  w2 - gamma * h2 <= 0
    G[19, [13, 18]] = 1.0, -gamma

    # -w3 + h3/gamma <= 0
    G[20, [14, 18]] = -1.0, 1.0 / gamma

    #  w3 - gamma * h3 <= 0
    G[21, [14, 19]] = 1.0, -gamma

    # -w4  + h4/gamma <= 0
    G[22, [15, 19]] = -1.0, 1.0 / gamma

    #  w4 - gamma * h4 <= 0
    G[23, [15, 20]] = 1.0, -gamma

    # -w5 + h5/gamma <= 0
    G[24, [16, 21]] = -1.0, 1.0 / gamma

    #  w5 - gamma * h5 <= 0.0
    G[25, [16, 21]] = 1.0, -gamma

    # solve and return W, H, x, y, w, h

    solvers.options.update(opts)
    sol = solvers.cpl(c, F, G, h)
    return  sol['x'][0], sol['x'][1], sol['x'][2:7], sol['x'][7:12], \
        sol['x'][12:17], sol['x'][17:], sol['x']
Ejemplo n.º 7
0
def solve_convex(p,mode):
    """
    Description
    -----------
    Solves the convex program p. It assumes p is the convex part 
    of an expanded and transformed program.

    Arguments
    ---------
    p: convex cvxpy_program.    
    mode: 'rel' (relaxation) or 'scp' (sequential convex programming).
    """

    # Select options
    if(mode == 'scp'):
        options = p.options['SCP_SOL']
    else:
        options = p.options['REL_SOL']
    quiet = p.options['quiet']

    # Printing format for cvxopt sparse matrices
    opt.spmatrix_str = opt.printing.spmatrix_str_triplet 	
    
    # Partial minimization expansion
    constr_list = pm_expand(p.constr)
    
    # Get variables
    variables = constr_list.get_vars()

    # Count variables
    n = len(variables)

    # Create a map (var - pos)
    if(options['show steps'] and not quiet):
        print '\nCreating variable - index map'
    var_to_index = {}
    for i in range(0,n,1):
        if(options['show steps'] and not quiet):
            print variables[i],'<-->',i
        var_to_index[variables[i]] = i

    # Construct objective vector
    c = construct_c(p.obj,var_to_index,n,p.action)
    if(options['show steps'] and not quiet):
        print '\nConstructing c vector'
        print 'c = '
        print c

    # Construct Ax == b
    A,b = construct_Ab(constr_list._get_eq(),var_to_index,n,options)
    if(options['show steps'] and not quiet):
        print '\nConstructing Ax == b'
        print 'A ='
        print A
        print 'b ='
        print b

    # Construct  Gx <= h
    G,h,dim_l,dim_q,dim_s = construct_Gh(constr_list._get_ineq_in(),
                                         var_to_index,n)
    if(options['show steps'] and not quiet):
        print '\nConstructing Gx <= h'
        print 'G ='
        print G
        print 'h ='
        print h
    
    # Construct F
    F = construct_F(constr_list._get_ineq_in(),var_to_index,n)
    if(options['show steps'] and not quiet):
        print '\nConstructing F'

    # Call cvxopt
    solvers.options['show_progress'] = options['solver progress'] and not quiet
    solvers.options['maxiters'] = options['maxiters']
    solvers.options['abstol'] = options['abstol']
    solvers.options['reltol'] = options['reltol']
    solvers.options['feastol'] = options['feastol']
    dims = {'l':dim_l, 'q':dim_q, 's':dim_s}
    if(F is None):
        if(options['show steps'] and not quiet):
            print '\nCalling cvxopt conelp solver'
        r =  solvers.conelp(c,G,h,dims,A,b)
    else:
        if(options['show steps'] and not quiet):
            print '\nCalling cvxopt cpl solver'
        r =  solvers.cpl(c,F,G,h,dims,A,b)

    # Store numerical values
    if(r['status'] != 'primal infeasible'):
        if(options['show steps'] and not quiet):
            print '\nStoring numerical values:'
        for v in variables:
            value = r['x'][var_to_index[v]]
            v.data =  value
            if(options['show steps']and not quiet):
                print v,' <- ', v.data

    # Return result
    return r
Ejemplo n.º 8
0
def max_returns(returns, risk_structure, risk, base=None, up=None, eq=None, noeq=None):
    """
    给定风险约束,最大化收益的最优投资组合
    :param returns: 下一期股票收益
    :param risk_structure: 风险结构
    :param risk: Double, 风险或是年化跟踪误差的上限
    :param base: Vector, 基准组合
    :param up: Double, 个股权重的上限
    :param eq: list, [A, B], 其余等式约束条件
    :param noeq: list, [G, h], 其余不等式约束条件
    :return: 最优化的投资组合
    """
    assert len(risk_structure) == len(returns), "numbers of companies in risk structure " \
                                                "and returns vector are not the same"

    if base is not None:
        assert len(base) == len(returns), "numbers of companies in  base vector and returns vector are not the same"

    if up is None:
        up = np.ones(len(returns))  # 默认取值为1
    else:
        up = np.ones(len(returns)) * up  # up 既可以为值也可以为列向量

    r, v = matrix(np.asarray(returns)) * -1, matrix(np.asarray(risk_structure))
    num = len(returns)
    base = matrix(np.asarray(base if base is not None else np.zeros(num))) * 1.0  # base 默认为0

    def func(x=None, z=None):
        if x is None:
            return 1, matrix(0.0, (len(r), 1))
        f = x.T * v * x - risk ** 2 / 12
        df = x.T * (v + v.T)
        if z is None:
            return f, df
        return f, df, z[0, 0] * (v + v.T)

    # 不能卖空
    g1 = matrix(np.diag(np.ones(num) * -1))
    h1 = base
    # 个股上限
    g2 = matrix(np.diag(np.ones(num)))
    h2 = matrix(up) - base
    g, h = matrix([g1, g2]), matrix([h1, h2])
    # 控制权重和
    # 0.0 if sum(base) > 0 else 1.0 在没有基准(即基准为 0.0)时为1.0,有基准时为0.0
    a = matrix(np.ones(num)).T
    b = matrix(0.0 if sum(base) > 0 else 1.0, (1, 1))

    if noeq is not None:
        assert type(noeq) == list and len(noeq) == 2, "不等式约束条件为形如 [G, H] 的列表"
        g3, h3 = matrix(noeq[0]), matrix(noeq[1])
        g, h = matrix([g, g3]), matrix([h, h3])

    if eq is not None:
        assert type(eq) == list and len(eq) == 2, "等式约束条件为形如 [A, B] 的列表"
        a1, b1 = matrix(eq[0]), matrix(eq[1])
        a, b = matrix([a, a1]), matrix([b, b1])

    solvers.options['show_progress'] = show_progress
    solvers.options['maxiters'] = 1000
    sol = solvers.cpl(r, func, g, h, A=a, b=b)
    return sol['x']
Ejemplo n.º 9
0
def max_returns(returns,
                risk_structure,
                risk,
                base=None,
                up=None,
                industry=None,
                deviate=None,
                factor=None,
                xk=None):
    """
    给定风险约束,最大化收益的最优投资组合
    :param returns: 下一期股票收益
    :param risk_structure: 风险结构
    :param risk: Double, 风险或是年化跟踪误差的上限
    :param base: Vector, 基准组合
    :param up: Double, 个股权重的上限
    :param industry: DataFrame, 行业哑变量矩阵
    :param deviate: Double, 行业偏离
    :param factor: DataFrame, 因子暴露
    :param xk: Double, 因子风险的上限
    :return: 最优化的投资组合
    """
    assert len(risk_structure) == len(returns), "numbers of companies in risk structure " \
                                                "and returns vector are not the same"
    if industry is not None:
        assert len(industry) == len(returns), "numbers of companies in industry dummy matrix " \
                                              "not equals to it in returns vector"
    if base is not None:
        assert len(base) == len(
            returns
        ), "numbers of companies in  base vector and returns vector are not the same"

    if up is None:
        up = np.ones(len(returns))
    else:
        up = np.ones(len(returns)) * up

    r, v = matrix(np.asarray(returns)) * -1, matrix(np.asarray(risk_structure))
    num = len(returns)
    base = matrix(
        np.asarray(base if base is not None else np.zeros(num))) * 1.0

    def func(x=None, z=None):
        if x is None:
            return 1, matrix(0.0, (len(r), 1))
        f = x.T * v * x - risk**2 / 12
        df = x.T * (v + v.T)
        if z is None:
            return f, df
        return f, df, z[0, 0] * (v + v.T)

    # 不能卖空
    g1 = matrix(np.diag(np.ones(num) * -1))
    h1 = base
    # 个股上限
    g2 = matrix(np.diag(np.ones(num)))
    h2 = matrix(up) - base
    g, h = matrix([g1, g2]), matrix([h1, h2])
    # 控制权重和
    # 0.0 if sum(base) > 0 else 1.0 在没有基准(即基准为 0.0)时为1.0,有基准时为0.0
    a = matrix(np.ones(num)).T
    b = matrix(0.0 if sum(base) > 0 else 1.0, (1, 1))

    # 因子风险约束
    if factor is not None:
        g3 = matrix(np.asarray(factor)).T
        h3 = matrix(xk, (len(factor.columns), 1))
        g, h = matrix([g, g3]), matrix([h, h3])

    # 对冲行业风险
    if industry is not None:
        m = matrix(np.asarray(industry) * 1.0).T
        c = matrix(deviate, (len(industry.columns), 1))
        if deviate == 0.0:
            a, base = m, c
        elif deviate > 0.0:
            g, h = matrix([matrix([g, m]), -m]), matrix([matrix([h, c]), c])

    solvers.options['show_progress'] = show_progress
    solvers.options['maxiters'] = 1000
    sol = solvers.cpl(r, func, g, h, A=a, b=b)
    return sol['x']
Ejemplo n.º 10
0
def solve_convex(p, mode):
    """
    Description
    -----------
    Solves the convex program p. It assumes p is the convex part 
    of an expanded and transformed program.

    Arguments
    ---------
    p: convex cvxpy_program.    
    mode: 'rel' (relaxation) or 'scp' (sequential convex programming).
    """

    # Select options
    if (mode == 'scp'):
        options = p.options['SCP_SOL']
    else:
        options = p.options['REL_SOL']
    quiet = p.options['quiet']

    # Printing format for cvxopt sparse matrices
    opt.spmatrix_str = opt.printing.spmatrix_str_triplet

    # Partial minimization expansion
    constr_list = pm_expand(p.constr)

    # Get variables
    variables = constr_list.get_vars()

    # Count variables
    n = len(variables)

    # Create a map (var - pos)
    if (options['show steps'] and not quiet):
        print '\nCreating variable - index map'
    var_to_index = {}
    for i in range(0, n, 1):
        if (options['show steps'] and not quiet):
            print variables[i], '<-->', i
        var_to_index[variables[i]] = i

    # Construct objective vector
    c = construct_c(p.obj, var_to_index, n, p.action)
    if (options['show steps'] and not quiet):
        print '\nConstructing c vector'
        print 'c = '
        print c

    # Construct Ax == b
    A, b = construct_Ab(constr_list._get_eq(), var_to_index, n, options)
    if (options['show steps'] and not quiet):
        print '\nConstructing Ax == b'
        print 'A ='
        print A
        print 'b ='
        print b

    # Construct  Gx <= h
    G, h, dim_l, dim_q, dim_s = construct_Gh(constr_list._get_ineq_in(),
                                             var_to_index, n)
    if (options['show steps'] and not quiet):
        print '\nConstructing Gx <= h'
        print 'G ='
        print G
        print 'h ='
        print h

    # Construct F
    F = construct_F(constr_list._get_ineq_in(), var_to_index, n)
    if (options['show steps'] and not quiet):
        print '\nConstructing F'

    # Call cvxopt
    solvers.options['show_progress'] = options['solver progress'] and not quiet
    solvers.options['maxiters'] = options['maxiters']
    solvers.options['abstol'] = options['abstol']
    solvers.options['reltol'] = options['reltol']
    solvers.options['feastol'] = options['feastol']
    dims = {'l': dim_l, 'q': dim_q, 's': dim_s}
    if (F is None):
        if (options['show steps'] and not quiet):
            print '\nCalling cvxopt conelp solver'
        r = solvers.conelp(c, G, h, dims, A, b)
    else:
        if (options['show steps'] and not quiet):
            print '\nCalling cvxopt cpl solver'
        r = solvers.cpl(c, F, G, h, dims, A, b)

    # Store numerical values
    if (r['status'] != 'primal infeasible'):
        if (options['show steps'] and not quiet):
            print '\nStoring numerical values:'
        for v in variables:
            value = r['x'][var_to_index[v]]
            v.data = value
            if (options['show steps'] and not quiet):
                print v, ' <- ', v.data

    # Return result
    return r
Ejemplo n.º 11
0
def floorplan(Amin):

    #     minimize    W+H
    #     subject to  Amin1 / h1 <= w1 
    #                 Amin2 / h2 <= w2 
    #                 Amin3 / h3 <= w3 
    #                 Amin4 / h4 <= w4 
    #                 Amin5 / h5 <= w5 
    #                 x1 >= 0
    #                 x2 >= 0
    #                 x4 >= 0
    #                 x1 + w1 + rho <= x3  
    #                 x2 + w2 + rho <= x3 
    #                 x3 + w3 + rho <= x5  
    #                 x4 + w4 + rho <= x5
    #                 x5 + w5 <= W
    #                 y2 >= 0  
    #                 y3 >= 0  
    #                 y5 >= 0 
    #                 y2 + h2 + rho <= y1 
    #                 y1 + h1 + rho <= y4 
    #                 y3 + h3 + rho <= y4
    #                 y4 + h4 <= H  
    #                 y5 + h5 <= H
    #                 h1/gamma <= w1 <= gamma*h1
    #                 h2/gamma <= w2 <= gamma*h2
    #                 h3/gamma <= w3 <= gamma*h3
    #                 h4/gamma <= w4 <= gamma*h4
    #                 h5/gamma <= w5 <= gamma*h5
    #
    # 22 Variables W, H, x (5), y (5), w (5), h (5).
    #
    # W, H:  scalars; bounding box width and height
    # x, y:  5-vectors; coordinates of bottom left corners of blocks
    # w, h:  5-vectors; widths and heigths of the 5 blocks

    rho, gamma = 1.0, 5.0   # min spacing, min aspect ratio

    # The objective is to minimize W + H.  There are five nonlinear 
    # constraints 
    #
    #     -w1 + Amin1 / h1 <= 0 
    #     -w2 + Amin2 / h2 <= 0 
    #     -w3 + Amin3 / h3 <= 0 
    #     -w4 + Amin4 / h4 <= 0 
    #     -w5 + Amin5 / h5 <= 0.

    c = matrix(2*[1.0] + 20*[0.0])

    def F(x=None, z=None):
        if x is None:  
            return 5, matrix(17*[0.0] + 5*[1.0])
        if min(x[17:]) <= 0.0:  
            return None 
        f = -x[12:17] + div(Amin, x[17:]) 
        Df = matrix(0.0, (5,22))
        Df[:,12:17] = spmatrix(-1.0, range(5), range(5))
        Df[:,17:] = spmatrix(-div(Amin, x[17:]**2), range(5), range(5))
        if z is None: 
            return f, Df
        H = spmatrix( 2.0* mul(z, div(Amin, x[17::]**3)), range(17,22), 
            range(17,22) )
        return f, Df, H

    # linear inequalities
    G = matrix(0.0, (26,22)) 
    h = matrix(0.0, (26,1))

    # -x1 <= 0
    G[0,2] = -1.0   

    # -x2 <= 0
    G[1,3] = -1.0   

    # -x4 <= 0
    G[2,5] = -1.0   

    # x1 - x3 + w1 <= -rho 
    G[3, [2, 4, 12]], h[3] = [1.0, -1.0, 1.0], -rho

    # x2 - x3 + w2 <= -rho 
    G[4, [3, 4, 13]], h[4] = [1.0, -1.0, 1.0], -rho
 
    # x3 - x5 + w3 <= -rho 
    G[5, [4, 6, 14]], h[5] = [1.0, -1.0, 1.0], -rho 

    # x4 - x5 + w4 <= -rho 
    G[6, [5, 6, 15]], h[6] = [1.0, -1.0, 1.0], -rho 

    # -W + x5 + w5 <= 0
    G[7, [0, 6, 16]] = -1.0, 1.0, 1.0

    # -y2 <= 0  
    G[8,8] = -1.0

    # -y3 <= 0  
    G[9,9] = -1.0

    # -y5 <= 0 
    G[10,11] = -1.0

    # -y1 + y2 + h2 <= -rho 
    G[11, [7, 8, 18]], h[11] = [-1.0, 1.0, 1.0], -rho 

    # y1 - y4 + h1 <= -rho 
    G[12, [7, 10, 17]], h[12] = [1.0, -1.0, 1.0], -rho 

    # y3 - y4 + h3 <= -rho 
    G[13, [9, 10, 19]], h[13] = [1.0, -1.0, 1.0], -rho 

    # -H + y4 + h4 <= 0  
    G[14, [1, 10, 20]] = -1.0, 1.0, 1.0

    # -H + y5 + h5 <= 0
    G[15, [1, 11, 21]] = -1.0, 1.0, 1.0

    # -w1 + h1/gamma <= 0 
    G[16, [12, 17]] = -1.0, 1.0/gamma

    # w1 - gamma * h1 <= 0
    G[17, [12, 17]] = 1.0, -gamma

    # -w2 + h2/gamma <= 0 
    G[18, [13, 18]] = -1.0, 1.0/gamma 

    # w2 - gamma * h2 <= 0
    G[19, [13, 18]] = 1.0, -gamma

    # -w3 + h3/gamma <= 0  
    G[20, [14, 18]] = -1.0, 1.0/gamma

    # w3 - gamma * h3 <= 0
    G[21, [14, 19]] = 1.0, -gamma

    # -w4  + h4/gamma <= 0 
    G[22, [15, 19]] = -1.0, 1.0/gamma

    # w4 - gamma * h4 <= 0
    G[23, [15, 20]] = 1.0, -gamma

    # -w5 + h5/gamma <= 0 
    G[24, [16, 21]] = -1.0, 1.0/gamma

    # w5 - gamma * h5 <= 0.0
    G[25, [16, 21]] = 1.0, -gamma

    # solve and return W, H, x, y, w, h 
    sol = solvers.cpl(c, F, G, h)
    return  sol['x'][0], sol['x'][1], sol['x'][2:7], sol['x'][7:12], \
        sol['x'][12:17], sol['x'][17:] 
Ejemplo n.º 12
0
    G[13, [9, 10, 19]], h[13] = [1.0, -1.0, 1.0], -rho  #  y3 - y4 + h3 <= -rho
    G[14, [1, 10, 20]] = -1.0, 1.0, 1.0                 # -H + y4 + h4 <= 0
    G[15, [1, 11, 21]] = -1.0, 1.0, 1.0                 # -H + y5 + h5 <= 0
    G[16, [12, 17]] = -1.0, 1.0/gamma                   # -w1 + h1/gamma <= 0
    G[17, [12, 17]] = 1.0, -gamma                       #  w1 - gamma * h1 <= 0
    G[18, [13, 18]] = -1.0, 1.0/gamma                   # -w2 + h2/gamma <= 0
    G[19, [13, 18]] = 1.0, -gamma                       #  w2 - gamma * h2 <= 0
    G[20, [14, 19]] = -1.0, 1.0/gamma                   # -w3 + h3/gamma <= 0
    G[21, [14, 19]] = 1.0, -gamma                       #  w3 - gamma * h3 <= 0
    G[22, [15, 20]] = -1.0, 1.0/gamma                   # -w4  + h4/gamma <= 0
    G[23, [15, 20]] = 1.0, -gamma                       #  w4 - gamma * h4 <= 0
    G[24, [16, 21]] = -1.0, 1.0/gamma                   # -w5 + h5/gamma <= 0
    G[25, [16, 21]] = 1.0, -gamma                       #  w5 - gamma * h5 <= 0.0

    # solve and return W, H, x, y, w, h
    sol = solvers.cpl(c, F, G, h)
    return  sol['x'][0], sol['x'][1], sol['x'][2:7], sol['x'][7:12], sol['x'][12:17], sol['x'][17:]

pylab.figure(facecolor='w')
pylab.subplot(221)
Amin = matrix([100., 100., 100., 100., 100.])
W, H, x, y, w, h =  floorplan(Amin)
for k in range(5):
    pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]],
               [y[k], y[k]+h[k], y[k]+h[k], y[k]], facecolor = '#D0D0D0')
    pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))
pylab.axis([-1.0, 26, -1.0, 26])
pylab.xticks([])
pylab.yticks([])

pylab.subplot(222)
Ejemplo n.º 13
0
	def train(self, X, Y, radius, normfac, prevw):

		solvers.options['show_progress'] = False
		
		# Reduce maxiters and tolerance to reasonable levels
		solvers.options['maxiters'] = 200
		solvers.options['abstol'] = 1e-2
		solvers.options['feastol'] = 1e-2

		row, col = X.shape		
		n = row + self.d
		prevw = prevw.reshape((self.d, 1))
		
		
		x_0 = matrix(0.0, (n, 1))
		x_0[:row] = 1.0 - Y * dot(X, prevw) / normfac
		x_0[row:] = prevw
		
		# x represents all the variables in an array, the first ones Ei and then each dimenstion of w, updated to 1/row
		c = matrix(row*[1.0] + self.d*[0.0])  										# the objective function represented as a sum of Ei
		scale_factor = float(dot(c.T, x_0))
		if scale_factor > 0.0:
		    c /= scale_factor
		
		helper = matrix(array(row*[0.0] + self.d*[1.0]).reshape((n, 1)))
		r2 = radius**2
		
		def F(x = None, z = None):
			
			if x is None:
			    return (2, x_0)                                                       # Ei starts from 1 and w starts from 1
			
			w = x[row:]
			diff = w - prevw
			f = matrix(0.0, (2, 1))
			f[0] = dot(diff.T, diff)[0] - r2				# the first non-linear constraint ||w-w[k-1]||^2 < r[k]^2
			f[1] = dot(w.T, w)[0] - 1.0										# the second non-linear constraint ||w||^2 < 1
			
			Df = matrix(0.0, (2, n))										# creating the Df martrix, one row for each non-linear equation with variables as columns
			Df[0, row:] = 2.0 * diff.T     							    # derivative of first non-linear equation, populates a sparse matrix
			Df[1, row:] = 2.0 * w.T											# derivative of second non-linear equation, populates a sparse matrix
			
			if z is None:
			    return f, Df
			
			diag_H = 2.0 * z[0] + 2.0 * z[1] * helper   # Each nonlinear constraint has second derivative 2I w.r.t. w and 0 w.r.t. eps
			H = spdiag(diag_H)
			return f, Df, H

		# for linear inequalities
		G = matrix(0.0, (row*2, n))											# there are two linear constaints for Ei, and for each Ei the entire w
		h = matrix(0.0, (row*2, 1))
		for i in range(row):
			G[i,i] = -1.0															# -Ei <= 0
			G[row+i, i] = -1.0
			h[row+i] = -1.0
			for j in range(self.d):
				G[row+i, row+j] = (-Y[i][0]/normfac)*X[i,j]							# -Ei - yi/Tk(w.xi) <= -1
				
		# solve and return w
		sol = solvers.cpl(c, F, G, h)
		self.w = sol['x'][row:]
		self.w = array(self.w).reshape((self.d,))
		#print
		#print sol['status']
		'''
		print 'Radius wanted'
		print radius
		print 'Output of quadratic solver'
		print self.w
		print ' Norm of output of quadratic solver pre-normalization'
		print sqrt(dot(self.w.T, self.w))
		print ' Distance to the previous weight vector pre-normalization'
		print sqrt(dot((self.w-prevw).T, (self.w-prevw)))
		'''
		self.w = self.w/sqrt(dot(self.w.T,self.w))									# Normalizing the vector output
		'''
Ejemplo n.º 14
0
def cc_approx(cep,cov,w_p=1.0,w_q=1.0,init_p=None,init_q=None,show_progress=False,
max_iter=100,exact_p_mask=None,exact_q_mask=None):
	""" Computes the power spactra approximatively matching given 
	cepstral and vovariance coefficients with weights alpha and 
	beta respectively."""

	m = len(cep)
	n = len(cov)
	
	# convert initial spectrum, if any, to matrix form
	if init_p is not None:
		i_p = iter2matrix(init_p/init_p[0])
	if init_q is not None:
		i_q = iter2matrix(init_q/init_p[0])
	
	# fuction for building weight matrices	
	def build_inv_weight(w, exact_mask=None):
		# as it is this function now if, for a certain k, w[k,k] is zero and 
		# exact_mask[k] is true at the same time, the first take precedence,
		# that is the corresponing parameter will not be matched at all. 
		I = []
		J = []
		E = []
		kk = 0
		for k in range(0,w.size[0]):
			 if not w[k,k] == 0:
			 	I.append(kk)
				J.append(k)
				E.append(1.0)
				kk += 1
			 if exact_mask is not None and w[k,k] == 0:
				del exact_mask[kk]
		I.append(kk-1)
		J.append(k)
		E.append(0.0)
		M = cb.spmatrix(E, I, J)
		w_r = M*w*M.T
		i_w_r = cb.matrix(linalg.inv(w_r))
		if exact_mask is None:
			return i_w_r, M
		for k in range(0,len(exact_mask)):
			if exact_mask[k]:
				i_w_r[k,:] = 0.0
				i_w_r[:,k] = 0.0
		return i_w_r, M
	
	# handle the weight matrices
	if type(w_p) is float or type(w_p) is int:
		# by default the entropy will not be matched
		new_w_p = cb.matrix(0.0, (m,m))
		new_w_p[m+1::m+1] = w_p
	if type(w_p) is ndarray:
		if len(w_p.shape) == 2:
			new_w_p = cb.matrix(w_p)
		if len(w_p.shape) == 1:
			new_w_p = cb.matrix(0.0, (m,m))
			new_w_p[m+1::m+1] = w_p[1:m]
		if new_w_p[0,0] is not 0.0:	
			# better avoid match the entropy!
			if show_progress:
				print "warning: entropy will not be matched"
			new_w_p[0,0] = 0.0	
	i_w_p, Mp = build_inv_weight(new_w_p,exact_p_mask)
	rm = Mp.size[0]
	
	if type(w_q) is float or type(w_q) is int:
		new_w_q = cb.matrix(0.0, (n,n))
		new_w_q[0::n+1] = w_q
	if type(w_q) is ndarray:
		if len(w_q.shape) == 2:
			new_w_q = cb.matrix(w_q)
		if len(w_q.shape) == 1:
			new_w_q = cb.matrix(0.0, (n,n))
			new_w_p[0::n+1] = w_p[:n]
	i_w_q, Mq = build_inv_weight(new_w_q,exact_q_mask)
	rn = Mq.size[0]	
	
	# for debugging purposes
	tmp_x = cb.matrix(1.0, (rm+rn+1,1))
	
	def F(x=None,z=None):
		if x is None:
			x = cb.matrix(0.0, (rm+rn+1,1))
			if init_p is None or init_q is None:
				x[rm] = 1
			else:
				x[:rm] = Mp*i_p
				x[rm:rm+rn] = Mq*i_q
			return 1, x
		xp = x[:rm]
		p = fromiter(Mp.T*xp, float)
		p[0] += 1
		xq = x[rm:rm+rn]
		q = fromiter(Mq*xq, float)
		num = pp2p(p)
		den = pp2p(q)
		if num is None or den is None:
			return None
		xcep = cb.matrix( arma2cep(num,den,m-1), (m,1))
		xcov = cb.matrix( arma2cov(num,den,n-1), (n,1))
		f = 0.5*xp.T*i_w_p*xp + 0.5*xq.T*i_w_q*xq + xp.T*Mp*xcep -1 + xcep[0] - x[rm+rn]
		Df = cb.matrix(-1.0, (1,rm+rn+1))
		Df[0,0:rm] = (i_w_p*xp + Mp*xcep).T
		Df[0,rm:rm+rn]  = (i_w_q*xq - Mq*xcov).T
		if z is None:
			return f, Df
		H = cb.matrix(0.0, (rm+rn+1,rm+rn+1))
		# evaluate hessian w.r.t p
		c_p = arma2cov(ones(1),num,2*m-2)
		H_pp = 0.5*toeplitz(c_p[:m]) + 0.5*hankel(c_p[:m], c_p[m-1:])
		H[:rm,:rm] = Mp*cb.matrix(H_pp, (m,m))*Mp.T + i_w_p
		# evaluate hessian w.r.t q
		c_q = arma2cov(num,polymul(den,den),2*n-2)
		H_qq = 0.5*toeplitz(c_q[:n]) + 0.5*hankel(c_q[:n], c_q[n-1:])
		H[rm:rm+rn,rm:rm+rn] = Mq*cb.matrix(H_qq, (n,n))*Mq.T + i_w_q
		# evaluate the mixed part
		cc = arma2cov(ones(1),den,n+m-2)
		H_pq = -0.5*toeplitz(cc[:m], cc[:n]) - 0.5*hankel(cc[:m],cc[m-1:])
		H[:rm,rm:rm+rn] = Mp*cb.matrix(H_pq, (m,n))*Mq.T
		H[rm:rm+rn,:rm] = H[:rm,rm:rm+rn].T
		# save for debugging purposes
		for k in range(0,rm+rn+1):
			tmp_x[k] = x[k]
		return f, Df, z[0]*H
	
	solvers.options['maxiters'] = max_iter
	solvers.options['show_progress']= show_progress
	try:
		c = cb.matrix(1.0, (rm+rn+1,1))
		cep = iter2matrix(cep, (m,1))
		c[:rm] = -Mp*cep
		cov = iter2matrix(cov, (n,1))
		c[rm:rm+rn] = Mq*cov
		sol = solvers.cpl(c,F)
	except ArithmeticError: 
		p = fromiter(Mp.T*tmp_x[0:rm], float)
		p[0] += 1
		q = fromiter(Mq.T*tmp_x[rm:rm+rn], float)
		num = pp2p(p)
		den = pp2p(q)
		if show_progress:
			print tmp_x
			print abs(roots(num))
			print abs(roots(den))
			my_plot = plot_spectra()
			my_plot.add(p,q)
			my_plot.save("debug")
		raise
	if sol['status'] == 'unknown':
		return None, None, sol['status']
	x = sol['x'].T
	opt_p = fromiter(Mp.T*x[:rm], float)
	opt_p[0] += 1
	opt_q = fromiter(Mq.T*x[rm:rm+rn], float)
	return opt_p/opt_p[0], opt_q/opt_p[0], sol['status']