Example #1
0
def estimate_confidence_bound_with_cvx(f_mat, num_reads_in_bams, fixed_i,
                                       mle_estimate, bound_type, alpha):
    if bound_type == 'lb': bound_type = 'LOWER'
    if bound_type == 'ub': bound_type = 'UPPER'
    assert bound_type in ('LOWER',
                          'UPPER'), ("Improper bound type '%s'" % bound_type)
    expected_array, observed_array = f_mat.expected_and_observed(
        bam_cnts=num_reads_in_bams)

    from cvxpy import matrix, variable, geq, log, eq, program, maximize, minimize, sum

    mle_log_lhd = calc_lhd(mle_estimate, observed_array, expected_array)

    lower_lhd_bound = mle_log_lhd - chi2.ppf(1 - alpha, 1) / 2.
    free_indices = set(range(expected_array.shape[1])) - set((fixed_i, ))

    Xs = matrix(observed_array)
    ps = matrix(expected_array)
    thetas = variable(ps.shape[1])
    constraints = [
        geq(Xs * log(ps * thetas), lower_lhd_bound),
        eq(sum(thetas), 1),
        geq(thetas, 0)
    ]

    if bound_type == 'UPPER':
        p = program(maximize(thetas[fixed_i, 0]), constraints)
    else:
        p = program(minimize(thetas[fixed_i, 0]), constraints)
    p.options['maxiters'] = 1500
    value = p.solve(quiet=not DEBUG_OPTIMIZATION)
    thetas_values = numpy.array(thetas.value.T.tolist()[0])
    log_lhd = calc_lhd(thetas_values, observed_array, expected_array)

    return chi2.sf(2 * (mle_log_lhd - log_lhd), 1), value
    def test_robust_regression(self):
        #
        # Compare cvxpy solutions to cvxopt ground truth
        #
        from cvxpy import (matrix, variable, program, minimize,
                           huber, sum, leq, geq, square, norm2,
                           ones, zeros, quad_form)
        tol_exp = 5 # Check solution to within 5 decimal places
        m, n = self.m, self.n
        A = matrix(self.A)
        b = matrix(self.b)

        # Method 1: using huber directly
        x = variable(n)
        p = program(minimize(sum(huber(A*x - b, 1.0))))
        p.solve(True)

        np.testing.assert_array_almost_equal(
            x.value, self.xh, tol_exp)

        # Method 2: solving the dual QP
        x = variable(n)
        u = variable(m)
        v = variable(m)
        p = program(minimize(0.5*quad_form(u, 1.0) + sum(v)),
                    [geq(u, 0.0), leq(u, 1.0), geq(v, 0.0),
                     leq(A*x - b, u + v), geq(A*x - b, -u - v)])
        p.solve(True)
        np.testing.assert_array_almost_equal(
            x.value, self.xh, tol_exp)
Example #3
0
    def test_robust_regression(self):
        #
        # Compare cvxpy solutions to cvxopt ground truth
        #
        from cvxpy import (matrix, variable, program, minimize, huber, sum,
                           leq, geq, square, norm2, ones, zeros, quad_form)
        tol_exp = 5  # Check solution to within 5 decimal places
        m, n = self.m, self.n
        A = matrix(self.A)
        b = matrix(self.b)

        # Method 1: using huber directly
        x = variable(n)
        p = program(minimize(sum(huber(A * x - b, 1.0))))
        p.solve(True)

        np.testing.assert_array_almost_equal(x.value, self.xh, tol_exp)

        # Method 2: solving the dual QP
        x = variable(n)
        u = variable(m)
        v = variable(m)
        p = program(minimize(0.5 * quad_form(u, 1.0) + sum(v)), [
            geq(u, 0.0),
            leq(u, 1.0),
            geq(v, 0.0),
            leq(A * x - b, u + v),
            geq(A * x - b, -u - v)
        ])
        p.solve(True)
        np.testing.assert_array_almost_equal(x.value, self.xh, tol_exp)
Example #4
0
 def con_ctm(self):
   return list(flatten([geq(link.v_flow, 0),
                        leq(link.v_flow, link.fd.q_max),
                        leq(link.v_flow, link.fd.v * link.v_dens),
                        leq(link.v_flow, link.fd.w * (link.fd.rho_max - link.v_dens)),
                        geq(link.v_dens, 0),
                        leq(link.v_dens, link.fd.rho_max),
                        ] for link in self.get_links()))
def construct_lp_relaxation( demand_hist, M, transport_graph, cost_label='cost' ) :
    """
    demand_hist is a dictionary from ordered station pairs (i,j) -> whole integers
    M is a membership graph with edges (i,x) for all corresponding stations-state pairs
    A is a DiGraph on X, with cost given by property 'cost'
    """
    APSP = nx.all_pairs_dijkstra_path_length( transport_graph, weight=cost_label )
    
    cost = 0.
    constr = []
    
    """ create enroute variables """
    S = nx.DiGraph()        # service "edges"
    for (i,j), NUM in demand_hist.iteritems() :
        VARS = []
        for x,y in itertools.product( M.neighbors_iter(i), M.neighbors_iter(j) ) :
            var = cvxpy.variable()
            distance = APSP[x][y]
            cost += var * distance
            constr.append( cvxpy.geq( var, 0. ) )   # needs to be non-negative
            
            S.add_edge( x, y, var=var, distance=distance )
            VARS.append( var )
            
        constr.append( cvxpy.eq( cvxpy.sum(VARS), NUM ) )   # total such trips should sum to num
            
    """ create balance variables """
    B = nx.DiGraph()
    HEADS = [ h for h, d in S.in_degree_iter() if d > 0 ]
    TAILS = [ t for t, d in S.out_degree_iter() if d > 0 ]
    for y,x in itertools.product( HEADS, TAILS ) :
        var = cvxpy.variable()
        cost += var * APSP[y][x]
        constr.append( cvxpy.geq( var, 0. ) )
        
        B.add_edge( y,x, var=var )
        
    """ generate flow conservation constraints """
    for x in S.nodes_iter() :
        sin = sum( [ data['var'] for _,__,data in S.in_edges_iter( x, data=True ) ] )
        sout = sum( [ data['var'] for _,__,data in S.out_edges_iter( x, data=True ) ] )
        bin = sum( [ data['var'] for _,__,data in B.in_edges_iter( x, data=True ) ] )
        bout = sum( [ data['var'] for _,__,data in B.out_edges_iter( x, data=True ) ] )
        
        constr.append( cvxpy.eq( sin, bout ) )
        constr.append( cvxpy.eq( sout, bin ) )
        
    #service_vars = S        # alias
    return cost, constr, S
