24 #ifndef PPL_Polyhedron_conversion_templates_hh
25 #define PPL_Polyhedron_conversion_templates_hh 1
41 #ifndef PPL_QUICK_NON_ADJ_TEST
42 #define PPL_QUICK_NON_ADJ_TEST 1
48 #ifndef PPL_QUICK_ADJ_TEST
49 #define PPL_QUICK_ADJ_TEST 1
367 template <
typename Source_Linear_System,
typename Dest_Linear_System>
371 Dest_Linear_System& dest,
374 typedef typename Dest_Linear_System::row_type dest_row_type;
375 typedef typename Source_Linear_System::row_type source_row_type;
379 PPL_ASSERT(source.space_dimension() == dest.space_dimension());
383 + (source.is_necessarily_closed() ? 1U : 2U);
389 std::vector<dest_row_type> recyclable_dest_rows;
397 PPL_ASSERT(dest_num_rows == sat.
num_rows());
400 PPL_ASSERT(start == 0 || start == source.first_pending_row());
405 bool dest_sorted = dest.is_sorted();
406 const dimension_type dest_first_pending_row = dest.first_pending_row();
409 std::vector<dimension_type> redundant_source_rows;
411 #if PPL_QUICK_ADJ_TEST
414 sat_num_ones.resize(dest_num_rows, 0);
416 sat_num_ones[i] = sat[i].count_ones();
418 #endif // PPL_QUICK_ADJ_TEST
423 const source_row_type& source_k = source[k];
426 #if PPL_QUICK_ADJ_TEST
428 PPL_ASSERT(sat_num_ones[i] == sat[i].count_ones());
430 #endif // PPL_QUICK_ADJ_TEST
438 if (dest_num_rows > scalar_prod.size()) {
439 scalar_prod.insert(scalar_prod.end(),
440 dest_num_rows - scalar_prod.size(),
446 for ( ; index_non_zero < dest_num_rows; ++index_non_zero) {
450 dest.sys.rows[index_non_zero]);
452 if (scalar_prod[index_non_zero] != 0) {
461 for (
dimension_type i = index_non_zero + 1; i < dest_num_rows; ++i) {
478 if (index_non_zero < num_lines_or_equalities) {
483 dest.sys.rows[index_non_zero].set_is_ray_or_point_or_inequality();
487 if (scalar_prod[index_non_zero] < 0) {
491 neg_assign(dest.sys.rows[index_non_zero].expr);
499 --num_lines_or_equalities;
500 if (index_non_zero != num_lines_or_equalities) {
501 swap(dest.sys.rows[index_non_zero],
502 dest.sys.rows[num_lines_or_equalities]);
503 swap(scalar_prod[index_non_zero],
504 scalar_prod[num_lines_or_equalities]);
506 const dest_row_type& dest_nle = dest.sys.rows[num_lines_or_equalities];
523 Coefficient& scalar_prod_nle = scalar_prod[num_lines_or_equalities];
524 PPL_ASSERT(scalar_prod_nle != 0);
526 i = index_non_zero; i < num_lines_or_equalities; ++i) {
527 if (scalar_prod[i] != 0) {
544 dest_row_type& dest_i = dest.sys.rows[i];
546 dest_i.expr.linear_combine(dest_nle.expr,
547 normalized_sp_o, normalized_sp_i);
548 dest_i.strong_normalize();
564 i = num_lines_or_equalities + 1; i < dest_num_rows; ++i) {
565 if (scalar_prod[i] != 0) {
582 dest_row_type& dest_i = dest.sys.rows[i];
585 dest_i.expr.linear_combine(dest_nle.expr,
586 normalized_sp_o, normalized_sp_i);
587 dest_i.strong_normalize();
603 Bit_Row& sat_nle = sat[num_lines_or_equalities];
604 if (source_k.is_ray_or_point_or_inequality()) {
605 sat_nle.
set(k - redundant_source_rows.size());
606 #if PPL_QUICK_ADJ_TEST
607 ++sat_num_ones[num_lines_or_equalities];
608 #endif // PPL_QUICK_ADJ_TEST
615 swap(dest.sys.rows[num_lines_or_equalities],
616 dest.sys.rows[dest_num_rows]);
617 recyclable_dest_rows.resize(recyclable_dest_rows.size() + 1);
618 swap(dest.sys.rows.back(), recyclable_dest_rows.back());
619 dest.sys.rows.pop_back();
620 PPL_ASSERT(dest_num_rows == dest.sys.rows.size());
622 swap(scalar_prod_nle, scalar_prod[dest_num_rows]);
623 swap(sat_nle, sat[dest_num_rows]);
624 #if PPL_QUICK_ADJ_TEST
625 swap(sat_num_ones[num_lines_or_equalities],
626 sat_num_ones[dest_num_rows]);
627 #endif // PPL_QUICK_ADJ_TEST
636 PPL_ASSERT(index_non_zero >= num_lines_or_equalities);
653 while (inf_bound > lines_or_equal_bound
654 && scalar_prod[lines_or_equal_bound] == 0) {
655 ++lines_or_equal_bound;
658 while (inf_bound > sup_bound) {
659 const int sp_sign =
sgn(scalar_prod[sup_bound]);
662 swap(dest.sys.rows[sup_bound], dest.sys.rows[lines_or_equal_bound]);
663 swap(scalar_prod[sup_bound], scalar_prod[lines_or_equal_bound]);
664 swap(sat[sup_bound], sat[lines_or_equal_bound]);
665 #if PPL_QUICK_ADJ_TEST
666 swap(sat_num_ones[sup_bound], sat_num_ones[lines_or_equal_bound]);
667 #endif // PPL_QUICK_ADJ_TEST
668 ++lines_or_equal_bound;
672 else if (sp_sign < 0) {
675 swap(dest.sys.rows[sup_bound], dest.sys.rows[inf_bound]);
676 swap(sat[sup_bound], sat[inf_bound]);
677 swap(scalar_prod[sup_bound], scalar_prod[inf_bound]);
678 #if PPL_QUICK_ADJ_TEST
679 swap(sat_num_ones[sup_bound], sat_num_ones[inf_bound]);
680 #endif // PPL_QUICK_ADJ_TEST
689 if (sup_bound == dest_num_rows) {
695 if (source_k.is_ray_or_point_or_inequality()) {
696 redundant_source_rows.push_back(k);
702 PPL_ASSERT(dest_num_rows >= lines_or_equal_bound);
703 while (dest_num_rows != lines_or_equal_bound) {
704 recyclable_dest_rows.resize(recyclable_dest_rows.size() + 1);
705 swap(dest.sys.rows.back(), recyclable_dest_rows.back());
706 dest.sys.rows.pop_back();
709 PPL_ASSERT(dest_num_rows == dest.sys.rows.size());
718 if (sup_bound == num_lines_or_equalities) {
722 PPL_ASSERT(dest_num_rows >= sup_bound);
723 while (dest_num_rows != sup_bound) {
724 recyclable_dest_rows.resize(recyclable_dest_rows.size() + 1);
725 swap(dest.sys.rows.back(), recyclable_dest_rows.back());
726 dest.sys.rows.pop_back();
729 PPL_ASSERT(dest_num_rows == dest.sys.rows.size());
746 #if PPL_QUICK_NON_ADJ_TEST
756 = source_num_columns - num_lines_or_equalities - 2;
758 const dimension_type max_saturators = k - redundant_source_rows.size();
759 #endif // PPL_QUICK_NON_ADJ_TEST
764 for (
dimension_type i = lines_or_equal_bound; i < sup_bound; ++i) {
772 || sat[i].last() < k);
774 || sat[j].last() < k);
780 Bit_Row new_satrow(sat[i], sat[j]);
788 #if (PPL_QUICK_NON_ADJ_TEST || PPL_QUICK_ADJ_TEST)
791 #endif // (PPL_QUICK_NON_ADJ_TEST || PPL_QUICK_ADJ_TEST)
793 #if PPL_QUICK_NON_ADJ_TEST
795 = max_saturators - new_satrow_ones;
796 if (num_common_satur < min_saturators) {
800 #endif // PPL_QUICK_NON_ADJ_TEST
802 #if PPL_QUICK_ADJ_TEST
809 = std::max(sat_num_ones[i], sat_num_ones[j]);
810 if (max_ones_i_j + 1 == new_satrow_ones) {
814 #endif // PPL_QUICK_ADJ_TEST
818 bool redundant =
false;
820 for (
dimension_type l = num_lines_or_equalities; l < bound; ++l) {
822 && subset_or_equal(sat[l], new_satrow)) {
829 PPL_ASSERT(bound >= num_lines_or_equalities);
837 #if PPL_QUICK_ADJ_TEST
839 #endif // PPL_QUICK_ADJ_TEST
842 dest_row_type new_row;
843 if (recyclable_dest_rows.empty()) {
845 #if PPL_QUICK_ADJ_TEST
846 sat_num_ones.push_back(new_satrow_ones);
847 #endif // PPL_QUICK_ADJ_TEST
850 swap(new_row, recyclable_dest_rows.back());
851 recyclable_dest_rows.pop_back();
852 new_row.set_space_dimension_no_ok(source_space_dim);
853 swap(sat[dest_num_rows], new_satrow);
854 #if PPL_QUICK_ADJ_TEST
855 swap(sat_num_ones[dest_num_rows], new_satrow_ones);
856 #endif // PPL_QUICK_ADJ_TEST
878 new_row = dest.sys.rows[j];
880 PPL_ASSERT(normalized_sp_i != 0);
881 PPL_ASSERT(normalized_sp_o != 0);
882 new_row.expr.linear_combine(dest.sys.rows[i].expr,
883 normalized_sp_i, normalized_sp_o);
886 new_row.strong_normalize();
894 PPL_ASSERT(scalar_prod.size() >= dest_num_rows);
895 if (scalar_prod.size() <= dest_num_rows) {
901 dest.sys.rows.resize(dest.sys.rows.size() + 1);
902 swap(dest.sys.rows.back(), new_row);
914 if (source_k.is_ray_or_point_or_inequality()) {
925 l < sup_bound; ++l) {
927 #if PPL_QUICK_ADJ_TEST
929 #endif // PPL_PPL_QUICK_ADJ_TEST
935 j = lines_or_equal_bound;
942 while (j < bound && i > bound) {
944 swap(dest.sys.rows[i], dest.sys.rows[j]);
945 swap(scalar_prod[i], scalar_prod[j]);
946 swap(sat[i], sat[j]);
947 #if PPL_QUICK_ADJ_TEST
948 swap(sat_num_ones[i], sat_num_ones[j]);
949 #endif // PPL_QUICK_ADJ_TEST
961 PPL_ASSERT(dest_num_rows >= new_num_rows);
962 while (dest_num_rows != new_num_rows) {
963 recyclable_dest_rows.resize(recyclable_dest_rows.size() + 1);
964 swap(dest.sys.rows.back(), recyclable_dest_rows.back());
965 dest.sys.rows.pop_back();
968 PPL_ASSERT(dest_num_rows == dest.sys.rows.size());
973 if (redundant_source_rows.size() > 0) {
974 source.remove_rows(redundant_source_rows);
985 if (start > 0 && start < source.num_rows()) {
986 source.set_sorted(
compare(source[start - 1], source[start]) <= 0);
989 source.unset_pending_rows();
993 if (!recyclable_dest_rows.empty()) {
994 const dimension_type num_removed_rows = recyclable_dest_rows.size();
1002 i < dest_num_rows; ++i) {
1003 if (
compare(dest.sys.rows[i - 1], dest.sys.rows[i]) > 0) {
1004 dest_sorted =
false;
1013 PPL_ASSERT(dest.sys.rows[i].OK());
1017 dest.sys.index_first_pending = dest.num_rows();
1018 dest.set_sorted(dest_sorted);
1019 PPL_ASSERT(dest.sys.OK());
1021 return num_lines_or_equalities;
1026 #endif // !defined(PPL_Polyhedron_conversion_templates_hh)
void swap(CO_Tree &x, CO_Tree &y)
size_t dimension_type
An unsigned integral type for representing space dimensions.
dimension_type num_rows() const
Returns the number of rows of *this.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
void set(unsigned long k)
Sets the bit in position k.
void add_recycled_row(Bit_Row &row)
Adds row to *this.
unsigned long count_ones() const
Returns the number of set bits in the row.
void swap(Polyhedron &x, Polyhedron &y)
Swaps x with y.
A row in a matrix of bits.
static dimension_type conversion(Source_Linear_System &source, dimension_type start, Dest_Linear_System &dest, Bit_Matrix &sat, dimension_type num_lines_or_equalities)
Performs the conversion from constraints to generators and vice versa.
void remove_trailing_columns(dimension_type n)
Removes the last n columns.
#define WEIGHT_ADD_MUL(delta, factor)
PPL_COEFFICIENT_TYPE Coefficient
An alias for easily naming the type of PPL coefficients.
int compare(const Linear_Expression &x, const Linear_Expression &y)
void remove_trailing_rows(dimension_type n)
Removes the last n rows.
#define PPL_DIRTY_TEMP(T, id)
dimension_type num_columns() const
Returns the number of columns of *this.
void neg_assign(GMP_Integer &x)
Coefficient_traits::const_reference Coefficient_zero()
Returns a const reference to a Coefficient with value 0.
The entire library is confined to this namespace.
int sgn(Boundary_Type type, const T &x, const Info &info)
void normalize2(Coefficient_traits::const_reference x, Coefficient_traits::const_reference y, Coefficient &n_x, Coefficient &n_y)
If is the GCD of x and y, the values of x and y divided by are assigned to n_x and n_y...
static void assign(Coefficient &z, const Linear_Expression &x, const Linear_Expression &y)
Computes the scalar product of x and y and assigns it to z.