Пример #1
0
void ast_gen::store_parallel_accesses_for_current_dimension(isl_ast_build * builder)
{
    // Parallel = { [a[i] -> a[j]] -> [[t_i] -> [t_j]] : t_i < t_j }

    // NOTE: Reduce number of relations by making the relation non-reflexive,
    // i.e. by relating times with < instead of !=.

    // NOTE: Since parallel accesses are only used for storage allocation
    // where only their distances matter,
    // and the distances remain the same accross periods,
    // it is sufficient to store accesses for a single period.

    isl::union_map schedule = isl_ast_build_get_schedule(builder);
    isl::space schedule_space = isl_ast_build_get_schedule_space(builder);
    int dimension = schedule_space.dimension(isl::space::output) - 1;

    auto access_relations = (m_model_summary.read_relations | m_model_summary.write_relations)
            .in_domain(m_model_summary.domains)
            .in_range(m_model_summary.array_domains);

    auto access_schedule = schedule;
    access_schedule.map_domain_through(access_relations);

    access_schedule.for_each([&](const isl::map & m)
    {
        auto parallel = m.cross(m);

        // parallel_times: { [i_0 ... i_d] -> [j_0 ... j_d] : i_0 == j_0 ... j_d < j_d }
        auto sched_relation_space = isl::space::from(schedule_space, schedule_space);
        auto parallel_times = isl::basic_map::universe(sched_relation_space);

        for (int i = 0; i < dimension; i++)
            parallel_times.add_constraint
                    (sched_relation_space.in(i) == sched_relation_space.out(i));

        parallel_times.add_constraint
                (sched_relation_space.in(dimension) < sched_relation_space.out(dimension));

        parallel = parallel.in_range(parallel_times.wrapped());

        auto parallel_accesses = parallel.domain().unwrapped();

        if (parallel_accesses.is_empty())
            return true;

        if (verbose<ast_gen>::enabled())
        {
            cout << "  -- Access schedule: " << endl;
            m_printer.print(m);
            cout << endl;

            cout << "  => Parallel accesses:" << endl;
            m_printer.print_each_in(parallel_accesses);
        }

        m_model.parallel_accesses |= parallel_accesses;

        return true;
    });
}
Пример #2
0
int main( ) {
  double x[state_dim+1];
  double objective[state_dim+1] = {0, -2.5, -5.0, -3.4};
  double ieq_coeff[ieq_dim] = {425, 400, 600};
  double ieq_matrix[ieq_dim][state_dim+1]
    = {{0,2,10,4}, {0,6,5,8}, {0, 7, 10, 8}};
  double eq_coeff[eq_dim]; // = {30};
  double eq_matrix[eq_dim][state_dim+1];
  //
  lprec *lp;
  //
  lp = make_lp(eq_dim+ieq_dim, state_dim);
  set_obj_fn (lp, objective);
  for(int i=0; i<ieq_dim; i++) {
    add_constraint( lp, ieq_matrix[i], LE, ieq_coeff[i] );
  }
  for(int i=0; i<eq_dim; i++) {
    add_constraint( lp, eq_matrix[i], EQ, eq_coeff[i] );
  }
  //
  set_verbose(lp, 0);
  set_presolve(lp, PRESOLVE_ROWS | PRESOLVE_COLS | PRESOLVE_LINDEP, get_presolveloops(lp));
  solve(lp);
  //
  std::cout << "f : " << get_objective(lp) << std::endl;
  std::cout << "x :"  ;
  double col0 = get_Norig_columns(lp);
  double row0 = get_Norig_rows(lp);
  for(int i = 1; i <= col0; i++) {
    double _x = get_var_primalresult(lp, row0 + i);
    std::cout << " " << _x ;
  }
  std::cout << std::endl;
}
Пример #3
0
bool ilp_problem_t::add_constraints_of_transitive_unification(
    term_t t1, term_t t2, term_t t3)
{
    std::string key =
        util::format("%ld:%ld:%ld", t1.get_hash(), t2.get_hash(), t3.get_hash());

    /* IGNORE TRIPLETS WHICH HAVE BEEN CONSIDERED ALREADY. */
    if (m_log_of_term_triplet_for_transitive_unification.count(key) > 0)
        return false;

    pg::node_idx_t n_t1t2 = m_graph->find_sub_node(t1, t2);
    pg::node_idx_t n_t2t3 = m_graph->find_sub_node(t2, t3);
    pg::node_idx_t n_t3t1 = m_graph->find_sub_node(t3, t1);

    if (n_t1t2 < 0 or n_t2t3 < 0 or n_t3t1 < 0) return false;

    variable_idx_t v_t1t2 = find_variable_with_node(n_t1t2);
    variable_idx_t v_t2t3 = find_variable_with_node(n_t2t3);
    variable_idx_t v_t3t1 = find_variable_with_node(n_t3t1);

    if (v_t1t2 < 0 or v_t2t3 < 0 or v_t3t1 < 0) return false;

    std::string name1 =
        util::format("transitivity:(%s,%s,%s)",
        t1.string().c_str(), t2.string().c_str(), t3.string().c_str());
    constraint_t con_trans1(name1, OPR_GREATER_EQ, -1);
    con_trans1.add_term(v_t1t2, +1.0);
    con_trans1.add_term(v_t2t3, -1.0);
    con_trans1.add_term(v_t3t1, -1.0);

    std::string name2 =
        util::format("transitivity:(%s,%s,%s)",
        t2.string().c_str(), t3.string().c_str(), t1.string().c_str());
    constraint_t con_trans2(name2, OPR_GREATER_EQ, -1);
    con_trans2.add_term(v_t1t2, -1.0);
    con_trans2.add_term(v_t2t3, +1.0);
    con_trans2.add_term(v_t3t1, -1.0);

    std::string name3 =
        util::format("transitivity:(%s,%s,%s)",
        t3.string().c_str(), t1.string().c_str(), t2.string().c_str());
    constraint_t con_trans3(name3, OPR_GREATER_EQ, -1);
    con_trans3.add_term(v_t1t2, -1.0);
    con_trans3.add_term(v_t2t3, -1.0);
    con_trans3.add_term(v_t3t1, +1.0);

    constraint_idx_t idx_trans1 = add_constraint(con_trans1);
    constraint_idx_t idx_trans2 = add_constraint(con_trans2);
    constraint_idx_t idx_trans3 = add_constraint(con_trans3);
    
    // FOR CUTTING-PLANE
    add_laziness_of_constraint(idx_trans1);
    add_laziness_of_constraint(idx_trans2);
    add_laziness_of_constraint(idx_trans3);

    m_log_of_term_triplet_for_transitive_unification.insert(key);

    return 1;
}
Пример #4
0
variable_idx_t ilp_problem_t::add_variable_of_edge(
    pg::edge_idx_t idx, double coef, bool do_add_constraint_for_node)
{
    const pg::edge_t &edge = m_graph->edge(idx);

    if (ms_do_economize)
    {
        variable_idx_t var(-1);

        if (edge.is_chain_edge())
            variable_idx_t var = find_variable_with_hypernode(edge.head());
        if (edge.is_unify_edge() and edge.head() < 0)
            variable_idx_t var = find_variable_with_hypernode(edge.tail());

        if (var >= 0)
        {
            m_map_edge_to_variable[idx] = var;
            return var;
        }
    }

    variable_idx_t var = add_variable(variable_t(
        util::format("edge(%d):hn(%d,%d)", idx, edge.tail(), edge.head()), 0.0));

    if (do_add_constraint_for_node)
    {
        variable_idx_t v_tail = find_variable_with_hypernode(edge.tail());
        variable_idx_t v_head = find_variable_with_hypernode(edge.head());

        /* IF THE EDGE IS TRUE, TAIL AND HEAD MUST BE TRUE, TOO. */
        if (v_tail >= 0 and (v_head >= 0 or edge.head() < 0))
        {
            constraint_t con(
                util::format("e_hn_dependency:e(%d):hn(%d,%d)",
                       idx, edge.tail(), edge.head()),
                OPR_GREATER_EQ, 0.0);
            
            con.add_term(v_tail, 1.0);
            if (edge.head() >= 0)
                con.add_term(v_head, 1.0);
            con.add_term(var, -1.0 * con.terms().size());
            add_constraint(con);
        }

        /* IF LITERAL NODES IN THE HEAD ARE TRUE, THE NODE MUST BE TRUE, TOO. */
        if (edge.is_chain_edge() and v_head >= 0)
        {
            constraint_t con(
                util::format("n_e_dependency:e(%d)", idx), OPR_GREATER_EQ, 0.0);
            con.add_term(v_head, -1.0);
            con.add_term(var, con.terms().size());
            add_constraint(con);
        }
    }

    m_map_edge_to_variable[idx] = var;
    return var;
}
Пример #5
0
void ilp_problem_t::
add_constrains_of_conditions_for_chain(pg::edge_idx_t idx)
{
    const pg::edge_t &edge = m_graph->edge(idx);
    variable_idx_t v_edge = find_variable_with_edge(idx);
    if (v_edge < 0) return;

    if (not edge.is_chain_edge())
        return;

    hash_set<pg::node_idx_t> conds1, conds2;
    bool is_available = m_graph->check_availability_of_chain(idx, &conds1, &conds2);

    // IF THE CHAIN IS NOT AVAILABLE, HEAD-HYPERNODE MUST BE FALSE.
    if (not is_available)
        add_constancy_of_variable(v_edge, 0.0);
    else
    {
        if (not conds1.empty())
        {
            // TO PERFORM THE CHAINING, NODES IN conds1 MUST BE TRUE.
            constraint_t con(
                util::format("node_must_be_true_for_chain:e(%d)", idx),
                OPR_GREATER_EQ, 0.0);

            for (auto n = conds1.begin(); n != conds1.end(); ++n)
            {
                variable_idx_t _v = find_variable_with_node(*n);
                assert(_v >= 0);
                con.add_term(_v, 1.0);
            }

            con.add_term(v_edge, -1.0 * con.terms().size());
            add_constraint(con);
        }

        if (not conds2.empty())
        {
            // TO PERFORM THE CHAINING, NODES IN conds2 MUST NOT BE TRUE.
            constraint_t con(
                util::format("node_must_be_false_for_chain:e(%d)", idx),
                OPR_GREATER_EQ, 0.0);

            for (auto n = conds2.begin(); n != conds2.end(); ++n)
            {
                variable_idx_t _v = find_variable_with_node(*n);
                assert(_v >= 0);
                con.add_term(_v, -1.0);
            }

            double b = -1.0 * con.terms().size();
            con.add_term(v_edge, b);
            con.set_bound(b);
            add_constraint(con);
        }
    }
}
Пример #6
0
void memory_model_sct::write_serialization_external(
  symex_target_equationt &equation)
{
  for(address_mapt::const_iterator
      a_it=address_map.begin();
      a_it!=address_map.end();
      a_it++)
  {
    const a_rect &a_rec=a_it->second;

    // This is quadratic in the number of writes
    // per address. Perhaps some better encoding
    // based on 'places'?
    for(event_listt::const_iterator
        w_it1=a_rec.writes.begin();
        w_it1!=a_rec.writes.end();
        ++w_it1)
    {
      event_listt::const_iterator next=w_it1;
      ++next;

      for(event_listt::const_iterator w_it2=next;
          w_it2!=a_rec.writes.end();
          ++w_it2)
      {
        // external?
        if((*w_it1)->source.thread_nr==
           (*w_it2)->source.thread_nr)
          continue;

        // ws is a total order, no two elements have the same rank
        // s -> w_evt1 before w_evt2; !s -> w_evt2 before w_evt1

        symbol_exprt s=nondet_bool_symbol("ws-ext");

        // write-to-write edge
        add_constraint(
          equation,
          implies_exprt(s, before(*w_it1, *w_it2)),
          "ws-ext",
          (*w_it1)->source);

        add_constraint(
          equation,
          implies_exprt(not_exprt(s), before(*w_it2, *w_it1)),
          "ws-ext",
          (*w_it1)->source);
      }
    }
  }
}
Пример #7
0
void hbox::add( area &a, double fraction )
{
	precondition( !_init, "cannot add new areas after update" );

	add_constraint( a.top() == _top + _padding + _spacing );
	add_constraint( a.bottom() == _bottom - _padding - _spacing );

//	if ( fraction > 1e-8 )
//		add_constraint( weak || a.width() >= width() * fraction );

	add_constraint( a.left() == _current + _spacing );
	add_constraint( a.width() >= a.minimum_width() );

	_current = a.right() + _spacing;
}
Пример #8
0
bool CFeasibilityMap::SolveLP(Matrix &A, ColumnVector &b) {
  lprec *lp ;
  int n_row = A.nrows(); int n_col = A.ncols();
  lp = make_lp(0,n_col) ; 

  double *input_row = new double[1+n_col];
  for (int i_row=1; i_row<=n_row; i_row++){
      input_row[0] = 0 ;
      for (int j=1; j<=n_col; j++){
          input_row[j] = A(i_row,j) ;
      }
      add_constraint(lp, input_row, LE, b(i_row)) ;
  }
  delete [] input_row;
  
  double *input_obj = new double[1+n_col];    // The first zero is for matrix form
  input_obj[0] = 0 ;
  for (int j=1; j<=n_col; j++){
      input_obj[j] = 1 ;
  }
  set_obj_fn(lp, input_obj) ;
  delete [] input_obj;
  set_verbose(lp, IMPORTANT); // NEUTRAL (0), IMPORTANT (3), NORMAL (4), FULL (6)
  bool is_feasible = (solve(lp)==0); // 0: feasible solution found,  2: not found
		                                 // solution for minimizing objective function
	delete_lp(lp);

  return is_feasible;
}
Пример #9
0
size_t ilp_problem_t::add_constrains_of_exclusive_chains(
    const std::list< hash_set<pg::edge_idx_t> > &exc)
{
    size_t num_of_added_constraints(0);

    for (auto it = exc.begin(); it != exc.end(); ++it)
    {
        std::string name =
            "exclusive_chains(" +
            util::join(it->begin(), it->end(), ",") + ")";
        constraint_t con(name, OPR_GREATER_EQ, -1.0);

        for (auto e = it->begin(); e != it->end(); ++e)
        {
            variable_idx_t v = find_variable_with_edge(*e);
            if (v >= 0)
                con.add_term(v, -1.0);
            else
                break;
        }

        if (con.terms().size() == it->size())
        {
            add_constraint(con);
            ++num_of_added_constraints;
        }
    }

    return num_of_added_constraints;
}
Пример #10
0
static void get_paren(
    char *buf,
    long *minp,
    long *maxp,
    int parent)
{
    int lth;

    get_must(0, buf);
    if (!strcmp(buf, size_w))
    {
        get_size(buf, minp, maxp, parent);
        // if (type == ASN_UTCTIME || type == ASN_GENTIME) *minp = *maxp = 0;
    }
    else
    {
        if (find_name(classname)->type != ASN_OBJ_ID &&
            (*buf == '_' || (*buf >= '0' && *buf <= '9') ||
             !strncmp(buf, min_w, 3)))
        {                       /* convert any upper bounds to numbers */
            get_min_max(buf, minp, maxp, parent);
            option |= ASN_RANGE_FLAG;
        }
        else
            for (; *buf != ')';
                 get_must(0, buf))
            {
                lth = strlen(buf);
                cat(&buf[lth++], " ");
                add_constraint(buf, lth);
            }
    }
}
Пример #11
0
 /** Add an edit constraint for a given variable.
  * The application should call this for every variable it is planning
  * to suggest a new value for, before calling begin_edit(). */
 simplex_solver& add_edit_var(const variable& v,
                              const strength& s = strength::strong(),
                              double weight = 1.0)
 {
     add_constraint(std::make_shared<edit_constraint>(v, s, weight));
     return *this;
 }
