A = np.zeros((m, n)) b = np.zeros(m) for i in range(m): a = np.random.randn(n) a = a / np.linalg.norm(a) bi = 1 + np.random.rand(1) A[i, :] = a b[i] = bi q = QCML() q.parse(''' dimensions m n variables x(n) r parameters A(m,n) b(m) maximize r A*x + r <= b ''') q.canonicalize() q.dims = {'m': m, 'n': n} q.codegen("python") socp_data = q.prob2socp(locals()) # stuffed variable size n = socp_data['G'].shape[1] ecos_sol = ecos.solve(**socp_data) socp_sol = ecos_sol['x'] prob_sol_x = q.socp2prob(ecos_sol['x'])['x']
# TODO: takeaways from this example: "diag" constructor? p = QCML(debug=True) p.parse(""" dimensions m n variable c(n) variable u(n) variable v(n) parameter noise positive parameter lambda(n) parameter data(m) parameter dictc(m,n) parameter dictu(m,n) parameter dictv(m,n) parameter radii(n,n) # diagonal matrix parameter rctheta(n,n) # diagonal matrix minimize noise*norm(data - (dictc*c + dictu*u + dictv*v)) + lambda'*c subject to # || (u[i], v[i]) || <= radii_i * c_i # norm([u_i v_i]) <= radii_i*c_i # norm(x,y) applies norm across rows of the matrix [x y] norm(u,v) <= radii*c # rctheta is going to be a diagonal matrix # rctheta[i]*c[i] <= u[i] implemented with rctheta a diag matrix rctheta*c <= u """) # More natural formulation would be: # minimize 1/(sqrt(2)*noisesigma) * (data - (dictc*c + dictu(u + dictv*v)) + lambda'*c) # subject to
import numpy as np from qcml import QCML import ecos m = 10 n = 20 A = np.random.randn(m, n) b = np.random.randn(m) q = QCML() q.parse(''' dimensions m n variable x(n) parameters A(m,n) b(m) minimize norm1(x) A*x == b ''') q.canonicalize() q.dims = {'m': m, 'n': n} q.codegen('python') socp_vars = q.prob2socp(locals()) # convert to CSR for fast row slicing to distribute problem socp_vars['A'] = socp_vars['A'].tocsr() socp_vars['G'] = socp_vars['G'].tocsr() # the size of the stuffed x or v n = socp_vars['A'].shape[1]
# a QCML model is specified by strings # the parser parses each model line by line and builds an internal # representation of an SOCP s = """ dimensions m n variable a(n) variable b parameter X(m,n) # positive samples parameter Y(m,n) # negative samples parameter gamma positive minimize (norm(a) + gamma*sum(pos(1 - X*a + b) + pos(1 + Y*a - b))) """ print s raw_input("press ENTER to parse....") p = QCML(debug=True) p.parse(s) raw_input("press ENTER to canonicalize....") p.canonicalize() raw_input("press ENTER to generate code....") p.dims = {'n': n, 'm': m} p.codegen("python") raw_input("press ENTER to solve with ECOS....") socp_data = p.prob2socp(params=locals()) import ecos sol = ecos.solve(**socp_data)
p = QCML(debug=True) p.parse( """ dimensions m n variable a(n) variable b parameter X(m,n) # positive samples parameter Y(m,n) # negative samples parameter Z(m,n) parameter W(m,n) parameter gamma positive parameter c(n) # variables x(n) z # # minimize huber(sum(x)) - sqrt(z) # x + z == 5 # x + z == 5 # # x(:,i+1) == A(:,:,i)*x(:,i) + B*u(:,i) for i = 1,...,T # # sum_{ij in E} # # # # matrix X # # A*X is map(A*x, X) # # X*A minimize (norm(a) + gamma*sum(pos(1 - X*a + b) + pos(1 + Y*a - b))) # minimize c'*a # norm(X*a,Y*a,Z*a, W*a) <= 1 """ ) # TODO: sum(norms(X))
problem += ["x%i == A*x%i + B*u%i" % (i+1,i,i), "norm_inf(u%i) <= 1" % i] objective = [] for i in xrange(T): objective += ["square(norm(Q*x%i)) + square(norm(R*u%i))" % (i,i)] #objective += ["square(norm(Q*x%i))" % T] problem += ["minimize (1/2)*(" + ' + '.join(objective) + ")"] s = '\n'.join(map(lambda x:' ' + x, problem)) print s raw_input("press ENTER to parse....") p = QCML(debug=True) p.parse(s) raw_input("press ENTER to canonicalize....") p.canonicalize() raw_input("press ENTER to generate code....") p.dims = {'n': n, 'm': m} p.codegen("python") raw_input("press ENTER to solve with ECOS....") socp_data = p.prob2socp(params=locals()) import ecos sol = ecos.solve(**socp_data)
#!/usr/bin/env python from qcml import QCML import argparse parser = argparse.ArgumentParser(description="Loads an external problem description to parse.") parser.add_argument("-f", dest="file", help="file to parse", required=True) # TODO: allow generation of code when dimensions are abstract # group = parser.add_mutually_exclusive_group(required=True) # group.add_argument("--ansi-c", help="generate ansi-C code; prints to command line", action="store_true") # group.add_argument("--python", help="generate python code; prints to command line", action="store_true") args = parser.parse_args() print "Reading", args.file with open(args.file, "r") as f: prob = f.read() print prob raw_input("press ENTER to parse....") p = QCML(debug=True) p.parse(prob) raw_input("press ENTER to canonicalize....") p.canonicalize()
group.add_argument("--portfolio", help="solve the portfolio problem", action="store_true") args = parser.parse_args() p = QCML(debug=True) m = args.m n = args.n q = args.q if args.svm: p.parse(""" dimensions m n variable a(n) variable b parameter X(m,n) # positive samples parameter Y(m,n) # negative samples parameter gamma positive minimize (norm(a) + gamma*sum(pos(1 - X*a + b) + pos(1 + Y*a - b))) """) p.canonicalize() p.dims = {'m':m,'n':n} if not args.cvx: p.codegen("python") else: p.codegen("matlab",cone_size=q) #p.prettyprint() elif args.portfolio: p.parse("""
dimensions mn two_mn variable x(mn) parameter g(mn) parameter mu positive parameter D(two_mn, mn) parameter blurmat(mn,mn) minimize mu*norm(blurmat*x - g) + norm(D*x) """ D = sp.vstack([dxmat, dymat]).tocsc() blurred = blurmat*imgvec + 5*np.random.randn(rows*cols) from qcml import QCML import ecos p = QCML() p.parse(text) p.canonicalize() dims = {'mn':rows*cols, 'two_mn':D.shape[0]} p.codegen("python") # this creates a solver in Python calling CVXOPT socp_data = p.prob2socp({'blurmat':blurmat, 'g':blurred, 'D':D, 'mu':25}, dims) # sol = ecos.solve(**socp_data) print socp_data A = socp_data['G'] c = socp_data['c'] b = socp_data['h'] data = {'A':A, 'c':c, 'b':b} cone = socp_data['dims'] sol = scs.solve(data, cone, opts = None, USE_INDIRECT = False)
group.add_argument("--portfolio", help="solve the portfolio problem", action="store_true") args = parser.parse_args() p = QCML(debug=True) m = args.m n = args.n q = args.q if args.svm: p.parse(""" dimensions m n variable a(n) variable b parameter X(m,n) # positive samples parameter Y(m,n) # negative samples parameter gamma positive minimize (norm(a) + gamma*sum(pos(1 - X*a + b) + pos(1 + Y*a - b))) """) p.canonicalize() p.dims = {'m':m,'n':n} if args.cvx: p.codegen("python") else: p.codegen("matlab",cone_size=q) #p.prettyprint() elif args.portfolio: p.parse("""
#!/usr/bin/env python from qcml import QCML import argparse parser = argparse.ArgumentParser( description="Loads an external problem description to parse.") parser.add_argument('-f', dest='file', help="file to parse", required=True) # TODO: allow generation of code when dimensions are abstract # group = parser.add_mutually_exclusive_group(required=True) # group.add_argument("--ansi-c", help="generate ansi-C code; prints to command line", action="store_true") # group.add_argument("--python", help="generate python code; prints to command line", action="store_true") args = parser.parse_args() print "Reading", args.file with open(args.file, "r") as f: prob = f.read() print prob raw_input("press ENTER to parse....") p = QCML(debug=True) p.parse(prob) raw_input("press ENTER to canonicalize....") p.canonicalize()
gamma = 1 p = QCML(debug=True) p.parse(""" dimensions m n variable a(n) variable b parameter X(m,n) # positive samples parameter Y(m,n) # negative samples parameter Z(m,n) parameter W(m,n) parameter gamma positive parameter c(n) # variables x(n) z # # minimize huber(sum(x)) - sqrt(z) # x + z == 5 # x + z == 5 # # x(:,i+1) == A(:,:,i)*x(:,i) + B*u(:,i) for i = 1,...,T # # sum_{ij in E} # # # # matrix X # # A*X is map(A*x, X) # # X*A minimize (norm(a) + gamma*sum(pos(1 - X*a + b) + pos(1 + Y*a - b))) # minimize c'*a # norm(X*a,Y*a,Z*a, W*a) <= 1 """) # TODO: sum(norms(X)) # A*x