PIPS
binaires.c
Go to the documentation of this file.
1 /*
2 
3  $Id: binaires.c 1671 2019-06-26 19:14:11Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of Linear/C3 Library.
8 
9  Linear/C3 Library is free software: you can redistribute it and/or modify it
10  under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  Linear/C3 Library is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with Linear/C3 Library. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 
25  /* package vecteur - operations binaires */
26 
27 /*LINTLIBRARY*/
28 
29 #ifdef HAVE_CONFIG_H
30  #include "config.h"
31 #endif
32 #include <stdio.h>
33 #include "linear_assert.h"
34 #include <limits.h>
35 
36 #include "boolean.h"
37 #include "arithmetique.h"
38 #include "vecteur.h"
39 
40 /* Pvecteur vect_add(Pvecteur v1, Pvecteur v2): allocation d'un vecteur v dont
41  * la valeur est la somme des deux vecteurs v1 et v2
42  *
43  * ->
44  * allocate v;
45  * -> -> ->
46  * v := v1 + v2;
47  * ->
48  * return v;
49  *
50  * RT: j'ai besoin d'un vect_add a effet de bord pour la normalisation d'expression
51  * lineaire. idem pour vect_substract, vect_mult, ...
52  */
54 Pvecteur v1;
55 Pvecteur v2;
56 {
57  Pvecteur v = vect_dup (v1);
58 
59  for ( ; v2!= NULL; v2=v2->succ)
60  vect_add_elem (&v,var_of(v2),val_of(v2));
61 
62  return (v);
63 }
64 
65 /* Pvecteur vect_substract(Pvecteur v1, Pvecteur v2): allocation d'un vecteur v
66  * dont la valeur est la difference des deux vecteurs v1 et v2
67  *
68  * ->
69  * allocate v;
70  * -> -> ->
71  * v := v1 - v2;
72  * ->
73  * return v;
74  */
76 Pvecteur v1,v2;
77 {
78  Pvecteur v = vect_dup (v1);
79 
80  for (; v2 != NULL; v2 = v2->succ)
82 
83  return (v);
84 }
85 
86 /* Pvecteur vect_substitute_dimension(Pvecteur v, Variable i, Pvecteur s)
87  *
88  * Vector v is updated to be equal to M v, where M is the identity
89  * matrix except for its ith column that is replaced by s. In other
90  * words, the resulting v is v + v_i s - v_i e_i = v + v_i (s - e_i),
91  * where e_i is the ith base vector.
92  *
93  * Because the transformation is applied to a constraint system, it is
94  * better to update s once, and not a this low-level. So this compute
95  * v + v_i s.
96  *
97  * Vector s is preserved.
98  */
100 {
101  Value v_i = vect_coeff(i, v);
102  //vect_add_elem(s, i, VALUE_MONE);
103  v = vect_cl(v, v_i, s);
104  return v;
105 }
106 
107 /* Pvecteur vect_cl_ofl_ctrl(Pvecteur v, Value lambda, Pvecteur u, int ofl_ctrl):
108  * etape d'acculumulation dans une combinaison lineaire;
109  * aucun sharing entre v et u n'est cree (allocation implicite)
110  * Le controle de l'overflow est effectue et traite par le retour
111  * du contexte correspondant au dernier CATCH(overflow_error) effectue.
112  *
113  * -> -> ->
114  * v := v + lambda u;
115  * ->
116  * return v;
117  *
118  * Modifications:
119  * - exploitation des lambdas 1 et -1; ca rallonge mechamment le code;
120  * non teste; u est casse mais en principe ce n'est pas grave car il n'est
121  * utilise qu'une seule fois (Francois Irigoin, 26/03/90)
122  * - add the cu variable to avoid side effects on parameter u;
123  * (Francois Irigoin, 17 December 1991)
124  * - add assert() to try to avoid most integer overflow; this is likely
125  * to (uselessly) slow down dependence tests since overflows occur
126  * only (?) in code generation phases; (Francois Irigoin, 17 December 1991)
127  */
128 Pvecteur vect_cl_ofl_ctrl(v, lambda, u, ofl_ctrl)
129 Pvecteur v;
130 Value lambda;
131 Pvecteur u;
132 int ofl_ctrl;
133 {
134  Pvecteur cu;
135 
136  if(lambda==VALUE_ZERO)
137  return v;
138  else if(v==NULL) {
139  /* ancienne version
140  * for( ;u!=NULL;u=u->succ)
141  * v = vect_chain(v,var_of(u),lambda*val_of(u));
142  */
143  v = vect_dup(u);
144  if (value_notone_p(lambda)) {
145  if (value_mone_p(lambda))
146  vect_chg_sgn(v);
147  else
148  v = vect_multiply(v, lambda);
149  }
150  }
151  else
152  if (value_one_p(lambda)) /* == 1 */
153  for(cu=u ;cu!=NULL;cu=cu->succ)
154  vect_add_elem(&v, var_of(cu), val_of(cu));
155  else if (value_mone_p(lambda)) /* == -1 */
156  for(cu=u ;cu!=NULL;cu=cu->succ)
157  vect_add_elem(&v, var_of(cu), value_uminus(val_of(cu)));
158  else
159  for(cu=u ;cu!=NULL;cu=cu->succ) {
160  /* bof, FC */
161  Value x = ofl_ctrl!=NO_OFL_CTRL?
162  value_protected_mult(lambda,val_of(cu)):
163  value_mult(lambda,val_of(cu));
164 
165  vect_add_elem(&v, var_of(cu), x);
166  }
167 
168  return v;
169 }
170 
171 
172 
174 Pvecteur v;
175 Value lambda;
176 Pvecteur u;
177 {
178  return vect_cl_ofl_ctrl(v, lambda, u, FWD_OFL_CTRL);
179 }
180 
181 Pvecteur vect_cl(v,lambda,u)
182 Pvecteur v;
183 Value lambda;
184 Pvecteur u;
185 {
186  return vect_cl_ofl_ctrl(v, lambda, u, NO_OFL_CTRL);
187 }
188 
189 /* Pvecteur vect_cl2_ofl(Value x1, Pvecteur v1, Value x2, Pvecteur v2):
190  * allocation d'un vecteur v dont la valeur est
191  * la combinaison lineaire des deux vecteurs v1 et v2 avec les
192  * coefficients respectifs x1 et x2
193  * Le controle de l'overflow est effectue par vect_cl_ofl et traite par
194  * le retour du contexte correspondant au dernier CATCH(overflow_error)
195  * effectue.
196  * ->
197  * allocate v;
198  * -> -> ->
199  * v := x1 v1 + x2 v2;
200  * ->
201  * return v;
202  *
203  */
204 Pvecteur vect_cl2_ofl_ctrl(x1, v1, x2, v2, ofl_ctrl)
205 Value x1;
206 Pvecteur v1;
207 Value x2;
208 Pvecteur v2;
209 int ofl_ctrl;
210 {
211  /* le bout de l'horreur sur ces vecteurs creux dont les composantes ne
212  sont pas triees; Malik a essaye d'eviter les allocations inutiles
213  en "marquant" les coefficients de v2 qui ont ete vus lors du parcours
214  des coefficients non-nuls de v1; puis il ajoute a ce premier resultat
215  la partie de x2 v2 qui n'a pas encore ete prise en compte parce
216  que le coefficient correspondant dans v1 etait nul;
217 
218  la variable de nom 0 est traitee a part car la procedure de
219  marquage (multiplication par -1) ne la marque pas
220 
221  Une autre solution, presque aussi efficace, consisterait a
222  allouer et calculer x1 v1 puis a y ajouter x2 v2 a coups
223  de vect_add_elem; on n'a pas de procedure faisant simultanement
224  l'allocation et la multiplication par un scalaire; on n'a pas
225  de procedure faisant l'addition sans allocation (accumulation);
226 
227  Francois Irigoin, 2 juin 1989 */
228 
229  Pvecteur v = NULL;
230 
231  v = vect_cl_ofl_ctrl(v,x1,v1, ofl_ctrl);
232  v = vect_cl_ofl_ctrl(v,x2,v2, ofl_ctrl);
233 
234  return(v);
235 }
236 
237 
238 Pvecteur vect_cl2_ofl(x1,v1,x2,v2)
239 Value x1;
240 Pvecteur v1;
241 Value x2;
242 Pvecteur v2;
243 {
244  return(vect_cl2_ofl_ctrl(x1,v1,x2,v2, FWD_OFL_CTRL));
245 }
246 
247 Pvecteur vect_cl2(x1,v1,x2,v2)
248 Value x1;
249 Pvecteur v1;
250 Value x2;
251 Pvecteur v2;
252 {
253  return(vect_cl2_ofl_ctrl(x1,v1,x2,v2, NO_OFL_CTRL));
254 }
255 
256 
257 
258 /* Pvecteur vect_subst(Variable v, Pvecteur v1, Pvecteur v2): calcul
259  * d'un vecteur v3 tel que l'intersection des hyperplans definis par
260  * v1 et v2 soit egale a l'intersection des hyperplans definis
261  * par v1 et v3, et que v appartiennent a l'hyperplan defini par v3.
262  * v3 est defini a une constante multiplicative pret et ses coefficients
263  * ne sont donc pas necessairement normalises, mais on s'arrange pour
264  * multiplier v2 par une constante positive ce qui est utile si v2
265  * represente une inegalite (cf. package contrainte).
266  *
267  * -> -> -> -> -> -> -> -> -> -> ->
268  * { U / V1 . u = 0 & v2 . u = 0 } = { u / v1 . u = 0 & v3 . u = 0 }
269  *
270  * -> ->
271  * v3 . v = 0
272  *
273  * Si v2 remplit la condition v2 . v = 0, on prend v3 = v2.
274  *
275  * Il faut comme precondition a l'appel que v1 . v != 0
276  *
277  * Le vecteur v1 est preserve. Le vecteur v2 est detruit. v3 est alloue.
278  *
279  * Cette routine peut servir a eliminer une variable entre deux egalites
280  * ou inegalites. C'est pourquoi v2 est detruit. Il est destine a etre
281  * remplace par v3. Voir contrainte_subst().
282  *
283  * ATTENTION: je ne comprends pas a quoi sert le vect_chg_coeff(). F.I.
284  * Les commentaires precedent sont donc partiellement (?) faux!!!
285  */
287 Variable v;
288 Pvecteur v1;
289 Pvecteur v2;
290 {
291  Pvecteur v3;
292  /* cv_v1 = coeff de v dans v1 */
293  Value cv_v1 = vect_coeff(v,v1);
294  /* cv_v2 = coeff de v dans v2 */
295  Value cv_v2 = vect_coeff(v,v2);
296 
297  if (cv_v2==VALUE_ZERO) {
298  /* v2 est solution; i.e., substitution non faite: var absente */
299  v3 = v2;
300  }
301  else {
302  if (cv_v1<VALUE_ZERO) {
303  v3 = vect_cl2(value_uminus(cv_v1),v2,cv_v2,v1);
304  vect_chg_coeff(&v3,v,value_uminus(cv_v2));
305  }
306  else {
307  v3 = vect_cl2(cv_v1,v2,value_uminus(cv_v2),v1);
308  vect_chg_coeff(&v3,v,cv_v2);
309  }
310  vect_rm(v2);
311  }
312  return(v3);
313 }
314 
#define VALUE_ZERO
#define value_mone_p(val)
#define value_uminus(val)
unary operators on values
#define value_notone_p(val)
#define value_one_p(val)
#define value_protected_mult(v, w)
protected versions
int Value
#define value_mult(v, w)
whether the default is protected or not this define makes no sense any more...
void vect_chg_sgn(Pvecteur v)
void vect_chg_sgn(Pvecteur v): multiplie v par -1
Definition: scalaires.c:151
Pvecteur vect_multiply(Pvecteur v, Value x)
Pvecteur vect_multiply(Pvecteur v, Value x): multiplication du vecteur v par le scalaire x,...
Definition: scalaires.c:123
static char * x
Definition: split_file.c:159
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
struct Svecteur * succ
Definition: vecteur-local.h:92
#define val_of(varval)
#define NO_OFL_CTRL
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....
Definition: vecteur-local.h:60
#define FWD_OFL_CTRL
#define var_of(varval)
Pvecteur vect_dup(Pvecteur v_in)
Pvecteur vect_dup(Pvecteur v_in): duplication du vecteur v_in; allocation de et copie dans v_out;.
Definition: alloc.c:51
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
Pvecteur vect_subst(Variable v, Pvecteur v1, Pvecteur v2)
Pvecteur vect_subst(Variable v, Pvecteur v1, Pvecteur v2): calcul d'un vecteur v3 tel que l'intersect...
Definition: binaires.c:286
Pvecteur vect_cl2_ofl_ctrl(Value x1, Pvecteur v1, Value x2, Pvecteur v2, int ofl_ctrl)
Pvecteur vect_cl2_ofl(Value x1, Pvecteur v1, Value x2, Pvecteur v2): allocation d'un vecteur v dont l...
Definition: binaires.c:204
Pvecteur vect_cl2(Value x1, Pvecteur v1, Value x2, Pvecteur v2)
Definition: binaires.c:247
Pvecteur vect_add(Pvecteur v1, Pvecteur v2)
package vecteur - operations binaires
Definition: binaires.c:53
Pvecteur vect_cl2_ofl(Value x1, Pvecteur v1, Value x2, Pvecteur v2)
Definition: binaires.c:238
Pvecteur vect_substitute_dimension(Pvecteur v, Variable i, Pvecteur s)
Pvecteur vect_substitute_dimension(Pvecteur v, Variable i, Pvecteur s)
Definition: binaires.c:99
Pvecteur vect_substract(Pvecteur v1, Pvecteur v2)
Pvecteur vect_substract(Pvecteur v1, Pvecteur v2): allocation d'un vecteur v dont la valeur est la di...
Definition: binaires.c:75
Pvecteur vect_cl_ofl(Pvecteur v, Value lambda, Pvecteur u)
Definition: binaires.c:173
Pvecteur vect_cl_ofl_ctrl(Pvecteur v, Value lambda, Pvecteur u, int ofl_ctrl)
Pvecteur vect_cl_ofl_ctrl(Pvecteur v, Value lambda, Pvecteur u, int ofl_ctrl): etape d'acculumulation...
Definition: binaires.c:128
Pvecteur vect_cl(Pvecteur v, Value lambda, Pvecteur u)
Definition: binaires.c:181
void vect_add_elem(Pvecteur *pvect, Variable var, Value val)
void vect_add_elem(Pvecteur * pvect, Variable var, Value val): addition d'un vecteur colineaire au ve...
Definition: unaires.c:72
Value vect_coeff(Variable var, Pvecteur vect)
Variable vect_coeff(Variable var, Pvecteur vect): coefficient de coordonnee var du vecteur vect —> So...
Definition: unaires.c:228
void vect_chg_coeff(Pvecteur *ppv, Variable var, Value val)
void vect_chg_coeff(Pvecteur *ppv, Variable var, Value val): mise de la coordonnee var du vecteur *pp...
Definition: unaires.c:143