00001 #include<scil/global.h>
00002 #include<scil/row.h>
00003 #include<scil/row_constraint.h>
00004 #include<scil/core/polynomial.h>
00005
00006 using namespace SCIL;
00007
00008 row::row(double d) {
00009
00010 NZ.push_back(row_entry(nil, d));
00011 }
00012
00013 cons_obj* row::operator== (row r1) {
00014 row r2=(*this)-r1;
00015 r2.normalize();
00016 return new row_constraint(r2, Equal);
00017 }
00018
00019 cons_obj* row::operator<= (row r1) {
00020 row r2=(*this)-r1;
00021 r2.normalize();
00022 return new row_constraint(r2, Less);
00023 }
00024
00025 cons_obj* row::operator>= (row r1) {
00026 row r2=(*this)-r1;
00027 r2.normalize();
00028 return new row_constraint(r2, Greater);
00029 }
00030
00031 row::row(var v) {
00032 NZ.push_back(row_entry(v,1));
00033 }
00034
00035 row::row(std::list<row_entry>& L) {
00036 NZ=L;
00037 }
00038
00039 row row::operator* (double d) {
00040 std::list<row_entry> NNZ;
00041 std::list<row_entry>::const_iterator it;
00042 for( it = NZ.begin (); it!=NZ.end (); it++ ){
00043 NNZ.push_back ( row_entry(it->Var, d*it->coeff));
00044 }
00045 return row(NNZ);
00046 }
00047
00048 polynomial row::operator*(const polynomial& p) {
00049 return polynomial(*this) * p;
00050 }
00051
00052 polynomial row::operator*(const var& v) {
00053 return *this * monomial(v);
00054 }
00055
00056 polynomial row::operator* (const monomial& m) {
00057 polynomial p;
00058 std::list<row_entry>::const_iterator re;
00059 for( re = NZ.begin(); re!=NZ.end(); re++ ){
00060 if(re->Var != NULL)
00061 p += (monomial(re->coeff, re->Var) *m);
00062 else if(re->coeff != 0)
00063 p += re->coeff * m;
00064 };
00065 return p;
00066 }
00067
00068 polynomial row::operator+ (const polynomial& p) {
00069 return polynomial(*this) + p;
00070 }
00071
00072 row row::operator+(const row& r) {
00073 std::list<row_entry> NNZ;
00074 double d;
00075 std::list<row_entry>::const_iterator it;
00076 std::list<row_entry>::const_iterator rit = r.NZ.begin();
00077 for (it = NZ.begin(); it != NZ.end(); it++) {
00078 d = 0;
00079 while ((rit != r.NZ.end()) && (rit->Var <= it->Var)) {
00080 if (rit->Var != it->Var) {
00081 NNZ.push_back(*rit);
00082 } else {
00083 d = rit->coeff;
00084 }
00085 rit++;
00086 }
00087 NNZ.push_back(row_entry(it->Var, it->coeff + d));
00088 }
00089 while( rit!=r.NZ.end() ){
00090 NNZ.push_back( *rit );
00091 rit++;
00092 }
00093 return row( NNZ );
00094 }
00095
00096 row& row::operator+=(const var& v) {
00097 NZ.push_back(row_entry(v,1));
00098 return *this;
00099 };
00100
00101 row& row::operator-=(const var& v) {
00102 NZ.push_back(row_entry(v,-1));
00103 return *this;
00104 };
00105
00106 row& row::operator+=(const row_entry& r) {
00107 NZ.push_back(r);
00108 return *this;
00109 };
00110
00111 row& row::operator+= (const row& r) {
00112 std::list<row_entry>::const_iterator rit;
00113 for( rit=r.NZ.begin(); rit!=r.NZ.end(); rit++ ) {
00114 NZ.push_back( *rit );
00115 }
00116 return *this;
00117 }
00118
00119 row& row::operator-=(const row& r) {
00120 std::list<row_entry>::const_iterator rit;
00121 for (rit = r.NZ.begin(); rit != r.NZ.end(); rit++) {
00122 NZ.push_back(row_entry(rit->Var, -rit->coeff));
00123 }
00124 return *this;
00125 }
00126
00127 row row::operator- (const var& v) {
00128 return *this - row(v);
00129 }
00130
00131 void row::normalize(bool clean) {
00132 NZ.sort();
00133
00134 std::list<row_entry>::iterator it = NZ.begin();
00135 std::list<row_entry>::iterator i;
00136 while(it!=NZ.end()) {
00137 i = it;
00138 i++;
00139 while( i!=NZ.end() && (it->Var==i->Var) ){
00140 it->coeff += i->coeff;
00141 i = NZ.erase(i);
00142 }
00143 it++;
00144 }
00145
00146 if( clean ) {
00147 it = NZ.begin();
00148 while( it!=NZ.end() ){
00149 if( (it->coeff * it->coeff) < .000001 ){
00150 it = NZ.erase(it);
00151 } else{
00152 it++;
00153 }
00154 }
00155 }
00156 }
00157
00158 row row::operator+ (const var& v) {
00159 return operator+(row(v));
00160 };
00161
00162 row row::operator+ (double d) {
00163 return operator+(row(d));
00164 };
00165
00166 row row::operator- (const row& r) {
00167 std::list<row_entry> NNZ;
00168 std::list<row_entry>::const_iterator rit = r.NZ.begin();
00169 std::list<row_entry>::const_iterator it;
00170 double d;
00171 for( it=NZ.begin(); it!=NZ.end(); it++ ){
00172 d=0;
00173 while((rit!=r.NZ.end()) && (rit->Var<=it->Var)) {
00174 if(rit->Var!=it->Var) {
00175 NNZ.push_back (row_entry(rit->Var, -rit->coeff));
00176 } else {
00177 d=-rit->coeff;
00178 }
00179 rit++;
00180 }
00181 NNZ.push_back(row_entry(it->Var, it->coeff+d));
00182 }
00183 while(rit!=r.NZ.end()) {
00184 NNZ.push_back(row_entry(rit->Var, -rit->coeff));
00185 rit++;
00186 }
00187 return row(NNZ);
00188 }
00189
00190 polynomial row::operator-(const polynomial& p) {
00191 return polynomial(*this) - p;
00192 }
00193
00194 row SCIL::operator*(double d, var v) {
00195 return row(v)*d;
00196 };
00197
00198 row SCIL::operator*(double d, row r) {
00199 return r*d;
00200 };
00201
00202 std::list<row_entry>::const_iterator row::begin() const {
00203 return NZ.begin();
00204 }
00205
00206 std::list<row_entry>::const_iterator row::end() const {
00207 return NZ.end();
00208 }
00209
00210 std::list<row_entry>::iterator row::begin() {
00211 return NZ.begin();
00212 }
00213
00214 std::list<row_entry>::iterator row::end() {
00215 return NZ.end();
00216 }
00217
00218 int row::size() const {
00219
00220 return NZ.size();
00221 }
00222
00223 std::ostream& SCIL::operator<<(std::ostream& o,const row& r) {
00224 std::list<row_entry>::const_iterator it;
00225 for( it = r.begin (); it!=r.end (); it++ ){ o<<*it<<"+"; }
00226 return o;
00227 };
00228
00229
00230 namespace SCIL {
00231 int compare(const row& r1, const row& r2) {
00232
00233 int l = r1.size() - r2.size();
00234
00235
00236
00237 if( l != 0 )
00238 return l;
00239
00240
00241 int st = 0;
00242 std::list<row_entry>::const_iterator it1, it2;
00243 it2 = r2.begin();
00244 for( it1=r1.begin(); it1!=r1.end(); it1++, it2++){
00245 st = compare( *it1, *it2 );
00246
00247 if( st != 0 )
00248 return st;
00249 }
00250
00251 return 0;
00252 }
00253 }