PIPS
sc_simplex_feasibility_fixprec.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <limits.h>
#include "boolean.h"
#include "arithmetique.h"
#include "linear_assert.h"
#include "vecteur.h"
#include "contrainte.h"
#include "sc.h"
+ Include dependency graph for sc_simplex_feasibility_fixprec.c:

Go to the source code of this file.

Data Structures

struct  hashtable_t
 this is already too much... More...
 

Macros

#define DEBUG(code)   { }
 debug macros may be trigered with -DDEBUG{,1,2} More...
 
#define DEBUG1(code)   { }
 
#define DEBUG2(code)   { }
 
#define DEBUG3(code)   { }
 
#define DIMENSION   sc->dimension
 
#define NUMERO   hashtable[h].numero
 
#define SOLUBLE(N)   soluble=N;goto FINSIMPLEX ;
 
#define CREVARVISIBLE   variables[compteur-3]=compteur-2;
 
#define CREVARCACHEE
 
#define tag(x)   /**printf(x); */
 for tracing macros after expansion: More...
 
#define G(j, a, b)
 maybe most of them should be functions? More...
 
#define GCD(j, a, b)
 
#define GCDZZN(j, a, b)
 
#define GCD_ZERO_CTRL(j, a, b)
 
#define SIMPL(a, b)
 SIMPL normalizes rational a/b (b<>0): divides by gcd(a,b) and returns with b>0 note that there should be no arithmetic exceptions within this macro: (well, only uminus may have trouble for VALUE_MIN...) ??? a==0 ? then a = a/b = 0 and b = b/b = 1. More...
 
#define SIMPLIFIE(f)
 SIMPLIFIE normalizes fraction f. More...
 
#define AFF(x, y)   {x.num=y.num; x.den=y.den;} /**x=y should be ok:-) */
 
#define AFF_PX(x, y)   {x->num=y.num; x->den=y.den;}
 
#define INV(x, y)   {x.num=y.den; x.den=y.num;} /**x=1/y */
 
#define INV_ZERO_CTRL(x, y)   {if (value_zero_p(y.num)) {fprintf(stderr,"ERROR : inverse of fraction zero !"); x.num = VALUE_ZERO; x.den = VALUE_ONE;} else {INV(x,y)}}
 ??? value_zero_p(y.num)? Then x.num != VALUE_ZERO and x.den = VALUE_ZERO, it's not good at all. More...
 
#define METINFINI(f)   {f.num=VALUE_MAX; f.den=VALUE_ONE;}
 
#define MET_ZERO(f)   {f.num=VALUE_ZERO; f.den=VALUE_ONE;}
 
#define MET_UN(f)   {f.num=VALUE_ONE; f.den=VALUE_ONE;}
 
#define EGAL1(x)   (value_eq(x.num,x.den))
 
#define EGAL0(x)   (value_zero_p(x.num))
 
#define NUL(x)   (value_zero_p(x.num))
 
#define NEGATIF(x)
 
#define POSITIF(x)
 
#define SUP1(x)
 
#define EGAL_MACRO(x, y, mult)
 
#define INF_MACRO(x, y, mult)   ((value_pos_p(mult(x.den,y.den)) && value_lt(mult(x.num,y.den),mult(x.den,y.num))) || (value_neg_p(mult(x.den,y.den)) && value_gt(mult(x.num,y.den),mult(x.den,y.num))))
 define INF_MACRO(x,y,mult) (value_lt(mult(x.num,y.den),mult(x.den,y.num))) DN: c'est pas assez pour la comparaison entre deux fractions, qu'est-ce qui se passe s'il y a seulement un denominateur negatif??? Ca donnera un resultat faux. More...
 
#define DIV_MACRO(x, y, z, mult)
 computes x = simplify(y/z) More...
 
#define MUL_MACRO(x, y, z, mult)
 computes x = simplify(y*z) More...
 
#define SUB_MACRO(X, A, B, mult)
 computes X = simplify(A-B) More...
 
#define FULL_PIVOT_MACRO_SIOUX(X, A, B, C, D, mult)
 computes X = A - B*C/D, trying to avoid arithmetic exceptions... More...
 
#define FULL_PIVOT_MACRO_DIRECT(X, A, B, C, D, mult)
 computes X = A - B*C/D, but does not try to avoid arithmetic exceptions More...
 
#define direct_p(v)   (value_lt(v,MAXVAL))
 
#define FULL_PIVOT_MACRO(X, A, B, C, D, mult)
 computes X = A - B*C/D, with a switch to use SIOUX or DIRECT thae rationale for the actual condition is quite fuzzy. More...
 
#define PARTIAL_PIVOT_MACRO_SIOUX(X, B, C, D, mult)
 idem if A==0 More...
 
#define PARTIAL_PIVOT_MACRO_DIRECT(X, B, C, D, mult)
 
#define PARTIAL_PIVOT_MACRO(X, B, C, D, mult)
 
#define PIVOT_MACRO(X, A, B, C, D, mult)
 Pivot : x = a - b c / d mult is used for multiplying values. More...
 
#define value_protected_mult(v, w)    value_protected_multiply(v,w,THROW(simplex_arithmetic_error))
 multiplies two Values of no arithmetic overflow, or throw exception. More...
 
#define MULT(RES, A, B)   RES=value_mult(A,B)
 Version with and without arithmetic exceptions... More...
 
#define MULTOFL(RES, A, B)   RES=value_protected_mult(A,B)
 
#define DIV(x, y, z)   DIV_MACRO(x,y,z,value_mult)
 
#define DIVOFL(x, y, z)   DIV_MACRO(x,y,z,value_protected_mult)
 
#define MUL(x, y, z)   MUL_MACRO(x,y,z,value_mult)
 
#define MULOFL(x, y, z)   MUL_MACRO(x,y,z,value_protected_mult)
 
#define SUB(X, A, B)   SUB_MACRO(X,A,B,value_mult)
 
#define SUBOFL(X, A, B)   SUB_MACRO(X,A,B,value_protected_mult)
 
#define PIVOT(X, A, B, C, D)   PIVOT_MACRO(X,A,B,C,D,value_mult)
 
#define PIVOTOFL(X, A, B, C, D)   PIVOT_MACRO(X,A,B,C,D,value_protected_mult)
 
#define EGAL(x, y)   EGAL_MACRO(x,y,value_mult)
 
#define EGALOFL(x, y)   EGAL_MACRO(x,y,value_protected_mult)
 
#define INF(x, y)   INF_MACRO(x,y,value_mult)
 
#define INFOFL(x, y)   INF_MACRO(x,y,value_protected_mult)
 

Enumerations

enum  { PTR_NIL = INTPTR_MIN+767 , INFINI = INTPTR_MAX-767 , MAX_VAR = 1971 , MAXVAL = 24 }
 Hmmm. More...
 

Functions

void frac_init (frac *f, int n)
 
void frac_simpl (Value *a, Value *b)
 
void frac_simplifie (frac *f)
 simplifie normalizes fraction f More...
 
void frac_div (frac *x, frac y, frac z, bool ofl_ctrl)
 
void frac_mul (frac *x, frac y, frac z, bool ofl_ctrl)
 computes x = simplify(y*z) More...
 
void frac_sub (frac *X, frac A, frac B, bool ofl_ctrl)
 
void full_pivot_sioux (frac *X, frac A, frac B, frac C, frac D, bool ofl_ctrl)
 
void full_pivot_direct (frac *X, frac A, frac B, frac C, frac D, bool ofl_ctrl)
 computes X = A - B*C/D, but does not try to avoid arithmetic exceptions More...
 
void full_pivot (frac *X, frac A, frac B, frac C, frac D, bool ofl_ctrl)
 
void partial_pivot_sioux (frac *X, frac B, frac C, frac D, bool ofl_ctrl)
 idem if A==0 More...
 
void partial_pivot_direct (frac *X, frac B, frac C, frac D, bool ofl_ctrl)
 
void partial_pivot (frac *X, frac B, frac C, frac D, bool ofl_ctrl)
 
void pivot (frac *X, frac A, frac B, frac C, frac D, bool ofl_ctrl)
 
static void __attribute__ ((unused))
 For debugging: More...
 
static void printfrac (frac x)
 
static int hash (Variable s)
 dump_tableau More...
 
bool sc_simplex_feasibility_ofl_ctrl_fixprec (Psysteme sc, int ofl_ctrl)
 fonction de calcul de la faisabilite' d'un systeme d'equations et d'inequations Auteur : Robert Mahl, Date : janvier 1994 More...
 

Variables