Example #6
0
  def con_od_flows(self):
    od_demands = filter(lambda dem: isinstance(dem, ODDemand), self.demands)
    route_demands = filter(lambda dem: isinstance(dem, RouteDemand), self.demands)

    def route_flows(link):
      flow = 0.0
      link_routes = link.routes()
      for route in link_routes:
        flow += route.v_flow
      for dem in route_demands:
        if dem.route in link_routes:
          flow += dem.flow
      return flow

    def od_flows(source, sink):
      flow = 0
      for route in self.od_routes[source, sink]:
        flow += route.v_flow
      return flow

    return [
           eq(route_flows(link), link.v_flow)
           for link in self.get_links()
           ] + [
    eq(od_flows(dem.source, dem.sink), dem.flow)
    for dem in od_demands
    ] + [
      geq(route.v_flow, 0.0) for route in self.all_routes()
    ]
Example #7
0
    def _MakeDrivingForceConstraints(self, ln_conc, driving_force_lb=0):
        """
            driving_force_lb can either be a cvxpy variable use later in the optimization
            or a scalar, which sets it as a constraint. By default the lower bound is 0.
        """
        constraints = []
        S = cvxpy.matrix(self.S)
        dg0r_primes = cvxpy.matrix(self.dG0_r_prime)
        for i in xrange(self.Nr):
            # if the dG0 is unknown, this reaction imposes no new constraints
            if np.isnan(self.dG0_r_prime[0, i]):
                continue

            curr_dgr = dg0r_primes[0, i] + RT * ln_conc * S[:, i]
            if self.fluxes[0, i] == 0:
                constraints += cvxpy.eq(curr_dgr, 0)
            else:
                if self.normalization == DeltaGNormalization.DIVIDE_BY_FLUX:
                    motive_force = -curr_dgr * (1.0 / self.fluxes[0, i])
                elif self.normalization == DeltaGNormalization.TIMES_FLUX:
                    motive_force = -curr_dgr * self.fluxes[0, i]
                elif self.normalization == DeltaGNormalization.SIGN_FLUX:
                    motive_force = -curr_dgr * np.sign(self.fluxes[0, i])
                else:
                    raise ValueError("bad value for normalization method: " +
                                     str(self.normalization))

                constraints += [cvxpy.geq(motive_force, driving_force_lb)]

        return constraints
Example #8
0
    def _MakeMinimalFeasbileConcentrationProblem(self, bounds=None, c_range=(1e-6, 1e-2)):
        # Define and apply the constraints on the concentrations
        constraints = []
        
        # Define and apply the constraints on the concentrations
        ln_conc = cvxpy.variable(1, self.Nc, name='lnC')
        constraints += self._MakeLnConcentratonBounds(ln_conc, bounds=bounds,
                                                      c_range=c_range)

        # find the row vector describing the overall stoichiometry
        S = cvxpy.matrix(self.S)
        dg0r_primes = cvxpy.matrix(self.dG0_r_prime)
        
        # Make flux-based constraints on reaction free energies.
        # All reactions must have negative dGr in the direction of the flux.
        # Reactions with a flux of 0 must be in equilibrium. 
        for i in xrange(self.Nr):
            # if the dG0 is unknown, this reaction imposes no new constraints
            if np.isnan(self.dG0_r_prime[0, i]):
                continue
            
            curr_dgr = dg0r_primes[0, i] + RT * ln_conc * S[:, i]

            if self.fluxes[0, i] != 0:
                constraints.append(cvxpy.leq(curr_dgr * np.sign(self.fluxes[0, i]),
                                             self.DEFAULT_REACTION_UB))
                constraints.append(cvxpy.geq(curr_dgr * np.sign(self.fluxes[0, i]),
                                             self.DEFAULT_REACTION_LB))
            else:
                constraints.append(cvxpy.eq(curr_dgr, 0))
        
        # Set the constraints
        return ln_conc, constraints
 def constraint(self):
   if self.type == self.Type.EQ:
     return eq(self.a, self.b)
   if self.type == self.Type.LEQ:
     return leq(self.a, self.b)
   if self.type == self.Type.GEQ:
     return geq(self.a, self.b)
Example #10
0
    def _MakeDrivingForceConstraints(self, ln_conc, driving_force_lb=0):
        """
            driving_force_lb can either be a cvxpy variable use later in the optimization
            or a scalar, which sets it as a constraint. By default the lower bound is 0.
        """
        constraints = []
        S = cvxpy.matrix(self.S)
        dg0r_primes = cvxpy.matrix(self.dG0_r_prime)
        for i in xrange(self.Nr):
            # if the dG0 is unknown, this reaction imposes no new constraints
            if np.isnan(self.dG0_r_prime[0, i]):
                continue
            
            curr_dgr = dg0r_primes[0, i] + RT * ln_conc * S[:, i]
            if self.fluxes[0, i] == 0:
                constraints += cvxpy.eq(curr_dgr, 0)
            else:
                if self.normalization == DeltaGNormalization.DIVIDE_BY_FLUX:
                    motive_force = -curr_dgr * (1.0 / self.fluxes[0, i])
                elif self.normalization == DeltaGNormalization.TIMES_FLUX:
                    motive_force = -curr_dgr * self.fluxes[0, i]
                elif self.normalization == DeltaGNormalization.SIGN_FLUX:
                    motive_force = -curr_dgr * np.sign(self.fluxes[0, i])
                else:
                    raise ValueError("bad value for normalization method: "
                                     + str(self.normalization))

                constraints += [cvxpy.geq(motive_force, driving_force_lb)]

        return constraints
def attach_flownx_constraints( flownx ) :
    """ add flow capacity constraints to edges """
    for _,__, data in flownx.edges_iter( data=True ) :
        flowvar = data.get('flow')
        constr = []
        
        minflow = data.get( 'minflow', -np.inf )
        if minflow > -np.inf : constr.append( cvxpy.geq( flowvar, minflow ) )
        maxflow = data.get( 'maxflow', np.inf )
        if maxflow < np.inf : constr.append( cvxpy.leq( flowvar, maxflow ) )
        
        data['constraints'] = constr
    
    """ add flow conservation constraints to nodes, besides 's' and 't' """
    for u, node_data in flownx.nodes_iter( data=True ) :
        if u in [ 's', 't' ] : continue
        
        in_flow = 0.
        for _,__, data in flownx.in_edges_iter( u, data=True ) :
            in_flow += data.get('flow')
            
        out_flow = 0.
        for _,__, data in flownx.out_edges_iter( u, data=True ) :
            out_flow += data.get('flow')
            
        node_data['constraints'] = [ cvxpy.eq( in_flow, out_flow ) ]
