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
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
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']
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']
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']
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']
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
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']
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']
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
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:]
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)
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 '''
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']