Пример #12
0
Файл: windll.c Проект: ks6g10/CA
/* Add a constraint to the problem,
   row is the constraint row,
   rh is the right hand side,
   constr_type is the type of constraint (LE (<=), GE(>=), EQ(=)) */
long __declspec(dllexport) WINAPI _add_constraint(lprec *lp, double *row, long constr_type, double rh)
 {
  long ret;

  if (lp != NULL) {
   freebuferror();
   ret = add_constraint(lp, row,(short) constr_type, rh);
  }
  else
   ret = 0;
  return(ret);
 }
Пример #13
0
nlopt_result
NLOPT_STDCALL nlopt_add_inequality_constraint(nlopt_opt opt,
					      nlopt_func fc, void *fc_data,
					      double tol)
{
     nlopt_result ret;
     if (!opt || !inequality_ok(opt->algorithm)) ret = NLOPT_INVALID_ARGS;
     else ret = add_constraint(&opt->m, &opt->m_alloc, &opt->fc,
			       1, fc, NULL, fc_data, &tol);
     if (ret < 0 && opt && opt->munge_on_destroy)
	  opt->munge_on_destroy(fc_data);
     return ret;
}
Пример #14
0
variable_idx_t ilp_problem_t::add_variable_of_hypernode(
    pg::hypernode_idx_t idx, double coef, bool do_add_constraint_for_member)
{
    const std::vector<pg::node_idx_t> &hypernode = m_graph->hypernode(idx);
    if (hypernode.empty()) return -1;

    if (ms_do_economize)
    {
        /* IF A HYERNODE INCLUDE ONLY ONE LITERAL-NODE,
        * USE THE NODE'S VARIABLE AS THE HYPERNODE'S VARIABLE. */
        if (hypernode.size() == 1)
        {
            const pg::node_t &node = m_graph->node(hypernode.front());
            if (not node.is_equality_node() and not node.is_non_equality_node())
            {
                variable_idx_t var = find_variable_with_node(hypernode.front());
                if (var >= 0)
                {
                    m_map_hypernode_to_variable[idx] = var;
                    return var;
                }
            }
        }
    }

    std::string nodes =
        util::join(hypernode.begin(), hypernode.end(), ",");
    std::string name = util::format("hn(%d):n(%s)", idx, nodes.c_str());
    variable_idx_t var = add_variable(variable_t(name, coef));

    if (do_add_constraint_for_member)
    {
        /* FOR A HYPERNODE BEING TRUE, ITS ALL MEMBERS MUST BE TRUE TOO. */
        constraint_t cons(
            util::format("hn_n_dependency:hn(%d):n(%s)", idx, nodes.c_str()),
            OPR_GREATER_EQ, 0.0);
        for (auto n = hypernode.begin(); n != hypernode.end(); ++n)
        {
            variable_idx_t v = find_variable_with_node(*n);
            if (v < 0) return -1;
            cons.add_term(v, 1.0);
        }

        cons.set_bound(0.0, 1.0 * (cons.terms().size() - 1));
        cons.add_term(var, -1.0 * cons.terms().size());
        add_constraint(cons);
    }

    m_map_hypernode_to_variable[idx] = var;
    return var;
}
Пример #15
0
int CLPLpsolve::addConstraint(CLPConstraint* c)
{
	if (!m_rowsPreAllocated) //false
	{
		if (c->getNumCoefficients() <= 0)
			return 0;

		REAL * row = new REAL[c->getNumCoefficients()];
		int * colno = new int[c->getNumCoefficients()];
		//double coefs = new double[c->getNumCoefficients()];

		for (int i = 0; i < c->getNumCoefficients(); ++i) {
			row[i] = c->getCoefficients().at(i);
			colno[i] = (c->getCoefficientColumns().at(i)) + 1;
		}

		//REAL *row = &c->getCoefficients().at(0);
		//int *colno = &c->getCoefficientColumns().at(0);

		char sense;
		switch (c->getType()) {
		case lpLessThanConstraint:
			sense = LE;
			break;

		case lpGreaterThanConstraint:
			sense = GE;
			break;

		case lpEqualToConstraint:
			sense = EQ;
			break;
		}
		
		
		//m_status = add_constraintex(m_env, c->getNumCoefficients(), row, colno, sense, c->getRhs());
		m_status = add_constraint(m_env, row, sense, c->getRhs());
		
		++m_rowCount;
		m_status = set_row_name(m_env, m_rowCount, const_cast<char*>(c->getName().c_str()));

		delete [] row;
		delete [] colno;
		
	}

	return getStatus();
}
nlopt_result
NLOPT_STDCALL nlopt_add_precond_equality_constraint(nlopt_opt opt,
						    nlopt_func fc,
						    nlopt_precond pre,
						    void *fc_data,
						    double tol)
{
     nlopt_result ret;
     if (!opt || !equality_ok(opt->algorithm)
	 || nlopt_count_constraints(opt->p, opt->h) + 1 > opt->n)
	  ret = NLOPT_INVALID_ARGS;
     else ret = add_constraint(&opt->p, &opt->p_alloc, &opt->h,
			       1, fc, NULL, pre, fc_data, &tol);
     if (ret < 0 && opt && opt->munge_on_destroy)
	  opt->munge_on_destroy(fc_data);
     return ret;
}
nlopt_result
NLOPT_STDCALL nlopt_add_inequality_mconstraint(nlopt_opt opt, unsigned m,
					       nlopt_mfunc fc, void *fc_data,
					       const double *tol)
{
     nlopt_result ret;
     if (!m) { /* empty constraints are always ok */
	  if (opt && opt->munge_on_destroy) opt->munge_on_destroy(fc_data);
	  return NLOPT_SUCCESS;
     }
     if (!opt || !inequality_ok(opt->algorithm)) ret = NLOPT_INVALID_ARGS;
     else ret = add_constraint(&opt->m, &opt->m_alloc, &opt->fc,
			       m, NULL, fc, NULL, fc_data, tol);
     if (ret < 0 && opt && opt->munge_on_destroy)
	  opt->munge_on_destroy(fc_data);
     return ret;
}
Пример #18
0
void memory_model_sct::program_order(
  symex_target_equationt &equation)
{
  per_thread_mapt per_thread_map;
  build_per_thread_map(equation, per_thread_map);

  thread_spawn(equation, per_thread_map);

  // iterate over threads

  for(per_thread_mapt::const_iterator
      t_it=per_thread_map.begin();
      t_it!=per_thread_map.end();
      t_it++)
  {
    const event_listt &events=t_it->second;

    // iterate over relevant events in the thread

    event_it previous=equation.SSA_steps.end();

    for(event_listt::const_iterator
        e_it=events.begin();
        e_it!=events.end();
        e_it++)
    {
      if(is_memory_barrier(*e_it))
         continue;

      if(previous==equation.SSA_steps.end())
      {
        // first one?
        previous=*e_it;
        continue;
      }

      add_constraint(
        equation,
        before(previous, *e_it),
        "po",
        (*e_it)->source);

      previous=*e_it;
    }
  }
}
Пример #19
0
bool CFeasibilityMap::SolveLP(Matrix &A, ColumnVector &b, ColumnVector &x) {
  lprec *lp ;
  int n_row = A.nrows(); int n_col = A.ncols();
  x = ColumnVector(n_col); x = 0;
  lp = make_lp(0,n_col) ; 
  
  double *input_row = new double[1+n_col];
  for (int i_row=1; i_row<=n_row; i_row++){
      input_row[0] = 0 ; // The first zero is for matrix form
      for (int j=1; j<=n_col; j++){
          input_row[j] = A(i_row,j) ;
      }
      add_constraint(lp, input_row, LE, b(i_row)) ;
  }
  delete [] input_row;
  
  double *input_obj = new double[1+n_col];    // The first zero is for matrix form
  input_obj[0] = 0 ;
  for (int j=1; j<=n_col; j++){
      input_obj[j] = 1 ;
  }
  set_obj_fn(lp, input_obj) ;
  delete [] input_obj;
  set_verbose(lp, IMPORTANT); // NEUTRAL (0), IMPORTANT (3), NORMAL (4), FULL (6)
  bool is_feasible = (solve(lp)==0); // 0: feasible solution found,  2: not found
                                     // solution for minimizing objective function                               
  double* x_min = new double[n_col];
  double* x_max = new double[n_col];                      
  if (is_feasible) {
    get_variables(lp, x_min);
    set_maxim(lp);
    is_feasible = (solve(lp)==0); // 0: feasible solution found,  2: not found
    if (is_feasible) {
      get_variables(lp, x_max);
      for (int i = 0; i < n_col; i++) {
        x(i+1) = (x_min[i] + x_max[i]) / 2.0;
      }
    }
  }
  
  delete [] x_min;
  delete [] x_max;
                                     
  delete_lp(lp);
  return is_feasible;
}
Пример #20
0
constraint_idx_t ilp_problem_t::add_constraint_of_mutual_exclusion(
    pg::node_idx_t n1, pg::node_idx_t n2, const pg::unifier_t &uni)
{
    std::string key = (n1 < n2) ?
        util::format("%d:%d", n1, n2) : util::format("%d:%d", n2, n1);

    /* IGNORE TUPLES WHICH HAVE BEEN CONSIDERED ALREADY. */
    if(m_log_of_node_tuple_for_mutual_exclusion.count(key) > 0)
        return -1;

    variable_idx_t var1 = find_variable_with_node(n1);
    variable_idx_t var2 = find_variable_with_node(n2);

    if( var1 < 0 or var2 < 0 ) return -1;

    /* N1 AND N2 CANNOT BE TRUE AT SAME TIME. */
    constraint_t con(
        util::format("inconsistency:n(%d,%d)", n1, n2), OPR_LESS_EQ, 1.0);
    con.add_term(var1, 1.0);
    con.add_term(var2, 1.0);

    bool f_fails = false;
    const std::set<literal_t> &subs = uni.substitutions();

    for (auto sub = subs.begin(); sub != subs.end(); ++sub)
    {
        const term_t &term1 = sub->terms[0];
        const term_t &term2 = sub->terms[1];
        if (term1.is_constant() and term2.is_constant() and term1 != term2)
            return -1;

        pg::node_idx_t sub_node = m_graph->find_sub_node(term1, term2);
        if (sub_node < 0) return -1;

        variable_idx_t sub_var = find_variable_with_node(sub_node);
        if (sub_var < 0) return -1;

        con.add_term(sub_var, 1.0);
        con.set_bound(con.bound() + 1.0);
    }

    m_log_of_node_tuple_for_mutual_exclusion.insert(key);

    return add_constraint(con);
}
Пример #21
0
bool add_constraints(int argc, char ** argv, struct mpd_connection *conn)
{
    struct constraint *constraints;

    if (argc % 2 != 0)
        DIE("arguments must be pairs of search types and queries\n");

    int numconstraints = get_constraints(argc, argv, &constraints);
    if (numconstraints < 0)
        return false;

    for (int i = 0; i < numconstraints; i++) {
        add_constraint(conn, &constraints[i]);
    }

    free(constraints);
    return true;
}
Пример #22
0
void ilp_problem_t::add_constraints_to_forbid_chaining_from_explained_node(
    pg::edge_idx_t idx_unify, pg::node_idx_t idx_explained,
    std::list<constraint_idx_t> *out)
{
    const pg::edge_t &e_uni = m_graph->edge(idx_unify);
    if (not e_uni.is_unify_edge()) return;

    // IF A LITERAL IS UNIFIED AND EXPLAINED BY ANOTHER ONE,
    // THEN CHAINING FROM THE LITERAL IS FORBIDDEN.

    variable_idx_t v_uni = find_variable_with_edge(idx_unify);
    if (v_uni < 0) return;

    auto from = m_graph->hypernode(e_uni.tail());
    if (from[0] != idx_explained and from[1] != idx_explained) return;

    auto hns = m_graph->search_hypernodes_with_node(idx_explained);
    for (auto hn = hns->begin(); hn != hns->end(); ++hn)
    {
        auto es = m_graph->search_edges_with_hypernode(*hn);
        for (auto j = es->begin(); j != es->end(); ++j)
        {
            const pg::edge_t &e_ch = m_graph->edge(*j);
            if (not e_ch.is_chain_edge() or e_ch.tail() != (*hn)) continue;

            constraint_t con(
                util::format("unify_or_chain:e(%d):e(%d)", idx_unify, *j), OPR_GREATER_EQ, -1.0);
            variable_idx_t v_ch = find_variable_with_edge(*j);

            if (v_ch >= 0)
            {
                con.add_term(v_ch, -1.0);
                con.add_term(v_uni, -1.0);

                constraint_idx_t con_idx = add_constraint(con);

                if (con_idx >= 0 and out != NULL)
                    out->push_back(con_idx);
            }
        }
    }
}
Пример #23
0
constraint_idx_t ilp_problem_t::
add_constraint_of_dependence_of_node_on_hypernode(pg::node_idx_t idx)
{   
    const pg::node_t &node = m_graph->node(idx);
    if (node.is_equality_node() or node.is_non_equality_node()) return -1;

    variable_idx_t var_node = find_variable_with_node(idx);
    if (var_node < 0) return -1;

    hash_set<pg::hypernode_idx_t> masters;
    if (node.is_equality_node() or node.is_non_equality_node())
    {
        auto hns = m_graph->search_hypernodes_with_node(idx);
        if (hns != NULL)
        {
            hash_set<pg::edge_idx_t> parental_edges;
            for (auto it = hns->begin(); it != hns->end(); ++it)
                m_graph->enumerate_parental_edges(*it, &parental_edges);

            for (auto it = parental_edges.begin(); it != parental_edges.end(); ++it)
                masters.insert(m_graph->edge(*it).head());
        }
    }
    else if (node.master_hypernode() >= 0)
        masters.insert(node.master_hypernode());

    /* TO LET A NODE BE TRUE, ITS MASTER-HYPERNODES IS TRUE */
    constraint_t con(util::format("n_dependency:n(%d)", idx), OPR_GREATER_EQ, 0.0);

    for (auto it = masters.begin(); it != masters.end(); ++it)
    {
        variable_idx_t var_master = find_variable_with_hypernode(*it);

        if (var_node != var_master and var_master >= 0)
            con.add_term(var_master, 1.0);
    }
    if (con.terms().empty()) return -1;

    con.add_term(var_node, -1.0);
    return add_constraint(con);
}
Пример #24
0
constraint_idx_t ilp_problem_t::
add_constraint_of_dependence_of_hypernode_on_parents(pg::hypernode_idx_t idx)
{
    variable_idx_t var = find_variable_with_hypernode(idx);
    if (var < 0) return -1;

    hash_set<pg::hypernode_idx_t> parents;
    m_graph->enumerate_parental_hypernodes(idx, &parents);
    if (parents.empty()) return -1;

    /* TO LET A HYPERNODE BE TRUE, ANY OF ITS PARENTS ARE MUST BE TRUE. */
    constraint_t con(util::format("hn_dependency:hn(%d)", idx), OPR_GREATER_EQ, 0.0);
    con.add_term(var, -1.0);
    for( auto hn = parents.begin(); hn != parents.end(); ++hn )
    {
        variable_idx_t v = find_variable_with_hypernode(*hn);
        if (v >= 0) con.add_term( v, 1.0 );
    }

    return add_constraint(con);
}
Пример #25
0
void memory_model_sct::thread_spawn(
  symex_target_equationt &equation,
  const per_thread_mapt &per_thread_map)
{
  // thread spawn: the spawn precedes the first
  // instruction of the new thread in program order

  unsigned next_thread_id=0;
  for(eventst::const_iterator
      e_it=equation.SSA_steps.begin();
      e_it!=equation.SSA_steps.end();
      e_it++)
  {
    if(is_spawn(e_it))
    {
      per_thread_mapt::const_iterator next_thread=
        per_thread_map.find(++next_thread_id);
      if(next_thread==per_thread_map.end()) continue;

      // For SC and several weaker memory models a memory barrier
      // at the beginning of a thread can simply be ignored, because
      // we enforce program order in the thread-spawn constraint
      // anyway. Memory models with cumulative memory barriers
      // require explicit handling of these.
      event_listt::const_iterator n_it=next_thread->second.begin();
      for( ;
          n_it!=next_thread->second.end() &&
          (*n_it)->is_memory_barrier();
          ++n_it)
        ;

      if(n_it!=next_thread->second.end())
        add_constraint(
          equation,
          before(e_it, *n_it),
          "thread-spawn",
          e_it->source);
    }
  }
}
Пример #26
0
void memory_model_sct::thread_spawn(
  symex_target_equationt &equation,
  const per_thread_mapt &per_thread_map)
{
  // thread spawn: the spawn precedes the first
  // instruction of the new thread in program order

  unsigned next_thread_id=0;
  for(eventst::const_iterator
      e_it=equation.SSA_steps.begin();
      e_it!=equation.SSA_steps.end();
      e_it++)
  {
    if(is_spawn(e_it))
    {
      per_thread_mapt::const_iterator next_thread=
        per_thread_map.find(++next_thread_id);
      if(next_thread==per_thread_map.end()) continue;

      // add a constraint for all events,
      // considering regression/cbmc-concurrency/pthread_create_tso1
      for(event_listt::const_iterator
          n_it=next_thread->second.begin();
          n_it!=next_thread->second.end();
          n_it++)
      {
        if(!(*n_it)->is_memory_barrier())
          add_constraint(
            equation,
            before(e_it, *n_it),
            "thread-spawn",
            e_it->source);
      }
    }
  }
}
Пример #27
0
char *call_lp(int next_expr(int))
{int i,constraints; expr_type_t goal_type; 
 char *retval, *retval2;
    /* initially the expression to be checked is in entropy_expr.
       determine first the variables */
    init_var_assignment(); /* start collecting variables */
    add_expr_variables();  /* variables in the expression to be checked */
    constraints=0;
    for(i=0;next_expr(i)==0;i++){ /* go over all constraints */
        constraints++;
         // Markov constraints give several cols
        if(entropy_expr.type==ent_Markov){
            constraints+=entropy_expr.n-3;
        }
        add_expr_variables();
    }
    /* figure out final variables, rows, cols, number of Shannon */
    if(do_variable_assignment()){ // number of variables is less than 2
        return "number of final random variables is less than 2";
    }
    /* get memory for row and column permutation */
    cols += constraints;
    rowperm=malloc((rows+1)*sizeof(int));
    colperm=malloc((cols+1)*sizeof(int));
    if(!rowperm || !colperm){
        if(rowperm){ free(rowperm); rowperm=NULL; }
        if(colperm){ free(colperm); colperm=NULL; }
        return "the problem is too large, not enough memory";
    }
    for(i=0;i<=rows;i++) rowperm[i]=i;    perm_array(rows+1,rowperm);
    for(i=0;i<=cols;i++) colperm[i]= i-1; perm_array(cols+1,colperm);
    /* the expression to be checked, this will be the goal */
    if(constraints) next_expr(-1);
    goal_type=entropy_expr.type; // ent_eq, ent_ge
    create_glp(); // create a new glp instance
    for(i=0;i<entropy_expr.n;i++){
        row_idx[i+1]=varidx(entropy_expr.item[i].var);
        row_val[i+1]=entropy_expr.item[i].coeff;
    }
    add_goal(entropy_expr.n); // right hand side value
    // go over the columns add them to the lp instance
    for(i=1;i<=cols;i++){
        int colct=colperm[i];
        if(add_shannon(i,colct)){ // this is a constraint
            add_constraint(i,colct-(shannon+var_no),next_expr);
        }
    }
    /* call the lp */
    init_glp_parameters();
    if(parm.presolve!=GLP_ON) // generate the first basis
        glp_adv_basis(P,0);

    retval=invoke_lp();
    // call again with -1.0 when checking for ent_eq
    if(goal_type==ent_eq && (retval==EXPR_TRUE || retval==EXPR_FALSE)){
        next_expr(-1); // reload the problem
        for(i=0;i<entropy_expr.n;i++){
            row_idx[i+1]=varidx(entropy_expr.item[i].var);
            row_val[i+1]=-entropy_expr.item[i].coeff;
        }
        add_goal(entropy_expr.n); // right hand side value
        retval2=invoke_lp();
        if(retval2==EXPR_TRUE){
            if(retval==EXPR_FALSE) retval=EQ_LE_ONLY;
        } else if(retval2==EXPR_FALSE){
            if(retval==EXPR_TRUE) retval=EQ_GE_ONLY;
        } else {
            retval=retval2;
        }
    }
    /* release allocated memory */
    release_glp();
    if(rowperm){ free(rowperm); rowperm=NULL; }
    if(colperm){ free(colperm); colperm=NULL; }
    return retval;
}
Пример #28
0
double QuadProg::solve_quadprog(Matrix<double>& G, Vector<double>& g0, 
                      const Matrix<double>& CE, const Vector<double>& ce0,  
                      const Matrix<double>& CI, const Vector<double>& ci0, 
                      Vector<double>& x)
{
  std::ostringstream msg;
  {
    //Ensure that the dimensions of the matrices and vectors can be
    //safely converted from unsigned int into to int without overflow.
    unsigned mx = std::numeric_limits<int>::max();
    if(G.ncols() >= mx || G.nrows() >= mx || 
       CE.nrows() >= mx || CE.ncols() >= mx ||
       CI.nrows() >= mx || CI.ncols() >= mx || 
       ci0.size() >= mx || ce0.size() >= mx || g0.size() >= mx){
      msg << "The dimensions of one of the input matrices or vectors were "
	  << "too large." << std::endl
	  << "The maximum allowable size for inputs to solve_quadprog is:"
	  << mx << std::endl;
      throw std::logic_error(msg.str());
    }
  }
  int n = G.ncols(), p = CE.ncols(), m = CI.ncols();
  if ((int)G.nrows() != n)
  {
    msg << "The matrix G is not a square matrix (" << G.nrows() << " x " 
	<< G.ncols() << ")";
    throw std::logic_error(msg.str());
  }
  if ((int)CE.nrows() != n)
  {
    msg << "The matrix CE is incompatible (incorrect number of rows " 
	<< CE.nrows() << " , expecting " << n << ")";
    throw std::logic_error(msg.str());
  }
  if ((int)ce0.size() != p)
  {
    msg << "The vector ce0 is incompatible (incorrect dimension " 
	<< ce0.size() << ", expecting " << p << ")";
    throw std::logic_error(msg.str());
  }
  if ((int)CI.nrows() != n)
  {
    msg << "The matrix CI is incompatible (incorrect number of rows " 
	<< CI.nrows() << " , expecting " << n << ")";
    throw std::logic_error(msg.str());
  }
  if ((int)ci0.size() != m)
  {
    msg << "The vector ci0 is incompatible (incorrect dimension " 
	<< ci0.size() << ", expecting " << m << ")";
    throw std::logic_error(msg.str());
  }
  x.resize(n);
  register int i, j, k, l; /* indices */
  int ip; // this is the index of the constraint to be added to the active set
  Matrix<double> R(n, n), J(n, n);
  Vector<double> s(m + p), z(n), r(m + p), d(n), np(n), u(m + p), x_old(n), u_old(m + p);
  double f_value, psi, c1, c2, sum, ss, R_norm;
  double inf;
  if (std::numeric_limits<double>::has_infinity)
    inf = std::numeric_limits<double>::infinity();
  else
    inf = 1.0E300;
  double t, t1, t2; /* t is the step lenght, which is the minimum of the partial step length t1 
    * and the full step length t2 */
  Vector<int> A(m + p), A_old(m + p), iai(m + p);
  int q, iq, iter = 0;
  Vector<bool> iaexcl(m + p);
	
  /* p is the number of equality constraints */
  /* m is the number of inequality constraints */
  q = 0;  /* size of the active set A (containing the indices of the active constraints) */
#ifdef TRACE_SOLVER
  std::cout << std::endl << "Starting solve_quadprog" << std::endl;
  print_matrix("G", G);
  print_vector("g0", g0);
  print_matrix("CE", CE);
  print_vector("ce0", ce0);
  print_matrix("CI", CI);
  print_vector("ci0", ci0);
#endif  
  
  /*
   * Preprocessing phase
   */
	
  /* compute the trace of the original matrix G */
  c1 = 0.0;
  for (i = 0; i < n; i++)
  {
    c1 += G[i][i];
  }
  /* decompose the matrix G in the form L^T L */
  cholesky_decomposition(G);
#ifdef TRACE_SOLVER
  print_matrix("G", G);
#endif
  /* initialize the matrix R */
  for (i = 0; i < n; i++)
  {
    d[i] = 0.0;
    for (j = 0; j < n; j++)
      R[i][j] = 0.0;
  }
  R_norm = 1.0; /* this variable will hold the norm of the matrix R */
  
  /* compute the inverse of the factorized matrix G^-1, this is the initial value for H */
  c2 = 0.0;
  for (i = 0; i < n; i++) 
  {
    d[i] = 1.0;
    forward_elimination(G, z, d);
    for (j = 0; j < n; j++)
      J[i][j] = z[j];
    c2 += z[i];
    d[i] = 0.0;
  }
#ifdef TRACE_SOLVER
  print_matrix("J", J);
#endif
  
  /* c1 * c2 is an estimate for cond(G) */
  
  /* 
    * Find the unconstrained minimizer of the quadratic form 0.5 * x G x + g0 x 
   * this is a feasible point in the dual space
   * x = G^-1 * g0
   */
  cholesky_solve(G, x, g0);
  for (i = 0; i < n; i++)
    x[i] = -x[i];
  /* and compute the current solution value */ 
  f_value = 0.5 * scalar_product(g0, x);
#ifdef TRACE_SOLVER
  std::cout << "Unconstrained solution: " << f_value << std::endl;
  print_vector("x", x);
#endif
  
  /* Add equality constraints to the working set A */
  iq = 0;
  for (i = 0; i < p; i++)
  {
    for (j = 0; j < n; j++)
      np[j] = CE[j][i];
    compute_d(d, J, np);
    update_z(z, J, d, iq);
    update_r(R, r, d, iq);
#ifdef TRACE_SOLVER
    print_matrix("R", R, n, iq);
    print_vector("z", z);
    print_vector("r", r, iq);
    print_vector("d", d);
#endif
    
    /* compute full step length t2: i.e., the minimum step in primal space s.t. the contraint 
      becomes feasible */
    t2 = 0.0;
    if (fabs(scalar_product(z, z)) > std::numeric_limits<double>::epsilon()) // i.e. z != 0
      t2 = (-scalar_product(np, x) - ce0[i]) / scalar_product(z, np);
    
    /* set x = x + t2 * z */
    for (k = 0; k < n; k++)
      x[k] += t2 * z[k];
    
    /* set u = u+ */
    u[iq] = t2;
    for (k = 0; k < iq; k++)
      u[k] -= t2 * r[k];
    
    /* compute the new solution value */
    f_value += 0.5 * (t2 * t2) * scalar_product(z, np);
    A[i] = -i - 1;
    
    if (!add_constraint(R, J, d, iq, R_norm))
    {	  
      // Equality constraints are linearly dependent
      throw std::runtime_error("Constraints are linearly dependent");
      return f_value;
    }
  }
  
  /* set iai = K \ A */
  for (i = 0; i < m; i++)
    iai[i] = i;
  
l1:	iter++;
#ifdef TRACE_SOLVER
  print_vector("x", x);
#endif
  /* step 1: choose a violated constraint */
  for (i = p; i < iq; i++)
  {
    ip = A[i];
    iai[ip] = -1;
  }
	
  /* compute s[x] = ci^T * x + ci0 for all elements of K \ A */
  ss = 0.0;
  psi = 0.0; /* this value will contain the sum of all infeasibilities */
  ip = 0; /* ip will be the index of the chosen violated constraint */
  for (i = 0; i < m; i++)
  {
    iaexcl[i] = true;
    sum = 0.0;
    for (j = 0; j < n; j++)
      sum += CI[j][i] * x[j];
    sum += ci0[i];
    s[i] = sum;
    psi += std::min(0.0, sum);
  }
#ifdef TRACE_SOLVER
  print_vector("s", s, m);
#endif
  
  
  if (fabs(psi) <= m * std::numeric_limits<double>::epsilon() * c1 * c2* 100.0)
  {
    /* numerically there are not infeasibilities anymore */
    q = iq;
    
    return f_value;
  }
  
  /* save old values for u and A */
  for (i = 0; i < iq; i++)
  {
    u_old[i] = u[i];
    A_old[i] = A[i];
  }
  /* and for x */
  for (i = 0; i < n; i++)
    x_old[i] = x[i];
  
l2: /* Step 2: check for feasibility and determine a new S-pair */
    for (i = 0; i < m; i++)
    {
      if (s[i] < ss && iai[i] != -1 && iaexcl[i])
      {
        ss = s[i];
        ip = i;
      }
    }
  if (ss >= 0.0)
  {
    q = iq;
    
    return f_value;
  }
  
  /* set np = n[ip] */
  for (i = 0; i < n; i++)
    np[i] = CI[i][ip];
  /* set u = [u 0]^T */
  u[iq] = 0.0;
  /* add ip to the active set A */
  A[iq] = ip;
  
#ifdef TRACE_SOLVER
  std::cout << "Trying with constraint " << ip << std::endl;
  print_vector("np", np);
#endif
  
l2a:/* Step 2a: determine step direction */
    /* compute z = H np: the step direction in the primal space (through J, see the paper) */
    compute_d(d, J, np);
  update_z(z, J, d, iq);
  /* compute N* np (if q > 0): the negative of the step direction in the dual space */
  update_r(R, r, d, iq);
#ifdef TRACE_SOLVER
  std::cout << "Step direction z" << std::endl;
  print_vector("z", z);
  print_vector("r", r, iq + 1);
  print_vector("u", u, iq + 1);
  print_vector("d", d);
  print_vector("A", A, iq + 1);
#endif
  
  /* Step 2b: compute step length */
  l = 0;
  /* Compute t1: partial step length (maximum step in dual space without violating dual feasibility */
  t1 = inf; /* +inf */
  /* find the index l s.t. it reaches the minimum of u+[x] / r */
  for (k = p; k < iq; k++)
  {
    if (r[k] > 0.0)
    {
      if (u[k] / r[k] < t1)
	    {
	      t1 = u[k] / r[k];
	      l = A[k];
	    }
    }
  }
  /* Compute t2: full step length (minimum step in primal space such that the constraint ip becomes feasible */
  if (fabs(scalar_product(z, z))  > std::numeric_limits<double>::epsilon()) // i.e. z != 0
    t2 = -s[ip] / scalar_product(z, np);
  else
    t2 = inf; /* +inf */
  
  /* the step is chosen as the minimum of t1 and t2 */
  t = std::min(t1, t2);
#ifdef TRACE_SOLVER
  std::cout << "Step sizes: " << t << " (t1 = " << t1 << ", t2 = " << t2 << ") ";
#endif
  
  /* Step 2c: determine new S-pair and take step: */
  
  /* case (i): no step in primal or dual space */
  if (t >= inf)
  {
    /* QPP is infeasible */
    // FIXME: unbounded to raise
    q = iq;
    return inf;
  }
  /* case (ii): step in dual space */
  if (t2 >= inf)
  {
    /* set u = u +  t * [-r 1] and drop constraint l from the active set A */
    for (k = 0; k < iq; k++)
      u[k] -= t * r[k];
    u[iq] += t;
    iai[l] = l;
    delete_constraint(R, J, A, u, n, p, iq, l);
#ifdef TRACE_SOLVER
    std::cout << " in dual space: " 
      << f_value << std::endl;
    print_vector("x", x);
    print_vector("z", z);
    print_vector("A", A, iq + 1);
#endif
    goto l2a;
  }
  
  /* case (iii): step in primal and dual space */
  
  /* set x = x + t * z */
  for (k = 0; k < n; k++)
    x[k] += t * z[k];
  /* update the solution value */
  f_value += t * scalar_product(z, np) * (0.5 * t + u[iq]);
  /* u = u + t * [-r 1] */
  for (k = 0; k < iq; k++)
    u[k] -= t * r[k];
  u[iq] += t;
#ifdef TRACE_SOLVER
  std::cout << " in both spaces: " 
    << f_value << std::endl;
  print_vector("x", x);
  print_vector("u", u, iq + 1);
  print_vector("r", r, iq + 1);
  print_vector("A", A, iq + 1);
#endif
  
  if (fabs(t - t2) < std::numeric_limits<double>::epsilon())
  {
#ifdef TRACE_SOLVER
    std::cout << "Full step has taken " << t << std::endl;
    print_vector("x", x);
#endif
    /* full step has taken */
    /* add constraint ip to the active set*/
    if (!add_constraint(R, J, d, iq, R_norm))
    {
      iaexcl[ip] = false;
      delete_constraint(R, J, A, u, n, p, iq, ip);
#ifdef TRACE_SOLVER
      print_matrix("R", R);
      print_vector("A", A, iq);
			print_vector("iai", iai);
#endif
      for (i = 0; i < m; i++)
        iai[i] = i;
      for (i = p; i < iq; i++)
	    {
	      A[i] = A_old[i];
	      u[i] = u_old[i];
				iai[A[i]] = -1;
	    }
      for (i = 0; i < n; i++)
        x[i] = x_old[i];
      goto l2; /* go to step 2 */
    }    
    else
      iai[ip] = -1;
#ifdef TRACE_SOLVER
    print_matrix("R", R);
    print_vector("A", A, iq);
		print_vector("iai", iai);
#endif
    goto l1;
  }
  
  /* a patial step has taken */
#ifdef TRACE_SOLVER
  std::cout << "Partial step has taken " << t << std::endl;
  print_vector("x", x);
#endif
  /* drop constraint l */
  iai[l] = l;
  delete_constraint(R, J, A, u, n, p, iq, l);
#ifdef TRACE_SOLVER
  print_matrix("R", R);
  print_vector("A", A, iq);
#endif
  
  /* update s[ip] = CI * x + ci0 */
  sum = 0.0;
  for (k = 0; k < n; k++)
    sum += CI[k][ip] * x[k];
  s[ip] = sum + ci0[ip];
  
#ifdef TRACE_SOLVER
  print_vector("s", s, m);
#endif
  goto l2a;
}
/*
	Solve the LP subproblem by calling lp_solve API 
*/
int LLW_solve_lp(double **gradient, const struct TrainingCache *cache, const struct Model *model)
{
	long i,k,l,ind_pattern,y_i;
	const long Q = model->Q;
	const double Qd = (double)Q;
	const long chunk_size = cache->chunk_size;
	const double *C = model->C;
	
	const int nRows = Q-1; 
	const int nCols = chunk_size * Q;

	double *obj = (double*)malloc(sizeof(double) * (1+nCols));
	double *row = (double*)malloc(sizeof(double) * (1+nCols));
	double *rhs = (double*)malloc(sizeof(double) * Q);
	long **lp_sol_table = matrix_l(nCols, 2);
	long **lp_sol_table_inv = matrix_l(chunk_size, Q);
	double *sol = (double*)malloc(sizeof(double) * (1+nRows+nCols));
	double epsel;
		
	// Make LP
	lprec *lp = make_lp(0, nCols);
	set_add_rowmode(lp, TRUE);

	// Make objective function
	int col = 1;
	for(i=1; i<=chunk_size; i++)
	  {
	  ind_pattern = cache->table_chunk[i];
	  for(k=1; k<=Q; k++)
	      {
	      	obj[col] = gradient[ind_pattern][k];
		lp_sol_table[col][1] = i;	// keep a table of correspondance between
		lp_sol_table[col][2] = k;	// LPSOLVE vector of variables and lp_sol matrix
		lp_sol_table_inv[i][k] = col++; // lp_sol[i][k] = the 'lp_solve_table_inv[i][k]'-th variable for LPSOLVE
	      }
	  }
	set_obj_fn(lp, obj);


/*	// Make RHS of constraints
	// -- complete computation --
	for(k=1; k<Q; k++)
	  {
	  rhs[k] = 0.0;
	  for(i=1; i<=nb_data; i++)
	    if(cache->in_chunk[i] == 0)
	      {
	      for(l=1; l<=Q; l++)
		 rhs[k] += model->alpha[i][l];
	      rhs[k] -= Qd * model->alpha[i][k];
		
	      }
	  }
*/	  

	// Make RHS of constraints
	// -- updates to cache->rhs are made in compute_new_alpha()
	//    to keep track of rhs
	//    we only need to remove the contribution of the examples in the chunk
	for(k=1; k<Q; k++)
	  {
	  rhs[k] = cache->lp_rhs[k];
	  for(i=1; i<=chunk_size; i++)
	      {
	      ind_pattern = cache->table_chunk[i];
	      for(l=1; l<=Q; l++)
		 rhs[k] -= model->alpha[ind_pattern][l];
	      rhs[k] += Qd * model->alpha[ind_pattern][k];		
	      }
	  }
	
	
	// Make constraints
	for(k=1; k<Q; k++)
	  {
	  for(col = 1;col <=nCols; col++)
	     row[col] = 0.0;

	  for(i=1; i<=chunk_size; i++)
	    {
	    ind_pattern = cache->table_chunk[i];
	    y_i = model->y[ind_pattern];

            for(l=1; l<=Q; l++)
              if(l != y_i)
        	{
        	row[lp_sol_table_inv[i][l]] = -1.0;
        	if(l == k)
        	     row[lp_sol_table_inv[i][l]] += Qd;
		}
	    }

	  add_constraint(lp, row, EQ, rhs[k]);
	  }

	// Upper bound constraints: alpha <= Cy_i
	for(col=1;col<=nCols;col++)
		set_upbo(lp, col, C[model->y[cache->table_chunk[lp_sol_table[col][1]]]]);

	/*
	for(i=1; i<=chunk_size; i++) {
	  for(k=1; k<=Q; k++)
	    if(k != model->y[cache->table_chunk[i]]) {
	    	col = (int)lp_sol_table_inv[i][k];
		set_upbo(lp, col, C);
	    }
	}
	*/
	
	// End of LP making
	set_add_rowmode(lp, FALSE);	
	//print_lp(lp);
	
	// Solve LP
	int jump = false;
	set_outputfile(lp,"");

	if(solve(lp)) {
		printf("Problem with the LP... \n");
		jump = true;
	}
	else {
		// Recover solution in the matrix lp_sol
		get_primal_solution(lp, sol);	// sol: template for lp_solve solution format
						// 	sol=[obj, constraints, variables] 

		epsel = get_epsel(lp);	// tolerance in lp_solve
		
		// Put solution into lp_sol
		for(col=1; col<= nCols; col++) {

			// Check feasibility of the col-th variable
			if((sol[nRows+col] < -epsel) || (sol[nRows+col] > C[model->y[cache->table_chunk[lp_sol_table[col][1]]]] + epsel)) {
				jump = true;
				break;
			}
			// Round off tolerance
			if(fabs(sol[nRows+col]) < epsel) 
				sol[nRows+col] = 0.0;
				
			else if(fabs(sol[nRows+col] - C[model->y[cache->table_chunk[lp_sol_table[col][1]]]]) < epsel)
				sol[nRows+col] = C[model->y[cache->table_chunk[lp_sol_table[col][1]]]];
				
			// Set the value in lp_sol matrix
			cache->lp_sol[lp_sol_table[col][1]][lp_sol_table[col][2]] = sol[nRows+col];
		}
		
	}

	delete_lp(lp);

	free(obj);
	free(row);
	free(rhs);
	free(lp_sol_table[1]);free(lp_sol_table);
	free(lp_sol_table_inv[1]);free(lp_sol_table_inv);
	free(sol);

	return jump;	
}
Пример #30
0
static void
create_constraints (Constraint **constraints,
                    GList       *windows)
{
  GList *tmp;

  tmp = windows;
  while (tmp != NULL)
    {
      MetaWindow *w = tmp->data;

      if (!WINDOW_IN_STACK (w))
        {
          meta_topic (META_DEBUG_STACK, "Window %s not in the stack, not constraining it\n",
                      w->desc);
          tmp = tmp->next;
          continue;
        }

      if (WINDOW_TRANSIENT_FOR_WHOLE_GROUP (w))
        {
          GSList *group_windows;
          GSList *tmp2;
          MetaGroup *group;

          group = meta_window_get_group (w);

          if (group != NULL)
            group_windows = meta_group_list_windows (group);
          else
            group_windows = NULL;

          tmp2 = group_windows;

          while (tmp2 != NULL)
            {
              MetaWindow *group_window = tmp2->data;

              if (!WINDOW_IN_STACK (group_window) ||
                  w->screen != group_window->screen ||
                  group_window->override_redirect)
                {
                  tmp2 = tmp2->next;
                  continue;
                }

#if 0
              /* old way of doing it */
              if (!(meta_window_is_ancestor_of_transient (w, group_window)) &&
                  !WINDOW_TRANSIENT_FOR_WHOLE_GROUP (group_window))  /* note */;/*note*/
#else
              /* better way I think, so transient-for-group are constrained
               * only above non-transient-type windows in their group
               */
              if (!WINDOW_HAS_TRANSIENT_TYPE (group_window))
#endif
                {
                  meta_topic (META_DEBUG_STACK, "Constraining %s above %s as it's transient for its group\n",
                              w->desc, group_window->desc);
                  add_constraint (constraints, w, group_window);
                }

              tmp2 = tmp2->next;
            }

          g_slist_free (group_windows);
        }
      else if (w->transient_for != NULL)
        {
          MetaWindow *parent;

          parent = w->transient_for;

          if (parent && WINDOW_IN_STACK (parent))
            {
              meta_topic (META_DEBUG_STACK, "Constraining %s above %s due to transiency\n",
                          w->desc, parent->desc);
              add_constraint (constraints, w, parent);
            }
        }

      tmp = tmp->next;
    }
}