PIPS
pnome-unaires.c
Go to the documentation of this file.
1 /*
2 
3  $Id: pnome-unaires.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-unaires.c
26  *
27  * UNARY OPERATIONS ON POLYNOMIALS
28  *
29  */
30 
31 #ifdef HAVE_CONFIG_H
32  #include "config.h"
33 #endif
34 #include <stdio.h>
35 #include <boolean.h>
36 #include "arithmetique.h"
37 #include "vecteur.h"
38 #include "polynome.h"
39 
40 
41 /* void polynome_negate(Ppolynome *ppp);
42  * changes sign of polynomial *ppp.
43  * !usage: polynome_negate(&pp);
44  */
45 void polynome_negate(ppp)
46 Ppolynome *ppp;
47 {
48  Ppolynome curpp;
49 
50  if ( !POLYNOME_UNDEFINED_P(*ppp) && !POLYNOME_NUL_P(*ppp) )
51  for(curpp = *ppp; curpp != POLYNOME_NUL; curpp = polynome_succ(curpp))
53 }
54 
55 /* Ppolynome polynome_opposed(Ppolynome pp);
56  * changes sign of polynomial pp.
57  * !usage: pp = polynome_negate(pp);
58  */
60 Ppolynome pp;
61 {
62  Ppolynome curpp;
63 
64  if ( !POLYNOME_UNDEFINED_P(pp) && !POLYNOME_NUL_P(pp) )
65  for(curpp = pp; curpp != POLYNOME_NUL; curpp = polynome_succ(curpp))
67 
68  return pp;
69 }
70 
71 
72 /* Ppolynome polynome_sum_of_power(Ppolynome ppsup, int p)
73  * calculates the sum of i^p for i=1 to (ppsup),
74  * returns the polynomial sigma{i=1, ppsup} (i^p).
75  * It does the job well until p=13; after, it goes wrong
76  * (the Bernouilli numbers are computed until p=12)
77  */
78 
80 Ppolynome ppsup;
81 int p;
82 {
83  Ppolynome ppresult = NULL, ppacc;
84  int i;
85 
86  if (POLYNOME_UNDEFINED_P(ppsup))
87  return (POLYNOME_UNDEFINED);
88  if (p < 0)
89  polynome_error("polynome_sum_of_power", "negative power: %d\n", p);
90  else if (p == 0)
91  ppresult = polynome_dup(ppsup);
92  else {
93  if ( polynome_constant_p(ppsup) ) { /* if the upper bound is constant ... */
94  double factor, result = 0;
95  double cste = (double)polynome_TCST(ppsup);
96 
97  if (cste<1) {
98  /* FI: That means, no iteration is executed whatsoever,
99  isn't it?
100 
101  Also, polynome_error() does stop the execution and we
102  are in trouble for Linear/C3 Library. We should init some exit
103  function towards pips_internal_error().
104  */
105  /*
106  polynome_error("polynome_sum_of_power",
107  "compute a sum from 1 to %f!\n", (float) cste);
108  */
109  ppresult = POLYNOME_NUL;
110  }
111  /*else if (cste==1)
112  ppresult = POLYNOME_NUL;*/
113  else {
114  result = intpower(cste, p) * ((double) (cste / (p+1)) + 0.5);
115  factor = ((double) p/2);
116 
117  for (i=1; 0<p-2*i+1; i++) {
118  result += (intpower(cste, p-2*i+1)
119  * ((double) (Bernouilli(i) * factor)));
120  factor *= - ((double) (p-2*i+1)*(p-2*i)) / ((double) (2*i+1)*(2*i+2));
121  }
122  ppresult = make_polynome((float) result, TCST, VALUE_ONE);
123  }
124  }
125  else { /* if the upper bound is a non-constant polynomial ... */
126  float factor;
127  /* (ppsup^(p+1)) / (p+1) */
128  ppresult = polynome_power_n(ppsup, p+1);
129  polynome_scalar_mult(&ppresult, (float) 1/(p+1));
130  /* 1/2 * ppsup^p */
131  ppacc = polynome_power_n(ppsup, p);
132  polynome_scalar_mult(&ppacc, (float) 1/2);
133  polynome_add(&ppresult, ppacc);
134  polynome_rm(&ppacc);
135 
136  factor = ((float) p / 2);
137  /* computes factors p(p-1).../(2i!) incrementally */
138 
139  for (i=1; 0 < p-2*i+1; i++) {
140  /* the current term of the remaining of the sum is: */
141  /* Ti = (1/(2i)!)*(Bi*p*(p-1)* . *(p-2*i+2)*ppsup^(p-2*i+1)) */
142 
143  ppacc = polynome_power_n(ppsup, p-2*i+1);
144  polynome_scalar_mult(&ppacc, (float) Bernouilli(i) * factor);
145 
146  polynome_add(&ppresult, ppacc);
147  polynome_rm(&ppacc);
148 
149  factor *= -((float)(p-2*i+1)*(p-2*i))/((float)(2*i+1)*(2*i+2));
150  }
151  }
152  }
153  return(ppresult);
154 }
155 
156 /* Ppolynome polynome_sigma(Ppolynome pp, Variable var, Ppolynome ppinf, ppsup)
157  * returns the sum of pp when its variable var is moving from ppinf to ppsup.
158  * Neither ppinf nor ppsup must contain variable var.
159  */
160 Ppolynome polynome_sigma(pp, var, ppinf, ppsup)
161 Ppolynome pp;
162 Variable var;
163 Ppolynome ppinf, ppsup;
164 {
165  Ppolynome ppacc, pptemp, ppfact, ppresult = POLYNOME_NUL;
166  int i;
167 
169  || POLYNOME_UNDEFINED_P(ppsup))
170  return (POLYNOME_UNDEFINED);
171 
172  for(i = 0; i <= polynome_degree(pp, var); i++) {
173  /* compute:
174  * sum(ppinf,ppsup) ppfact * x ^ i
175  * as:
176  * ppfact * ( sum(1, ppsup) x ^ i -
177  * sum(1, ppinf) x ^ i +
178  * ppfin ^ i )
179  * where:
180  * ppfact is the term associated to x ^ i in pp
181  *
182  * Note that this decomposition is correct wrt standard
183  * mathematical notations if and only if:
184  * ppsup >= ppinf >= 1
185  * although the correct answer can be obtained when
186  * ppsup >= ppinf
187  *
188  * Thus:
189  * sum(1, ppsup) x ^ i
190  * is extended for ppsup < 1 and defined as:
191  * - (sum(ppsup, -1) x ^ i)
192  */
193  ppfact = polynome_factorize(pp, var, i);
194 
195  if (!POLYNOME_NUL_P(ppfact)) {
196  ppacc = polynome_sum_of_power(ppsup, i);
197  /* LZ: if ppinf == 1: no need to compute next sigma (pptemp),
198  * nor ppinf^i (FI: apparently not implemented) */
199  pptemp = polynome_sum_of_power(ppinf, i);
200 
201  polynome_negate(&pptemp);
202  polynome_add(&ppacc, pptemp);
203  /* ppacc = sigma{1,ppsup} - sigma{1,ppinf} */
204  polynome_rm(&pptemp);
205 
206  /* ppacc == (sigma{k=1,ppsup} k^i) - (sigma{k=1,ppinf} k^i) */
207 
208  pptemp = polynome_power_n(ppinf, i);
209  polynome_add(&ppacc, pptemp);
210  polynome_rm(&pptemp);
211 
212  pptemp = polynome_mult(ppfact, ppacc);
213 
214  polynome_add(&ppresult, pptemp);
215 
216  polynome_rm(&pptemp);
217  polynome_rm(&ppacc);
218  }
219  }
220  return(ppresult);
221 }
222 
223 
224 /* Ppolynome polynome_sort((Ppolynome *) ppp, bool (*is_inferior_var)())
225  * Sorts the polynomial *ppp: monomials are sorted by the private routine
226  * "is_inferior_monome" based on the user one "is_inferior_var".
227  * !usage: polynome_sort(&pp, is_inferior_var);
228  */
230 Ppolynome *ppp;
232 {
233  Ppolynome ppcur;
234  Ppolynome ppsearchmin;
235  Pmonome pmtemp;
236 
237  if ((!POLYNOME_NUL_P(*ppp)) && (!POLYNOME_UNDEFINED_P(*ppp))) {
238  for (ppcur = *ppp; ppcur != POLYNOME_NUL; ppcur = polynome_succ(ppcur)) {
239  Pmonome pm = polynome_monome(ppcur);
240  Pvecteur pv = monome_term(pm);
241  pv = vect_sort(pv, vect_compare);
242  /* pv = vect_tri(pv, is_inferior_var); */
243  }
244  for (ppcur = *ppp; polynome_succ(ppcur) != POLYNOME_NUL; ppcur = polynome_succ(ppcur)) {
245  for(ppsearchmin = polynome_succ(ppcur);
246  ppsearchmin != POLYNOME_NUL;
247  ppsearchmin = polynome_succ(ppsearchmin)) {
248 
249  if (!is_inferior_monome(polynome_monome(ppsearchmin),
250  polynome_monome(ppcur), is_inferior_var)) {
251  pmtemp = polynome_monome(ppsearchmin);
252  polynome_monome(ppsearchmin) = polynome_monome(ppcur);
253  polynome_monome(ppcur) = pmtemp;
254  }
255  }
256  }
257  }
258  return (*ppp);
259 }
260 
261 /* void polynome_chg_var(Ppolynome *ppp, Variable v_old, Variable v_new)
262  * replace the variable v_old by v_new
263  */
264 void polynome_chg_var(ppp,v_old,v_new)
265 Ppolynome *ppp;
266 Variable v_old,v_new;
267 {
268  Ppolynome ppcur;
269 
270  for (ppcur = *ppp; ppcur != POLYNOME_NUL; ppcur = polynome_succ(ppcur)) {
271  Pmonome pmcur = polynome_monome(ppcur);
272  /* Should it be comparated against MONOME_NUL (that is different
273  of 0) instead? */
274  if ( pmcur != NULL ) {
275  Pvecteur pvcur = monome_term(pmcur);
276 
277  vect_chg_var(&pvcur,v_old,v_new);
278  }
279  }
280 }
void const char const char const int
#define VALUE_ONE
bool is_inferior_var(Variable, Variable)
Definition: polynome_ri.c:118
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
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_mult(Ppolynome pp1, Ppolynome pp2)
Ppolynome polynome_mult(Ppolynome pp1, Ppolynome pp2) returns pp1 * pp2.
Definition: pnome-bin.c:287
void polynome_add(Ppolynome *ppp, Ppolynome pp2)
void polynome_add(Ppolynome* ppp, Ppolynome pp2) (*ppp) = (*ppp) + pp2.
Definition: pnome-bin.c:171
void polynome_error(const char *name, char *fmt,...)
INTLIBRARY.
Definition: pnome-error.c:62
float Bernouilli(int i)
float Bernouilli(int i) PRIVATE returns Bi = i-th Bernouilli number
bool is_inferior_monome(Pmonome pm1, Pmonome pm2, int *is_inferior_var)
bool is_inferior_monome(Pmonome pm1, pm2, int (*is_inferior_var)()) returns the qsort comparison (pm1...
double intpower(double d, int n)
double intpower(double d, int n) returns d^n for all integers n
int polynome_degree(Ppolynome pp, Variable var)
int polynome_degree(Ppolynome pp, Variable var) returns the degree of polynomial pp viewed as a polyn...
Definition: pnome-reduc.c:93
float polynome_TCST(Ppolynome pp)
float polynome_TCST(Ppolynome pp) returns the constant term of polynomial pp.
Definition: pnome-reduc.c:156
bool polynome_constant_p(Ppolynome pp)
bool polynome_constant_p(Ppolynome pp) return true if pp is a constant polynomial (including null pol...
Definition: pnome-reduc.c:180
Ppolynome polynome_factorize(Ppolynome pp, Variable var, int n)
Ppolynome polynome_factorize(Ppolynome pp, Variable var, int n) returns the (polynomial) coefficient ...
Definition: pnome-reduc.c:131
Ppolynome polynome_power_n(Ppolynome pp, int n)
Ppolynome polynome_power_n(Ppolynome pp, int n) returns pp ^ n (n>=0)
Definition: pnome-scal.c:121
void polynome_scalar_mult(Ppolynome *ppp, float factor)
void polynome_scalar_mult(Ppolynome* ppp, float factor) (*ppp) = factor * (*ppp) !...
Definition: pnome-scal.c:46
Ppolynome polynome_sigma(Ppolynome pp, Variable var, Ppolynome ppinf, Ppolynome ppsup)
Ppolynome polynome_sigma(Ppolynome pp, Variable var, Ppolynome ppinf, ppsup) returns the sum of pp wh...
Ppolynome polynome_opposed(Ppolynome pp)
Ppolynome polynome_opposed(Ppolynome pp); changes sign of polynomial pp.
Definition: pnome-unaires.c:59
void polynome_negate(Ppolynome *ppp)
void polynome_negate(Ppolynome *ppp); changes sign of polynomial *ppp.
Definition: pnome-unaires.c:45
Ppolynome polynome_sum_of_power(Ppolynome ppsup, int p)
Ppolynome polynome_sum_of_power(Ppolynome ppsup, int p) calculates the sum of i^p for i=1 to (ppsup),...
Definition: pnome-unaires.c:79
void polynome_chg_var(Ppolynome *ppp, Variable v_old, Variable v_new)
void polynome_chg_var(Ppolynome *ppp, Variable v_old, Variable v_new) replace the variable v_old by v...
Ppolynome polynome_sort(Ppolynome *ppp, int *is_inferior_var)
Ppolynome polynome_sort((Ppolynome *) ppp, bool (*is_inferior_var)()) Sorts the polynomial *ppp: mono...
#define POLYNOME_NUL
#define POLYNOME_UNDEFINED
#define POLYNOME_UNDEFINED_P(pp)
#define monome_term(pm)
#define polynome_monome(pp)
#define monome_coeff(pm)
Macros definitions.
#define POLYNOME_NUL_P(pp)
#define polynome_succ(pp)
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
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
int vect_compare(Pvecteur *pv1, Pvecteur *pv2)
for qsort, returns:
Definition: unaires.c:352
Pvecteur vect_sort(Pvecteur v, int *compare)
Pvecteur vect_sort(v, compare) Pvecteur v; int (*compare)();.
Definition: unaires.c:335
void vect_chg_var(Pvecteur *ppv, Variable v_old, Variable v_new)
void vect_chg_var(Pvecteur *ppv, Variable v_old, Variable v_new) replace the variable v_old by v_new
Definition: unaires.c:168