Example #12
0
    def FindMtdf_Regularized(self,
                             c_range=(1e-6, 1e-2),
                             bounds=None,
                             c_mid=1e-3,
                             min_mtdf=None,
                             max_mtdf=None):
        """Find the MTDF (Maximal Thermodynamic Driving Force).
        
        Uses l2 regularization to minimize the log difference of 
        concentrations from c_mid.
        
        Args:
            c_range: a tuple (min, max) for concentrations (in M).
            bounds: a list of (lower bound, upper bound) tuples for compound
                concentrations.
            c_mid: the defined midpoint concentration.
            max_mtdf: the maximum value for the motive force.
        
        Returns:
            A 3 tuple (optimal dGfs, optimal concentrations, optimal mtdf).
        """
        ln_conc, motive_force_lb, constraints = self._MakeMtdfProblem(
            c_range, bounds)

        # Set the objective and solve.
        norm2_resid = cvxpy.norm2(ln_conc - np.log(c_mid))
        if max_mtdf is not None and min_mtdf is not None:
            constraints.append(cvxpy.leq(motive_force_lb, max_mtdf))
            constraints.append(cvxpy.geq(motive_force_lb, min_mtdf))
            objective = cvxpy.minimize(norm2_resid)
        elif max_mtdf is not None:
            constraints.append(cvxpy.leq(motive_force_lb, max_mtdf))
            objective = cvxpy.minimize(norm2_resid)
        elif min_mtdf is not None:
            constraints.append(cvxpy.geq(motive_force_lb, min_mtdf))
            objective = cvxpy.minimize(norm2_resid)
        else:
            objective = cvxpy.minimize(motive_force_lb + norm2_resid)

        program = cvxpy.program(objective, constraints)
        program.solve(quiet=True)
        return ln_conc.value, program.objective.value
Example #13
0
    def _MakeMinimumFeasbileConcentrationsProblem(self,
                                                  bounds=None,
                                                  c_range=(1e-6, 1e-2)):
        """Creates the CVXOPT problem for finding minimum total concentrations.
        
        Returns:
            Two tuple (ln_concentrations var, problem).
        """
        assert self.dG0_f_prime is not None

        constraints = []

        # Define and apply the constraints on the concentrations
        ln_conc = cvxpy.variable(1, self.Nc, name='lnC')
        constraints += self._MakeLnConcentratonBounds(ln_conc,
                                                      bounds=bounds,
                                                      c_range=c_range)

        # Make the objective and problem.
        S = cvxpy.matrix(self.S)

        # Make flux-based constraints on reaction free energies.
        # All reactions must have negative dGr in the direction of the flux.
        # Reactions with a flux of 0 must be in equilibrium.
        dgf_primes = RT * ln_conc + cvxpy.matrix(self.dG0_f_prime)
        for i in xrange(self.Nr):
            if self.fluxes[0, i] > 0:
                constraints.append(
                    cvxpy.leq(S[i, :] * dgf_primes, self.DEFAULT_REACTION_UB))
                constraints.append(
                    cvxpy.geq(S[i, :] * dgf_primes, self.DEFAULT_REACTION_LB))
            elif self.fluxes[0, i] == 0:
                constraints.append(cvxpy.eq(S[i, :] * dgf_primes, 0))
            else:
                constraints.append(
                    cvxpy.geq(S[i, :] * dgf_primes, -self.DEFAULT_REACTION_UB))
                constraints.append(
                    cvxpy.leq(S[i, :] * dgf_primes, -self.DEFAULT_REACTION_LB))

        return ln_conc, constraints
Example #14
0
    def FindMtdf_Regularized(self, c_range=(1e-6, 1e-2), bounds=None,
                             c_mid=1e-3,
                             min_mtdf=None,
                             max_mtdf=None):
        """Find the MTDF (Maximal Thermodynamic Driving Force).
        
        Uses l2 regularization to minimize the log difference of 
        concentrations from c_mid.
        
        Args:
            c_range: a tuple (min, max) for concentrations (in M).
            bounds: a list of (lower bound, upper bound) tuples for compound
                concentrations.
            c_mid: the defined midpoint concentration.
            max_mtdf: the maximum value for the motive force.
        
        Returns:
            A 3 tuple (optimal dGfs, optimal concentrations, optimal mtdf).
        """
        ln_conc, motive_force_lb, constraints = self._MakeMtdfProblem(c_range, bounds)
        
        # Set the objective and solve.
        norm2_resid = cvxpy.norm2(ln_conc - np.log(c_mid))
        if max_mtdf is not None and min_mtdf is not None:
            constraints.append(cvxpy.leq(motive_force_lb, max_mtdf))
            constraints.append(cvxpy.geq(motive_force_lb, min_mtdf))
            objective = cvxpy.minimize(norm2_resid)
        elif max_mtdf is not None:
            constraints.append(cvxpy.leq(motive_force_lb, max_mtdf))
            objective = cvxpy.minimize(norm2_resid)
        elif min_mtdf is not None:
            constraints.append(cvxpy.geq(motive_force_lb, min_mtdf))
            objective = cvxpy.minimize(norm2_resid)
        else:
            objective = cvxpy.minimize(motive_force_lb + norm2_resid)

        program = cvxpy.program(objective, constraints)
        program.solve(quiet=True)
        return ln_conc.value, program.objective.value
Example #15
0
 def _MakeMinimumFeasbileConcentrationsProblem(self, bounds=None,
                                               c_range=(1e-6, 1e-2)):
     """Creates the CVXOPT problem for finding minimum total concentrations.
     
     Returns:
         Two tuple (ln_concentrations var, problem).
     """
     assert self.dG0_f_prime is not None
     
     constraints = []
     
     # Define and apply the constraints on the concentrations
     ln_conc = cvxpy.variable(1, self.Nc, name='lnC')
     constraints += self._MakeLnConcentratonBounds(ln_conc, bounds=bounds,
                                                   c_range=c_range)
     
     # Make the objective and problem.
     S = cvxpy.matrix(self.S)
     
     # Make flux-based constraints on reaction free energies.
     # All reactions must have negative dGr in the direction of the flux.
     # Reactions with a flux of 0 must be in equilibrium.
     dgf_primes = RT * ln_conc + cvxpy.matrix(self.dG0_f_prime)
     for i in xrange(self.Nr):
         if self.fluxes[0, i] > 0:
             constraints.append(cvxpy.leq(S[i, :] * dgf_primes,
                                          self.DEFAULT_REACTION_UB))
             constraints.append(cvxpy.geq(S[i, :] * dgf_primes,
                                          self.DEFAULT_REACTION_LB))
         elif self.fluxes[0, i] == 0:
             constraints.append(cvxpy.eq(S[i, :] * dgf_primes,
                                         0))
         else:
             constraints.append(cvxpy.geq(S[i, :] * dgf_primes,
                                          -self.DEFAULT_REACTION_UB))
             constraints.append(cvxpy.leq(S[i, :] * dgf_primes,
                                          -self.DEFAULT_REACTION_LB))
     
     return ln_conc, constraints
