def __init__(self, A=None, B=None, C=None, D=None): """Generate internal variables. The spectrahedron is the surface det(xA + yB + zC + D) = 0. mins holds the minimizing points of randomly-generated SDPs. pmins is an array indicating points with multiplicities. Each element of pmins takes the form (min, occurances) """ self.mins = [] self.pmins = [] self.nodes = [] # location, eigenvalue pairs self.spec_nodes = [] self.sym_nodes = [] # number of cvx calls self.trials = 0 # track whether the spectrahedron contains an NSD component, # and whether how many optimization directions are # simultaneously unbounded for both (or neither) components self.psd_spec = True self.nsd_spec = True self.fully_bounded_directions = 0 self.fully_unbounded_directions = 0 if A is None: self.A = rand_matrix(5,5,symmetric=True,integer=True) else: self.A = A if B is None: self.B = rand_matrix(5,5,symmetric=True,integer=True) else: self.B = B if C is None: self.C = rand_matrix(5,5,symmetric=True,integer=True) else: self.C = C if D is None: self.D = numpy.identity(5, dtype=int) else: self.D = D # list of matrices for convenience self.matrices = [self.A, self.B, self.C, self.D]
def gen_matrix(): """Generate a matrix of corank 2, such that each eigenvalue is negative with probability given by --negative """ vecs = rand_matrix(5,3,sigma=30,integer=True) signature = numpy.zeros((3,3), dtype=int) for i in range(len(signature)): if random.random() > args.negative: signature[i,i] = -1 else: signature[i,i] = 1 return vecs.dot(signature).dot(vecs.T)
def solve(self, n=1, verbose=False): """Solve optimization problems. n: number of optimizations verbose: whether cvx should print verbose output to stdout Appends results to mins, plus additional side effects described in cvx_solve(). """ for i in range(n): c, = rand_matrix(1, 3) psd, nsd = self.cvx_solve(c, verbose) if psd is not None: self.mins.append(psd) if nsd is not None: self.mins.append(nsd) self.trials += n
def solve(self, n=1, verbose=False): """Solve n optimization problems, and return argmin array.""" for i in range(n): c = rand_matrix(3,1) x = cvx.Variable(name='x') y = cvx.Variable(name='y') z = cvx.Variable(name='z') # dummy variable to code semidefinite constraint T = cvx.SDPVar(5,name='T') spec = self.A * x + self.B * y + self.C * z + self.D obj = cvx.Minimize(c[0,0]*x + c[1,0]*y + c[2,0]*z) # check psd component if self.psd_spec: psd_status = cvx.get_status( cvx.Problem(obj, [T == spec]).solve(verbose=verbose) ) if psd_status == cvx.SOLVED: self.mins.append([x.value, y.value, z.value]) elif psd_status == cvx.INFEASIBLE: self.psd_spec = False # check NSD component if self.nsd_spec: nsd_status = cvx.get_status( cvx.Problem(obj, [T == -spec]).solve(verbose=verbose) ) if nsd_status == cvx.SOLVED: self.mins.append([x.value, y.value, z.value]) if psd_status == cvx.SOLVED: self.fully_bounded_directions += 1 elif nsd_status == cvx.UNBOUNDED \ and psd_status == cvx.UNBOUNDED: self.fully_unbounded_directions += 1 elif nsd_status == cvx.INFEASIBLE: self.nsd_spec = False self.trials += n
def __init__(self, A=None, B=None, C=None, D=None): """Generate internal variables. The spectrahedron is the surface det(xA + yB + zC + D) = 0 All points are represented as lists of floats A, B, C, D: represented as numpy ndarrays matrices: [A, B, C, D], collected for convenience mins: list of minimizing points of randomly-generated SDPs pmins: list indicating points with multiplicities Each element of pmins takes the form [location, occurances, eigenvalues] nodes: list of spectrahedral nodes, in the form [location, fractional occurances, eigenvalues]. Nodes are sorted in descending order by frequency. spec_nodes: nodes on surface of spectrahedron sym_nodes: other real nodes on symmetroid complex_nodes: nodes with nonzero imaginary parts all nodes represented as [location, eigenvalues] total_nodes: total number of nodes (including complex) trials: number of calls to cvx psd_spec: whether spectrahedron contains psd component nsd_spec: ditto for nsd fully_bounded_directions (fully_unbounded_directions): number of directions in which optimizations on both spectrahedra are bounded (unbounded) """ self.mins = [] self.pmins = [] self.nodes = [] self.spec_nodes = [] self.sym_nodes = [] self.complex_nodes = [] self.total_nodes = 0 self.trials = 0 self.psd_spec = True self.nsd_spec = True self.fully_bounded_directions = 0 self.fully_unbounded_directions = 0 if A is None: self.A = rand_matrix(5, 5, symmetric=True, integer=True) else: self.A = A if B is None: self.B = rand_matrix(5, 5, symmetric=True, integer=True) else: self.B = B if C is None: self.C = rand_matrix(5, 5, symmetric=True, integer=True) else: self.C = C if D is None: self.D = numpy.identity(5, dtype=int) else: self.D = D self.matrices = [self.A, self.B, self.C, self.D]