static int NB_EQ = 0
 test du simplex : Si on compile grace a` "make simp" dans le repertoire /projects/C3/Linear/Development/polyedre/Tests alors on peut tester l'execution dans le meme directory en faisant : make test_simp More...
 
static int NB_INEQ = 0
 
static frac frac0 ={(Value)0,(Value)1,0}
 
static int nbvariables
 Le nombre de variables visibles est : compteur-2 La i-eme variable visible a le numero : variables[i+1]=i (0 <= i < compteur-2) Le nombre de variables cachees est : nbvarables La i-eme variable cachee a le numero : variablescachees[i+1]=MAX_VAR+i-1 (0 <= i < nbvariables) More...
 
static int variablescachees [MAX_VAR]
 
static int variables [MAX_VAR]
 

Macro Definition Documentation

◆ AFF

#define AFF (   x,
 
)    {x.num=y.num; x.den=y.den;} /**x=y should be ok:-) */

Definition at line 224 of file sc_simplex_feasibility_fixprec.c.

◆ AFF_PX

#define AFF_PX (   x,
 
)    {x->num=y.num; x->den=y.den;}

Definition at line 225 of file sc_simplex_feasibility_fixprec.c.

◆ CREVARCACHEE

#define CREVARCACHEE
Value:
if (nbvariables ++ >= MAX_VAR) abort(); }
#define abort()
Definition: misc-local.h:53
static int variablescachees[MAX_VAR]
static int nbvariables
Le nombre de variables visibles est : compteur-2 La i-eme variable visible a le numero : variables[i+...

Definition at line 122 of file sc_simplex_feasibility_fixprec.c.

◆ CREVARVISIBLE

#define CREVARVISIBLE   variables[compteur-3]=compteur-2;

Definition at line 121 of file sc_simplex_feasibility_fixprec.c.

◆ DEBUG

#define DEBUG (   code)    { }

debug macros may be trigered with -DDEBUG{,1,2}

Definition at line 61 of file sc_simplex_feasibility_fixprec.c.

◆ DEBUG1

#define DEBUG1 (   code)    { }

Definition at line 68 of file sc_simplex_feasibility_fixprec.c.

◆ DEBUG2

#define DEBUG2 (   code)    { }

Definition at line 75 of file sc_simplex_feasibility_fixprec.c.

◆ DEBUG3

#define DEBUG3 (   code)    { }

Definition at line 82 of file sc_simplex_feasibility_fixprec.c.

◆ DIMENSION

#define DIMENSION   sc->dimension

Definition at line 118 of file sc_simplex_feasibility_fixprec.c.

◆ direct_p

#define direct_p (   v)    (value_lt(v,MAXVAL))

Definition at line 393 of file sc_simplex_feasibility_fixprec.c.

◆ DIV

#define DIV (   x,
  y,
 
)    DIV_MACRO(x,y,z,value_mult)

Definition at line 491 of file sc_simplex_feasibility_fixprec.c.

◆ DIV_MACRO

#define DIV_MACRO (   x,
  y,
  z,
  mult 
)
Value:
{tag("DIV_MACRO") \
if (value_zero_p(y.num)) \
{ \
MET_ZERO(x); \
} \
else \
{ \
if (value_zero_p(z.num)) \
{ \
fprintf(stderr,"ATTENTION : divided by zero number!"); \
MET_ZERO(x); \
} \
else \
{ \
x.num=mult(y.num,z.den); \
x.den=mult(y.den,z.num); \
SIMPLIFIE(x); \
} \
} \
}
#define value_zero_p(val)
#define tag(x)
for tracing macros after expansion:
static char * x
Definition: split_file.c:159

computes x = simplify(y/z)

define DIV_MACRO(x,y,z,mult) \ {tag("DIV_MACRO") \ if (value_zero_p(y.num)) \ { \ MET_ZERO(x); \ } \ else \ { \ x.num=mult(y.num,z.den); \ x.den=mult(y.den,z.num); \ SIMPLIFIE(x); \ } \ } DN: This macro DIV_MACRO doesn't test if z = 0, then x = y/z means x.num = y.num*z.den and x.den = 0. We better add the test : if z = 0 then x.num = 0 and x.den = 1 We try to avoid the denominator equal to 0.

Definition at line 292 of file sc_simplex_feasibility_fixprec.c.

◆ DIVOFL

#define DIVOFL (   x,
  y,
 
)    DIV_MACRO(x,y,z,value_protected_mult)

Definition at line 492 of file sc_simplex_feasibility_fixprec.c.

◆ EGAL

#define EGAL (   x,
 
)    EGAL_MACRO(x,y,value_mult)

Definition at line 503 of file sc_simplex_feasibility_fixprec.c.

◆ EGAL0

#define EGAL0 (   x)    (value_zero_p(x.num))

Definition at line 240 of file sc_simplex_feasibility_fixprec.c.

◆ EGAL1

#define EGAL1 (   x)    (value_eq(x.num,x.den))

Definition at line 239 of file sc_simplex_feasibility_fixprec.c.

◆ EGAL_MACRO

#define EGAL_MACRO (   x,
  y,
  mult 
)
Value:
((value_zero_p(x.num) && value_zero_p(y.num)) || \
(value_notzero_p(x.den) && value_notzero_p(y.den) && \
value_eq(mult(x.num,y.den),mult(x.den,y.num))))
#define value_notzero_p(val)

Definition at line 255 of file sc_simplex_feasibility_fixprec.c.

◆ EGALOFL

#define EGALOFL (   x,
 
)    EGAL_MACRO(x,y,value_protected_mult)

Definition at line 504 of file sc_simplex_feasibility_fixprec.c.

◆ FULL_PIVOT_MACRO

#define FULL_PIVOT_MACRO (   X,
  A,
  B,
  C,
  D,
  mult 
)
Value:
{ tag("FULL_PIVOT") \
if (direct_p(A.den) && direct_p(B.den) && \
direct_p(C.den) && direct_p(value_abs(D.num))) \
{ \
FULL_PIVOT_MACRO_DIRECT(X,A,B,C,D,mult); \
} \
else \
{ \
FULL_PIVOT_MACRO_SIOUX(X,A,B,C,D,mult); \
} \
}
#define value_abs(val)
#define B(A)
Definition: iabrev.h:61
#define D(A)
Definition: iabrev.h:56
#define X
Definition: r1.c:42
#define direct_p(v)
Definition: pip__tab.h:25

computes X = A - B*C/D, with a switch to use SIOUX or DIRECT thae rationale for the actual condition is quite fuzzy.

Definition at line 398 of file sc_simplex_feasibility_fixprec.c.

◆ FULL_PIVOT_MACRO_DIRECT

#define FULL_PIVOT_MACRO_DIRECT (   X,
  A,
  B,
  C,
  D,
  mult 
)
Value:
{ \
Value v; tag("FULL_PIVOT_DIRECT") \
X.num = mult(A.num,B.den); \
X.num = mult(X.num,C.den); \
X.num = mult(X.num,D.num); \
v = mult(A.den,B.num); \
v = mult(v,C.num); \
v = mult(v,D.den); \
value_substract(X.num,v); \
X.den = mult(A.den,B.den); \
X.den = mult(X.den,C.den); \
X.den = mult(X.den,D.num); \
SIMPLIFIE(X); \
}

computes X = A - B*C/D, but does not try to avoid arithmetic exceptions

Definition at line 377 of file sc_simplex_feasibility_fixprec.c.

◆ FULL_PIVOT_MACRO_SIOUX

#define FULL_PIVOT_MACRO_SIOUX (   X,
  A,
  B,
  C,
  D,
  mult 
)
Value:
{ \
frac u,v,w; tag("FULL_PIVOT_SIOUX") \
AFF(u,B); AFF(v,C); INV_ZERO_CTRL(w,D); /**u*v*w == B*C/D */ \
SIMPL(u.num,v.den); SIMPL(u.num,w.den); \
SIMPL(v.num,u.den); SIMPL(v.num,w.den); \
SIMPL(w.num,u.den); SIMPL(w.num,v.den); \
u.num = mult(u.num,v.num); /**u*=v */ \
u.den = mult(u.den,v.den); \
u.num = mult(u.num,w.num); /**u*=w */ \
u.den = mult(u.den,w.den); \
SUB_MACRO(X,A,u,mult); \
}
#define AFF(x, y)
#define INV_ZERO_CTRL(x, y)
??? value_zero_p(y.num)? Then x.num != VALUE_ZERO and x.den = VALUE_ZERO, it's not good at all.
#define SIMPL(a, b)
SIMPL normalizes rational a/b (b<>0): divides by gcd(a,b) and returns with b>0 note that there should...

computes X = A - B*C/D, trying to avoid arithmetic exceptions...

Definition at line 361 of file sc_simplex_feasibility_fixprec.c.

◆ G

#define G (   j,
  a,
 
)
Value:
{tag("G") \
j=b; \
if (value_gt(b,VALUE_ONE)) \
{ \
Value i=a, k; \
while(value_notzero_p(k=value_mod(i,j))) \
i=j, j=k; \
} \
if (value_neg_p(j)) \
value_oppose(j); \
}
#define value_gt(v1, v2)
#define VALUE_ONE
#define value_mod(v1, v2)
#define value_neg_p(val)

maybe most of them should be functions?

G computes j=gcd(a,b) assuming b>0 and better with a>b. there can be no artihmetic errors.

Definition at line 136 of file sc_simplex_feasibility_fixprec.c.

◆ GCD

#define GCD (   j,
  a,
 
)
Value:
{tag("GCD") \
if (value_gt(a,b)) \
{ G(j,a,b); } \
else \
{ G(j,b,a); } \
}
#define G(j, a, b)
maybe most of them should be functions?

Definition at line 149 of file sc_simplex_feasibility_fixprec.c.

◆ GCD_ZERO_CTRL

#define GCD_ZERO_CTRL (   j,
  a,
 
)
Value:
{tag("GCD_ZERO_CTRL") \
if ((value_notzero_p(a)) && (value_notzero_p(b))) \
{ GCDZZN(j,a,b);} \
else \
{fprintf(stderr,"********************************************************************Error : GCD of number zero !"); \
j = (VALUE_ONE);} \
}
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
#define GCDZZN(j, a, b)

Definition at line 181 of file sc_simplex_feasibility_fixprec.c.

◆ GCDZZN

#define GCDZZN (   j,
  a,
 
)
Value:
{tag("GCDZZN") \
Value i,k; \
i = (value_absolute(a)), k = (value_absolute(b)); \
while(value_notzero_p(j=value_mod(i,k))) \
i=k, k=j; \
j = k; \
}
#define value_absolute(ref)

Definition at line 172 of file sc_simplex_feasibility_fixprec.c.

◆ INF

#define INF (   x,
 
)    INF_MACRO(x,y,value_mult)

Definition at line 506 of file sc_simplex_feasibility_fixprec.c.

◆ INF_MACRO

#define INF_MACRO (   x,
  y,
  mult 
)    ((value_pos_p(mult(x.den,y.den)) && value_lt(mult(x.num,y.den),mult(x.den,y.num))) || (value_neg_p(mult(x.den,y.den)) && value_gt(mult(x.num,y.den),mult(x.den,y.num))))

define INF_MACRO(x,y,mult) (value_lt(mult(x.num,y.den),mult(x.den,y.num))) DN: c'est pas assez pour la comparaison entre deux fractions, qu'est-ce qui se passe s'il y a seulement un denominateur negatif??? Ca donnera un resultat faux.

a/b < c/d <=> if b*d > 0 then a*d < b*c else a*d < b*c

Definition at line 266 of file sc_simplex_feasibility_fixprec.c.

◆ INFOFL

#define INFOFL (   x,
 
)    INF_MACRO(x,y,value_protected_mult)

Definition at line 507 of file sc_simplex_feasibility_fixprec.c.

◆ INV

#define INV (   x,
 
)    {x.num=y.den; x.den=y.num;} /**x=1/y */

Definition at line 226 of file sc_simplex_feasibility_fixprec.c.

◆ INV_ZERO_CTRL

#define INV_ZERO_CTRL (   x,
 
)    {if (value_zero_p(y.num)) {fprintf(stderr,"ERROR : inverse of fraction zero !"); x.num = VALUE_ZERO; x.den = VALUE_ONE;} else {INV(x,y)}}

??? value_zero_p(y.num)? Then x.num != VALUE_ZERO and x.den = VALUE_ZERO, it's not good at all.

(assuming y.den != VALUE_ZERO) This means : test if y = 0 then x = 0 else x = 1/y Change in line 286 : DN.

Definition at line 232 of file sc_simplex_feasibility_fixprec.c.

◆ MET_UN

#define MET_UN (   f)    {f.num=VALUE_ONE; f.den=VALUE_ONE;}

Definition at line 237 of file sc_simplex_feasibility_fixprec.c.

◆ MET_ZERO

#define MET_ZERO (   f)    {f.num=VALUE_ZERO; f.den=VALUE_ONE;}

Definition at line 236 of file sc_simplex_feasibility_fixprec.c.

◆ METINFINI

#define METINFINI (   f)    {f.num=VALUE_MAX; f.den=VALUE_ONE;}

Definition at line 235 of file sc_simplex_feasibility_fixprec.c.

◆ MUL

#define MUL (   x,
  y,
 
)    MUL_MACRO(x,y,z,value_mult)

Definition at line 494 of file sc_simplex_feasibility_fixprec.c.

◆ MUL_MACRO

#define MUL_MACRO (   x,
  y,
  z,
  mult 
)
Value:
{tag("MUL_MACRO") \
if(value_zero_p(y.num) || value_zero_p(z.num)) \
MET_ZERO(x) \
else \
{ \
x.num=mult(y.num,z.num); \
x.den=mult(y.den,z.den); \
SIMPLIFIE(x); \
} \
}

computes x = simplify(y*z)

Definition at line 317 of file sc_simplex_feasibility_fixprec.c.

◆ MULOFL

#define MULOFL (   x,
  y,
 
)    MUL_MACRO(x,y,z,value_protected_mult)

Definition at line 495 of file sc_simplex_feasibility_fixprec.c.

◆ MULT

#define MULT (   RES,
  A,
  B 
)    RES=value_mult(A,B)

Version with and without arithmetic exceptions...

Definition at line 488 of file sc_simplex_feasibility_fixprec.c.

◆ MULTOFL

#define MULTOFL (   RES,
  A,
  B 
)    RES=value_protected_mult(A,B)

Definition at line 489 of file sc_simplex_feasibility_fixprec.c.

◆ NEGATIF

#define NEGATIF (   x)
Value:
((value_neg_p(x.num) && value_pos_p(x.den)) || \
(value_pos_p(x.num) && value_neg_p(x.den)))
#define value_pos_p(val)

Definition at line 243 of file sc_simplex_feasibility_fixprec.c.

◆ NUL

#define NUL (   x)    (value_zero_p(x.num))

Definition at line 241 of file sc_simplex_feasibility_fixprec.c.

◆ NUMERO

#define NUMERO   hashtable[h].numero

Definition at line 119 of file sc_simplex_feasibility_fixprec.c.

◆ PARTIAL_PIVOT_MACRO

#define PARTIAL_PIVOT_MACRO (   X,
  B,
  C,
  D,
  mult 
)
Value:
{ \
if (direct_p(B.den) && direct_p(C.den) && direct_p(D.num)) \
{ \
PARTIAL_PIVOT_MACRO_DIRECT(X,B,C,D,mult); \
} \
else \
{ \
PARTIAL_PIVOT_MACRO_SIOUX(X,B,C,D,mult); \
} \
}

Definition at line 431 of file sc_simplex_feasibility_fixprec.c.

◆ PARTIAL_PIVOT_MACRO_DIRECT

#define PARTIAL_PIVOT_MACRO_DIRECT (   X,
  B,
  C,
  D,
  mult 
)
Value:
{ tag("PARTIAL_PIVOT_DIRECT") \
X.num = mult(B.num,C.num); \
X.num = mult(X.num,D.den); \
value_oppose(X.num); \
X.den = mult(B.den,C.den); \
X.den = mult(X.den,D.num); \
SIMPLIFIE(X); \
}

Definition at line 421 of file sc_simplex_feasibility_fixprec.c.

◆ PARTIAL_PIVOT_MACRO_SIOUX

#define PARTIAL_PIVOT_MACRO_SIOUX (   X,
  B,
  C,
  D,
  mult 
)
Value:
{ tag("PARTIAL_PIVOT_SIOUX") \
frac u; \
MUL_MACRO(u,B,C,mult); /**u=simplify(b*c) */ \
DIV_MACRO(X,u,D,mult); /**x=simplify(u/d) */ \
value_oppose(X.num); /**x=-x */ \
}

idem if A==0

Definition at line 413 of file sc_simplex_feasibility_fixprec.c.

◆ PIVOT

#define PIVOT (   X,
  A,
  B,
  C,
  D 
)    PIVOT_MACRO(X,A,B,C,D,value_mult)

Definition at line 500 of file sc_simplex_feasibility_fixprec.c.

◆ PIVOT_MACRO

#define PIVOT_MACRO (   X,
  A,
  B,
  C,
  D,
  mult 
)
Value:
{ if (value_zero_p(D.num)) fprintf(stderr,"division of zero!!!"); \
DEBUG3(fprintf(stdout, "pivot on: "); \
printfrac(A); printfrac(B); printfrac(C); printfrac(D)); \
if (value_zero_p(A.num))/**a==0? */ \
{ \
if (value_zero_p(B.num) || value_zero_p(C.num) || value_zero_p(D.den)) \
{ MET_ZERO(X);} \
else /**b*c/d != 0, calculons! */ \
{ PARTIAL_PIVOT_MACRO(X,B,C,D,mult);} \
} \
else /**a!=0 */ \
if (value_zero_p(B.num) || value_zero_p(C.num) || value_zero_p(D.den)) \
{ AFF(X,A);} \
else /** b*c/d != 0, calculons! */ \
if (value_one_p(D.num) && value_one_p(A.den) && \
value_one_p(B.den) && value_one_p(C.den)) \
{ /**no den to compute */ \
Value v = mult(B.num,C.num); \
v = mult(v,D.den); \
X.num=value_minus(A.num,v); \
X.den=VALUE_ONE; \
} \
else /**well, we must compute the full formula! */ \
{ FULL_PIVOT_MACRO(X,A,B,C,D,mult);} \
DEBUG3(fprintf(stdout, " = "); printfrac(X); fprintf(stdout, "\n")); \
}
#define value_minus(v1, v2)
#define value_one_p(val)
#define MET_ZERO(f)
#define FULL_PIVOT_MACRO(X, A, B, C, D, mult)
computes X = A - B*C/D, with a switch to use SIOUX or DIRECT thae rationale for the actual condition ...
#define PARTIAL_PIVOT_MACRO(X, B, C, D, mult)
static void printfrac(frac x)

Pivot : x = a - b c / d mult is used for multiplying values.

the macro has changed a lot, for indentation and so... FC. DN: Why don't we test d.num = 0 ? (meanwhile, we do test d.den = 0)

Definition at line 449 of file sc_simplex_feasibility_fixprec.c.

◆ PIVOTOFL

#define PIVOTOFL (   X,
  A,
  B,
  C,
  D 
)    PIVOT_MACRO(X,A,B,C,D,value_protected_mult)

Definition at line 501 of file sc_simplex_feasibility_fixprec.c.

◆ POSITIF

#define POSITIF (   x)
Value:
((value_pos_p(x.num) && value_pos_p(x.den)) || \
(value_neg_p(x.num) && value_neg_p(x.den)))

Definition at line 247 of file sc_simplex_feasibility_fixprec.c.

◆ SIMPL

#define SIMPL (   a,
 
)
Value:
{ \
if (value_notone_p(b) && value_notone_p(a) && \
{ \
register Value i=a, j=b, k; \
while (value_notzero_p(k=value_mod(i,j))) \
i=j, j=k; \
value_division(a,j), value_division(b,j); \
} \
if (value_neg_p(b)) \
value_oppose(a), value_oppose(b); \
}
#define value_oppose(ref)
#define value_notone_p(val)
int Value
#define value_notmone_p(val)
#define value_division(ref, val)

SIMPL normalizes rational a/b (b<>0): divides by gcd(a,b) and returns with b>0 note that there should be no arithmetic exceptions within this macro: (well, only uminus may have trouble for VALUE_MIN...) ??? a==0 ? then a = a/b = 0 and b = b/b = 1.

Definition at line 197 of file sc_simplex_feasibility_fixprec.c.

◆ SIMPLIFIE

#define SIMPLIFIE (   f)
Value:
{tag("SIMPLIFIE") \
if (value_zero_p(f.den)) \
{ MET_ZERO(f);} \
else { \
if (value_zero_p(f.num)) \
f.den = VALUE_ONE; \
SIMPL(f.num,f.den); } \
}
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15

SIMPLIFIE normalizes fraction f.

Definition at line 213 of file sc_simplex_feasibility_fixprec.c.

◆ SOLUBLE

#define SOLUBLE (   N)    soluble=N;goto FINSIMPLEX ;

Definition at line 120 of file sc_simplex_feasibility_fixprec.c.

◆ SUB

#define SUB (   X,
  A,
  B 
)    SUB_MACRO(X,A,B,value_mult)

Definition at line 497 of file sc_simplex_feasibility_fixprec.c.

◆ SUB_MACRO

#define SUB_MACRO (   X,
  A,
  B,
  mult 
)
Value:
{ tag("SUB_MACRO") \
if (value_zero_p(A.num)) \
X.num = value_uminus(B.num), \
X.den = B.den; \
else if (value_zero_p(B.num)) \
{ AFF(X, A); } \
else if (value_eq(A.den,B.den)) \
{ \
X.num = value_minus(A.num,B.num); \
X.den = A.den; \
if (value_notone_p(A.den)) \
{ SIMPLIFIE(X);} \
} \
else /**must compute the stuff: */ \
{ \
Value ad=A.den, bd=B.den, gd, v; \
GCD_ZERO_CTRL(gd,ad,bd); \
if (value_notone_p(gd)) value_division(ad,gd), value_division(bd,gd); \
X.num = mult(A.num,bd); \
v = mult(B.num,ad); \
value_substract(X.num,v); \
v = mult(ad,bd); \
X.den = mult(v,gd); \
SIMPLIFIE(X); \
} \
}
#define value_uminus(val)
unary operators on values
#define value_eq(v1, v2)
bool operators on values
#define SIMPLIFIE(f)
SIMPLIFIE normalizes fraction f.

computes X = simplify(A-B)

Definition at line 331 of file sc_simplex_feasibility_fixprec.c.

◆ SUBOFL

#define SUBOFL (   X,
  A,
  B 
)    SUB_MACRO(X,A,B,value_protected_mult)

Definition at line 498 of file sc_simplex_feasibility_fixprec.c.

◆ SUP1

#define SUP1 (   x)
Value:
((value_pos_p(x.num) && value_pos_p(x.den) && value_gt(x.num,x.den)) || \
(value_neg_p(x.num) && value_neg_p(x.den) && value_gt(x.den,x.num)))

Definition at line 251 of file sc_simplex_feasibility_fixprec.c.

◆ tag

#define tag (   x)    /**printf(x); */

for tracing macros after expansion:

Definition at line 127 of file sc_simplex_feasibility_fixprec.c.

◆ value_protected_mult

#define value_protected_mult (   v,
 
)     value_protected_multiply(v,w,THROW(simplex_arithmetic_error))

multiplies two Values of no arithmetic overflow, or throw exception.

this version is local to the simplex. note that under some defined macros value_mult can expand to value_protected_mult, which would be ok.

Definition at line 483 of file sc_simplex_feasibility_fixprec.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

Hmmm.

To be compatible with some weird old 16-bit constants... RK

Enumerator
PTR_NIL 
INFINI 
MAX_VAR 
MAXVAL 

nombre max de variables

seuil au dela duquel on se mefie d'un overflow

Definition at line 104 of file sc_simplex_feasibility_fixprec.c.

104  {
105  PTR_NIL = INTPTR_MIN+767,
106  INFINI = INTPTR_MAX-767,
107  MAX_VAR = 1971, /* nombre max de variables */
108  /* seuil au dela duquel on se mefie d'un overflow
109  */
110 #if defined(LINEAR_VALUE_IS_LONGLONG)
111  MAXVAL = 576,
112 #else
113  MAXVAL = 24
114 #endif
115 };
@ MAXVAL
nombre max de variables
#define INTPTR_MIN
7.18.2.4.
Definition: stdint.in.h:471
#define INTPTR_MAX
Definition: stdint.in.h:472

Function Documentation

◆ __attribute__()

static void __attribute__ ( (unused)  )
static

For debugging:

Definition at line 812 of file sc_simplex_feasibility_fixprec.c.

813  {
814  int i;
815  for(i=0;i<MAX_VAR;i++)
816  if(VARIABLE_DEFINED_P(hashtable[i].nom))
817  printf("%s %d ", (char *) hashtable[i].nom, hashtable[i].numero),
818  print_Value(hashtable[i].val),
819  printf("\n");
820 }
void print_Value(Value)
io.c
Definition: io.c:37
int printf()
#define VARIABLE_DEFINED_P(v)
Definition: vecteur-local.h:66

References MAX_VAR, print_Value(), printf(), and VARIABLE_DEFINED_P.

+ Here is the call graph for this function:

◆ frac_div()

void frac_div ( frac x,
frac  y,
frac  z,
bool  ofl_ctrl 
)

Definition at line 567 of file sc_simplex_feasibility_fixprec.c.

568 {tag("FRAC_DIV")
569  if (value_zero_p(y.num))
570  {
571  MET_ZERO((*x));
572  }
573  else
574  {
575  if (value_zero_p(z.num))
576  {
577  fprintf(stderr,"ATTENTION : divided by zero number!");
578  MET_ZERO((*x));
579  }
580  else
581  {
582  if (ofl_ctrl == FWD_OFL_CTRL) {
583  x->num=value_protected_mult(y.num,z.den);
584  x->den=value_protected_mult(y.den,z.num);
585  }
586  else {
587  x->num=value_mult(y.num,z.den);
588  x->den=value_mult(y.den,z.num);
589  }
590  frac_simplifie(x);
591  }
592  }
593 }
#define value_mult(v, w)
whether the default is protected or not this define makes no sense any more...
static int num
Definition: bourdoncle.c:137
if(!(yy_init))
Definition: genread_lex.c:1029
#define value_protected_mult(v, w)
multiplies two Values of no arithmetic overflow, or throw exception.
void frac_simplifie(frac *f)
simplifie normalizes fraction f
#define FWD_OFL_CTRL

References frac::den, fprintf(), frac_simplifie(), FWD_OFL_CTRL, MET_ZERO, frac::num, tag, value_mult, value_protected_mult, value_zero_p, and x.

Referenced by partial_pivot_sioux(), and sc_simplex_feasibility_ofl_ctrl_fixprec().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ frac_init()

void frac_init ( frac f,
int  n 
)

Definition at line 523 of file sc_simplex_feasibility_fixprec.c.

524 {
525  int i;
526  for (i=0;i<n;i++) {
527  f[i].num = (Value)0;
528  f[i].den = (Value)1;
529  f[i].numero = 0;
530  }
531 }

References f().

Referenced by sc_simplex_feasibility_ofl_ctrl_fixprec().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ frac_mul()

void frac_mul ( frac x,
frac  y,
frac  z,
bool  ofl_ctrl 
)

computes x = simplify(y*z)

Definition at line 598 of file sc_simplex_feasibility_fixprec.c.

599 {tag("FRAC_MUL")
601  MET_ZERO((*x))
602  else
603  {
604  if (ofl_ctrl == FWD_OFL_CTRL) {
605  x->num=value_protected_mult(y.num,z.num);
606  x->den=value_protected_mult(y.den,z.den);
607  }
608  else {
609  x->num=value_mult(y.num,z.num);
610  x->den=value_mult(y.den,z.den);
611  }
612  frac_simplifie(x);
613  }
614 }
else
Definition: set.c:239

References frac::den, frac_simplifie(), FWD_OFL_CTRL, MET_ZERO, frac::num, tag, value_mult, value_protected_mult, value_zero_p, and x.

Referenced by partial_pivot_sioux().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ frac_simpl()

void frac_simpl ( Value a,
Value b 
)

Definition at line 533 of file sc_simplex_feasibility_fixprec.c.

534 {
535  if (value_notone_p(*b) && value_notone_p(*a) &&
536  value_notmone_p(*b) && value_notmone_p(*a))
537  {
538  register long long int lli = ABS(VALUE_TO_LONG(*a)), llj= ABS(VALUE_TO_LONG(*b)),k;
539  if (lli<llj) {
540  long long int tmp = lli;
541  lli=llj;llj=tmp;}
542 
543  while ((k=lli%llj) !=0)
544  lli=llj, llj=k;
545  value_division(*a,llj), value_division(*b,llj);
546  }
547  if (value_neg_p(*b))
548  value_oppose(*a), value_oppose(*b);
549 }
#define ABS(x)
was: #define value_mult(v,w) value_direct_multiply(v,w) #define value_product(v,w) value_direct_produ...
#define VALUE_TO_LONG(val)

References ABS, value_division, value_neg_p, value_notmone_p, value_notone_p, value_oppose, and VALUE_TO_LONG.

Referenced by frac_simplifie(), and full_pivot_sioux().

+ Here is the caller graph for this function:

◆ frac_simplifie()

void frac_simplifie ( frac f)

simplifie normalizes fraction f

Definition at line 553 of file sc_simplex_feasibility_fixprec.c.

554 {
555  tag("frac_simplifie")
556  if (value_zero_p(f->den))
557  {
558  MET_ZERO((*f));}
559  else {
560  if (value_zero_p(f->num))
561  f->den = VALUE_ONE;
562  else
563  frac_simpl(&(f->num),&(f->den));
564  }
565 }
void frac_simpl(Value *a, Value *b)

References f(), frac_simpl(), MET_ZERO, tag, VALUE_ONE, and value_zero_p.

Referenced by frac_div(), frac_mul(), frac_sub(), full_pivot_direct(), partial_pivot_direct(), and sc_simplex_feasibility_ofl_ctrl_fixprec().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ frac_sub()

void frac_sub ( frac X,
frac  A,
frac  B,
bool  ofl_ctrl 
)

must compute the stuff:

Definition at line 615 of file sc_simplex_feasibility_fixprec.c.

616 { tag("FRAC_SUB")
617  if (value_zero_p(A.num))
618  X->num = value_uminus(B.num),
619  X->den = B.den;
621  { AFF_PX(X, A); }
622  else if (value_eq(A.den,B.den))
623  {
624  X->num = value_minus(A.num,B.num);
625  X->den = A.den;
626  if (value_notone_p(A.den))
627  { frac_simplifie(X);}
628  }
629  else /* must compute the stuff: */
630  {
631  Value ad=A.den, bd=B.den, gd, v;
632  GCD_ZERO_CTRL(gd,ad,bd);
633  if (value_notone_p(gd)) value_division(ad,gd), value_division(bd,gd);
634  if (ofl_ctrl == FWD_OFL_CTRL) {
635  X->num = value_protected_mult(A.num,bd);
636  v = value_protected_mult(B.num,ad);
637  value_substract(X->num,v);
638  v =value_protected_mult(ad,bd);
639  X->den = value_protected_mult(v,gd);
640  }
641  else {
642  X->num = value_mult(A.num,bd);
643  v = value_mult(B.num,ad);
644  value_substract(X->num,v);
645  v =value_mult(ad,bd);
646  X->den = value_mult(v,gd);
647  }
648  frac_simplifie(X);
649  }
650 }
#define value_substract(ref, val)
#define GCD_ZERO_CTRL(j, a, b)
#define AFF_PX(x, y)

References AFF_PX, B, frac_simplifie(), FWD_OFL_CTRL, GCD_ZERO_CTRL, tag, value_division, value_eq, value_minus, value_mult, value_notone_p, value_protected_mult, value_substract, value_uminus, value_zero_p, and X.

Referenced by full_pivot_sioux().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ full_pivot()

void full_pivot ( frac X,
frac  A,
frac  B,
frac  C,
frac  D,
bool  ofl_ctrl 
)

Definition at line 710 of file sc_simplex_feasibility_fixprec.c.

711 { tag("FULL_PIVOT")
712 
713  if (direct_p(A.den) && direct_p(B.den) &&
714  direct_p(C.den) && direct_p(value_abs(D.num)))
715  {
716  full_pivot_direct(X,A,B,C,D,ofl_ctrl);
717  }
718  else
719  {
720  full_pivot_sioux(X,A,B,C,D,ofl_ctrl);
721  }
722 }
void full_pivot_direct(frac *X, frac A, frac B, frac C, frac D, bool ofl_ctrl)
computes X = A - B*C/D, but does not try to avoid arithmetic exceptions
void full_pivot_sioux(frac *X, frac A, frac B, frac C, frac D, bool ofl_ctrl)

References B, D, frac::den, direct_p, full_pivot_direct(), full_pivot_sioux(), tag, value_abs, and X.

Referenced by pivot().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ full_pivot_direct()

void full_pivot_direct ( frac X,
frac  A,
frac  B,
frac  C,
frac  D,
bool  ofl_ctrl 
)

computes X = A - B*C/D, but does not try to avoid arithmetic exceptions

Definition at line 681 of file sc_simplex_feasibility_fixprec.c.

682 {
683  Value v; tag("FULL_PIVOT_DIRECT")
684  if (ofl_ctrl == FWD_OFL_CTRL) {
685  X->num = value_protected_mult(A.num,B.den);
686  X->num = value_protected_mult(X->num,C.den);
687  X->num = value_protected_mult(X->num,D.num);
688  v = value_protected_mult(A.den,B.num);
689  v = value_protected_mult(v,C.num);
690  v = value_protected_mult(v,D.den);
691  value_substract(X->num,v);
692  X->den = value_protected_mult(A.den,B.den);
693  X->den = value_protected_mult(X->den,C.den);
694  X->den = value_protected_mult(X->den,D.num);
695  }
696  else {
697  X->num = value_mult(A.num,B.den);
698  X->num = value_mult(X->num,C.den);
699  X->num = value_mult(X->num,D.num);
700  v = value_mult(A.den,B.num);
701  v = value_mult(v,C.num);
702  v = value_mult(v,D.den);
703  value_substract(X->num,v);
704  X->den = value_mult(A.den,B.den);
705  X->den = value_mult(X->den,C.den);
706  X->den = value_mult(X->den,D.num);
707  }
708  frac_simplifie(X);
709 }

References B, D, frac::den, frac_simplifie(), FWD_OFL_CTRL, frac::num, tag, value_mult, value_protected_mult, value_substract, and X.

Referenced by full_pivot().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ full_pivot_sioux()

void full_pivot_sioux ( frac X,
frac  A,
frac  B,
frac  C,
frac  D,
bool  ofl_ctrl 
)

u*v*w == B*C/D

u*=v

u*=w

u*=v

u*=w

Definition at line 652 of file sc_simplex_feasibility_fixprec.c.

653 {
654  frac u,v,w;
655  tag("FULL_PIVOT_SIOUX")
656  AFF(u,B); AFF(v,C); INV_ZERO_CTRL(w,D); /* u*v*w == B*C/D */
657  frac_simpl(&(u.num),&(v.den));
658  frac_simpl(&(u.num),&(w.den));
659  frac_simpl(&(v.num),&(u.den));
660  frac_simpl(&(v.num),&(w.den));
661  frac_simpl(&(w.num),&(u.den));
662  frac_simpl(&(w.num),&(v.den));
663  if (ofl_ctrl == FWD_OFL_CTRL) {
664  u.num = value_protected_mult(u.num,v.num); /* u*=v */
665  u.den = value_protected_mult(u.den,v.den);
666  u.num =value_protected_mult(u.num,w.num); /* u*=w */
667  u.den =value_protected_mult(u.den,w.den);
668  }
669  else {
670  u.num = value_mult(u.num,v.num); /* u*=v */
671  u.den = value_mult(u.den,v.den);
672  u.num =value_mult(u.num,w.num); /* u*=w */
673  u.den =value_mult(u.den,w.den);
674  }
675  frac_sub(X,A,u,ofl_ctrl);
676 
677 }
void frac_sub(frac *X, frac A, frac B, bool ofl_ctrl)

References AFF, B, D, frac::den, frac_simpl(), frac_sub(), FWD_OFL_CTRL, INV_ZERO_CTRL, frac::num, tag, value_mult, value_protected_mult, and X.

Referenced by full_pivot().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ hash()

static int hash ( Variable  s)
static

dump_tableau

calcule le hashcode d'un pointeur sous forme d'un nombre compris entre 0 et MAX_VAR

Definition at line 867 of file sc_simplex_feasibility_fixprec.c.

868 { long l ;
869  l=(long)s % MAX_VAR ;
870  return l ;
871 }

References MAX_VAR.

Referenced by sc_min(), and sc_simplex_feasibility_ofl_ctrl_fixprec().

+ Here is the caller graph for this function:

◆ partial_pivot()

void partial_pivot ( frac X,
frac  B,
frac  C,
frac  D,
bool  ofl_ctrl 
)

Definition at line 755 of file sc_simplex_feasibility_fixprec.c.

756 {
757 
758  if (direct_p(B.den) && direct_p(C.den) && direct_p(D.num))
759  {
760  partial_pivot_direct(X,B,C,D,ofl_ctrl);
761  }
762  else
763  {
764  partial_pivot_sioux(X,B,C,D,ofl_ctrl);
765  }
766 }
void partial_pivot_direct(frac *X, frac B, frac C, frac D, bool ofl_ctrl)
void partial_pivot_sioux(frac *X, frac B, frac C, frac D, bool ofl_ctrl)
idem if A==0

References B, D, frac::den, direct_p, partial_pivot_direct(), partial_pivot_sioux(), and X.

Referenced by pivot().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ partial_pivot_direct()

void partial_pivot_direct ( frac X,
frac  B,
frac  C,
frac  D,
bool  ofl_ctrl 
)

Definition at line 736 of file sc_simplex_feasibility_fixprec.c.

737 { tag("PARTIAL_PIVOT_DIRECT")
738  if (ofl_ctrl == FWD_OFL_CTRL) {
739  X->num = value_protected_mult(B.num,C.num);
740  X->num = value_protected_mult(X->num,D.den);
741  value_oppose(X->num);
742  X->den =value_protected_mult(B.den,C.den);
743  X->den = value_protected_mult(X->den,D.num);
744  }
745  else {
746  X->num = value_mult(B.num,C.num);
747  X->num = value_mult(X->num,D.den);
748  value_oppose(X->num);
749  X->den =value_mult(B.den,C.den);
750  X->den = value_mult(X->den,D.num);
751  }
752  frac_simplifie(X);
753 }

References B, D, frac::den, frac_simplifie(), FWD_OFL_CTRL, frac::num, tag, value_mult, value_oppose, value_protected_mult, and X.

Referenced by partial_pivot().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ partial_pivot_sioux()

void partial_pivot_sioux ( frac X,
frac  B,
frac  C,
frac  D,
bool  ofl_ctrl 
)

idem if A==0

u=simplify(b*c)

x=simplify(u/d)

x=-x

Definition at line 726 of file sc_simplex_feasibility_fixprec.c.

727 {
728  tag("PARTIAL_PIVOT_SIOUX")
729  frac u = {(Value)0,(Value)1,0};
730 
731  frac_mul(&u,B,C,ofl_ctrl); /* u=simplify(b*c) */
732  frac_div(X,u,D,ofl_ctrl); /* x=simplify(u/d) */
733  value_oppose(X->num); /* x=-x */
734 }
void frac_div(frac *x, frac y, frac z, bool ofl_ctrl)
void frac_mul(frac *x, frac y, frac z, bool ofl_ctrl)
computes x = simplify(y*z)

References B, D, frac_div(), frac_mul(), tag, value_oppose, and X.

Referenced by partial_pivot().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pivot()

void pivot ( frac X,
frac  A,
frac  B,
frac  C,
frac  D,
bool  ofl_ctrl 
)

a==0?

b*c/d != 0, calculons!

a!=0

b*c/d != 0, calculons!

no den to compute

well, we must compute the full formula!

Definition at line 770 of file sc_simplex_feasibility_fixprec.c.

771 {
772  if (value_zero_p(D.num))
773  fprintf(stderr,"division of zero!!!");
774  DEBUG3(fprintf(stdout, "pivot on: ");
775  printfrac(A);
776  printfrac(B);
777  printfrac(C);
778  printfrac(D));
779  if (value_zero_p(A.num))/* a==0? */
780  {
781  if (value_zero_p(B.num) || value_zero_p(C.num) || value_zero_p(D.den))
782  { MET_ZERO((*X)); }
783  else /* b*c/d != 0, calculons! */
784  { partial_pivot(X,B,C,D,ofl_ctrl);}
785  }
786  else /* a!=0 */
787  if (value_zero_p(B.num) || value_zero_p(C.num) || value_zero_p(D.den))
788  { AFF_PX(X,A);}
789  else /* b*c/d != 0, calculons! */
790  if (value_one_p(D.num) && value_one_p(A.den) &&
791  value_one_p(B.den) && value_one_p(C.den))
792  { /* no den to compute */
793  Value v;
794  if (ofl_ctrl == FWD_OFL_CTRL) {
795  v= value_protected_mult(B.num,C.num);
796  v = value_protected_mult(v,D.den);
797  }
798  else {
799  v= value_mult(B.num,C.num);
800  v = value_mult(v,D.den);
801  }
802  X->num=value_minus(A.num,v);
803  X->den=VALUE_ONE;
804  }
805  else /* well, we must compute the full formula! */
806  { full_pivot(X,A,B,C,D,ofl_ctrl);}
807  DEBUG3(fprintf(stdout, " = ");
808  printfrac(X); fprintf(stdout, "\n"));
809 }
#define DEBUG3(code)
void full_pivot(frac *X, frac A, frac B, frac C, frac D, bool ofl_ctrl)
void partial_pivot(frac *X, frac B, frac C, frac D, bool ofl_ctrl)

References AFF_PX, B, D, DEBUG3, frac::den, fprintf(), full_pivot(), FWD_OFL_CTRL, MET_ZERO, frac::num, partial_pivot(), printfrac(), value_minus, value_mult, VALUE_ONE, value_one_p, value_protected_mult, value_zero_p, and X.

Referenced by choisir_piv(), dualentier(), gauss(), iprimal(), is2(), pivoter(), sc_min(), sc_simplex_feasibility_ofl_ctrl_fixprec(), simbad(), simplexe(), and simplexedual().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ printfrac()

static void printfrac ( frac  x)
static

Definition at line 832 of file sc_simplex_feasibility_fixprec.c.

832  {
833  printf(" "); print_Value(x.num);
834  printf("/"); print_Value(x.den);
835 }

References print_Value(), printf(), and x.

Referenced by pivot(), sc_min(), and sc_simplex_feasibility_ofl_ctrl_fixprec().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sc_simplex_feasibility_ofl_ctrl_fixprec()

bool sc_simplex_feasibility_ofl_ctrl_fixprec ( Psysteme  sc,
int  ofl_ctrl 
)

fonction de calcul de la faisabilite' d'un systeme d'equations et d'inequations Auteur : Robert Mahl, Date : janvier 1994

Retourne : 1 si le systeme est soluble (faisable) en rationnels, 0 s'il n'y a pas de solution.

overflow control : ofl_ctrl == NO_OFL_CTRL => no overflow control ofl_ctrl == FWD_OFL_CTRL
=> overflow control is made THROW(overflow_error,5) BC, 13/12/94

All the folowing automatic variables are used when coming back from longjmp (i.e. in a CATCH block) so they need to be declared volatile as specified by the documentation

tete de liste des noms de variables

Necessaire de declarer "hashtable" static pour initialiser tout automatiquement a` 0. Necessaire de chainer les enregistrements pour reinitialiser a 0 en sortie de la procedure.