Example #16
0
def nuc_al(I, X, turn, epsilon=.1, quiet=False):

	m,K = np.shape(X)


	if not turn:
		V = cp.variable(m,K, name='V')
		U = X

	else:
		V = X
		U = cp.variable(m,K, name='U')

	f_cost = cp.parameter(name='f_cost')
	f_cost.value = 0

	J = cp.parameter(K,K, name='J')
	J.value = cp.zeros((K,K))


	# define the cost parameter
	for k in range(K):
		# create a list of interferer indeces Ik
		# from the interference set I
		Ik = np.arange(1,K+1)*I[k,:]	# careful about zero indexing...
		Ik = Ik[Ik>0] - 1
		#print 'I_%d = ' % k, Ik
		if len(Ik) > 0:
			for l in Ik:
				l = int(l)
				J[k,l] = U[:,k].T*V[:,l]	# interference terms
			f_cost = f_cost + cp.nuclear_norm(J[k,:])
			#f_cost = f_cost + cp.norm1(J[k,:])

	# create constraints
	constraints = []
	for k in range(K):
		c = cp.geq(U[:,k].T*V[:,k], epsilon)
		#c = cp.geq(cp.lambda_min(U[:,k].T*V[:,k]), epsilon)
		constraints.append(c)

	p = cp.program(cp.minimize(f_cost), constraints)
	print 'minimize: ', p.objective
	print 'subject to:'
	print p.constraints
	p.solve(quiet)

	if not turn:
		return V.value
	else:
		return U.value
Example #17
0
def nuc_al(I, X, turn, epsilon=.1, quiet=False):

    m, K = np.shape(X)

    if not turn:
        V = cp.variable(m, K, name='V')
        U = X

    else:
        V = X
        U = cp.variable(m, K, name='U')

    f_cost = cp.parameter(name='f_cost')
    f_cost.value = 0

    J = cp.parameter(K, K, name='J')
    J.value = cp.zeros((K, K))

    # define the cost parameter
    for k in range(K):
        # create a list of interferer indeces Ik
        # from the interference set I
        Ik = np.arange(1, K + 1) * I[k, :]  # careful about zero indexing...
        Ik = Ik[Ik > 0] - 1
        #print 'I_%d = ' % k, Ik
        if len(Ik) > 0:
            for l in Ik:
                l = int(l)
                J[k, l] = U[:, k].T * V[:, l]  # interference terms
            f_cost = f_cost + cp.nuclear_norm(J[k, :])
            #f_cost = f_cost + cp.norm1(J[k,:])

    # create constraints
    constraints = []
    for k in range(K):
        c = cp.geq(U[:, k].T * V[:, k], epsilon)
        #c = cp.geq(cp.lambda_min(U[:,k].T*V[:,k]), epsilon)
        constraints.append(c)

    p = cp.program(cp.minimize(f_cost), constraints)
    print 'minimize: ', p.objective
    print 'subject to:'
    print p.constraints
    p.solve(quiet)

    if not turn:
        return V.value
    else:
        return U.value
def mincost_maxflow( flownx, cost='cost', DELTA=None ) :
    if DELTA is None : DELTA = DEFAULT_DELTA
    
    total_flow = compute_totalflow( flownx )
    total_cost = compute_totalcost( flownx, cost=cost )
    constraints = collect_constraints( flownx )
    
    prog1 = cvxpy.program( cvxpy.maximize( total_flow ), constraints )
    max_flow = prog1.solve()
    
    constraints2 = [ c for c in constraints ]
    constraints2.append( cvxpy.geq( total_flow, max_flow - DELTA ) )
    prog2 = cvxpy.program( cvxpy.minimize( total_cost ), constraints2 )
    res = prog2.solve()
    return res
Example #19
0
 def find_decoders_cvxopt(self, values, neus_in_pop, min_w = 0 , max_w = 1):
     '''
     find optimal decoders using convex bounded optimization
     '''
     tuning = self.tuning_curves[neus_in_pop]
     A=np.array(tuning)
     A_m = np.matrix(np.matrix(A))
     aa = cx.zeros(np.shape(A))
     aa[A_m.nonzero()] = A_m[A_m.nonzero()]
     bb = cx.zeros(np.shape(value))
     bb[value.nonzero()[0]] = value[value.nonzero()[0]]
     m,n = np.shape(aa)
     dec = cx.variable(m)
     p = cx.program(cx.minimize(cx.norm2((aa)*(dec)-(bb))), [cx.leq(dec,max_w),cx.geq(dec,min_w)])
     p.solve()
     return dec.value
def PROGRAM( roadnet, surplus, objectives ) :
    """ construct the program """
    # optvars
    assist = dict()
    cost = dict()
    DELTA = .00001   # cvxpy isn't quite robust to non-full dimensional optimization
    
    for _,__,road in roadnet.edges_iter( keys=True ) :
        assist[road] = cvxpy.variable( name='z_{%s}' % road )
        cost[road] = cvxpy.variable( name='c_{%s}' % road )
    #print assist
    #print cost
        
    objfunc = sum( cost.values() )
    OBJECTIVE = cvxpy.minimize( objfunc )
    
    CONSTRAINTS = []
    
    # the flow conservation constraints
    for u in roadnet.nodes_iter() :
        INFLOWS = []
        for _,__,road in roadnet.in_edges( u, keys=True ) :
            INFLOWS.append( assist[road] + surplus[road] )
            
        OUTFLOWS = []
        for _,__,road in roadnet.out_edges( u, keys=True ) :
            OUTFLOWS.append( assist[road] )
            
        #conserve_u = cvxpy.eq( sum(OUTFLOWS), sum(INFLOWS) )
        error_u = sum(OUTFLOWS) - sum(INFLOWS)
        conserve_u = cvxpy.leq( cvxpy.abs( error_u ), DELTA )
        
        CONSTRAINTS.append( conserve_u )
        
    # the cost-form constraints
    for road in cost :
        for f, line in objectives[road].iter_items() :
            # is this plus or minus alpha?
            LB = cvxpy.geq( cost[road], line.offset + line.slope * assist[road] )
            CONSTRAINTS.append( LB )
    
    prog = cvxpy.program( OBJECTIVE, CONSTRAINTS )
    return prog, assist
Example #21
0
    def test_problem_expdesign(self):

        # test problem needs review
        print 'skipping, needs review'
        return
        
        from cvxpy import (matrix, variable, program, minimize,
                           log, det_rootn, diag, sum, geq, eq, zeros)
        tol_exp = 6
        V = matrix(self.V)
        n = V.shape[1]
        x = variable(n)

        # Use cvxpy to solve the problem above
        p = program(minimize(-log(det_rootn(V*diag(x)*V.T))),
                    [geq(x, 0.0), eq(sum(x), 1.0)])
        p.solve(True)
        np.testing.assert_array_almost_equal(
            x.value, self.xd, tol_exp)
