PIPS
pnome-bin.c
Go to the documentation of this file.
1 /*
2 
3  $Id: pnome-bin.c 1641 2016-03-02 08:20:19Z 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 /******************************************************************* pnome-bin.c
26  *
27  * BINARY OPERATIONS ON POLYNOMIALS
28  *
29  */
30 
31 #ifdef HAVE_CONFIG_H
32  #include "config.h"
33 #endif
34 #include <stdio.h>
35 #include <stdlib.h>
36 
37 #include "boolean.h"
38 #include "arithmetique.h"
39 #include "vecteur.h"
40 #include "polynome.h"
41 
42 /* void polynome_monome_add(Ppolynome* ppp, Pmonome pm)
43  * PRIVATE
44  * Add monomial pm to polynomial *ppp, in place.
45  * There is no new polynomial malloc.
46  * Monomial pm doesn't become part of the polynomial:
47  * it is duplicated if needed.
48  * !usage: polynome_monome_add(&pp, pm);
49  */
50 void polynome_monome_add(ppp, pm)
51 Ppolynome *ppp;
52 Pmonome pm;
53 {
54  Ppolynome prevpp = POLYNOME_NUL;
55  float coeff;
56 
57  if (POLYNOME_NUL_P(*ppp)) {
59  }
60  else if (POLYNOME_UNDEFINED_P(*ppp))
61  ;
62  else if (MONOME_UNDEFINED_P(pm)) {
63  polynome_rm(ppp);
64  *ppp = POLYNOME_UNDEFINED;
65  }
66  else if (!MONOME_NUL_P(pm)) {
67  Ppolynome curpp;
68  for(curpp = *ppp; curpp != POLYNOME_NUL; prevpp = curpp,curpp = polynome_succ(curpp)) {
69  if (monome_colin(polynome_monome(curpp), pm)) {
70  coeff = monome_coeff(polynome_monome(curpp)) + monome_coeff(pm);
71  if ((coeff < PNOME_MACH_EPS) && (coeff > -PNOME_MACH_EPS)) {
72  /* This monomial is null now. We free it */
73  if (curpp == *ppp)
74  *ppp = polynome_succ(*ppp);
75  else
76  polynome_succ(prevpp) = polynome_succ(curpp);
77  polynome_succ(curpp) = POLYNOME_NUL;
78  polynome_rm(&curpp);
79  curpp = ( prevpp==POLYNOME_NUL ? *ppp : prevpp );
80  if ( curpp == POLYNOME_NUL ) /* no element in polynome */
81  *ppp = POLYNOME_NUL;
82  }
83  else /* Save new value of monomial coefficient. */
84  monome_coeff(polynome_monome(curpp)) = coeff;
85  break;
86  }
87  }
88 
89  if ( curpp == POLYNOME_NUL && !POLYNOME_NUL_P(*ppp) ) {
90  /* Add a copy of the monomial at the end */
91  good_polynome_assert("polynome_monome_add about prevpp before",prevpp);
92  if ( polynome_succ(prevpp) == POLYNOME_NUL ) {
93  if ( MONOME_NUL_P(pm) || MONOME_UNDEFINED_P(pm) )
94  printf("monome is poor\n");
95  else
97  }
98  good_polynome_assert("polynome_monome_add about prevpp at end",prevpp);
99  }
100  }
101  good_polynome_assert("polynome_monome_add about *ppp at end",*ppp);
102 }
103 
104 /* Ppolynome polynome_monome_addition(Ppolynome pp, Pmonome pm)
105  * PRIVATE
106  * Add monomial pm to polynomial pp, in place.
107  * There is no new polynomial malloc.
108  * Monomial pm doesn't become part of the polynomial:
109  * it is duplicated if needed.
110  * !usage: pp = polynome_monome_add(pp, pm);
111  */
113 Ppolynome pp;
114 Pmonome pm;
115 {
116  Ppolynome prevpp = POLYNOME_UNDEFINED;
117 
118  if (POLYNOME_NUL_P(pp)) {
120  }
121  else if (POLYNOME_UNDEFINED_P(pp))
122  ;
123  else if (MONOME_UNDEFINED_P(pm)) {
124  pp = polynome_free(pp);
125  pp = POLYNOME_UNDEFINED;
126  }
127  else if (!MONOME_NUL_P(pm)) {
128  Ppolynome curpp;
129  for(curpp = pp; curpp != POLYNOME_NUL; prevpp = curpp,curpp = polynome_succ(curpp)) {
130  if (monome_colin(polynome_monome(curpp), pm)) {
131  float coeff = monome_coeff(polynome_monome(curpp)) + monome_coeff(pm);
132 
133  if ((coeff < PNOME_MACH_EPS) && (coeff > -PNOME_MACH_EPS)) {
134  /* This monomial is null now. We free it */
135  if (curpp == pp)
136  pp = polynome_succ(pp);
137  else
138  polynome_succ(prevpp) = polynome_succ(curpp);
139  polynome_succ(curpp) = POLYNOME_NUL;
140  polynome_rm(&curpp);
141  curpp = ( prevpp==POLYNOME_NUL ? pp : prevpp );
142  if ( curpp == POLYNOME_NUL ) /* no element in polynome */
143  pp = POLYNOME_NUL;
144  }
145  else /* Save new value of monomial coefficient. */
146  monome_coeff(polynome_monome(curpp)) = coeff;
147  break;
148  }
149  }
150 
151  if ( curpp == POLYNOME_NUL && !POLYNOME_NUL_P(pp) ) {
152  /* Add a copy of the monomial at the end */
153  good_polynome_assert("polynome_monome_add about prevpp before",prevpp);
154  if ( polynome_succ(prevpp) == POLYNOME_NUL ) {
155  if ( MONOME_NUL_P(pm) || MONOME_UNDEFINED_P(pm) )
156  printf("monome is poor\n");
157  else
159  }
160  good_polynome_assert("polynome_monome_add about prevpp at end",prevpp);
161  }
162  }
163  good_polynome_assert("polynome_monome_add about pp at end",pp);
164  return pp;
165 }
166 
167 /* void polynome_add(Ppolynome* ppp, Ppolynome pp2)
168  * (*ppp) = (*ppp) + pp2.
169  * !usage: polynome_add(&pp, pp2);
170  */
171 void polynome_add(ppp, pp2)
172 Ppolynome *ppp,pp2;
173 {
174  if (POLYNOME_NUL_P(*ppp)) {
175  if ( !POLYNOME_NUL_P(pp2))
176  *ppp = polynome_dup(pp2);
177  else
178  *ppp = POLYNOME_NUL;
179  }
180  else if (POLYNOME_UNDEFINED_P(pp2)) {
181  polynome_rm(ppp);
182  *ppp = POLYNOME_UNDEFINED;
183  }
184  else if (!POLYNOME_UNDEFINED_P(*ppp)) {
185  for (;pp2 != POLYNOME_NUL; pp2 = polynome_succ(pp2)) {
187  }
188  }
189 }
190 
191 /* Ppolynome polynome_addition(Ppolynome pp, Ppolynome pp2)
192  * pp = pp + pp2.
193  * !usage: pp = polynome_add(pp, pp2);
194  */
196 Ppolynome pp,pp2;
197 {
199 
200  if (POLYNOME_NUL_P(pp)) {
201  if ( !POLYNOME_NUL_P(pp2))
202  newpp = polynome_dup(pp2);
203  else
204  newpp = POLYNOME_NUL;
205  }
206  else if (POLYNOME_UNDEFINED_P(pp2)) {
207  pp = polynome_free(pp);
208  newpp = POLYNOME_UNDEFINED;
209  }
210  else if (!POLYNOME_UNDEFINED_P(pp)) {
211  newpp = pp;
212  for (;pp2 != POLYNOME_NUL; pp2 = polynome_succ(pp2)) {
213  newpp = polynome_monome_addition(newpp, polynome_monome(pp2));
214  }
215  }
216  return newpp;
217 }
218 
219 
220 /* void monome_monome_mult(Pmonome *pm, Pmonome pm2)
221  * PRIVATE
222  * (*pm) = (*pm) * pm2.
223  * !usage: monome_monome_mult(&pm, pm2);
224  */
225 static void monome_monome_mult(ppm, pm2)
226 Pmonome *ppm, pm2;
227 {
228  Pvecteur produit;
229 
230  if (MONOME_UNDEFINED_P(*ppm))
231  ;
232  else if (MONOME_UNDEFINED_P(pm2)) {
233  monome_rm(ppm);
234  *ppm = MONOME_UNDEFINED;
235  }
236  else if (!MONOME_NUL_P(*ppm)) {
237  if (MONOME_NUL_P(pm2))
238  monome_rm(ppm); /* returns ppm pointing to MONOME_NUL */
239  else {
240  if (MONOME_CONSTANT_P(pm2))
241  produit = vect_dup(monome_term(*ppm));
242  else if (MONOME_CONSTANT_P(*ppm))
243  produit = vect_dup(monome_term(pm2));
244  else {
245  if (var_of(monome_term(*ppm))==var_of(monome_term(pm2)) &&
247  val_of(monome_term(pm2))))) {
248  /* M^-1 *M should be 1 . 26/10/92 LZ
249  and the vecteur must be same. 09/11/92 */
250  produit = vect_new(TCST, VALUE_ONE);
251  }
252  else
253  produit = vect_add(monome_term(*ppm), monome_term(pm2));
254  }
255  monome_coeff(*ppm) *= monome_coeff(pm2);
256  vect_rm(monome_term(*ppm));
257  monome_term(*ppm) = produit;
258  }
259  }
260 }
261 
262 /* Ppolynome polynome_monome_mult(Ppolynome pp, Pmonome pm)
263  * PRIVATE
264  * returns pp * pm.
265  */
267 Ppolynome pp;
268 Pmonome pm;
269 {
270  Ppolynome curpp, ppdup;
272  return (POLYNOME_UNDEFINED);
273  else if (POLYNOME_NUL_P(pp) || MONOME_NUL_P(pm))
274  return (POLYNOME_NUL);
275  else {
276  ppdup = polynome_dup(pp);
277  for (curpp = ppdup ; curpp != POLYNOME_NUL; curpp = polynome_succ(curpp))
278  monome_monome_mult(&(polynome_monome(curpp)), pm);
279  return (ppdup);
280  }
281 }
282 
283 
284 /* Ppolynome polynome_mult(Ppolynome pp1, Ppolynome pp2)
285  * returns pp1 * pp2.
286  */
288 Ppolynome pp1, pp2;
289 {
291 
293  return (POLYNOME_UNDEFINED);
294  if (POLYNOME_NUL_P(pp1) || POLYNOME_NUL_P(pp2))
295  return (POLYNOME_NUL);
296  else {
297  Ppolynome pppartiel, ppresult = POLYNOME_NUL;
298 
299  for (mp2 = pp2 ; mp2 != POLYNOME_NUL; mp2 = polynome_succ(mp2)) {
300  pppartiel = polynome_monome_mult(pp1, polynome_monome(mp2));
301  polynome_add(&ppresult, pppartiel);
302  polynome_rm(&pppartiel);
303  }
304  return (ppresult);
305  }
306 }
307 
308 /* Pmonome monome_monome_div(Pmonome pm1, Pmonome pm2)
309  * PRIVATE
310  * (pm1) = (pm1) / pm2.
311  * !usage: monome_monome_div(pm, pm2);
312  * Lei Zhou , 09/07/91
313  */
315 Pmonome pm1, pm2;
316 {
317  if (MONOME_UNDEFINED_P(pm1))
318  return (MONOME_UNDEFINED);
319  else if (MONOME_UNDEFINED_P(pm2)) {
320  monome_rm(&pm1);
321  return (MONOME_UNDEFINED);
322  }
323  else if (!MONOME_NUL_P(pm1)) {
324  if (MONOME_NUL_P(pm2)) {
325  monome_rm(&pm1); /* returns ppm pointing to MONOME_NUL */
326  return (MONOME_UNDEFINED);
327  }
328  else {
329  Pmonome pmr = new_monome();
330 
331  if (MONOME_CONSTANT_P(pm2))
332  monome_term(pmr) = vect_dup(monome_term(pm1));
333  else if (MONOME_CONSTANT_P(pm1)) {
334  Pvecteur pv = vect_dup(monome_term(pm2));
335  vect_chg_sgn(pv);
336  monome_term(pmr) = pv;
337  }
338  else {
340  if ( monome_term(pmr) == VECTEUR_NUL )
342  }
343  monome_coeff(pmr) = monome_coeff(pm1)/monome_coeff(pm2);
344 
345  return (pmr);
346  }
347  }
348  polynome_error("monome_monome_div","Unreachable...\n");
349  return MONOME_UNDEFINED;
350 }
351 
352 /* Ppolynome polynome_monome_div(Ppolynome pp, Pmonome pm)
353  * PRIVATE
354  * returns p = pp / pm.
355  */
357 Ppolynome pp;
358 Pmonome pm;
359 {
361  return (POLYNOME_UNDEFINED);
362  else if (POLYNOME_NUL_P(pp) || MONOME_NUL_P(pm))
363  return (POLYNOME_NUL);
364  else {
365  Ppolynome ppresult = POLYNOME_NUL;
366  Ppolynome curpp, ppdup;
367  ppdup = polynome_dup(pp);
368 
369  for (curpp = ppdup ; curpp != POLYNOME_NUL; curpp = polynome_succ(curpp)) {
370  Pmonome pmtmp = monome_monome_div(polynome_monome(curpp), pm);
371  polynome_monome_add(&ppresult,pmtmp);
372  }
373  return (ppresult);
374  }
375 }
376 
377 
378 /* Ppolynome polynome_div(Ppolynome pp1, Ppolynome pp2)
379  * returns p = pp1 / pp2.
380  */
382 Ppolynome pp1, pp2;
383 {
385  || POLYNOME_NUL_P(pp2) )
386  return (POLYNOME_UNDEFINED);
387  if (POLYNOME_NUL_P(pp1))
388  return (POLYNOME_NUL);
389  else {
390  Ppolynome ppresult;
391 
392  if (is_single_monome(pp2)) {
393  ppresult = polynome_monome_div(pp1, polynome_monome(pp2));
394  }
395  else {
396  fprintf(stdout,"The divider has at least two elements!\n");
397  exit(3);
398  }
399  return (ppresult);
400  }
401 }
402 /*============================================================================*/
403 /* Ppolynome vecteur_to_polynome(Pvecteur pv): translates a Pvecteur into a
404  * Ppolynome.
405  */
407 {
408  Ppolynome pp;
409 
410  if(VECTEUR_NUL_P(pv))
411  pp = POLYNOME_NUL;
412  else {
413  Pvecteur vec;
414 
415  pp = NULL;
416  for(vec = pv; vec != NULL; vec = vec->succ) {
417  Variable var = vecteur_var(vec);
418  float val = VALUE_TO_FLOAT(vecteur_val(vec));
419  Ppolynome newpp;
420 
421  newpp = make_polynome(val, var, VALUE_ONE);
422  polynome_succ(newpp) = pp;
423  pp = newpp;
424  }
425  }
426 
427  return(pp);
428 }
#define value_zero_p(val)
#define VALUE_TO_FLOAT(val)
#define value_plus(v1, v2)
binary operators on values
#define VALUE_ONE
#define exit(code)
Definition: misc-local.h:54
Ppolynome monome_to_new_polynome(Pmonome pm)
Ppolynome monome_to_new_polynome(Pmonome pm) PRIVATE allocates space for, and creates the polynomial ...
Definition: pnome-alloc.c:115
Ppolynome make_polynome(float coeff, Variable var, Value expo)
Ppolynome make_polynome(float coeff, Variable var, Value expo) PRIVATE allocates space for,...
Definition: pnome-alloc.c:100
void monome_rm(Pmonome *ppm)
void monome_rm(Pmonome* ppm) PRIVATE frees space occupied by monomial *ppm returns *ppm pointing to M...
Definition: pnome-alloc.c:154
Pmonome new_monome()
INTLIBRARY.
Definition: pnome-alloc.c:48
Ppolynome polynome_dup(Ppolynome pp)
Ppolynome polynome_dup(Ppolynome pp) creates and returns a copy of pp.
Definition: pnome-alloc.c:211
void polynome_rm(Ppolynome *ppp)
void polynome_rm(Ppolynome* ppp) frees space occupied by polynomial *ppp returns *ppp pointing to POL...
Definition: pnome-alloc.c:170
Ppolynome polynome_free(Ppolynome pp)
Ppolynome polynome_free(Ppolynome pp) frees space occupied by polynomial pp returns pp == POLYNOME_NU...
Definition: pnome-alloc.c:191
Pmonome monome_dup(Pmonome pm)
Pmonome monome_dup(Pmonome pm) PRIVATE creates and returns a copy of pm.
Definition: pnome-alloc.c:132
Ppolynome vecteur_to_polynome(Pvecteur pv)
===========================================================================
Definition: pnome-bin.c:406
Ppolynome polynome_monome_mult(Ppolynome pp, Pmonome pm)
Ppolynome polynome_monome_mult(Ppolynome pp, Pmonome pm) PRIVATE returns pp * pm.
Definition: pnome-bin.c:266
void polynome_monome_add(Ppolynome *ppp, Pmonome pm)
void polynome_monome_add(Ppolynome* ppp, Pmonome pm) PRIVATE Add monomial pm to polynomial *ppp,...
Definition: pnome-bin.c:50
Ppolynome polynome_addition(Ppolynome pp, Ppolynome pp2)
Ppolynome polynome_addition(Ppolynome pp, Ppolynome pp2) pp = pp + pp2.
Definition: pnome-bin.c:195
Ppolynome polynome_div(Ppolynome pp1, Ppolynome pp2)
Ppolynome polynome_div(Ppolynome pp1, Ppolynome pp2) returns p = pp1 / pp2.
Definition: pnome-bin.c:381
Pmonome monome_monome_div(Pmonome pm1, Pmonome pm2)
Pmonome monome_monome_div(Pmonome pm1, Pmonome pm2) PRIVATE (pm1) = (pm1) / pm2.
Definition: pnome-bin.c:314
Ppolynome polynome_mult(Ppolynome pp1, Ppolynome pp2)
Ppolynome polynome_mult(Ppolynome pp1, Ppolynome pp2) returns pp1 * pp2.
Definition: pnome-bin.c:287
Ppolynome polynome_monome_addition(Ppolynome pp, Pmonome pm)
Ppolynome polynome_monome_addition(Ppolynome pp, Pmonome pm) PRIVATE Add monomial pm to polynomial pp...
Definition: pnome-bin.c:112
Ppolynome polynome_monome_div(Ppolynome pp, Pmonome pm)
Ppolynome polynome_monome_div(Ppolynome pp, Pmonome pm) PRIVATE returns p = pp / pm.
Definition: pnome-bin.c:356
static void monome_monome_mult(Pmonome *ppm, Pmonome pm2)
void monome_monome_mult(Pmonome *pm, Pmonome pm2) PRIVATE (*pm) = (*pm) * pm2.
Definition: pnome-bin.c:225
void polynome_add(Ppolynome *ppp, Ppolynome pp2)
void polynome_add(Ppolynome* ppp, Ppolynome pp2) (*ppp) = (*ppp) + pp2.
Definition: pnome-bin.c:171
void good_polynome_assert(char *function,...)
void good_polynome_assert(va_alist) Check if the second argument is a valid polynomial.
Definition: pnome-error.c:84
void polynome_error(const char *name, char *fmt,...)
INTLIBRARY.
Definition: pnome-error.c:62
bool monome_colin(Pmonome pm1, Pmonome pm2)
bool monome_colin(Pmonome pm1, Pmonome pm2) PRIVATE returns true if the two monomials are "colinear":...
Definition: pnome-private.c:77
#define POLYNOME_NUL
#define PNOME_MACH_EPS
#define POLYNOME_UNDEFINED
#define POLYNOME_UNDEFINED_P(pp)
#define monome_term(pm)
#define MONOME_UNDEFINED_P(pm)
#define polynome_monome(pp)
#define monome_coeff(pm)
Macros definitions.
#define POLYNOME_NUL_P(pp)
#define MONOME_CONSTANT_P(pm)
#define is_single_monome(pp)
#define MONOME_NUL_P(pm)
#define polynome_succ(pp)
#define MONOME_UNDEFINED
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
int printf()
void vect_chg_sgn(Pvecteur v)
void vect_chg_sgn(Pvecteur v): multiplie v par -1
Definition: scalaires.c:151
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 TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define vecteur_val(v)
#define vecteur_var(v)
#define val_of(varval)
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.
#define VECTEUR_NUL_P(v)
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 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
Pvecteur vect_new(Variable var, Value coeff)
Pvecteur vect_new(Variable var,Value coeff): allocation d'un vecteur colineaire au vecteur de base va...
Definition: alloc.c:110
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
Pvecteur vect_add(Pvecteur v1, Pvecteur v2)
package vecteur - operations binaires
Definition: binaires.c:53
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