tableau des inegalite's

les colonnes 0 et 1 sont reservees au terme const:

valeur retournee par feasible

objectif de max pour simplex : somme des (b2,c2) termes constants "inferieurs"

count number of calls of this function (at the beginning)

int soluble = 1;

N.

recompute the base so as to only allocate necessary columns some bases are quite large although all variables do not appear in actual contraints. The base is used to store all variants in preconditions for instance.

Allocation a priori du tableau des egalites. "eg" : tableau a "nb_eq" lignes et "dimension"+2 colonnes.

DEBUG(fprintf(stdout, "\n\n IN sc_simplexe_feasibility_ofl_ctrl:\n"); sc_fprint(stdout, sc, default_variable_to_string);)

c_default_dump_to_file(); print to file

the input Psysteme must be consistent; this is not the best way to do this; array bound checks should be added instead in proper places; no time to do it properly for the moment. BC.

Do not allocate place for NULL constraints

ifscdebug(2) { fprintf(stderr,"[sc_simplexe_feasibility_ofl_ctrl] arithmetic error\n"); }

restore initial base

ethrow whatever the exception is

HROW(user_exception_error);

need CATCH(user_exception_error) before calling sc_simplexe_feasibility)

if don't catch exception, then default is feasible

f (ofl_ctrl == FWD_OFL_CTRL)