Example #22
0
    def _MakeMinimalFeasbileConcentrationProblem(self,
                                                 bounds=None,
                                                 c_range=(1e-6, 1e-2)):
        # Define and apply the constraints on the concentrations
        constraints = []

        # Define and apply the constraints on the concentrations
        ln_conc = cvxpy.variable(1, self.Nc, name='lnC')
        constraints += self._MakeLnConcentratonBounds(ln_conc,
                                                      bounds=bounds,
                                                      c_range=c_range)

        # find the row vector describing the overall stoichiometry
        S = cvxpy.matrix(self.S)
        dg0r_primes = cvxpy.matrix(self.dG0_r_prime)

        # Make flux-based constraints on reaction free energies.
        # All reactions must have negative dGr in the direction of the flux.
        # Reactions with a flux of 0 must be in equilibrium.
        for i in xrange(self.Nr):
            # if the dG0 is unknown, this reaction imposes no new constraints
            if np.isnan(self.dG0_r_prime[0, i]):
                continue

            curr_dgr = dg0r_primes[0, i] + RT * ln_conc * S[:, i]

            if self.fluxes[0, i] != 0:
                constraints.append(
                    cvxpy.leq(curr_dgr * np.sign(self.fluxes[0, i]),
                              self.DEFAULT_REACTION_UB))
                constraints.append(
                    cvxpy.geq(curr_dgr * np.sign(self.fluxes[0, i]),
                              self.DEFAULT_REACTION_LB))
            else:
                constraints.append(cvxpy.eq(curr_dgr, 0))

        # Set the constraints
        return ln_conc, constraints
Example #23
0
    def _MakeLnConcentratonBounds(self, ln_conc, bounds=None, c_range=None):
        """Make bounds on logarithmic concentrations."""
        _c_range = c_range or self.DEFAULT_C_RANGE
        c_lower, c_upper = c_range
        ln_conc_lb = np.ones((1, self.Nc)) * np.log(c_lower)
        ln_conc_ub = np.ones((1, self.Nc)) * np.log(c_upper)

        if bounds:
            for i, bound in enumerate(bounds):
                lb, ub = bound
                log_lb = np.log(lb or c_lower)
                log_ub = np.log(ub or c_upper)
                if log_lb > log_ub:
                    raise Exception("Lower bound is greater than upper bound: "
                                    "%d > %d" % (log_lb, log_ub))
                elif abs(log_lb - log_ub) < 1e-2:
                    log_lb = log_ub - 1e-2

                ln_conc_lb[0, i] = log_lb
                ln_conc_ub[0, i] = log_ub

        return [cvxpy.geq(ln_conc, cvxpy.matrix(ln_conc_lb)) + \
                cvxpy.leq(ln_conc, cvxpy.matrix(ln_conc_ub))]
Example #24
0
 def _MakeLnConcentratonBounds(self, ln_conc, bounds=None, c_range=None):
     """Make bounds on logarithmic concentrations."""
     _c_range = c_range or self.DEFAULT_C_RANGE
     c_lower, c_upper = c_range
     ln_conc_lb = np.ones((1, self.Nc)) * np.log(c_lower)
     ln_conc_ub = np.ones((1, self.Nc)) * np.log(c_upper)
     
     if bounds:
         for i, bound in enumerate(bounds):
             lb, ub = bound
             log_lb = np.log(lb or c_lower)
             log_ub = np.log(ub or c_upper)
             if log_lb > log_ub:
                 raise Exception("Lower bound is greater than upper bound: "
                                 "%d > %d" % (log_lb, log_ub))
             elif abs(log_lb - log_ub) < 1e-2:
                 log_lb = log_ub - 1e-2
                 
             ln_conc_lb[0, i] = log_lb
             ln_conc_ub[0, i] = log_ub
     
     return [cvxpy.geq(ln_conc, cvxpy.matrix(ln_conc_lb)) + \
             cvxpy.leq(ln_conc, cvxpy.matrix(ln_conc_ub))]
Example #25
0
def estimate_transcript_frequencies_with_cvxopt(observed_array,
                                                expected_array,
                                                sparse_penalty,
                                                sparse_index,
                                                verbose=False):
    from cvxpy import matrix, variable, geq, log, eq, program, maximize, \
        minimize, sum, quad_over_lin

    Xs = matrix(observed_array)
    ps = matrix(expected_array)
    thetas = variable(ps.shape[1])
    constraints = [eq(sum(thetas), 1), geq(thetas, 0)]

    if sparse_penalty == None:
        p = program(maximize(Xs * log(ps * thetas)), constraints)
    else:
        p = program(
            maximize(Xs * log(ps * thetas) - sparse_penalty *
                     quad_over_lin(1., thetas[sparse_index, 0])), constraints)

    p.options['maxiters'] = 1500
    value = p.solve(quiet=not verbose)
    thetas_values = numpy.array(thetas.value.T.tolist()[0])
    return thetas_values
