| 123 | */ |
| 124 | template<class View> |
| 125 | inline bool |
| 126 | normalize(Term<View>* t, int &n, |
| 127 | Term<View>* &t_p, int &n_p, |
| 128 | Term<View>* &t_n, int &n_n, |
| 129 | int& g) { |
| 130 | // Number terms by position |
| 131 | for (int i=0; i<n; i++) |
| 132 | t[i].p = i; |
| 133 | |
| 134 | /* |
| 135 | * Join coefficients for aliased variables: |
| 136 | * |
| 137 | */ |
| 138 | { |
| 139 | // Group same variables |
| 140 | TermByView<View> tl; |
| 141 | Support::quicksort<Term<View>,TermByView<View>>(t,n,tl); |
| 142 | |
| 143 | // Join adjacent variables |
| 144 | int i = 0; |
| 145 | int j = 0; |
| 146 | while (i < n) { |
| 147 | Limits::check(t[i].a,"Int::linear"); |
| 148 | long long int a = t[i].a; |
| 149 | int p = t[i].p; |
| 150 | View x = t[i].x; |
| 151 | while ((++i < n) && (t[i].x == x)) { |
| 152 | a += t[i].a; |
| 153 | p = std::min(p,t[i].p); |
| 154 | Limits::check(a,"Int::linear"); |
| 155 | } |
| 156 | if (a != 0) { |
| 157 | t[j].a = static_cast<int>(a); t[j].x = x; t[j].p = p; j++; |
| 158 | } |
| 159 | } |
| 160 | n = j; |
| 161 | } |
| 162 | |
| 163 | /* |
| 164 | * Partition into positive/negative coefficients |
| 165 | * |
| 166 | */ |
| 167 | if (n > 0) { |
| 168 | int i = 0; |
| 169 | int j = n-1; |
| 170 | while (true) { |
| 171 | while ((t[j].a < 0) && (--j >= 0)) ; |
| 172 | while ((t[i].a > 0) && (++i < n)) ; |
| 173 | if (j <= i) break; |
| 174 | std::swap(t[i],t[j]); |
| 175 | } |
| 176 | t_p = t; n_p = i; |
| 177 | t_n = t+n_p; n_n = n-n_p; |
| 178 | } else { |
| 179 | t_p = t; n_p = 0; |
| 180 | t_n = t; n_n = 0; |
| 181 | } |
| 182 | |