HROW(overflow_error);

eturn true; default is feasible

of CATCH(simplex_arithmetic_error)

egin of TRY

Allocation a priori du tableau du simplex "t" par colonnes. Soit "dimension" le nombre de variables, la taille maximum du tableau est de (1 + nb_ineq) lignes et de (2 + dimension + nb_ineq + nb_eq) colonnes On y ajoute en fait le double du nombre d'egalite's. Ce tableau sera rempli de la facon suivante :

  • ligne 0 : critere d'optimisation
  • lignes 1 a nb_ineq : les inequations
  • colonne 0 : le terme constant (composante de poids 1)
  • colonne 1 : le terme constant (composante de poids M)
  • colonnes 2 et suivantes : les elements initiaux et les termes d'ecart Le tableau a une derniere colonne temporaire pour pivoter un vecteur unitaire.

Initialisation de l'objectif

Entree des inegalites dans la table

skip if empty

val terme const

Creation de variable d'ecart ?

Mise a jour des colonnes 0 et 1

Element de poids M en 1ere colonne

Creation d'une colonne cachee

NON IMPLEMENTE'

Elimination de Gauss-Jordan dans le tableau "eg" Chaque variable a` eliminer est marquee eg[ ].existe = 2 Si le processus d'elimination ne revele pas d'impossibilite', il est suivi du processus d'elimination dans les inegalites.

FIN DE NON IMPLEMENTE'

SOLUTION PROVISOIRE Pour chaque egalite on introduit 2 inequations complementaires

Added by bc: do nothing for nul equalities

val terme const

Creation de variable d'ecart ?

Mise a jour des colonnes 0 et 1

Element de poids M en 1ere colonne

Creation d'une colonne cachee

Added by bc: do nothing for nul equalities

val terme const

Creation de variable d'ecart ?

Mise a jour des colonnes 0 et 1

Element de poids M en 1ere colonne

Creation d'une colonne cachee

FIN DE SOLUTION PROVISOIRE

Algorithme du simplexe - methode primale simple. L'objectif est d'etudier la faisabilite' d'un systeme de contraintes sans trouver l'optimum. Les contraintes ont la forme : a x <= b et d x = e La methode de resolution procede comme suit :

1) Creer un tableau a b d e Eliminer autant de variables que posible par Gauss-Jordan

2) Travailler sur les inegalites seulement. Poser x = x' - M 1 ou` 1 est le vecteur de chiffres 1. Les inequations prennent alors la forme : a1 x <= b1 + M c1 a2 x >= b2 + M c2 avec c1 et c2 positifs On introduit les variables d'ecart y (autant que d'inequations du 2eme type) et on cherche max{1(a2 x - y) | x,y >= 0 ; a1 x <= b1 + M c1 ; a2 x - y <= b2 + M c2} On cree donc le tableau : 0 0 1 a2 1 0 0 b1 c1 a1 0 I 0 b2 c2 a2 -I 0 I