Example #26
0
    def solve(self):
        ''' solver for the optimal purchasing of gas at stations
        does not return anything, but attaches some resulting properties at the end'''
        
        n = len(self.route.stations)

        if self.method == "dynamic":
            
            def conditionallyFillUp(gas_in_tank,station):
                print 'filling up'
                distance_to_end = sum([self.route.distances[j]
                                       for j in range(station,n)]
                                      )
                bought.append(max(0,min(distance_to_end / self.car.economy, self.car.tank_max) - gas_in_tank))

            prices = [station.regular for station in self.route.stations]
            
            print 'prices: ' + str(prices)
            
            i = 0
            range_of_car = (self.car.tank_max - self.gas_min) * self.car.economy
            print 'range of car: ' + str(range_of_car)
            
            #set initial stations
            current_price = self.route.stations[i].regular
            station_chosen = i
            

            #Probably safe to assume both are zero, call api if necessary
            distance_to_first_station = 0
            distance_from_last_station = 0
            
            if (self.car.start - distance_to_first_station / self.car.economy < self.gas_min):
                raise Exception("Unfeasible to reach")
            else:
                gas_in_tank_at_last_station = self.car.start - (distance_to_first_station / self.car.economy)
            
            #Make parameter (probably as proportion of full tank) on website
            gas_at_end = self.gas_min
                        
            #for export
            stations_chosen = []
            bought = []
            
            #simulte partially filled tank as miles already driven
            miles_since_last_stop = (self.car.tank_max - gas_in_tank_at_last_station) * self.car.economy + distance_to_first_station
            
            #make sure you can get home
            self.route.distances.append(distance_from_last_station)

            while i < n:
                
                #for feasibility check
                firstStationOnTank = i
                
                #determine where car should stop
                while i < n:
                    
                    #check if next stop is cheaper
                    print i
                    print current_price
                    if self.route.stations[i].regular < current_price:
                        current_price = self.route.stations[i].regular
                        station_chosen = i
                        print 'station_chosen: ' + str(station_chosen)
                    
                    #increment
                    miles_since_last_stop += self.route.distances[i]
                    i = i + 1
                    print 'miles_since_last_stop: ' + str(miles_since_last_stop)
                    if miles_since_last_stop > range_of_car:
                        print i
                        if (gas_in_tank_at_last_station - self.route.distances[firstStationOnTank] / self.car.economy < self.gas_min):
                            raise Exception("Unfeasible to reach")
                        stations_chosen.append(station_chosen)
                        current_price = self.route.stations[i].regular
                        station_chosen = i
                        break

                #determine how much gas car should get
                if len(stations_chosen) > 1:
                    distance_between_stations = sum([self.route.distances[j]
                                           for j in range(stations_chosen[len(stations_chosen) - 2],stations_chosen[len(stations_chosen) - 1])]
                                          )
                    print stations_chosen
                    print 'last_station: ' + str(stations_chosen[len(stations_chosen) - 2]) + ", price:" + str(self.route.stations[stations_chosen[len(stations_chosen) - 2]].regular)
                    print 'this station: ' + str(stations_chosen[len(stations_chosen) - 1]) + ", price:" + str(self.route.stations[stations_chosen[len(stations_chosen) - 1]].regular)
                    if (self.route.stations[stations_chosen[len(stations_chosen) - 2]].regular < self.route.stations[stations_chosen[len(stations_chosen) - 1]].regular):
                        #fill 'er up, errr, conditionally
                        conditionallyFillUp(gas_in_tank_at_last_station, stations_chosen[len(stations_chosen) - 2])
                    else:
                        #only get enough gas to get to next station
                        print 'getting minimum'
                        bought.append(distance_between_stations / self.car.economy)
                    
                    gas_in_tank_at_last_station = gas_in_tank_at_last_station - (distance_between_stations / self.car.economy) + bought[len(bought) - 1]
                    
                miles_since_last_stop = 0
                
            stations_chosen.append(station_chosen)
            
            conditionallyFillUp(gas_in_tank_at_last_station, stations_chosen[len(stations_chosen) - 1])
            
            print 'stations_chosen: ' + str(stations_chosen)
            print 'bought: ' + str(bought)
            
            objective_value = sum(
                            [self.route.stations[stations_chosen[j]].regular*bought[j]
                                for j in range(len(stations_chosen))]
                            )
            
            self.stations_chosen = stations_chosen
            
        else: 
            # how to constrain the LP
            in_tank = variable(n,name ='gas in tank') # how much gas in tank var
            bought = variable(n,name = 'gas bought') # how much to buy at each station var

            constraints = ([eq(in_tank[0,0],self.car.start)] + # starting gas
                           [eq(in_tank[i+1,0], # mass balance
                               in_tank[i,0] +
                               bought[i,0] -
                               self.route.distances[i]/self.car.economy)#DV: Changed from * to /
                               for i in range(n-1)] + 
                            [geq(in_tank,self.gas_min)] + # can't dip below certain amount
                            [leq(in_tank + bought,self.car.tank_max)] + # max size of tank
                            [geq(bought,0)] # physical constraint (cannot cyphon gas for sale to bum)
                            )
            
            # the total cost of the fuel
            fuel_cost = sum(
                            [self.route.stations[j].regular*bought[j,0]
                             for j in range(n)]
                            )
            
            # define program
            p = program(minimize(fuel_cost), constraints)
            objective_value = p.solve()
            
            # attach properties to access later
            
            self.in_tank = in_tank
            self.program = p
        
        self.bought = bought
        self.objective_value = objective_value
Example #27
0
    def FindMTDF(self, concentration_bounds=None, normalization=None):
        """Finds the MTDF.
        
        Args:
            bounds: the Bounds objects setting concentration bounds.
        """        
        my_bounds = concentration_bounds or self.DefaultConcentrationBounds()
        normalization = normalization or self.DeltaGNormalization.DEFAULT
                
        # Constrain concentrations
        ln_conc = cvxpy.variable(m=1, n=self.Ncompounds, name='lnC')
        ln_conc_lb, ln_conc_ub = my_bounds.GetLnBounds(self.compounds)
        constr = [cvxpy.geq(ln_conc, cvxpy.matrix(ln_conc_lb)),
                  cvxpy.leq(ln_conc, cvxpy.matrix(ln_conc_ub))]
        
        # Make the objective
        motive_force_lb = cvxpy.variable(name='B')
        my_dG0_r_primes = np.matrix(self.dG0_r_prime)

        
        # Make flux-based constraints on reaction free energies.
        # All reactions must have negative dGr in the direction of the flux.
        # Reactions with a flux of 0 must be in equilibrium.
        S = np.matrix(self.S)
        
        for i, flux in enumerate(self.fluxes):
            
            curr_dg0 = my_dG0_r_primes[0, i]
            # if the dG0 is unknown, this reaction imposes no new constraints
            if np.isnan(curr_dg0):
                continue
            
            rcol = cvxpy.matrix(S[:, i])
            curr_dgr = curr_dg0 + RT * ln_conc * rcol
            if flux == 0:
                constr.append(cvxpy.eq(curr_dgr, 0))
            else:
                motive_force = self.DeltaGNormalization.NormalizeDGByFlux(
                    curr_dgr, flux, normalization)
                
                constr.append(cvxpy.geq(motive_force, motive_force_lb))
        
        objective = cvxpy.maximize(motive_force_lb)
        problem = cvxpy.program(objective, constr, name='MTDF_OPT')
        
        problem.solve(quiet=True)
        """
        if status != 'optimal':
            status = optimized_pathway.OptimizationStatus.Infeasible(
                'Pathway infeasible given bounds.')
            return MTDFOptimizedPathway(
                self._model, self._thermo,
                my_bounds, optimization_status=status)
        """
        
        mtdf = float(motive_force_lb.value)
        opt_ln_conc = np.matrix(np.array(ln_conc.value))
        result = MTDFOptimizedPathway(
            self._model, self._thermo,
            my_bounds, optimal_value=mtdf,
            optimal_ln_metabolite_concentrations=opt_ln_conc)
        result.SetNormalization(normalization)
        return result
        
        
        
