00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <ppl-config.h>
00025
00026 #include "Linear_Row.defs.hh"
00027 #include "Coefficient.defs.hh"
00028 #include <algorithm>
00029 #include <iostream>
00030
00031 namespace PPL = Parma_Polyhedra_Library;
00032
00033 void
00034 PPL::Linear_Row::sign_normalize() {
00035 if (is_line_or_equality()) {
00036 Linear_Row& x = *this;
00037 const dimension_type sz = x.size();
00038
00039
00040
00041 dimension_type first_non_zero;
00042 for (first_non_zero = 1; first_non_zero < sz; ++first_non_zero)
00043 if (x[first_non_zero] != 0)
00044 break;
00045 if (first_non_zero < sz)
00046
00047
00048 if (x[first_non_zero] < 0) {
00049 for (dimension_type j = first_non_zero; j < sz; ++j)
00050 neg_assign(x[j]);
00051
00052 neg_assign(x[0]);
00053 }
00054 }
00055 }
00056
00057 bool
00058 PPL::Linear_Row::check_strong_normalized() const {
00059 Linear_Row tmp = *this;
00060 tmp.strong_normalize();
00061 return compare(*this, tmp) == 0;
00062 }
00063
00065 int
00066 PPL::compare(const Linear_Row& x, const Linear_Row& y) {
00067 const bool x_is_line_or_equality = x.is_line_or_equality();
00068 const bool y_is_line_or_equality = y.is_line_or_equality();
00069 if (x_is_line_or_equality != y_is_line_or_equality)
00070
00071 return y_is_line_or_equality ? 2 : -2;
00072
00073
00074 const dimension_type xsz = x.size();
00075 const dimension_type ysz = y.size();
00076 const dimension_type min_sz = std::min(xsz, ysz);
00077 dimension_type i;
00078 for (i = 1; i < min_sz; ++i)
00079 if (const int comp = cmp(x[i], y[i]))
00080
00081 return (comp > 0) ? 2 : -2;
00082
00083
00084 if (xsz != ysz) {
00085 for( ; i < xsz; ++i)
00086 if (const int sign = sgn(x[i]))
00087 return (sign > 0) ? 2 : -2;
00088 for( ; i < ysz; ++i)
00089 if (const int sign = sgn(y[i]))
00090 return (sign < 0) ? 2 : -2;
00091 }
00092
00093
00094
00095
00096 if (const int comp = cmp(x[0], y[0]))
00097 return (comp > 0) ? 1 : -1;
00098
00099
00100 return 0;
00101 }
00102
00103 void
00104 PPL::Linear_Row::linear_combine(const Linear_Row& y, const dimension_type k) {
00105 Linear_Row& x = *this;
00106
00107 PPL_ASSERT(x.size() == y.size());
00108 PPL_ASSERT(y[k] != 0 && x[k] != 0);
00109
00110
00111
00112 PPL_DIRTY_TEMP_COEFFICIENT(normalized_x_k);
00113 PPL_DIRTY_TEMP_COEFFICIENT(normalized_y_k);
00114 normalize2(x[k], y[k], normalized_x_k, normalized_y_k);
00115 for (dimension_type i = size(); i-- > 0; )
00116 if (i != k) {
00117 Coefficient& x_i = x[i];
00118 x_i *= normalized_y_k;
00119 sub_mul_assign(x_i, y[i], normalized_x_k);
00120 }
00121 x[k] = 0;
00122 x.strong_normalize();
00123 }
00124
00125 bool
00126 PPL::Linear_Row::is_zero() const {
00127 const Linear_Row& x = *this;
00128 for (dimension_type i = x.size(); i-- > 0; )
00129 if (x[i] != 0)
00130 return false;
00131 return true;
00132 }
00133
00134 bool
00135 PPL::Linear_Row::all_homogeneous_terms_are_zero() const {
00136 const Linear_Row& x = *this;
00137 for (dimension_type i = x.size(); --i > 0; )
00138 if (x[i] != 0)
00139 return false;
00140 return true;
00141 }
00142
00143 namespace {
00144
00145
00146 const char* rpi_valid = "RPI_V";
00147 const char* is_rpi = "RPI";
00148 const char* nnc_valid = "NNC_V";
00149 const char* is_nnc = "NNC";
00150 const char* bit_names[] = {rpi_valid, is_rpi, nnc_valid, is_nnc};
00151
00152 }
00153
00154 void
00155 PPL::Linear_Row::Flags::ascii_dump(std::ostream& s) const {
00156 s << (test_bits(1 << Flags::rpi_validity_bit) ? '+' : '-')
00157 << rpi_valid << ' '
00158 << (test_bits(1 << Flags::rpi_bit) ? '+' : '-')
00159 << is_rpi << ' '
00160 << ' '
00161 << (test_bits(1 << Flags::nnc_validity_bit) ? '+' : '-')
00162 << nnc_valid << ' '
00163 << (test_bits(1 << Flags::nnc_bit) ? '+' : '-')
00164 << is_nnc;
00165 }
00166
00167 PPL_OUTPUT_DEFINITIONS_ASCII_ONLY(Linear_Row::Flags)
00168
00169 bool
00170 PPL::Linear_Row::Flags::ascii_load(std::istream& s) {
00171 std::string str;
00172
00173 reset_bits(std::numeric_limits<base_type>::max());
00174 for (unsigned int bit = 0;
00175 bit < (sizeof(bit_names) / sizeof(char*));
00176 ++bit) {
00177 if (!(s >> str))
00178 return false;
00179 if (str[0] == '+')
00180 set_bits(1 << (Row::Flags::first_free_bit + bit));
00181 else if (str[0] != '-')
00182 return false;
00183 if (str.compare(1, strlen(bit_names[bit]), bit_names[bit]) != 0)
00184 return false;
00185 }
00186 return true;
00187 }
00188
00189 void
00190 PPL::Linear_Row::ascii_dump(std::ostream& s) const {
00191 const Row& x = *this;
00192 const dimension_type x_size = x.size();
00193 s << "size " << x_size << " ";
00194 for (dimension_type i = 0; i < x_size; ++i)
00195 s << x[i] << ' ';
00196 s << "f ";
00197 flags().ascii_dump(s);
00198 s << "\n";
00199 }
00200
00201 PPL_OUTPUT_DEFINITIONS_ASCII_ONLY(Linear_Row)
00202
00203 bool
00204 PPL::Linear_Row::ascii_load(std::istream& s) {
00205 std::string str;
00206 if (!(s >> str) || str != "size")
00207 return false;
00208 dimension_type new_size;
00209 if (!(s >> new_size))
00210 return false;
00211
00212 Row& x = *this;
00213 const dimension_type old_size = x.size();
00214 if (new_size < old_size)
00215 x.shrink(new_size);
00216 else if (new_size > old_size) {
00217 Row y(new_size, Row::Flags());
00218 x.swap(y);
00219 }
00220
00221 for (dimension_type col = 0; col < new_size; ++col)
00222 if (!(s >> x[col]))
00223 return false;
00224 if (!(s >> str) || str != "f")
00225 return false;
00226 return flags().ascii_load(s);
00227 }
00228
00229 bool
00230 PPL::Linear_Row::OK() const {
00231 return Row::OK();
00232 }
00233
00234 bool
00235 PPL::Linear_Row::OK(const dimension_type row_size,
00236 const dimension_type row_capacity) const {
00237 return Row::OK(row_size, row_capacity);
00238 }