On applique ensuite l'algorithme du simplex en se souvenant que c1 et c2 sont a multiplier par un infiniment grand. Si l'optimum est egal a (1 b2 , 1 c2), il y a une solution.

Structures de donnees : on travaille sur des tableaux de fractions rationnelles.

Recherche d'un nombre negatif 1ere ligne

Terminaison

Recherche de la ligne de pivot
si ii==-1, pas encore trouve, min{1,2} non valides...

computing rapport{1,2}

first assignment is forced

POSITIF(t[jj].colonne[i]))

it may skip over

Cas d'impossibilite'

Modification des numeros des variables

Pivot autour de la ligne ii / colonne jj Dans ce qui suit, j = colonne courante, k = numero element dans la nouvelle colonne qui remplacera la colonne j, cc = element (colonne j, ligne ii)

Remplir la derniere colonne temporaire de t qui contient un 1 en position ligne ii

N

0 en colonne j ligne t[jj].colonne[i1].numero

0 en col jj, ligne t[j].colonne[i].numero

Restauration des entrees vides de la table hashee

restore initial base

Definition at line 888 of file sc_simplex_feasibility_fixprec.c.

891 {
892  Pcontrainte pc, pc_tmp ;
893  Pvecteur pv ;
894  /* All the folowing automatic variables are used when coming back from
895  * longjmp (i.e. in a CATCH block) so they need to be declared volatile as
896  * specified by the documentation*/
897  intptr_t volatile premier_hash = PTR_NIL; /* tete de liste des noms de variables */
898  /* Necessaire de declarer "hashtable" static
899  * pour initialiser tout automatiquement a` 0.
900  * Necessaire de chainer les enregistrements
901  * pour reinitialiser a 0
902  * en sortie de la procedure.
903  */
904  static hashtable_t volatile hashtable[MAX_VAR];
905  Pbase volatile saved_base;
906  int volatile saved_dimension;
907  // tableau * volatile eg = NULL; /* tableau des egalite's */
908  tableau * volatile t = NULL; /* tableau des inegalite's */
909  frac * volatile nlle_colonne = NULL;
910  /* les colonnes 0 et 1 sont reservees au terme const: */
911  int compteur = 2 ;
912  intptr_t i, j, k, h, trouve, ligne, i0, i1, jj, ii ;
913  Value poidsM, valeur, tmpval;
914  intptr_t w ;
915  int soluble; /* valeur retournee par feasible */
916  frac* colo;
917  frac objectif[2] ; /* objectif de max pour simplex :
918  somme des (b2,c2) termes constants "inferieurs" */
919  frac rapport1, rapport2, min1, min2, piv, cc ;
920 
921 
922  DEBUG(static int simplex_sc_counter = 0;)
923  /* count number of calls of this function (at the beginning) */
924 
925  soluble=1;/* int soluble = 1;*/
926 
927  rapport1 =frac0, rapport2 =frac0, min1 =frac0, min2 =frac0, piv=frac0, cc =frac0 ;
928  objectif[0] = frac0, objectif[1] = frac0;
929  i=-1, j=-1, k=-1, h=-1, trouve=-1, ligne=-1, i0=-1, i1=-1, jj=-1, ii=-1;
930  poidsM =-1, valeur=-1, tmpval=-1,w=-1;/*DN.*/
931 
932  /* recompute the base so as to only allocate necessary columns
933  * some bases are quite large although all variables do not appear in
934  * actual contraints. The base is used to store all variants in
935  * preconditions for instance.
936  */
937 
938  saved_base = sc_base(sc);
939  saved_dimension = sc_dimension(sc);
940  sc_base(sc) = BASE_NULLE;
941 
942  sc_creer_base(sc);
943 
944 
945  /* Allocation a priori du tableau des egalites.
946  * "eg" : tableau a "nb_eq" lignes et "dimension"+2 colonnes.
947  */
948  if (ofl_ctrl!=FWD_OFL_CTRL)
949  fprintf(stderr, "[sc_simplexe_feasibility_ofl_ctrl] "
950  "should not (yet) be called with control %d...\n", ofl_ctrl);
951 
952  /* DEBUG(fprintf(stdout, "\n\n IN sc_simplexe_feasibility_ofl_ctrl:\n");
953  sc_fprint(stdout, sc, default_variable_to_string);)*/
954 
955  DEBUG(simplex_sc_counter ++;
956  fprintf(stderr,"BEGIN SIMPLEX : %d th\n",simplex_sc_counter);
957  sc_default_dump(sc);/*sc_default_dump_to_file(); print to file */
958  );
959 
960  /* the input Psysteme must be consistent; this is not the best way to
961  * do this; array bound checks should be added instead in proper places;
962  * no time to do it properly for the moment. BC.
963  */
964  linear_assert("sc is weakly consistent", sc_weak_consistent_p(sc));
965 
966  /* Do not allocate place for NULL constraints */
967  NB_EQ = 0;
968  NB_INEQ = 0;
969  for(pc_tmp = sc->egalites; pc_tmp!= NULL; pc_tmp=pc_tmp->succ)
970  {
971  if (pc_tmp->vecteur != NULL)
972  NB_EQ++;
973  }
974  for(pc_tmp = sc->inegalites; pc_tmp!= NULL; pc_tmp=pc_tmp->succ)
975  {
976  if (pc_tmp->vecteur != NULL)
977  NB_INEQ++;
978  }
979 
981  {
982  /* ifscdebug(2) {
983  fprintf(stderr,"[sc_simplexe_feasibility_ofl_ctrl] arithmetic error\n");
984  }
985  */
986  DEBUG(fprintf(stderr, "arithmetic error or timeout in simplex\n"););
987 
988  for(i = premier_hash ; i != PTR_NIL; i = hashtable[i].succ) {
989  hashtable[i].nom = VARIABLE_UNDEFINED ;
990  hashtable[i].numero = 0 ;
991  hashtable[i].hash = 0 ;
992  hashtable[i].val = (Value)0 ;
993  }
994 
995  for(i=0;i<(3 + NB_INEQ + NB_EQ + DIMENSION); i++)
996  free(t[i].colonne);
997  free(t);
998  free(nlle_colonne);
999 
1000  /* restore initial base */
1001  base_rm(sc_base(sc));
1002  sc_base(sc) = saved_base;
1003  sc_dimension(sc) = saved_dimension;
1004 
1005 #ifdef CONTROLING
1006  alarm(0); /*clear the alarm*/
1007 #endif
1008 
1009  if (ofl_ctrl == FWD_OFL_CTRL) {
1010  RETHROW(); /*rethrow whatever the exception is*/
1011  }
1012  /*THROW(user_exception_error);*/
1013  /* need CATCH(user_exception_error) before calling sc_simplexe_feasibility)*/
1014  ifscdebug(5) {fprintf(stderr,"DNDNDN WARNING: Exception not treated, return feasible!");}
1015  return true; /* if don't catch exception, then default is feasible */
1016 
1017  /*if (ofl_ctrl == FWD_OFL_CTRL) */
1018  /*THROW(overflow_error);*/
1019 
1020  /*return true; default is feasible */
1021  }/* of CATCH(simplex_arithmetic_error)*/
1022 
1023  /*begin of TRY*/
1024 
1025 #ifdef CONTROLING
1026  /*start the alarm*/
1027  if (CONTROLING_TIMEOUT_SIMPLEX) {
1028  signal(SIGALRM, controling_catch_alarm_Simplex);
1029  alarm(CONTROLING_TIMEOUT_SIMPLEX);
1030  } /*else nothing*/
1031 #endif
1032 
1033 
1034 
1035  /* Allocation a priori du tableau du simplex "t" par
1036  * colonnes. Soit
1037  * "dimension" le nombre de variables, la taille maximum
1038  * du tableau est de (1 + nb_ineq) lignes
1039  * et de (2 + dimension + nb_ineq + nb_eq) colonnes
1040  * On y ajoute en fait le double du nombre d'egalite's.
1041  * Ce tableau sera rempli de la facon suivante :
1042  * - ligne 0 : critere d'optimisation
1043  * - lignes 1 a nb_ineq : les inequations
1044  * - colonne 0 : le terme constant (composante de poids 1)
1045  * - colonne 1 : le terme constant (composante de poids M)
1046  * - colonnes 2 et suivantes : les elements initiaux
1047  * et les termes d'ecart
1048  * Le tableau a une derniere colonne temporaire pour
1049  * pivoter un vecteur unitaire.
1050  * */
1051 
1052  t = (tableau*)malloc((3 + NB_INEQ + NB_EQ + DIMENSION)*sizeof(tableau));
1053  for(i=0;i<(3 + NB_INEQ + NB_EQ + DIMENSION); i++) {
1054  t[i].colonne= (frac*) malloc((4 + 2*NB_EQ + NB_INEQ)*sizeof(frac)) ;
1055  frac_init(t[i].colonne,4 + 2*NB_EQ + NB_INEQ);
1056  t[i].existe = 0 ;
1057  t[i].taille = 1 ;
1058  t[i].colonne[0].numero = 0 ;
1059  t[i].colonne[0].num = VALUE_ZERO ;
1060  t[i].colonne[0].den = VALUE_ONE ;
1061  }
1062  nbvariables= 0 ;
1063  /* Initialisation de l'objectif */
1064 
1065  for(i=0;i<=1;i++)
1066  objectif[i].num=VALUE_ZERO, objectif[i].den=VALUE_ONE;
1067 
1068  DEBUG2(dump_hashtable(hashtable);)
1069 
1070  /* Entree des inegalites dans la table */
1071 
1072  for(pc=sc->inegalites, ligne=1; pc!=0; pc=pc->succ, ligne++)
1073  {
1074  pv=pc->vecteur;
1075  if (pv!=NULL) /* skip if empty */
1076  {
1077  valeur = VALUE_ZERO ;
1078  poidsM = VALUE_ZERO ;
1079  for(; pv !=0 ; pv=pv->succ)
1080  if(vect_coeff(pv->var,sc_base(sc)))
1081  value_addto(poidsM,pv->val) ;
1082  else
1083  valeur = value_uminus(pv->val) ; /* val terme const */
1084 
1085  for(pv=pc->vecteur ; pv !=0 ; pv=pv->succ) {
1086  if(value_notzero_p(vect_coeff(pv->var,sc_base(sc)))) {
1087  h = hash((Variable) pv->var) ; trouve=0 ;
1088  while (VARIABLE_DEFINED_P(hashtable[h].nom)) {
1089  if (hashtable[h].nom==pv->var) {
1090  trouve=1 ;
1091  break ;
1092  }
1093  else { h = (h+1) % MAX_VAR ; }
1094  }
1095  if(!trouve) {
1096  hashtable[h].succ=premier_hash ;
1097  premier_hash = h ;
1098  hashtable[h].val = VALUE_NAN ;
1099  hashtable[h].numero=compteur++ ;
1100  hashtable[h].nom=pv->var ;
1101  CREVARVISIBLE ;
1102  }
1103  linear_assert("current NUMERO in bound",
1104  (NUMERO) < (3 + NB_INEQ + NB_EQ + DIMENSION));
1105  if (value_neg_p(poidsM) ||
1106  (value_zero_p(poidsM) && value_neg_p(valeur)))
1107  {value_addto(t[NUMERO].colonne[0].num,pv->val),
1108  t[NUMERO].colonne[0].den = VALUE_ONE ;}
1109  t[NUMERO].existe = 1 ;
1110  t[NUMERO].colonne[t[NUMERO].taille].numero=ligne ;
1111  if(value_neg_p(poidsM) ||
1112  (value_zero_p(poidsM) && value_neg_p(valeur)))
1113  tmpval = value_uminus(pv->val) ;
1114  else tmpval = pv->val ;
1115  t[NUMERO].colonne[t[NUMERO].taille].num = tmpval ;
1117  t[NUMERO].taille++ ;
1118  }
1119  }
1120 
1121  /* Creation de variable d'ecart ? */
1122  if(value_neg_p(poidsM) ||
1123  (value_zero_p(poidsM) && value_neg_p(valeur))) {
1124  DEBUG1(dump_tableau("cre var ec", t, compteur);)
1125  i=compteur++ ;
1126  CREVARVISIBLE ;
1127  t[i].existe = 1 ; t[i].taille = 2 ;
1128  t[i].colonne[0].num = VALUE_ONE ;
1129  t[i].colonne[0].den = VALUE_ONE ;
1130  DEBUG1(printf("ligne ecart = %ld, colonne %ld\n",ligne,i);)
1131  t[i].colonne[1].numero = ligne ;
1132  t[i].colonne[1].num = VALUE_MONE ;
1133  t[i].colonne[1].den = VALUE_ONE ;
1134  value_oppose(poidsM);
1136  value_addto(objectif[0].num,valeur) ;
1137  value_addto(objectif[1].num,poidsM) ;
1138  }
1139 
1140  /* Mise a jour des colonnes 0 et 1 */
1141  t[0].colonne[t[0].taille].numero = ligne ;
1142  t[0].colonne[t[0].taille].den = VALUE_ONE ;
1143  t[0].colonne[t[0].taille].num = valeur ;
1144  t[0].existe = 1 ;
1145  t[0].taille++ ;
1146  /* Element de poids M en 1ere colonne */
1147  t[1].colonne[t[1].taille].numero = ligne ;
1148  t[1].colonne[t[1].taille].num = poidsM ;
1149  t[1].colonne[t[1].taille].den = VALUE_ONE ;
1150  t[1].existe = 1 ;
1151  t[1].taille++ ;
1152  /* Creation d'une colonne cachee */
1153  CREVARCACHEE ;
1154  DEBUG1(dump_tableau("cre col cach", t, compteur);)
1155  }
1156  else
1157  ligne--;
1158  }
1159 
1160  DEBUG1(dump_hashtable(hashtable);)
1161  DEBUG1(dump_tableau("avant sol prov", t, compteur);)
1162 
1163  /* NON IMPLEMENTE' */
1164 
1165  /* Elimination de Gauss-Jordan dans le tableau "eg"
1166  * Chaque variable a` eliminer est marquee
1167  * eg[ ].existe = 2
1168  * Si le processus d'elimination ne revele pas
1169  * d'impossibilite', il est suivi du processus
1170  * d'elimination dans les inegalites.
1171  */
1172  /* FIN DE NON IMPLEMENTE' */
1173 
1174  /* SOLUTION PROVISOIRE
1175  * Pour chaque egalite on introduit
1176  * 2 inequations complementaires
1177  */
1178 
1179  for(pc=sc->egalites ; pc!=0; pc=pc->succ, ligne++)
1180  {
1181  /* Added by bc: do nothing for nul equalities */
1182  if (pc->vecteur == NULL) continue;
1183 
1184  valeur = VALUE_ZERO ;
1185  poidsM = VALUE_ZERO ;
1186  for(pv=pc->vecteur ; pv !=0 ; pv=pv->succ)
1187  if(vect_coeff(pv->var,sc_base(sc)))
1188  value_addto(poidsM,pv->val) ;
1189  else valeur = value_uminus(pv->val); /* val terme const */
1190  for(pv=pc->vecteur ; pv !=0 ; pv=pv->succ) {
1191  if(vect_coeff(pv->var,sc_base(sc))) {
1192  h = hash((Variable) pv->var) ; trouve=0 ;
1193  while (VARIABLE_DEFINED_P(hashtable[h].nom)) {
1194  if (hashtable[h].nom==pv->var) {
1195  trouve=1 ;
1196  break ;
1197  }
1198  else { h = (h+1) % MAX_VAR ; }
1199  }
1200  if(!trouve) {
1201  hashtable[h].succ=premier_hash ;
1202  premier_hash = h ;
1203  hashtable[h].val = VALUE_NAN ;
1204  hashtable[h].numero=compteur++ ;
1205  CREVARVISIBLE ;
1206  hashtable[h].nom=pv->var ;
1207  }
1208  linear_assert("current NUMERO in bound",
1209  (NUMERO) < (3 + NB_INEQ + NB_EQ + DIMENSION));
1210  if(value_neg_p(poidsM) ||
1211  (value_zero_p(poidsM) && value_neg_p(valeur)))
1212  {value_addto(t[NUMERO].colonne[0].num,pv->val),
1213  t[NUMERO].colonne[0].den = VALUE_ONE ;}
1214  t[NUMERO].existe = 1 ;
1215  t[NUMERO].colonne[t[NUMERO].taille].numero=ligne ;
1216  if(value_neg_p(poidsM) ||
1217  (value_zero_p(poidsM) && value_neg_p(valeur)))
1218  tmpval = value_uminus(pv->val);
1219  else tmpval = pv->val ;
1220  t[NUMERO].colonne[t[NUMERO].taille].num = tmpval ;
1222  t[NUMERO].taille++ ;
1223  }
1224  }
1225  /* Creation de variable d'ecart ? */
1226  if(value_neg_p(poidsM) ||
1227  (value_zero_p(poidsM) && value_neg_p(valeur))) {
1228  i=compteur++ ;
1229  CREVARVISIBLE ;
1230  t[i].existe = 1 ; t[i].taille = 2 ;
1231  t[i].colonne[0].num = VALUE_ONE ;
1232  t[i].colonne[0].den = VALUE_ONE ;
1233  t[i].colonne[1].numero = ligne ;
1234  t[i].colonne[1].num = VALUE_MONE ;
1235  t[i].colonne[1].den = VALUE_ONE ;
1236  value_oppose(poidsM),
1238  value_addto(objectif[0].num,valeur) ;
1239  value_addto(objectif[1].num,poidsM) ;
1240  }
1241  /* Mise a jour des colonnes 0 et 1 */
1242  t[0].colonne[t[0].taille].numero = ligne ;
1243  t[0].colonne[t[0].taille].num = valeur ;
1244  t[0].colonne[t[0].taille].den = VALUE_ONE ;
1245  t[0].existe = 1 ;
1246  t[0].taille++ ;
1247  /* Element de poids M en 1ere colonne */
1248  t[1].colonne[t[1].taille].numero = ligne ;
1249  t[1].colonne[t[1].taille].num = poidsM ;
1250  t[1].colonne[t[1].taille].den = VALUE_ONE ;
1251  t[1].existe = 1 ;
1252  t[1].taille++ ;
1253  /* Creation d'une colonne cachee */
1254  CREVARCACHEE ;
1255  DEBUG1(dump_tableau("cre col cach 2", t, compteur);)
1256  }
1257 
1258  for(pc=sc->egalites ; pc!=0; pc=pc->succ, ligne++)
1259  {
1260  /* Added by bc: do nothing for nul equalities */
1261  if (pc->vecteur == NULL) continue;
1262 
1263  valeur = VALUE_ZERO ;
1264  poidsM = VALUE_ZERO ;
1265  for(pv=pc->vecteur ; pv !=0 ; pv=pv->succ)
1266  if(vect_coeff(pv->var,sc_base(sc)))
1267  value_substract(poidsM, pv->val) ;
1268  else
1269  valeur = pv->val ; /* val terme const */
1270 
1271  for(pv=pc->vecteur ; pv !=0 ; pv=pv->succ) {
1272  if (vect_coeff(pv->var,sc_base(sc))) {
1273  h = hash((Variable) pv->var) ; trouve=0 ;
1274  while (VARIABLE_DEFINED_P(hashtable[h].nom)) {
1275  if (hashtable[h].nom==pv->var) {
1276  trouve=1 ;
1277  break ;
1278  }
1279  else { h = (h+1) % MAX_VAR ; }
1280  }
1281  if(!trouve) {
1282  hashtable[h].succ=premier_hash ;
1283  premier_hash = h ;
1284  hashtable[h].val = VALUE_NAN ;
1285  hashtable[h].numero=compteur++ ;
1286  hashtable[h].nom=pv->var ;
1287  CREVARVISIBLE ;
1288  }
1289  assert((NUMERO) < (3 + NB_INEQ + NB_EQ + DIMENSION));
1290  if(value_neg_p(poidsM) ||
1291  (value_zero_p(poidsM) && value_neg_p(valeur)))
1292  {value_substract(t[NUMERO].colonne[0].num,pv->val),
1293  t[NUMERO].colonne[0].den = VALUE_ONE ;}
1294  t[NUMERO].existe = 1 ;
1295  t[NUMERO].colonne[t[NUMERO].taille].numero=ligne ;
1296  if(value_neg_p(poidsM) ||
1297  (value_zero_p(poidsM) && value_neg_p(valeur)))
1298  tmpval = pv->val ;
1299  else tmpval = value_uminus(pv->val) ;
1300  t[NUMERO].colonne[t[NUMERO].taille].num = tmpval ;
1302  t[NUMERO].taille++ ;
1303  }
1304  }
1305  /* Creation de variable d'ecart ? */
1306  if(value_neg_p(poidsM) ||
1307  (value_zero_p(poidsM) && value_neg_p(valeur))) {
1308  i=compteur++ ;
1309  CREVARVISIBLE ;
1310  t[i].existe = 1 ; t[i].taille = 2 ;
1311  t[i].colonne[0].num = VALUE_ONE ;
1312  t[i].colonne[0].den = VALUE_ONE ;
1313  t[i].colonne[1].numero = ligne ;
1314  t[i].colonne[1].num = VALUE_MONE ;
1315  t[i].colonne[1].den = VALUE_ONE ;
1316  value_oppose(poidsM),
1318  value_addto(objectif[0].num,valeur) ;
1319  value_addto(objectif[1].num,poidsM) ;
1320  }
1321  /* Mise a jour des colonnes 0 et 1 */
1322  t[0].colonne[t[0].taille].numero = ligne ;
1323  t[0].colonne[t[0].taille].num = valeur ;
1324  t[0].colonne[t[0].taille].den = VALUE_ONE ;
1325  t[0].existe = 1 ;
1326  t[0].taille++ ;
1327  /* Element de poids M en 1ere colonne */
1328  t[1].colonne[t[1].taille].numero = ligne ;
1329  t[1].colonne[t[1].taille].num = poidsM ;
1330  t[1].colonne[t[1].taille].den = VALUE_ONE ;
1331  t[1].existe = 1 ;
1332  t[1].taille++ ;
1333  /* Creation d'une colonne cachee */
1334  CREVARCACHEE ;
1335  DEBUG1(dump_tableau("cre col cach 3", t, compteur);)
1336  }
1337 
1338  /* FIN DE SOLUTION PROVISOIRE */
1339 
1340  /* Algorithme du simplexe - methode primale simple.
1341  * L'objectif est d'etudier la faisabilite' d'un systeme
1342  * de contraintes sans trouver l'optimum.
1343  * Les contraintes ont la forme : a x <= b
1344  * et d x = e
1345  * La methode de resolution procede comme suit :
1346  *
1347  * 1) Creer un tableau
1348  * a b
1349  * d e
1350  * Eliminer autant de variables que posible par
1351  * Gauss-Jordan
1352  *
1353  * 2) Travailler sur les inegalites seulement.
1354  * Poser x = x' - M 1
1355  * ou` 1 est le vecteur de chiffres 1.
1356  * Les inequations prennent alors la forme :
1357  * a1 x <= b1 + M c1
1358  * a2 x >= b2 + M c2
1359  * avec c1 et c2 positifs
1360  * On introduit les variables d'ecart y (autant que
1361  * d'inequations du 2eme type) et on cherche
1362  * max{1(a2 x - y) | x,y >= 0 ; a1 x <= b1 + M c1 ;
1363  * a2 x - y <= b2 + M c2}
1364  * On cree donc le tableau :
1365  * 0 0 1 a2 1 0 0
1366  * b1 c1 a1 0 I 0
1367  * b2 c2 a2 -I 0 I
1368  *
1369  * On applique ensuite l'algorithme du simplex en
1370  * se souvenant que c1 et c2 sont a multiplier par un
1371  * infiniment grand.
1372  * Si l'optimum est egal a (1 b2 , 1 c2), il y a une
1373  * solution.
1374  *
1375  * Structures de donnees : on travaille sur des tableaux
1376  * de fractions rationnelles.
1377  */
1378  nlle_colonne=(frac *) malloc((4 + 2*NB_EQ + NB_INEQ+1)*sizeof(frac)) ;
1379  frac_init(nlle_colonne,4 + 2*NB_EQ + NB_INEQ);
1380  while(1) {
1381 
1382  /* Recherche d'un nombre negatif 1ere ligne
1383  */
1384  for(j=2, jj= -1 ;j<compteur;j++)
1385  if(t[j].existe && NEGATIF(t[j].colonne[0]))
1386  {
1387  jj=j ; break ;
1388  }
1389 
1390  /* Terminaison */
1391  if(jj == -1) {
1392  bool cond;
1393  DEBUG1({
1394  printf ("solution :\n") ;
1395  dump_tableau("sol", t, compteur) ;
1396  printf("objectif : "); printfrac(objectif[0]) ;
1397  printfrac(objectif[1]) ; printf("\n") ;
1398  });
1399 
1400  if (ofl_ctrl == FWD_OFL_CTRL)
1401  cond = EGALOFL(objectif[0],t[0].colonne[0]) &&
1402  EGALOFL(objectif[1],t[1].colonne[0]);
1403  else
1404  cond = EGAL(objectif[0],t[0].colonne[0]) &&
1405  EGAL(objectif[1],t[1].colonne[0]);
1406 
1407  if(cond)
1408  {
1409  DEBUG1(printf("Systeme soluble (faisable) en rationnels\n");)
1410  SOLUBLE(1)
1411  }
1412  else
1413  {
1414  DEBUG1(printf("Systeme insoluble (infaisable)\n");)
1415  SOLUBLE(0)
1416  }
1417  DEBUG1(printf("fin\n");)
1418  }
1419 
1420  DEBUG1(printf("1 : jj= %ld\n",jj);
1421  dump_tableau("avant ch pivot", t, compteur);)
1422 
1423  DEBUG1(min1.num = 32700; min1.den=1; min2=min1;)
1424 
1425  /* Recherche de la ligne de pivot
1426  * si ii==-1, pas encore trouve, min{1,2} non valides...
1427  */
1428  for(i=1, i0=1, i1=1, ii=-1 ; i<t[jj].taille ; )
1429  {
1430  bool cond;
1431 
1432  DEBUG1(fprintf(stdout, "itering i{,0,1} = %ld %ld %ld\n",
1433  i, i0, i1);)
1434 
1435  if(((i0<t[0].taille && t[jj].colonne[i].numero <=
1436  t[0].colonne[i0].numero) || i0>=t[0].taille)
1437  && ((i1<t[1].taille && t[jj].colonne[i].numero <=
1438  t[1].colonne[i1].numero) || i1>=t[1].taille)) {
1439  if( POSITIF(t[jj].colonne[i])) {
1440  /* computing rapport{1,2}
1441  */
1442  frac f1 =
1443  (i0<t[0].taille &&
1444  t[jj].colonne[i].numero==t[0].colonne[i0].numero)?
1445  t[0].colonne[i0]:frac0;
1446  frac f2 = t[jj].colonne[i];
1447  frac f3 =
1448  (i1<t[1].taille &&
1449  t[jj].colonne[i].numero==t[1].colonne[i1].numero)?
1450  t[1].colonne[i1]:frac0;
1451 
1452  frac_div(&rapport1,f1,f2,ofl_ctrl);
1453  frac_div(&rapport2,f3,f2,ofl_ctrl);
1454 
1455 
1456  DEBUG1(fprintf(stdout, "rapports:");
1457  printfrac(rapport1);
1458  printfrac(min1);
1459  printfrac(rapport2);
1460  printfrac(min2);
1461  fprintf(stdout, "\nand cond: ");)
1462 
1463  if (ii==-1)
1464  cond = true; /* first assignment is forced */
1465  else
1466  if (ofl_ctrl == FWD_OFL_CTRL)
1467  cond = INFOFL(rapport2,min2) ||
1468  (EGALOFL(rapport2,min2) &&
1469  INFOFL(rapport1,min1));
1470  else
1471  cond = INF(rapport2,min2) ||
1472  (EGAL(rapport2,min2) &&
1473  INF(rapport1,min1));
1474 
1475  DEBUG1(fprintf(stdout, "%d\n", cond);)
1476 
1477  if (cond) {
1478  AFF(min1,rapport1) ;
1479  AFF(min2,rapport2) ;
1480  AFF(piv,t[jj].colonne[i]) ;
1481  frac_simplifie(&piv);
1482  ii=t[jj].colonne[i].numero ;
1483  }
1484  } /* POSITIF(t[jj].colonne[i])) */
1485  i++ ;
1486  }
1487  else {
1488  if(i0<t[0].taille && /* it may skip over */
1489  t[jj].colonne[i].numero> t[0].colonne[i0].numero) i0++ ;
1490  if(i1<t[1].taille &&
1491  t[jj].colonne[i].numero > t[1].colonne[i1].numero) i1++ ;
1492  }
1493 
1494  DEBUG1(printf("i=%ld i0=%ld i1=%ld %d %d %d\n",
1495  i,i0,i1,
1496  i<t[jj].taille? t[jj].colonne[i].numero: -1,
1497  i0<t[0].taille? t[0].colonne[i0].numero: -1,
1498  i1<t[1].taille? t[1].colonne[i1].numero: -1);)
1499  }
1500 
1501  /* Cas d'impossibilite' */
1502  if(ii==-1) {
1503  DEBUG1(dump_tableau("sol infinie", t, compteur);
1504  fprintf(stderr,"Solution infinie\n");)
1505  SOLUBLE(1)
1506  }
1507 
1508  /* Modification des numeros des variables */
1509 
1510  j = variables[jj-2];
1511  k = variablescachees[ii-1];
1512  variables[jj-2] = k;
1513  variablescachees[ii-1] = j;
1514 
1515  DEBUG2({
1516  printf("Visibles :");
1517  for(j=0;j<compteur-2;j++)
1518  printf(" %d",variables[j]);
1519  printf("\nCachees :");
1520  for(j=0;j<nbvariables;j++)
1521  printf(" %d",variablescachees[j]);
1522  printf("\n");
1523  });
1524 
1525  /* Pivot autour de la ligne ii / colonne jj
1526  * Dans ce qui suit, j = colonne courante,
1527  * k = numero element dans la nouvelle colonne
1528  * qui remplacera la colonne j,
1529  * cc = element (colonne j, ligne ii)
1530  */
1531  DEBUG(printf("Pivoter %ld %ld\n",ii,jj);)
1532 
1533  /* Remplir la derniere colonne temporaire de t
1534  * qui contient un 1 en position ligne ii
1535  */
1536  t[compteur].taille = 2 ;
1537  t[compteur].colonne[0].numero = 0 ;
1538  t[compteur].colonne[0].num = VALUE_ZERO ;
1539  t[compteur].colonne[0].den = VALUE_ONE ;
1540  t[compteur].colonne[1].numero = ii;
1541  t[compteur].colonne[1].num = VALUE_ONE ;
1542  t[compteur].colonne[1].den = VALUE_ONE ;
1543  t[compteur].existe = 1 ;
1544 
1545  for(j=0 ; j<=compteur ; j=(j==(jj-1))?(j+2):(j+1)) {
1546  if(t[j].existe)
1547  {
1548  k=0 ;
1549  cc.num= VALUE_ZERO ;
1550  cc.den= VALUE_ONE ;
1551  for(i=1;i<t[j].taille;i++)
1552  if(t[j].colonne[i].numero==ii)
1553  { AFF(cc,t[j].colonne[i]); break ; }
1554  else if(t[j].colonne[i].numero>ii)
1555  {cc.num= VALUE_ZERO ; cc.den=VALUE_ONE ; break ; }
1556  for(i=0,i1=0;i<t[j].taille || i1<t[jj].taille ;) {
1557 
1558  DEBUG2(printf("k=%ld, j=%ld, i=%ld i1=%ld\n",k,j,i,i1);
1559  printf("fractions: ");
1560  printfrac(t[j].colonne[i]) ;
1561  printfrac(t[jj].colonne[i1]) ;
1562  if (value_zero_p(t[jj].colonne[i1].den))
1563  printf("ATTENTION fraction 0/0 ");/*DN*/
1564  printfrac(cc);
1565  printfrac(piv);)
1566 
1567  if(i<t[j].taille &&
1568  i1<t[jj].taille &&
1569  t[j].colonne[i].numero == t[jj].colonne[i1].numero)
1570  {
1571  if(t[j].colonne[i].numero == ii) {
1572  AFF(nlle_colonne[k],t[j].colonne[i]);
1573  } else {
1574  frac *n = &nlle_colonne[k],
1575  *a = &t[j].colonne[i],
1576  *b = &t[jj].colonne[i1];
1577  pivot(n, (*a), (*b), cc, piv,ofl_ctrl);
1578  }
1579 
1580  if(i==0||nlle_colonne[k].num!=0) {
1581  nlle_colonne[k].numero = t[j].colonne[i].numero ;
1582  k++ ;
1583  }
1584 
1585  i++ ; i1++ ;
1586  }
1587  else
1588  if(i>=t[j].taille ||
1589  (i1<t[jj].taille &&
1590  t[j].colonne[i].numero > t[jj].colonne[i1].numero))
1591  {
1592  DEBUG1(
1593  if (i<t[j].taille)
1594  {
1595  printf("t[j].colonne[i].numero > "
1596  "t[jj].colonne[i1].numero , "
1597  "k=%ld, j=%ld, i=%ld i1=%ld\n",
1598  k,j,i,i1);
1599  printf("j = %ld t[j].taille=%d , "
1600  "t[jj].taille=%d\n",
1601  j,t[j].taille,t[jj].taille);
1602  printf("t[j].colonne[i].numero=%d , "
1603  "t[jj].colonne[i1].numero=%d\n",
1604  t[j].colonne[i].numero,
1605  t[jj].colonne[i1].numero);
1606  });
1607 
1608  /* 0 en colonne j ligne t[jj].colonne[i1].numero */
1609  if(t[jj].colonne[i1].numero == ii) {
1610  AFF(nlle_colonne[k],frac0)
1611  } else {
1612  frac *n = &(nlle_colonne[k]),
1613  *b = &(t[jj].colonne[i1]);
1614  pivot(n,frac0,(*b),cc,piv,ofl_ctrl) ;
1615  }
1616 
1617  if(i==0||nlle_colonne[k].num!=0)
1618  {
1619  nlle_colonne[k].numero =
1620  t[jj].colonne[i1].numero ;
1621  k++ ;
1622  }
1623  if(i1<t[jj].taille) i1++ ; else i++ ;
1624  }
1625  else if(i1>=t[jj].taille ||
1626  t[j].colonne[i].numero <
1627  t[jj].colonne[i1].numero)
1628  {
1629  /* 0 en col jj, ligne t[j].colonne[i].numero */
1630  DEBUG2(printf("t[j].colonne[i].numero < "
1631  "t[jj].colonne[i1].numero , "
1632  "k=%ld, j=%ld, i=%ld i1=%ld\n",
1633  k,j,i,i1);
1634  printf("j = %ld t[j].taille=%d , "
1635  "t[jj].taille=%d\n",
1636  j,t[j].taille,t[jj].taille););
1637  AFF(nlle_colonne[k],t[j].colonne[i]) ;
1638  if(i==0||nlle_colonne[k].num!=0) {
1639  nlle_colonne[k].numero =
1640  t[j].colonne[i].numero ;
1641  k++ ;
1642  }
1643  if(i<t[j].taille) i++ ; else i1++ ;
1644  }
1645  else
1646  DEBUG2(printf(" ??? ");)
1647 
1648  DEBUG2(printf(" -> ");
1649  printfrac(nlle_colonne[k-1]);
1650  printf(" [ligne numero %d]\n",
1651  nlle_colonne[k-1].numero);)
1652 
1653  }
1654  if(j==compteur) w = jj ; else w = j ;
1655  colo = t[w].colonne ;
1656  t[w].colonne=nlle_colonne ;
1657  nlle_colonne = colo ;
1658  t[w].taille=k ;
1659  DEBUG1(printf("w = %ld t[w].taille=%d \n",w,t[w].taille);
1660  dump_tableau("last", t, compteur););
1661  }
1662  }
1663  }
1664 
1665  /* Restauration des entrees vides de la table hashee */
1666  FINSIMPLEX :
1667  DEBUG1(dump_tableau("fin simplexe", t, compteur);)
1668  DEBUG(fprintf(stderr, "soluble = %d\n", soluble);)
1669 
1670  DEBUG(fprintf(stderr,"END SIMPLEX: %d th\n",simplex_sc_counter);)
1671 
1672  for(i = premier_hash ; i != PTR_NIL; i = hashtable[i].succ){
1673  hashtable[i].nom = VARIABLE_UNDEFINED;
1674  hashtable[i].numero = 0 ;
1675  hashtable[i].hash = 0 ;
1676  hashtable[i].val = (Value)0 ;
1677  }
1678 
1679 
1680  for(i=0;i<(3 + NB_INEQ + NB_EQ + DIMENSION); i++)
1681  free(t[i].colonne);
1682  free(t);
1683  free(nlle_colonne);
1684 
1685 #ifdef CONTROLING
1686  alarm(0); /*clear the alarm*/
1687 #endif
1689 
1690  /* restore initial base */
1691  vect_rm(sc_base(sc));
1692  sc_base(sc) = saved_base;
1693  sc_dimension(sc) = saved_dimension;
1694 
1695  return soluble;
1696 } /* main */
#define CATCH(what)
@ overflow_error
@ simplex_arithmetic_error
@ timeout_error
#define UNCATCH(what)
#define RETHROW()
#define VALUE_ZERO
#define VALUE_MONE
#define value_addto(ref, val)
#define VALUE_NAN
struct col tableau
void * malloc(YYSIZE_T)
void free(void *)
#define linear_assert(msg, ex)
Definition: linear_assert.h:51
#define assert(ex)
Definition: newgen_assert.h:41
#define true
Definition: newgen_types.h:81
int f2(int off1, int off2, int w, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:1
bool sc_weak_consistent_p(Psysteme sc)
check that sc is well defined, that the numbers of equalities and inequalities are consistent with th...
Definition: sc.c:362
void sc_creer_base(Psysteme ps)
void sc_creer_base(Psysteme ps): initialisation des parametres dimension et base d'un systeme lineair...
Definition: sc_alloc.c:129
void sc_default_dump(Psysteme sc)
void sc_default_dump(Psysteme sc): dump to stderr
Definition: sc_io.c:170
#define EGALOFL(x, y)
#define DEBUG2(code)
void pivot(frac *X, frac A, frac B, frac C, frac D, bool ofl_ctrl)
#define INFOFL(x, y)
static int NB_EQ
test du simplex : Si on compile grace a` "make simp" dans le repertoire /projects/C3/Linear/Developme...
#define DEBUG(code)
debug macros may be trigered with -DDEBUG{,1,2}
#define POSITIF(x)
static frac frac0
static int variables[MAX_VAR]
#define CREVARVISIBLE
#define EGAL(x, y)
#define NEGATIF(x)
#define INF(x, y)
#define CREVARCACHEE
void frac_init(frac *f, int n)
static int hash(Variable s)
dump_tableau
#define DEBUG1(code)
static int NB_INEQ
#define SOLUBLE(N)
#define intptr_t
Definition: stdint.in.h:294
Pvecteur vecteur
struct Scontrainte * succ
Pcontrainte inegalites
Definition: sc-local.h:71
Pcontrainte egalites
Definition: sc-local.h:70
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
Value val
Definition: vecteur-local.h:91
Variable var
Definition: vecteur-local.h:90
struct Svecteur * succ
Definition: vecteur-local.h:92
frac * colonne
this is already too much...
Entier valeur(Tableau *tp, int i, int j, Entier D)
Definition: traiter.c:178
#define base_rm(b)
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 VARIABLE_UNDEFINED
Definition: vecteur-local.h:64
#define BASE_NULLE
MACROS SUR LES BASES.
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
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

References AFF, assert, BASE_NULLE, base_rm, CATCH, col::colonne, CREVARCACHEE, CREVARVISIBLE, DEBUG, DEBUG1, DEBUG2, frac::den, DIMENSION, EGAL, Ssysteme::egalites, EGALOFL, col::existe, f2(), fprintf(), frac0, frac_div(), frac_init(), frac_simplifie(), free(), FWD_OFL_CTRL, hashtable_t::hash, hash(), Ssysteme::inegalites, INF, INFOFL, intptr_t, linear_assert, malloc(), MAX_VAR, NB_EQ, NB_INEQ, nbvariables, NEGATIF, hashtable_t::nom, frac::num, num, frac::numero, NUMERO, hashtable_t::numero, overflow_error, pivot(), POSITIF, printf(), printfrac(), PTR_NIL, RETHROW, sc_creer_base(), sc_default_dump(), sc_weak_consistent_p(), simplex_arithmetic_error, SOLUBLE, Scontrainte::succ, hashtable_t::succ, Svecteur::succ, col::taille, timeout_error, UNCATCH, hashtable_t::val, Svecteur::val, valeur(), value_addto, VALUE_MONE, VALUE_NAN, value_neg_p, value_notzero_p, VALUE_ONE, value_oppose, value_substract, value_uminus, VALUE_ZERO, value_zero_p, Svecteur::var, VARIABLE_DEFINED_P, VARIABLE_UNDEFINED, variables, variablescachees, vect_coeff(), vect_rm(), and Scontrainte::vecteur.

Referenced by sc_simplex_feasibility_ofl_ctrl().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ frac0

frac frac0 ={(Value)0,(Value)1,0}
static

◆ NB_EQ

int NB_EQ = 0
static

test du simplex : Si on compile grace a` "make simp" dans le repertoire /projects/C3/Linear/Development/polyedre/Tests alors on peut tester l'execution dans le meme directory en faisant : make test_simp

To replace #define NB_EQ and #define NB_INEQ - BC, 2/4/96 - NB_EQ and NB_INEQ are initialized at the beginning of the main subroutine. they represent the number of non-NULL constraints in sc. This is useful to allocate the minimum amount of memory necessary.

Definition at line 53 of file sc_simplex_feasibility_fixprec.c.

Referenced by sc_simplex_feasibility_ofl_ctrl_fixprec().

◆ NB_INEQ

int NB_INEQ = 0
static

◆ nbvariables

int nbvariables
static

Le nombre de variables visibles est : compteur-2 La i-eme variable visible a le numero : variables[i+1]=i (0 <= i < compteur-2) Le nombre de variables cachees est : nbvarables La i-eme variable cachee a le numero : variablescachees[i+1]=MAX_VAR+i-1 (0 <= i < nbvariables)

utilise'es par dump_tableau ; a rendre local

Definition at line 830 of file sc_simplex_feasibility_fixprec.c.

Referenced by sc_simplex_feasibility_ofl_ctrl_fixprec().

◆ variables

◆ variablescachees

int variablescachees[MAX_VAR]
static