Example #28
0
    def ACT2Corrected(self,gene,num_iterations=5):
        """
            Next steps: Some way to preserve flows at divergence nodes
            One way could be reallocate flows at all divergence nodes in the original ratio and fix it 
            Iterate 10 times
        """
        inwgs=self.wgsdict[gene]
        outwgs=inwgs
        component1=1.0
        for iteri in range(num_iterations):
            component1=1.0-iteri*1.0/num_iterations
            wgs=addwgs(inwgs,outwgs,component1)
            A,B,X=self.wgs2problem(wgs)
            Xvar = cvx.variable(len(X),1)    
            A=cvx.matrix(A)
            B=cvx.matrix(B)
            B=B.T
            p = cvx.program(cvx.minimize(cvx.norm2(A*Xvar-B)),[cvx.geq(Xvar,0.0)])
            try:
                p.solve(quiet=1)
            except:
                message='Could not solve for %s'%(gene)
                common.printstatus(message,'W',common.func_name(),1)   
                return (outwgs,100.0)   
            if iteri==0:                          # Get optimal value
                err=cvx.norm2(A*Xvar-B)
            #print err.value/len(X)
            Xval=Xvar.T.value.tolist()[0]
            X_corr= [a[:] for a in X]
            for i in range(len(Xval)):
                X_corr[i][3]=int(Xval[i]*100)/100.0
            
            #print X_corr
            exonlist=[[a[1],a[2]] for a in X_corr if a[0]==2]
            exonwtlist=[a[3] for a in X_corr if a[0]==2]
            #print 'E',exonlist
            intronlist=[]
            intronwtlist=[]
            splicelist=[[a[1],a[2]] for a in X_corr if a[0]==3]
            splicewtlist=[a[3] for a in X_corr if a[0]==3]
            removelist=[]
            for i in range(len(exonlist)):
                exon=exonlist[i]
                if exon in splicelist:
                    exonwt=exonwtlist[i]
                    intronlist.append([exon[0]+1,exon[1]-1])
                    intronwtlist.append(exonwt)
                    removelist.append(i)
            removelist.reverse()
            for i in removelist:
                exonlist.pop(i)
                exonwtlist.pop(i)
                    
            #print 'E',exonlist
            startnodelist=[a[1]for a in X_corr if a[0]==1]
            endnodelist=[a[1]for a in X_corr if a[0]==-1]
            novelnodelist=wgs[5]
            #print exonlist
            #print wgs[0]
            #print intronlist
            #print wgs[1]

            exonwtlist1=[exonwtlist[i] for i in range(len(exonwtlist)) if exonlist[i] in wgs[0]]
            intronwtlist1=[exonwtlist[i] for i in range(len(exonwtlist)) if exonlist[i] in wgs[1]]
            #wgrstuple=(exonlist,intronlist,splicelist,startnodelist,endnodelist,novelnodelist,exonwtlist,intronwtlist,splicewtlist)
            outwgs=(wgs[0],wgs[1],splicelist,wgs[3],wgs[4],novelnodelist,exonwtlist1,intronwtlist1,splicewtlist)
        
        return (outwgs,err.value/len(X))
Example #29
0
def compute_decoders_convex_bounded(x_values,A,nsteps,function=lambda x:x, min_x = -0.2, max_x = 0.2):
    '''solve convex optimization problem with cvxpy '''
    import cvxpy as cx
    import numpy as np

    A_m = np.matrix(np.matrix(A))
    aa = cx.zeros(np.shape(A))
    aa[A_m.nonzero()] = A_m[A_m.nonzero()]
    
    #function to be encoded  
    value=np.array([[function(x)] for x in x_values]) 
    value=np.reshape(value,nsteps)

    bb = cx.zeros(np.shape(value))
    bb[0,value.nonzero()[0]] = value[value.nonzero()[0]]    

    m,n = np.shape(aa)
    dec = cx.variable(m)
    
    p = cx.program(cx.minimize(cx.norm2(np.transpose(aa)*(dec)-np.transpose(bb))), [cx.leq(dec,max_x),cx.geq(dec,min_x)])
    p.solve()

    return dec.value
    def MinimizeConcentration(self,
                              metabolite_index=None,
                              concentration_bounds=None):
        """Finds feasible concentrations minimizing the concentration
           of metabolite i.
        
        Args:
            metabolite_index: the index of the metabolite to minimize.
                if == None, minimize the sum of all concentrations.
            concentration_bounds: the Bounds objects setting concentration bounds.
        """
        my_bounds = concentration_bounds or self.DefaultConcentrationBounds()

        ln_conc = cvxpy.variable(m=1, n=self.Ncompounds, name='lnC')
        ln_conc_lb, ln_conc_ub = my_bounds.GetLnBounds(self.compounds)
        constr = [
            cvxpy.geq(ln_conc, cvxpy.matrix(ln_conc_lb)),
            cvxpy.leq(ln_conc, cvxpy.matrix(ln_conc_ub))
        ]

        my_dG0_r_primes = np.matrix(self.dG0_r_prime)

        # Make flux-based constraints on reaction free energies.
        # All reactions must have negative dGr in the direction of the flux.
        # Reactions with a flux of 0 must be in equilibrium.
        S = np.matrix(self.S)

        for i, flux in enumerate(self.fluxes):

            curr_dg0 = my_dG0_r_primes[0, i]
            # if the dG0 is unknown, this reaction imposes no new constraints
            if np.isnan(curr_dg0):
                continue

            rcol = cvxpy.matrix(S[:, i])
            curr_dgr = curr_dg0 + RT * ln_conc * rcol
            if flux == 0:
                constr.append(cvxpy.eq(curr_dgr, 0.0))
            else:
                constr.append(cvxpy.leq(curr_dgr, 0.0))

        objective = None
        if metabolite_index is not None:
            my_conc = ln_conc[0, metabolite_index]
            objective = cvxpy.minimize(cvxpy.exp(my_conc))
        else:
            objective = cvxpy.minimize(cvxpy.sum(cvxpy.exp(ln_conc)))

        name = 'CONC_OPT'
        if metabolite_index:
            name = 'CONC_%d_OPT' % metabolite_index
        problem = cvxpy.program(objective, constr, name=name)
        optimum = problem.solve(quiet=True)
        """
        status = problem.solve(quiet=True)
        if status != 'optimal':
            status = optimized_pathway.OptimizationStatus.Infeasible(
                'Pathway infeasible given bounds.')
            return ConcentrationOptimizedPathway(
                self._model, self._thermo,
                my_bounds, optimization_status=status)
        """
        opt_ln_conc = np.matrix(np.array(ln_conc.value))
        result = ConcentrationOptimizedPathway(
            self._model,
            self._thermo,
            my_bounds,
            optimal_value=optimum,
            optimal_ln_metabolite_concentrations=opt_ln_conc)
        return result
Example #31
0
    def FindMTDF(self, concentration_bounds=None, normalization=None):
        """Finds the MTDF.
        
        Args:
            bounds: the Bounds objects setting concentration bounds.
        """
        my_bounds = concentration_bounds or self.DefaultConcentrationBounds()
        normalization = normalization or self.DeltaGNormalization.DEFAULT

        # Constrain concentrations
        ln_conc = cvxpy.variable(m=1, n=self.Ncompounds, name='lnC')
        ln_conc_lb, ln_conc_ub = my_bounds.GetLnBounds(self.compounds)
        constr = [
            cvxpy.geq(ln_conc, cvxpy.matrix(ln_conc_lb)),
            cvxpy.leq(ln_conc, cvxpy.matrix(ln_conc_ub))
        ]

        # Make the objective
        motive_force_lb = cvxpy.variable(name='B')
        my_dG0_r_primes = np.matrix(self.dG0_r_prime)

        # Make flux-based constraints on reaction free energies.
        # All reactions must have negative dGr in the direction of the flux.
        # Reactions with a flux of 0 must be in equilibrium.
        S = np.matrix(self.S)

        for i, flux in enumerate(self.fluxes):

            curr_dg0 = my_dG0_r_primes[0, i]
            # if the dG0 is unknown, this reaction imposes no new constraints
            if np.isnan(curr_dg0):
                continue

            rcol = cvxpy.matrix(S[:, i])
            curr_dgr = curr_dg0 + RT * ln_conc * rcol
            if flux == 0:
                constr.append(cvxpy.eq(curr_dgr, 0))
            else:
                motive_force = self.DeltaGNormalization.NormalizeDGByFlux(
                    curr_dgr, flux, normalization)

                constr.append(cvxpy.geq(motive_force, motive_force_lb))

        objective = cvxpy.maximize(motive_force_lb)
        problem = cvxpy.program(objective, constr, name='MTDF_OPT')

        problem.solve(quiet=True)
        """
        if status != 'optimal':
            status = optimized_pathway.OptimizationStatus.Infeasible(
                'Pathway infeasible given bounds.')
            return MTDFOptimizedPathway(
                self._model, self._thermo,
                my_bounds, optimization_status=status)
        """

        mtdf = float(motive_force_lb.value)
        opt_ln_conc = np.matrix(np.array(ln_conc.value))
        result = MTDFOptimizedPathway(
            self._model,
            self._thermo,
            my_bounds,
            optimal_value=mtdf,
            optimal_ln_metabolite_concentrations=opt_ln_conc)
        result.SetNormalization(normalization)
        return result
Example #32
0
    # Choose regularization parameter
    # lambda > lambda_max -> zero solution
    lambda_max = 2*norm(dot(nA.T, rSig.T), np.inf) 

    lamb = 1.0e-8*lambda_max
    
    print('Solving L1 penalized system with cvxpy...')

    coefs = cvx.variable(n_qpnts,1)
    A     = cvx.matrix(nA)
    rhs   = cvx.matrix(rSig).T

    objective = cvx.minimize(cvx.norm2(A*coefs - rhs) +
                             lamb*cvx.norm1(coefs) )
    constraints = [cvx.geq(coefs,0.0)]
    prob = cvx.program(objective, constraints)

    # Call the solver
    prob.solve(quiet=True)  #Use quiet=True to suppress output


    # Convert the cvxmod objects to plain numpy arrays for further processing
    nd_coefs_l1 = np.array(coefs.value).squeeze()

    # Cutoff those coefficients that are less than cutoff
    cutoff =  nd_coefs_l1.mean() + 2.0*nd_coefs_l1.std(ddof=1)
    nd_coefs_l1_trim = np.where(nd_coefs_l1 > cutoff, nd_coefs_l1, 0)

    # Get indices needed for sorting coefs, in reverse order.
    sortedIndex = nd_coefs_l1_trim.argsort()[::-1]
Example #33
0
 def check_feasible_constraints(self):
   return list(flatten(
     [geq(link.v_flow, link.flow), geq(link.v_dens, link.rho),leq(link.v_flow, link.flow), leq(link.v_dens, link.rho)]
       for link in self.get_links()
   ))
    def MinimizeConcentration(self, metabolite_index=None,
                              concentration_bounds=None):
        """Finds feasible concentrations minimizing the concentration
           of metabolite i.
        
        Args:
            metabolite_index: the index of the metabolite to minimize.
                if == None, minimize the sum of all concentrations.
            concentration_bounds: the Bounds objects setting concentration bounds.
        """
        my_bounds = concentration_bounds or self.DefaultConcentrationBounds()

        ln_conc = cvxpy.variable(m=1, n=self.Ncompounds, name='lnC')
        ln_conc_lb, ln_conc_ub = my_bounds.GetLnBounds(self.compounds)
        constr = [cvxpy.geq(ln_conc, cvxpy.matrix(ln_conc_lb)),
                  cvxpy.leq(ln_conc, cvxpy.matrix(ln_conc_ub))]
        
        my_dG0_r_primes = np.matrix(self.dG0_r_prime)
        
        # Make flux-based constraints on reaction free energies.
        # All reactions must have negative dGr in the direction of the flux.
        # Reactions with a flux of 0 must be in equilibrium.
        S = np.matrix(self.S)
        
        for i, flux in enumerate(self.fluxes):
            
            curr_dg0 = my_dG0_r_primes[0, i]
            # if the dG0 is unknown, this reaction imposes no new constraints
            if np.isnan(curr_dg0):
                continue
            
            rcol = cvxpy.matrix(S[:, i])
            curr_dgr = curr_dg0 + RT * ln_conc * rcol
            if flux == 0:
                constr.append(cvxpy.eq(curr_dgr, 0.0))
            else:
                constr.append(cvxpy.leq(curr_dgr, 0.0))        
        
        objective = None
        if metabolite_index is not None:
            my_conc = ln_conc[0, metabolite_index]
            objective = cvxpy.minimize(cvxpy.exp(my_conc))
        else:
            objective = cvxpy.minimize(
                cvxpy.sum(cvxpy.exp(ln_conc)))
        
        name = 'CONC_OPT'
        if metabolite_index:
            name = 'CONC_%d_OPT' % metabolite_index
        problem = cvxpy.program(objective, constr, name=name)
        optimum = problem.solve(quiet=True)        

        """
        status = problem.solve(quiet=True)
        if status != 'optimal':
            status = optimized_pathway.OptimizationStatus.Infeasible(
                'Pathway infeasible given bounds.')
            return ConcentrationOptimizedPathway(
                self._model, self._thermo,
                my_bounds, optimization_status=status)
        """
        opt_ln_conc = np.matrix(np.array(ln_conc.value))
        result = ConcentrationOptimizedPathway(
            self._model, self._thermo,
            my_bounds, optimal_value=optimum,
            optimal_ln_metabolite_concentrations=opt_ln_conc)
        return result