equation.c
Go to the documentation of this file.
1 #include "equation.h"
2 
3 #include "defines.h"
4 
5 #include <string.h>
6 #include <math.h>
7 
25 
33 void PurgeEquation(Tequation *eq);
34 
36 {
37  unsigned int i;
38 
39  eq->polynomial=TRUE;
40 
41  for(i=0;i<eq->nMonomials;i++)
42  {
43  DeleteMonomial(eq->monomials[i]);
44  free(eq->monomials[i]);
45  eq->monomials[i]=NULL;
46  }
47 
48  eq->nMonomials=0;
49 }
50 
52 {
53  Tequation eq1;
54  unsigned int i;
55  boolean changed;
56 
57  InitEquation(&eq1);
58 
59  eq1.cmp=eq->cmp;
60  eq1.type=eq->type;
61 
62  changed=FALSE;
63  if (fabs(eq->value)<=ZERO)
64  {
65  eq1.value=0.0;
66  changed=(eq->value!=0.0);
67  }
68  else
69  eq1.value=eq->value;
70 
71  for(i=0;i<eq->nMonomials;i++)
72  {
73  if (fabs(GetMonomialCt(eq->monomials[i]))>ZERO)
74  AddMonomial(eq->monomials[i],&eq1);
75  else
76  changed=TRUE;
77  }
78  if (changed)
79  {
80  DeleteEquation(eq);
81  CopyEquation(eq,&eq1);
82  }
83  DeleteEquation(&eq1);
84 }
85 
87 {
88  unsigned int i;
89 
90  eq->cmp=NOCMP;
91  eq->type=NOTYPE_EQ;
92  eq->polynomial=TRUE;
93  eq->order=0;
94  eq->value=0.0;
95 
97  eq->nMonomials=0;
99 
100  for(i=0;i<eq->maxMonomials;i++)
101  eq->monomials[i]=NULL;
102 
103  InitVarSet(&(eq->vars));
104 }
105 
107 {
108  Tinterval error;
109  double ct=0;
110  unsigned int cmp=EQU;
111  Tmonomial m;
112  unsigned int i,n;
113 
114  InitEquation(eq);
115 
116  GetLinearConstraintError(&error,lc);
117  if (IntervalSize(&error)==0)
118  {
119  ct=IntervalCenter(&error);
120  cmp=EQU;
121  }
122  else
123  {
124  if (LowerLimit(&error)==-INF)
125  {
126  ct=UpperLimit(&error);
127  cmp=LEQ;
128  }
129  else
130  {
131  if (UpperLimit(&error)==INF)
132  {
133  ct=LowerLimit(&error);
134  cmp=GEQ;
135  }
136  else
137  Error("The input linear constraint can not be converted into a single equation");
138  }
139  }
140  eq->cmp=cmp;
141  eq->value=ct;
142 
144  for(i=0;i<n;i++)
145  {
146  InitMonomial(&m);
149 
150  AddMonomial(&m,eq);
151  DeleteMonomial(&m);
152  }
153 }
154 
155 
157 {
158  Tinterval error1,error2;
159  double ct1,ct2;
160  Tmonomial m;
161  unsigned int i,j,n1,n2;
162 
163  InitEquation(eq);
164 
165  GetLinearConstraintError(&error1,lc1);
166  if (IntervalSize(&error1)==0)
167  ct1=IntervalCenter(&error1);
168  else
169  Error("The input linear constraint can not be converted into an equation");
170 
171  GetLinearConstraintError(&error2,lc2);
172  if (IntervalSize(&error2)==0)
173  ct2=IntervalCenter(&error2);
174  else
175  Error("The input linear constraint can not be converted into an equation");
176 
179  for(i=0;i<n1;i++)
180  {
181  for(j=0;j<n2;j++)
182  {
183  InitMonomial(&m);
186 
189 
190  AddMonomial(&m,eq);
191  DeleteMonomial(&m);
192  }
193  }
194 
195  for(i=0;i<n1;i++)
196  {
197  InitMonomial(&m);
198  AddCt2Monomial(ct2,&m);
201  AddMonomial(&m,eq);
202  DeleteMonomial(&m);
203  }
204 
205  for(j=0;j<n2;j++)
206  {
207  InitMonomial(&m);
208  AddCt2Monomial(ct1,&m);
211  AddMonomial(&m,eq);
212  DeleteMonomial(&m);
213  }
214 }
215 
216 void CopyEquation(Tequation *eq_dst,Tequation *eq_orig)
217 {
218  unsigned int i;
219 
220  eq_dst->cmp=eq_orig->cmp;
221  eq_dst->type=eq_orig->type;
222  eq_dst->polynomial=eq_orig->polynomial;
223  eq_dst->value=eq_orig->value;
224 
225  eq_dst->maxMonomials=eq_orig->maxMonomials;
226  eq_dst->nMonomials=0;
227  NEW(eq_dst->monomials,eq_dst->maxMonomials,Tmonomial*);
228 
229  InitVarSet(&(eq_dst->vars));
230  eq_dst->order=0;
231 
232 
233  for(i=0;i<eq_orig->nMonomials;i++)
234  AddMonomial(eq_orig->monomials[i],eq_dst);
235 }
236 
237 void RewriteEquation2Simp(double epsilon,Tmapping *map,Tequation *eqOut,Tequation *eq)
238 {
239  unsigned int i,nv,o;
240  double ct;
241  unsigned int v,v1,v2;
242  TLinearConstraint lc,lc1,lc2;
243  Tvariable_set *vars;
244  Tequation eqTmp,eqRw;
245 
246  InitEquation(&eqRw);
247  eqRw.cmp=eq->cmp;
248  eqRw.polynomial=eq->polynomial;
249  eqRw.type=eq->type;
250  eqRw.value=eq->value;
251 
252  for(i=0;i<eq->nMonomials;i++)
253  {
254  vars=GetMonomialVariables(eq->monomials[i]);
255  nv=VariableSetSize(vars);
256  switch (nv)
257  {
258  case 0:
259  AddMonomial(eq->monomials[i],&eqRw);
260  break;
261 
262  case 1:
263  if (GetVariableFunctionN(0,vars)!=NFUN)
264  AddMonomial(eq->monomials[i],&eqRw);
265  else
266  {
267  v=GetVariableN(0,vars);
268  GetOriginalVarRelation(v,&lc,map);
269  o=MonomialOrder(eq->monomials[i]);
270 
271  if (o==1)
272  EquationFromLinearConstraint(&lc,&eqTmp);
273  else
274  {
275  if (o==2)
276  EquationFromLinearConstraintProduct(&lc,&lc,&eqTmp);
277  else
278  Error("Cubic factor in a equation");
279  }
280  ct=GetMonomialCt(eq->monomials[i]);
281  AccumulateEquations(&eqTmp,ct,&eqRw);
282 
284  DeleteEquation(&eqTmp);
285  }
286  break;
287 
288  case 2:
289  if ((GetVariableFunctionN(0,vars)!=NFUN)||
290  (GetVariableFunctionN(1,vars)!=NFUN))
291  AddMonomial(eq->monomials[i],&eqRw);
292  else
293  {
294  v1=GetVariableN(0,vars);
295  GetOriginalVarRelation(v1,&lc1,map);
296 
297  v2=GetVariableN(1,vars);
298  GetOriginalVarRelation(v2,&lc2,map);
299 
300  EquationFromLinearConstraintProduct(&lc1,&lc2,&eqTmp);
301  ct=GetMonomialCt(eq->monomials[i]);
302  AccumulateEquations(&eqTmp,ct,&eqRw);
303 
306  DeleteEquation(&eqTmp);
307  }
308  break;
309 
310  default:
311  Error("Only constant, linear or bilinear monomials are allowed");
312  }
313  }
314  PurgeEquation(&eqRw);
315  if (eq==eqOut)
316  DeleteEquation(eq);
317  CopyEquation(eqOut,&eqRw);
318  DeleteEquation(&eqRw);
319 }
320 
322 {
323  unsigned int i,j,nv,vID;
324  Tmonomial f;
325  Tvariable_set *vars;
326  Tequation eqRw;
327 
328  /*
329  All the variables in the simplified system are also in the original one
330  and thus, we only need to replace variable the identifiers for all the monomials
331  in the equation.
332  */
333  InitEquation(&eqRw);
334  eqRw.cmp=eq->cmp;
335  eqRw.type=eq->type;
336  eqRw.polynomial=eq->polynomial;
337  eqRw.value=eq->value;
338 
339  InitMonomial(&f);
340 
341  for(i=0;i<eq->nMonomials;i++)
342  {
343  vars=GetMonomialVariables(eq->monomials[i]);
344  nv=VariableSetSize(vars);
345  for(j=0;j<nv;j++)
346  {
347  vID=GetVarIDInOriginal(GetVariableN(j,vars),map);
348  if (vID==NO_UINT)
349  Error("Simplied var is not in original (RewriteEquation2Orig)");
351  GetVariablePowerN(j,vars),&f);
352  }
353 
354 
356  AddMonomial(&f,&eqRw);
357  ResetMonomial(&f);
358  }
359  DeleteMonomial(&f);
360  if (eq==eqOut)
361  DeleteEquation(eq);
362  CopyEquation(eqOut,&eqRw);
363  DeleteEquation(&eqRw);
364 }
365 
366 void AccumulateEquations(Tequation *eqn,double ct,Tequation *eq)
367 {
368  unsigned int i;
369 
370  for(i=0;i<eqn->nMonomials;i++)
371  AddScaledMonomial(ct,eqn->monomials[i],eq);
372 
373  eq->value+=(ct*eqn->value);
374  PurgeEquation(eq);
375 }
376 
377 void VarAccumulateEquations(Tequation *eqn,unsigned int v,Tequation *eq)
378 {
379  unsigned int i;
380  Tmonomial fnew;
381 
382  for(i=0;i<eqn->nMonomials;i++)
383  {
384  CopyMonomial(&fnew,eqn->monomials[i]);
385  AddVariable2Monomial(NFUN,v,1,&fnew);
386  AddMonomial(&fnew,eq);
387  DeleteMonomial(&fnew);
388  }
389  InitMonomial(&fnew);
390  SetMonomialCt(eqn->value,&fnew);
391  AddVariable2Monomial(NFUN,v,1,&fnew);
392  AddMonomial(&fnew,eq);
393  DeleteMonomial(&fnew);
394 
395  PurgeEquation(eq);
396 }
397 
399 {
400  unsigned int i,j;
401  Tmonomial fnew;
402  Tequation *eq;
403 
404  if ((eq1->cmp!=eq2->cmp)||(eq1->type!=eq2->type))
405  Error("Product of equations of different type in ProductEquations");
406 
407  if ((eqOut==eq1)||(eqOut==eq2))
408  NEW(eq,1,Tequation)
409  else
410  eq=eqOut;
411 
412  InitEquation(eq);
413  eq->cmp=eq->cmp;
414  eq->type=eq->type;
415 
416  for(i=0;i<eq1->nMonomials;i++)
417  {
418  for(j=0;j<eq2->nMonomials;j++)
419  {
420  MonomialProduct(eq1->monomials[i],eq2->monomials[j],&fnew);
421  AddMonomial(&fnew,eq);
422  DeleteMonomial(&fnew);
423  }
424  }
425 
426  AccumulateEquations(eq1,-eq2->value,eq);
427  AccumulateEquations(eq2,-eq1->value,eq);
428 
429  eq->value+=(eq1->value*eq2->value);
430 
431  PurgeEquation(eq);
432 
433  if ((eqOut==eq1)||(eqOut==eq2))
434  {
435  DeleteEquation(eqOut);
436  CopyEquation(eqOut,eq);
437  DeleteEquation(eq);
438  free(eq);
439  }
440 }
441 
443 {
444  eq->cmp=NOCMP;
445  eq->type=NOTYPE_EQ;
446  eq->polynomial=TRUE;
447  eq->value=0.0;
448  eq->order=0;
449 
451 
452  ResetVarSet(&(eq->vars));
453 }
454 
455 /*
456  Returns
457  0: normal case
458  1: the equation becomes constant and it holds
459  2 the equation becomes constant and it does not hold
460 */
461 unsigned int FixVariableInEquation(double epsilon,unsigned int nv,double b,Tequation *eq)
462 {
464  unsigned int r;
465 
467 
468  AddCt2LinearConstraint(b,&lc);
469  r=ReplaceVariableInEquation(epsilon,nv,&lc,eq);
471 
472  return(r);
473 }
474 
475 /*
476  Returns
477  0: normal case
478  1: the equation becomes constant and it holds
479  2 the equation becomes constant and it does not hold
480 */
481 unsigned int ReplaceVariableInEquation(double epsilon,unsigned int nv,
483 {
484  unsigned int n;
485 
487 
488  if ((n==0)||(eq->polynomial))
489  {
490  /* We are either in the case var=ct or dealing with a monomial without
491  (trigonometric) functions. */
492 
493  unsigned int i,j,k;
494  Tequation eqNew;
495  Tmonomial m;
496  unsigned int np;
497  unsigned int p;
498  Tvariable_set *vm;
499  Tinterval error;
500  double a,a1,ct;
501  unsigned int ind,ind1;
502 
503  InitEquation(&eqNew);
504  SetEquationCmp(GetEquationCmp(eq),(&eqNew));
505  SetEquationType(GetEquationType(eq),(&eqNew));
506  SetEquationValue(GetEquationValue(eq),(&eqNew));
507 
508  GetLinearConstraintError(&error,lc);
509  if (IntervalSize(&error)>ZERO)
510  Error("Only linear constraints with constant offset can be used in simplification");
511  ct=-IntervalCenter(&error);
512 
513  i=0;
514  while(i<eq->nMonomials)
515  {
516  vm=GetMonomialVariables(eq->monomials[i]);
517  np=GetPlaceinSet(nv,vm);
518  if (np!=NO_UINT)
519  {
520  /*The variable is in the monomial */
521  if (!PolynomialMonomial(eq->monomials[i]))
522  {
523  /* Replace var=ct */
524  CopyMonomial(&m,eq->monomials[i]);
525  FixVariableInMonomial(nv,ct,&m);
526  AddMonomial(&m,&eqNew);
527  DeleteMonomial(&m);
528  }
529  else
530  {
531  /* Replace var=linear_constraint inside a polynomial monomial */
532  p=GetVariablePowerN(np,vm);
533  if (p==1)
534  {
535  for(k=0;k<n;k++)
536  {
538  ind=GetLinearConstraintVariable(k,lc);
539 
540  CopyMonomial(&m,eq->monomials[i]);
541  AddVariable2Monomial(NFUN,ind,1,&m);
542  FixVariableInMonomial(nv,1,&m);
543  AddCt2Monomial(a,&m);
544  AddMonomial(&m,&eqNew);
545  DeleteMonomial(&m);
546  }
547 
548  CopyMonomial(&m,eq->monomials[i]);
549  FixVariableInMonomial(nv,1,&m);
550  AddCt2Monomial(ct,&m);
551  AddMonomial(&m,&eqNew);
552  DeleteMonomial(&m);
553  }
554  else
555  {
556  /* if we fix a variable (n==0) we do not care about the degree (p).
557  In this case, we do not enter the loop below and we have to take
558  into account that the degree can be larger than 2 */
559  if ((n>0)&&
560  ((p>2)||(VariableSetSize(vm)>1)))
561  Error("Monomials should be lineal, bilineal or quadratic");
562  /* here we have a monomial of the form c*x^2 and we need to
563  apply a subtitution x=a*y+b that gives
564  c*(a*y+b)^2=c*(a^2*y^2+2*a*y*b+b^2)=c*(a*y)^2+c*(2*a*b*y)+c*(b^2)
565  */
566 
567  for(k=0;k<n;k++)
568  {
570  ind=GetLinearConstraintVariable(k,lc);
571 
572  for(j=0;j<n;j++)
573  {
575  ind1=GetLinearConstraintVariable(j,lc);
576 
577  CopyMonomial(&m,eq->monomials[i]);
578  AddVariable2Monomial(NFUN,ind,1,&m);
579  AddVariable2Monomial(NFUN,ind1,1,&m);
580  FixVariableInMonomial(nv,1,&m);
581  AddCt2Monomial(a*a1,&m);
582  AddMonomial(&m,&eqNew);
583  DeleteMonomial(&m);
584  }
585 
586  CopyMonomial(&m,eq->monomials[i]);
587  AddVariable2Monomial(NFUN,ind,1,&m);
588  FixVariableInMonomial(nv,1,&m);
589  AddCt2Monomial(2*a*ct,&m);
590  AddMonomial(&m,&eqNew);
591  DeleteMonomial(&m);
592  }
593 
594  /* Take into account the constant term (the only term if
595  the variable is replaced by a ct) */
596  CopyMonomial(&m,eq->monomials[i]);
597  FixVariableInMonomial(nv,1,&m);
598  AddCt2Monomial(pow(ct,(double)p),&m);
599  AddMonomial(&m,&eqNew);
600  DeleteMonomial(&m);
601  }
602  }
603  }
604  else
605  {
606  CopyMonomial(&m,eq->monomials[i]);
608  AddMonomial(&m,&eqNew);
609  DeleteMonomial(&m);
610  }
611  i++;
612  }
613 
614  DeleteEquation(eq);
615  CopyEquation(eq,&eqNew);
616  DeleteEquation(&eqNew);
617 
618  NormalizeEquation(eq);
619 
620  if (eq->nMonomials>0)
621  return(0);
622  else
623  {
624  boolean hold=TRUE;
625 
626  switch (eq->cmp)
627  {
628  case EQU:
629  hold=(fabs(eq->value)<=epsilon);
630  break;
631  case LEQ:
632  hold=(-epsilon<=eq->value);
633  break;
634  case GEQ:
635  hold=( epsilon>=eq->value);
636  break;
637  }
638 
639  if (!hold)
640  {
641  printf("Ct equation does not hold: %g\n",eq->value);
642  return(2);
643  }
644  else
645  return(1);
646  }
647  }
648  else
649  return(1); /* No replacement */
650 }
651 
652 void CtScaleEquation(double ct,Tequation *eq)
653 {
654  if (eq->cmp==EQU)
655  {
656  unsigned int i;
657 
658  if (fabs(ct)<ZERO)
659  Error("Scaling an equation by 0");
660 
661  for(i=0;i<eq->nMonomials;i++)
662  AddCt2Monomial(ct,eq->monomials[i]);
663  eq->value*=ct;
664  }
665  else
666  Error("CtScaleEquation for non-equalities is not implemented yet");
667 }
668 
669 void VarScaleEquation(unsigned int v,Tequation *eq)
670 {
671  if (eq->cmp==EQU)
672  {
673  unsigned int i;
674  Tmonomial m;
675 
676  ResetVarSet(&(eq->vars));
677  for(i=0;i<eq->nMonomials;i++)
678  {
679  AddVariable2Monomial(NFUN,v,1,eq->monomials[i]);
681  }
682 
683  InitMonomial(&m);
684  AddCt2Monomial(-eq->value,&m);
685  AddVariable2Monomial(NFUN,v,1,&m);
686  AddMonomial(&m,eq);
687  DeleteMonomial(&m);
688 
689  eq->value=0;
690  }
691  else
692  Error("VarScaleEquation for non-equalities is not implemented yet");
693 }
694 
695 /*
696  Simple form of normalization to avoid numerical inestabilities
697  If all monomials have the same ct (up to ZERO) we make them
698  all equal to one.
699  This helps in many cases when we replace variables to avoid
700  transforming a circle equation into a scaled circle equation
701  (that is not identified as a circle!)
702 */
704 {
705  boolean equal;
706  unsigned int i;
707  double s,s1;
708 
709  PurgeEquation(eq);
710  if ((eq->nMonomials>0)&&(eq->cmp==EQU))
711  {
712  /*first monomial is set to possitive*/
713  s=GetMonomialCt(eq->monomials[0]);
714  s=(s<0?-1.0:1.0);
715  for(i=0;i<eq->nMonomials;i++)
716  AddCt2Monomial(s,eq->monomials[i]);
717  eq->value*=s;
718 
719  /* if all constants in the momomials are "almost" the same
720  we set all them to 1 (or -1)*/
721  equal=TRUE;
722  s=GetMonomialCt(eq->monomials[0]); /* s is possitive !! */
723  for(i=1;((equal)&&(i<eq->nMonomials));i++)
724  {
725  s1=GetMonomialCt(eq->monomials[i]);
726  equal=((fabs(s-s1)<=ZERO)||(fabs(s+s1)<=ZERO));
727  }
728 
729  if (equal)
730  {
731  if (fabs(eq->value-s)<=ZERO)
732  eq->value=1;
733  else
734  {
735  if (fabs(eq->value+s)<=ZERO)
736  eq->value=-1;
737  else
738  eq->value/=s;
739  }
740  for(i=0;i<eq->nMonomials;i++)
741  {
742  s1=GetMonomialCt(eq->monomials[i]);
743  if (s1>0)
744  SetMonomialCt(+1,eq->monomials[i]);
745  else
746  SetMonomialCt(-1,eq->monomials[i]);
747  }
748  }
749  }
750 }
751 
752 boolean CleanInfEquation(Tequation *eq_in,Tinterval *varValues,boolean *changed,Tequation *eq_out)
753 {
754  Tinterval m,rhs;
755  boolean bounded;
756  unsigned int i;
757 
758  #if (_DEBUG>6)
759  printf(" Cleaning equation inf\n");
760  #endif
761  InitEquation(eq_out);
762 
763  NewInterval(0,0,&rhs);
764  *changed=FALSE;
765  for(i=0;i<eq_in->nMonomials;i++)
766  {
767  EvaluateMonomialInt(varValues,&m,eq_in->monomials[i]);
768  if (IntervalSize(&m)==INF)
769  {
770  IntervalSubstract(&rhs,&m,&rhs);
771  *changed=TRUE;
772  }
773  else
774  AddMonomial(eq_in->monomials[i],eq_out);
775 
776  #if (_DEBUG>6)
777  printf(" Monomial %u ",i);
778  PrintInterval(stdout,&m);
779  printf(" ->");
780  PrintInterval(stdout,&rhs);
781  printf("\n");
782  #endif
783  }
784 
785  if (*changed)
786  {
787  #if (_DEBUG>6)
788  printf(" Changing equation to rhs ");
789  PrintInterval(stdout,&rhs);
790  printf("\n");
791  #endif
792  if ((LowerLimit(&rhs)==-INF)&&(UpperLimit(&rhs)==+INF))
793  {
794  bounded=FALSE;
795  #if (_DEBUG>6)
796  printf(" Unbounded\n");
797  #endif
798  }
799  else
800  {
801  /* Only one of the extremes of rhs is INF */
802  bounded=TRUE;
803  IntervalOffset(&rhs,eq_in->value,&rhs);
804  #if (_DEBUG>6)
805  printf(" rhs arter offset ");
806  PrintInterval(stdout,&rhs);
807  printf("\n");
808  #endif
809  if (LowerLimit(&rhs)==-INF)
810  {
811  /* upper limit is finite -> <= */
812  eq_out->value=UpperLimit(&rhs);
813  eq_out->cmp=LEQ;
814  #if (_DEBUG>6)
815  printf(" Changing to LEQ %f\n",eq_out->value);
816  #endif
817  }
818  else
819  {
820  /* lower limit is finite -> >= */
821  eq_out->value=UpperLimit(&rhs);
822  eq_out->cmp=GEQ;
823  #if (_DEBUG>6)
824  printf(" Changing to GEQ %f\n",eq_out->value);
825  #endif
826  }
827  }
828  }
829  else
830  {
831  eq_out->cmp=eq_in->cmp;
832  eq_out->type=eq_in->type;
833  eq_out->value=eq_in->value;
834  bounded=TRUE;
835  }
836 
837  return((bounded)&&(eq_out->nMonomials>0));
838 }
839 
840 boolean IsSimplificable(unsigned int simpLevel,unsigned int nTerms,boolean *systemVars,Tbox *cb,
841  unsigned int *v,TLinearConstraint *lc,
842  Tequation *eq)
843 {
844  boolean s;
845 
846  s=FALSE;
847  *v=NO_UINT;
848 
849  if ((eq->polynomial)&&
850  (eq->cmp==EQU)&&
851  (simpLevel>0)&&
852  (((simpLevel==1)&&(nTerms==0))||
853  ((simpLevel==2)&&(nTerms<=MAX_TERMS_SIMP))||
854  ((simpLevel==3)&&(nTerms<=MAX_TERMS_SIMP))
855  ))
856  {
857  unsigned int o,nveq,j,l,r;
858  signed int i;
859  double ct;
860  boolean found;
861 
862  o=GetEquationOrder(eq);
863  nveq=VariableSetSize(&(eq->vars));
864 
865  switch(o)
866  {
867  case 1:
868  if (nveq==(nTerms+1))
869  {
870  if (simpLevel<3) /*simpLevel=1,2 -> nTerms = 0,1 -> nveq=1,2*/
871  {
872  /* x=ct */
873  /* x + a * y = ct */
874  found=FALSE;
875  /* two loops, in the first one we try to find a non-system variable
876  we can put in function of other (including system) variables.
877  If this is not possible, we try, as a last resort, to put remove
878  system variables (to put them in function of other variables, possibly
879  non system ones) */
880  for(r=0;((!found)&&(r<2));r++)
881  {
882  /* The loop is tail to head just to get nice results in a particular
883  example. It can be also head to tail without any problem. */
884  i=eq->nMonomials-1;
885  while((!found)&&(i>=0))
886  {
888 
889  if (((r==0)&&(!systemVars[l]))||
890  ((r==1)&&(systemVars[l])))
891  {
892  ct=GetMonomialCt(eq->monomials[i]);
893 
894  if ((ct==1)||(ct==-1))
895  found=TRUE;
896  else
897  i--;
898  }
899  else
900  i--;
901  }
902  }
903  }
904  else
905  {
906  /*simpLevel=3 -> nTerms=2*/
907  /*General case: a*x+b*y=ct*/
908  unsigned int k;
909  double d,d1,d2,ct1,dm;
910 
911  found=FALSE;
912  /* two loops, in the first one we try to find a non-system variable
913  we can put in function of other (including system) variables.
914  If this is not possible, we try, as a last resort, to put remove
915  system variables (to put them in function of other variables, possibly
916  non system ones) */
917  for(r=0;((!found)&&(r<2));r++)
918  {
919  dm=INF;
920  for(k=0;((!found)&&(k<eq->nMonomials));k++)
921  {
923 
924  if (((r==0)&&(!systemVars[l]))||
925  ((r==1)&&(systemVars[l])))
926  {
927  ct1=GetMonomialCt(eq->monomials[k]);
928  d1=fabs(ct1-1);
929  d2=fabs(ct1+1);
930  d=(d1<d2?d1:d2);
931  if (d<dm)
932  {
933  found=TRUE;
934  i=k;
935  ct=ct1;
936  dm=d;
937  }
938  }
939  }
940  }
941  }
942 
943  if (found)
944  {
947  s=TRUE;
948  for(j=0;j<eq->nMonomials;j++)
949  {
950  if (j!=i)
951  {
953  -GetMonomialCt(eq->monomials[j]),
954  lc
955  );
956  }
957  }
959  if (ct!=1)
960  {
961  if (ct==-1)
963  else
964  ScaleLinearConstraint(1/ct,lc);
965  }
966  }
967  }
968  break;
969  case 2:
970  if ((nveq==1)&&(nTerms==0))
971  {
972  if (eq->value==0)
973  {
974  /* a x^2 =0 -> x=0 */
975  s=TRUE;
976 
979  }
980  else
981  {
982  if (simpLevel>1)
983  {
984  /* a x^2 = b with x in [c,d] c>0 or d<0 -> unique solution */
986 
987  if (LowerLimit(GetBoxInterval(*v,cb))>=0)
988  {
989  s=TRUE;
991  AddCt2LinearConstraint(sqrt(eq->value/GetMonomialCt(eq->monomials[0])),lc);
992  }
993  else
994  {
995  if (UpperLimit(GetBoxInterval(*v,cb))<=0)
996  {
997  s=TRUE;
999  AddCt2LinearConstraint(-sqrt((eq->value/GetMonomialCt(eq->monomials[0]))),lc);
1000  }
1001  }
1002  }
1003  }
1004  }
1005  break;
1006  }
1007  }
1008 
1009  return(s);
1010 }
1011 
1012 
1013 void SetEquationType(unsigned int type,Tequation *eq)
1014 {
1015  eq->type=type;
1016 }
1017 
1018 void SetEquationCmp(unsigned int cmp,Tequation *eq)
1019 {
1020  if ((cmp!=EQU)&&(cmp!=LEQ)&&(cmp!=GEQ))
1021  Error("Unknow equation cmp");
1022 
1023  eq->cmp=cmp;
1024 }
1025 
1026 void SetEquationValue(double v,Tequation *eq)
1027 {
1028  eq->value=v;
1029 }
1030 
1032 {
1033  return((eq->nMonomials==0)&&(fabs(eq->value)<ZERO));
1034 }
1035 
1037 {
1038  boolean l;
1039  unsigned int i;
1040 
1041  l=eq->polynomial;
1042  for(i=0;((l)&&(i<eq->nMonomials));i++)
1043  {
1044  l=((CtMonomial(eq->monomials[i]))||(LinearMonomial(eq->monomials[i])));
1045  }
1046  return(l);
1047 }
1048 
1050 {
1051  /* A polynomial equation with monomial of order at most two (quadratic or involving
1052  at most two variables) */
1053 
1054  boolean b;
1055  unsigned int i;
1056 
1057  b=eq->polynomial;
1058  for(i=0;((b)&&(i<eq->nMonomials));i++)
1059  {
1060  b=((CtMonomial(eq->monomials[i]))||
1061  (LinearMonomial(eq->monomials[i]))||
1062  (QuadraticMonomial(eq->monomials[i]))||
1063  (BilinearMonomial(eq->monomials[i])));
1064  }
1065  return(b);
1066 }
1067 
1069 {
1070  /* x^2 + y^2 = r^2 */
1071 
1072  boolean c=FALSE;
1073 
1074  if ((eq->polynomial)&&(eq->nMonomials==2)&&(eq->value>0.0)&&
1075  (GetMonomialCt(eq->monomials[0])==1.0)&&(QuadraticMonomial(eq->monomials[0]))&&
1076  (GetMonomialCt(eq->monomials[1])==1.0)&&(QuadraticMonomial(eq->monomials[1])))
1077  c=TRUE;
1078 
1079  return(c);
1080 }
1081 
1083 {
1084  /* x^2 + y^2 + z^2 = r^2 */
1085  boolean s=FALSE;
1086 
1087  if ((eq->polynomial)&&(eq->nMonomials==3)&&(eq->value>0.0)&&
1088  (GetMonomialCt(eq->monomials[0])==1.0)&&(QuadraticMonomial(eq->monomials[0]))&&
1089  (GetMonomialCt(eq->monomials[1])==1.0)&&(QuadraticMonomial(eq->monomials[1]))&&
1090  (GetMonomialCt(eq->monomials[2])==1.0)&&(QuadraticMonomial(eq->monomials[2])))
1091  s=TRUE;
1092 
1093  return(s);
1094 }
1095 
1097 {
1098  /* x*y + \alpha*z = \beta */
1099  boolean s=FALSE;
1100 
1101  if ((eq->polynomial)&&(eq->nMonomials==2)&&(eq->cmp==EQU)&&
1102  (GetMonomialCt(eq->monomials[0])==1.0)&&(BilinearMonomial(eq->monomials[0]))&&
1103  (LinearMonomial(eq->monomials[1])))
1104  s=TRUE;
1105 
1106  return(s);
1107 }
1108 
1110 {
1111  /* x*y = \beta */
1112  boolean s=FALSE;
1113 
1114  if ((eq->polynomial)&&(eq->nMonomials==1)&&(eq->cmp==EQU)&&
1115  (GetMonomialCt(eq->monomials[0])==1.0)&&(BilinearMonomial(eq->monomials[0])))
1116  s=TRUE;
1117 
1118  return(s);
1119 }
1120 
1122 {
1123  /* x^2 + \alpha*y = \beta */
1124  boolean s=FALSE;
1125 
1126  if ((eq->polynomial)&&(eq->nMonomials==2)&&(eq->cmp==EQU)&&
1127  (GetMonomialCt(eq->monomials[0])==1.0)&&(QuadraticMonomial(eq->monomials[0]))&&
1128  (LinearMonomial(eq->monomials[1])))
1129  s=TRUE;
1130 
1131  return(s);
1132 }
1133 
1135 {
1136  return(eq->polynomial);
1137 }
1138 
1139 inline unsigned int GetEquationCmp(Tequation *eq)
1140 {
1141  return(eq->cmp);
1142 }
1143 
1144 inline unsigned int GetEquationType(Tequation *eq)
1145 {
1146  return(eq->type);
1147 }
1148 
1149 inline double GetEquationValue(Tequation *eq)
1150 {
1151  return(eq->value);
1152 }
1153 
1155 {
1156  switch(eq->cmp)
1157  {
1158  case EQU:
1159  NewInterval(eq->value,eq->value,bounds);
1160  break;
1161  case GEQ:
1162  NewInterval(eq->value,+INF,bounds);
1163  break;
1164  case LEQ:
1165  NewInterval(-INF,eq->value,bounds);
1166  break;
1167  case NOCMP:
1168  Error("Undefined equation cmp in GetEquationBounds");
1169  break;
1170  }
1171 }
1172 
1173 unsigned int GetEquationOrder(Tequation *eq)
1174 {
1175  return(eq->order);
1176 }
1177 
1179 {
1180  return(&(eq->vars));
1181 }
1182 
1184 {
1186 }
1187 
1188 unsigned int CmpEquations(Tequation *eq1,Tequation *eq2)
1189 {
1190 
1191  unsigned int r;
1192 
1193  if (eq1->polynomial<eq2->polynomial)
1194  r=2;
1195  else
1196  if (eq2->polynomial<eq1->polynomial)
1197  r=1;
1198  else
1199  {
1200  if (eq1->type<eq2->type)
1201  r=2;
1202  else
1203  {
1204  if (eq2->type<eq1->type)
1205  r=1;
1206  else
1207  {
1208  /* Here both equations are of the same type */
1209  unsigned int o1,o2;
1210 
1211  o1=GetEquationOrder(eq1);
1212  o2=GetEquationOrder(eq2);
1213 
1214  if ((eq1->cmp>eq2->cmp)||
1215  ((eq1->cmp==eq2->cmp)&&(o1>o2))||
1216  ((eq1->cmp==eq2->cmp)&&(o1==o2)&&(eq1->nMonomials>eq2->nMonomials)))
1217  r=1;
1218  else
1219  {
1220  if ((eq2->cmp>eq1->cmp)||
1221  ((eq1->cmp==eq2->cmp)&&(o2>o1))||
1222  ((eq1->cmp==eq2->cmp)&&(o1==o2)&&(eq2->nMonomials>eq1->nMonomials)))
1223  r=2;
1224  else
1225  {
1226  /*the two equations have the same cmp, order, and number of monomials*/
1227  unsigned int i;
1228 
1229  i=0;
1230  r=0;
1231  while ((i<eq1->nMonomials)&&(r==0))
1232  {
1233  r=CmpMonomial(eq1->monomials[i],eq2->monomials[i]);
1234  if (r==0)
1235  i++;
1236  }
1237 
1238  if (r==0)
1239  {
1240  /*the 2 equations have the same order and the same
1241  set of monomials. We compare the value*/
1242  if (eq1->value>eq2->value)
1243  r=1;
1244  else
1245  {
1246  if (eq2->value>eq1->value)
1247  r=2;
1248  else
1249  r=0;
1250  }
1251  }
1252  }
1253  }
1254  }
1255  }
1256  }
1257  if (r!=0)
1258  return(2);
1259  else
1260  return(r);
1261 }
1262 
1263 void AddScaledMonomial(double sc,Tmonomial* f,Tequation *eq)
1264 {
1265  double ct;
1266 
1267  ct=sc*GetMonomialCt(f);
1268 
1269  /* Ensure that we are not adding an empty monomial */
1270  if ((!EmptyMonomial(f))&&(fabs(ct)>ZERO))
1271  {
1272  if (CtMonomial(f))
1273  eq->value-=ct;
1274  else
1275  {
1276  unsigned int j;
1277 
1278  j=FindMonomial(f,eq);
1279 
1280  if (j!=NO_UINT)
1281  {
1282  /* The equation already has a monomial with the same equations as the
1283  one we are adding -> just add the constants*/
1284  SetMonomialCt(GetMonomialCt(eq->monomials[j])+ct,eq->monomials[j]);
1285 
1286  if (CtMonomial(eq->monomials[j]))
1287  {
1288  unsigned int n,o;
1289 
1290  /* A non-constant monomial can only become constant if it
1291  becomes 0 */
1292  if (fabs(GetMonomialCt(eq->monomials[j]))>ZERO)
1293  Error("Non Zero constant monomial");
1294 
1295  /*If the monomial becomes ct (i.e., 0) we have to compact the
1296  monomials and recompute the varset for the equation*/
1297 
1298  /*Remove the Zeroed monomial from the equation*/
1299  DeleteMonomial(eq->monomials[j]);
1300  free(eq->monomials[j]);
1301 
1302  for(n=j+1;n<eq->nMonomials;n++)
1303  eq->monomials[n-1]=eq->monomials[n];
1304  eq->nMonomials--;
1305  eq->monomials[eq->nMonomials]=NULL;
1306 
1307  /*Recompute the variables in the equation, the monomial flag, and the order */
1308  ResetVarSet(&(eq->vars));
1309  eq->polynomial=TRUE;
1310  eq->order=0;
1311  for(n=0;n<eq->nMonomials;n++)
1312  {
1314  eq->polynomial=((eq->polynomial)&&(PolynomialMonomial(eq->monomials[n])));
1315  o=MonomialOrder(f);
1316  if (o>eq->order)
1317  eq->order=o;
1318  }
1319  }
1320  }
1321  else
1322  {
1323  /* A new (not null) monomial -> add it to the equation */
1324  unsigned int o,j;
1325  Tmonomial *s;
1326 
1327  if (eq->nMonomials==eq->maxMonomials)
1329 
1330  NEW(eq->monomials[eq->nMonomials],1,Tmonomial);
1331  CopyMonomial(eq->monomials[eq->nMonomials],f);
1332  AddCt2Monomial(sc,eq->monomials[eq->nMonomials]);
1333  eq->nMonomials++;
1334 
1335  o=MonomialOrder(f);
1336  if (eq->order<o)
1337  eq->order=o;
1338 
1340 
1341  j=eq->nMonomials-1;
1342  while((j>0)&&(CmpMonomial(eq->monomials[j-1],eq->monomials[j])==1))
1343  {
1344  s=eq->monomials[j-1];
1345  eq->monomials[j-1]=eq->monomials[j];
1346  eq->monomials[j]=s;
1347 
1348  j--;
1349  }
1350  eq->polynomial=((eq->polynomial)&&(PolynomialMonomial(f)));
1351  }
1352  }
1353  }
1354 }
1355 
1356 inline void AddMonomial(Tmonomial* f,Tequation *eq)
1357 {
1358  AddScaledMonomial(1.0,f,eq);
1359 }
1360 
1361 void GenerateParabolaEquation(unsigned int vx,unsigned int vy,Tequation *eq)
1362 {
1363  GenerateScaledParabolaEquation(1,vx,vy,eq);
1364 }
1365 
1367  unsigned int vx,unsigned int vy,Tequation *eq)
1368 {
1369  Tmonomial f;
1370 
1371  if (s==0)
1372  Error("Defining a scaled parabola equation with scale equal to 0.");
1373 
1374  InitEquation(eq);
1375  InitMonomial(&f);
1376 
1377  AddVariable2Monomial(NFUN,vx,2,&f);
1378  AddMonomial(&f,eq);
1379  ResetMonomial(&f);
1380 
1381  AddVariable2Monomial(NFUN,vy,1,&f);
1382  AddCt2Monomial(-s,&f);
1383  AddMonomial(&f,eq);
1384 
1385  DeleteMonomial(&f);
1386 
1387  SetEquationCmp(EQU,eq);
1388  SetEquationValue(0,eq);
1390 }
1391 
1392 void GenerateSaddleEquation(unsigned int vx,unsigned int vy,unsigned int vz,
1393  Tequation *eq)
1394 {
1395  GenerateScaledSaddleEquation(1,vx,vy,vz,eq);
1396 }
1397 
1399  unsigned int vx,unsigned int vy,unsigned int vz,
1400  Tequation *eq)
1401 {
1402  if (s==0)
1403  Error("Defining a scaled saddle equation with scale equal to 0.");
1404 
1405  if (vx==vy)
1406  GenerateScaledParabolaEquation(s,vx,vz,eq);
1407  else
1408  {
1409  Tmonomial f;
1410 
1411  InitEquation(eq);
1412  InitMonomial(&f);
1413 
1414  AddVariable2Monomial(NFUN,vx,1,&f);
1415  AddVariable2Monomial(NFUN,vy,1,&f);
1416  AddMonomial(&f,eq);
1417  ResetMonomial(&f);
1418 
1419  AddVariable2Monomial(NFUN,vz,1,&f);
1420  AddCt2Monomial(-s,&f);
1421  AddMonomial(&f,eq);
1422 
1423  DeleteMonomial(&f);
1424 
1425  SetEquationCmp(EQU,eq);
1426  SetEquationValue(0,eq);
1428  }
1429 }
1430 
1431 void GenerateNormEquation(unsigned int vx,unsigned int vy,unsigned int vz,
1432  double n,
1433  Tequation *eq)
1434 {
1435  unsigned int v[3];
1436 
1437  v[0]=vx;
1438  v[1]=vy;
1439  v[2]=vz;
1440  GenerateGeneralNormEquation(3,v,n,eq);
1441 }
1442 
1443 void GenerateGeneralNormEquation(unsigned int nv,unsigned int *v,double n,Tequation *eq)
1444 {
1445  Tmonomial f;
1446  unsigned int i;
1447 
1448  InitEquation(eq);
1449 
1450  InitMonomial(&f);
1451  for(i=0;i<nv;i++)
1452  {
1453  AddVariable2Monomial(NFUN,v[i],2,&f);
1454  AddMonomial(&f,eq);
1455  ResetMonomial(&f);
1456  }
1457  DeleteMonomial(&f);
1458 
1459  SetEquationCmp(EQU,eq);
1460  SetEquationValue(n,eq);
1462 }
1463 
1464 void GenerateCrossProductEquations(unsigned int v1x,unsigned int v1y,unsigned int v1z,
1465  unsigned int v2x,unsigned int v2y,unsigned int v2z,
1466  unsigned int v3x,unsigned int v3y,unsigned int v3z,
1467  unsigned int vs,
1468  double s,
1469  Tequation *eq)
1470 {
1471 
1472  Tmonomial f;
1473  unsigned int i;
1474 
1475  for(i=0;i<3;i++)
1476  InitEquation(&(eq[i]));
1477 
1478  InitMonomial(&f);
1479 
1480  AddCt2Monomial(+1.0,&f);AddVariable2Monomial(NFUN,v1y,1,&f);AddVariable2Monomial(NFUN,v2z,1,&f);
1481  AddMonomial(&f,&(eq[0]));ResetMonomial(&f);
1482  AddCt2Monomial(-1.0,&f);AddVariable2Monomial(NFUN,v1z,1,&f);AddVariable2Monomial(NFUN,v2y,1,&f);
1483  AddMonomial(&f,&(eq[0]));ResetMonomial(&f);
1484  AddCt2Monomial(-1,&f);
1485  if (vs==NO_UINT)
1486  AddCt2Monomial(s,&f);
1487  else
1488  AddVariable2Monomial(NFUN,vs,1,&f);
1489  AddVariable2Monomial(NFUN,v3x,1,&f);
1490  AddMonomial(&f,&(eq[0]));ResetMonomial(&f);
1491 
1492  AddCt2Monomial(+1.0,&f);AddVariable2Monomial(NFUN,v1z,1,&f);AddVariable2Monomial(NFUN,v2x,1,&f);
1493  AddMonomial(&f,&(eq[1]));ResetMonomial(&f);
1494  AddCt2Monomial(-1.0,&f);AddVariable2Monomial(NFUN,v1x,1,&f);AddVariable2Monomial(NFUN,v2z,1,&f);
1495  AddMonomial(&f,&(eq[1]));ResetMonomial(&f);
1496  AddCt2Monomial(-1,&f);
1497  if (vs==NO_UINT)
1498  AddCt2Monomial(s,&f);
1499  else
1500  AddVariable2Monomial(NFUN,vs,1,&f);
1501  AddVariable2Monomial(NFUN,v3y,1,&f);
1502  AddMonomial(&f,&(eq[1]));ResetMonomial(&f);
1503 
1504  AddCt2Monomial(+1.0,&f);AddVariable2Monomial(NFUN,v1x,1,&f);AddVariable2Monomial(NFUN,v2y,1,&f);
1505  AddMonomial(&f,&(eq[2]));ResetMonomial(&f);
1506  AddCt2Monomial(-1.0,&f);AddVariable2Monomial(NFUN,v1y,1,&f);AddVariable2Monomial(NFUN,v2x,1,&f);
1507  AddMonomial(&f,&(eq[2]));ResetMonomial(&f);
1508  AddCt2Monomial(-1,&f);
1509  if (vs==NO_UINT)
1510  AddCt2Monomial(s,&f);
1511  else
1512  AddVariable2Monomial(NFUN,vs,1,&f);
1513  AddVariable2Monomial(NFUN,v3z,1,&f);
1514  AddMonomial(&f,&(eq[2]));
1515 
1516  DeleteMonomial(&f);
1517 
1518  for(i=0;i<3;i++)
1519  {
1520  SetEquationCmp(EQU,&(eq[i]));
1521  SetEquationValue(0.0,&(eq[i]));
1522  SetEquationType(SYSTEM_EQ,&(eq[i]));
1523  }
1524 }
1525 
1526 void GenerateDotProductEquation(unsigned int v1x,unsigned int v1y,unsigned int v1z,
1527  unsigned int v2x,unsigned int v2y,unsigned int v2z,
1528  unsigned int vc,
1529  double c,
1530  Tequation *eq)
1531 {
1532  Tmonomial f;
1533 
1534  InitEquation(eq);
1535 
1536  InitMonomial(&f);
1537 
1538  AddCt2Monomial(+1.0,&f);AddVariable2Monomial(NFUN,v1x,1,&f);AddVariable2Monomial(NFUN,v2x,1,&f);
1539  AddMonomial(&f,eq);ResetMonomial(&f);
1540  AddCt2Monomial(+1.0,&f);AddVariable2Monomial(NFUN,v1y,1,&f);AddVariable2Monomial(NFUN,v2y,1,&f);
1541  AddMonomial(&f,eq);ResetMonomial(&f);
1542  AddCt2Monomial(+1.0,&f);AddVariable2Monomial(NFUN,v1z,1,&f);AddVariable2Monomial(NFUN,v2z,1,&f);
1543  AddMonomial(&f,eq);ResetMonomial(&f);
1544 
1545  if (vc!=NO_UINT)
1546  {
1547  AddCt2Monomial(-1.0,&f);AddVariable2Monomial(NFUN,vc,1,&f);
1548  AddMonomial(&f,eq);ResetMonomial(&f);
1549  SetEquationValue(0.0,eq);
1550  }
1551  else
1552  SetEquationValue(c,eq);
1553 
1554  DeleteMonomial(&f);
1555 
1556  SetEquationCmp(EQU,eq);
1558 
1559 }
1560 
1561 unsigned int FindMonomial(Tmonomial *f,Tequation *eq)
1562 {
1563  unsigned int j;
1564  boolean found;
1565  Tvariable_set *vf;
1566 
1567  vf=GetMonomialVariables(f);
1568 
1569  found=FALSE;
1570  j=0;
1571  while((j<eq->nMonomials)&&(!found))
1572  {
1573  if (CmpVarSet(vf,GetMonomialVariables(eq->monomials[j]))==0)
1574  found=TRUE;
1575  else
1576  j++;
1577  }
1578  if (found)
1579  return(j);
1580  else
1581  return(NO_UINT);
1582 }
1583 
1584 Tmonomial *GetMonomial(unsigned int i,Tequation *eq)
1585 {
1586  if (i<eq->nMonomials)
1587  return(eq->monomials[i]);
1588  else
1589  return(NULL);
1590 }
1591 
1592 unsigned int GetNumMonomials(Tequation *eq)
1593 {
1594  return(eq->nMonomials);
1595 }
1596 
1598 {
1600  if ((eq->polynomial)&&(GetEquationOrder(eq)<2))
1601  {
1602  unsigned int i,v;
1603  double ct;
1604 
1605  for(i=0;i<eq->nMonomials;i++)
1606  {
1608  ct=GetMonomialCt(eq->monomials[i]);
1609  AddTerm2LinearConstraint(v,ct,lc);
1610  }
1611  AddCt2LinearConstraint(-eq->value,lc);
1612  }
1613 }
1614 
1615 inline double EvaluateWholeEquation(double *varValues,Tequation *eq)
1616 {
1617  double v;
1618  unsigned int i;
1619 
1620  #if (_DEBUG>2)
1621  if (eq->cmp==NOCMP)
1622  Error("Evaluation of an undefined equation");
1623  #endif
1624 
1625  v=-eq->value;
1626 
1627  for(i=0;i<eq->nMonomials;i++)
1628  v+=EvaluateMonomial(varValues,eq->monomials[i]);
1629 
1630  return(v);
1631 }
1632 
1633 double EvaluateEquation(double *varValues,Tequation *eq)
1634 {
1635  double v;
1636  unsigned int i;
1637 
1638  if (eq->cmp==NOCMP)
1639  Error("Evaluation of an undefined equation");
1640 
1641  v=0.0;
1642 
1643  for(i=0;i<eq->nMonomials;i++)
1644  v+=EvaluateMonomial(varValues,eq->monomials[i]);
1645 
1646  return(v);
1647 }
1648 
1650 {
1651  unsigned int i;
1652  Tinterval i_aux;
1653 
1654  if (eq->cmp==NOCMP)
1655  Error("Evaluation of an undefined equation");
1656 
1657  NewInterval(0,0,i_out);
1658  for(i=0;i<eq->nMonomials;i++)
1659  {
1660  EvaluateMonomialInt(varValues,&i_aux,eq->monomials[i]);
1661  IntervalAdd(i_out,&i_aux,i_out);
1662  }
1663 }
1664 
1665 void DeriveEquation(unsigned int nv,Tequation *d,Tequation *eq)
1666 {
1667  Tmonomial f;
1668  unsigned int i;
1669 
1670  d->cmp=EQU;
1671  d->type=DERIVED_EQ;
1672  d->polynomial=TRUE;
1673  d->order=0.0;
1674  d->value=0.0;
1675 
1676  d->maxMonomials=eq->maxMonomials;
1677  d->nMonomials=0;
1679 
1680  for(i=0;i<d->maxMonomials;i++)
1681  d->monomials[i]=NULL;
1682  InitVarSet(&(d->vars));
1683 
1684  for(i=0;i<eq->nMonomials;i++)
1685  {
1686  DeriveMonomial(nv,&f,eq->monomials[i]);
1687  AddMonomial(&f,d);
1688  DeleteMonomial(&f);
1689  }
1690 }
1691 
1692 void PrintMonomials(FILE *f,char **varNames,Tequation *eq)
1693 {
1694  unsigned int i;
1695 
1696  if (eq->cmp!=EQU)
1697  PrintEquation(f,varNames,eq);
1698  else
1699  {
1700  for(i=0;i<eq->nMonomials;i++)
1701  PrintMonomial(f,(i==0),varNames,eq->monomials[i]);
1702 
1703  if (fabs(eq->value)>ZERO)
1704  fprintf(f,"%+.12g",-eq->value);
1705  else
1706  {
1707  if (eq->nMonomials==0)
1708  fprintf(f,"0");
1709  }
1710  fprintf(f,"\n");
1711  }
1712 }
1713 
1714 void PrintEquation(FILE *f,char **varNames,Tequation *eq)
1715 {
1716  unsigned int i;
1717  double s;
1718 
1719  fprintf(f," ");
1720  for(i=0;i<eq->nMonomials;i++)
1721  PrintMonomial(f,(i==0),varNames,eq->monomials[i]);
1722 
1723  if (eq->nMonomials>0)
1724  {
1725  switch(eq->cmp)
1726  {
1727  case EQU:
1728  fprintf(f," = ");
1729  break;
1730  case GEQ:
1731  fprintf(f," >= ");
1732  break;
1733  case LEQ:
1734  fprintf(f," <= ");
1735  break;
1736  case NOCMP:
1737  fprintf(f,"??\n");
1738  Error("Unkown equation type in PrintEquation");
1739  break;
1740  }
1741  s=1.0;
1742  }
1743  else
1744  s=-1.0;
1745  fprintf(f,"%.12g;\n",s*eq->value);
1746 }
1747 
1749 {
1751  free(eq->monomials);
1752 
1753  DeleteVarSet(&(eq->vars));
1754 }
void DeleteVarSet(Tvariable_set *vs)
Destructor.
Definition: variable_set.c:852
Definition of the Tequation type and the associated functions.
void DeleteLinearConstraint(TLinearConstraint *lc)
Destructor.
void RewriteEquation2Simp(double epsilon, Tmapping *map, Tequation *eqOut, Tequation *eq)
Applies the simplification mapping to an equation.
Definition: equation.c:237
Tinterval * GetBoxInterval(unsigned int n, Tbox *b)
Returns a pointer to one of the intervals defining the box.
Definition: box.c:270
double EvaluateWholeEquation(double *varValues, Tequation *eq)
Evaluates an equation in a given point.
Definition: equation.c:1615
#define SYSTEM_EQ
One of the possible type of equations.
Definition: equation.h:146
Tmonomial * GetMonomial(unsigned int i, Tequation *eq)
Gets a monomial from an equation.
Definition: equation.c:1584
void DeriveEquation(unsigned int nv, Tequation *d, Tequation *eq)
Derives an equation.
Definition: equation.c:1665
#define FALSE
FALSE.
Definition: boolean.h:30
void GenerateSaddleEquation(unsigned int vx, unsigned int vy, unsigned int vz, Tequation *eq)
Construtor. Generates a saddle equation.
Definition: equation.c:1392
void DeriveMonomial(unsigned int nv, Tmonomial *df, Tmonomial *f)
Derives an monomial.
Definition: monomial.c:238
boolean BilinealMonomialEquation(Tequation *eq)
Identify single bilineal monomial equations.
Definition: equation.c:1109
void SetMonomialCt(double k, Tmonomial *f)
Changes the scale factor of a monomial.
Definition: monomial.c:144
void SetEquationType(unsigned int type, Tequation *eq)
Changes the type of the equation (SYSTEM_EQ, CARTESIAN_EQ, DUMMY_EQ, DERIVED_EQ). ...
Definition: equation.c:1013
void GenerateCrossProductEquations(unsigned int v1x, unsigned int v1y, unsigned int v1z, unsigned int v2x, unsigned int v2y, unsigned int v2z, unsigned int v3x, unsigned int v3y, unsigned int v3z, unsigned int vs, double s, Tequation *eq)
Construtor. Generates the three equations of the cross product of two unitary vectors.
Definition: equation.c:1464
#define NEW(_var, _n, _type)
Allocates memory space.
Definition: defines.h:385
void MonomialProduct(Tmonomial *f1, Tmonomial *f2, Tmonomial *f)
Product of two monomials.
Definition: monomial.c:183
void GenerateNormEquation(unsigned int vx, unsigned int vy, unsigned int vz, double n, Tequation *eq)
Construtor. Generates an equation that is the norm of a 3d vector.
Definition: equation.c:1431
boolean LinearMonomial(Tmonomial *f)
Checks if a monomial is lienal: K*x, with K a constant.
Definition: monomial.c:79
void EvaluateEquationInt(Tinterval *varValues, Tinterval *i_out, Tequation *eq)
Interval evaluation of an equation.
Definition: equation.c:1649
A linear constraint with an associated error.
void DeleteEquation(Tequation *eq)
Destructor.
Definition: equation.c:1748
unsigned int GetVarIDInOriginal(unsigned int v, Tmapping *m)
Gets the original identifier of a simplified variable.
Definition: csmapping.c:135
void AddScaledMonomial(double sc, Tmonomial *f, Tequation *eq)
Adds a new scaled monomial to the equation.
Definition: equation.c:1263
boolean CtMonomial(Tmonomial *f)
Checks if a monomial is constant.
Definition: monomial.c:58
void LinearEquation2LinearConstraint(TLinearConstraint *lc, Tequation *eq)
Converts a linear equation into a linear constraint.
Definition: equation.c:1597
void IntervalAdd(Tinterval *i1, Tinterval *i2, Tinterval *i_out)
Addition of two intervals.
Definition: interval.c:418
unsigned int GetEquationNumVariables(Tequation *eq)
Gets the number of variables equation used in the equation.
Definition: equation.c:1183
double EvaluateEquation(double *varValues, Tequation *eq)
Evaluates an equation in a given point.
Definition: equation.c:1633
void CopyEquation(Tequation *eq_dst, Tequation *eq_orig)
Copy constructor.
Definition: equation.c:216
#define EQU
In a Tequation, the equation relational operator is equal.
Definition: equation.h:201
#define DUMMY_EQ
One of the possible type of equations.
Definition: equation.h:164
void InitLinearConstraint(TLinearConstraint *lc)
Constructor.
unsigned int maxMonomials
Definition: equation.h:245
void UnionVarSet(boolean fun, Tvariable_set *vs_new, Tvariable_set *vs)
Produces a variable set that is the union of two variable sets.
Definition: variable_set.c:221
boolean IsSimplificable(unsigned int simpLevel, unsigned int nTerms, boolean *systemVars, Tbox *cb, unsigned int *v, TLinearConstraint *lc, Tequation *eq)
Identify equations than can trigger variable simplifications.
Definition: equation.c:840
boolean EmptyMonomial(Tmonomial *f)
Checks if a monomial is empty.
Definition: monomial.c:53
void GenerateParabolaEquation(unsigned int vx, unsigned int vy, Tequation *eq)
Construtor. Generates a parabola equation.
Definition: equation.c:1361
unsigned int ReplaceVariableInEquation(double epsilon, unsigned int nv, TLinearConstraint *lc, Tequation *eq)
Replaces a variable.
Definition: equation.c:481
unsigned int GetLinearConstraintVariable(unsigned int i, TLinearConstraint *lc)
Gets the a particular variable index.
#define INIT_NUM_MONOMIALS
Initial room for monomials.
Definition: equation.h:40
#define TRUE
TRUE.
Definition: boolean.h:21
Mapping between the sets of variables in two different cuiksystems.
Definition: csmapping.h:53
#define LEQ
In a Tequation, the equation relational operator is less equal.
Definition: equation.h:195
void ResetEquationMonomials(Tequation *eq)
Resets the information about monomials stored in the equation.
Definition: equation.c:35
unsigned int CmpEquations(Tequation *eq1, Tequation *eq2)
Equation comparison.
Definition: equation.c:1188
unsigned int nMonomials
Definition: equation.h:246
void InitEquation(Tequation *eq)
Constructor.
Definition: equation.c:86
Tmonomial ** monomials
Definition: equation.h:247
void Error(const char *s)
General error function.
Definition: error.c:80
#define NFUN
No trigonometric function for the variable.
Definition: variable_set.h:36
void InvertLinearConstraint(TLinearConstraint *lc)
Changes the sign of a linear constraint.
#define NOCMP
In a Tequation, the equation relational operator is not defined yet.
Definition: equation.h:207
void ResetVarSet(Tvariable_set *vs)
Resets the information stored in a variable set.
Definition: variable_set.c:79
void FixVariableInMonomial(unsigned int nv, double v, Tmonomial *f)
Replaces a variable by a constant.
Definition: monomial.c:31
double EvaluateMonomial(double *varValues, Tmonomial *f)
Evaluates a monomial for a given set of value for the variables.
Definition: monomial.c:197
#define ZERO
Floating point operations giving a value below this constant (in absolute value) are considered 0...
Definition: defines.h:37
void AddTerm2LinearConstraint(unsigned int ind, double val, TLinearConstraint *lc)
Adds a scaled variable to the linear constraint.
unsigned int CmpVarSet(Tvariable_set *vs1, Tvariable_set *vs2)
Variable set comparison.
Definition: variable_set.c:112
void SetEquationValue(double v, Tequation *eq)
Changes the right-hand value of the equation.
Definition: equation.c:1026
unsigned int GetPlaceinSet(unsigned int id, Tvariable_set *vs)
Gets the position of a variable index in a set of variable indexes.
Definition: variable_set.c:165
Tvariable_set vars
Definition: equation.h:249
void AddMonomial(Tmonomial *f, Tequation *eq)
Adds a new monomial to the equation.
Definition: equation.c:1356
unsigned int cmp
Definition: equation.h:241
unsigned int GetVariableFunctionN(unsigned int n, Tvariable_set *vs)
Gets a variable function from a variable set.
Definition: variable_set.c:474
#define GEQ
In a Tequation, the equation relational operator is great equal.
Definition: equation.h:189
unsigned int GetVariableN(unsigned int n, Tvariable_set *vs)
Gets a variable identifier from a variable set.
Definition: variable_set.c:447
void CtScaleEquation(double ct, Tequation *eq)
Scales an equation by a constant factor.
Definition: equation.c:652
boolean BilinearMonomial(Tmonomial *f)
Checks if a monomial is bilienal: K*x*y, with K a constant.
Definition: monomial.c:71
boolean polynomial
Definition: equation.h:239
void PrintEquation(FILE *f, char **varNames, Tequation *eq)
Prints an equation.
Definition: equation.c:1714
void SetEquationCmp(unsigned int cmp, Tequation *eq)
Changes the relational operator (LEQ, GEQ, EQU) of the equation.
Definition: equation.c:1018
#define NOTYPE_EQ
One of the possible type of equations.
Definition: equation.h:182
void EquationFromLinearConstraintProduct(TLinearConstraint *lc1, TLinearConstraint *lc2, Tequation *eq)
Defines a new equation from the product of two linear constraints.
Definition: equation.c:156
void ResetMonomial(Tmonomial *f)
Reset the monomial information.
Definition: monomial.c:24
double LowerLimit(Tinterval *i)
Gets the lower limit.
Definition: interval.c:79
unsigned int GetVariablePowerN(unsigned int n, Tvariable_set *vs)
Gets a variable power from a variable set.
Definition: variable_set.c:463
void GenerateGeneralNormEquation(unsigned int nv, unsigned int *v, double n, Tequation *eq)
Construtor. Generates an equation that is the norm of a vector.
Definition: equation.c:1443
boolean PolynomialMonomial(Tmonomial *f)
Identifies monimials not involving any kind of (trigonomitric function).
Definition: monomial.c:86
unsigned int CmpMonomial(Tmonomial *f1, Tmonomial *f2)
Monomial comparison.
Definition: monomial.c:103
unsigned int order
Definition: equation.h:242
void VarScaleEquation(unsigned int v, Tequation *eq)
Scales an equation with a variable factor.
Definition: equation.c:669
An equation.
Definition: equation.h:236
Definitions of constants and macros used in several parts of the cuik library.
void IntervalSubstract(Tinterval *i1, Tinterval *i2, Tinterval *i_out)
Substraction of two intervals.
Definition: interval.c:437
void ShiftVarIndexes(unsigned int nv, Tvariable_set *vs)
Reduces the variable indexes above a given index.
Definition: variable_set.c:99
boolean ParabolaEquation(Tequation *eq)
Identify scaled parabola equations.
Definition: equation.c:1121
boolean EmptyEquation(Tequation *eq)
Identify empty equations.
Definition: equation.c:1031
void ScaleLinearConstraint(double a, TLinearConstraint *lc)
Scales a linear constraint.
A set of variable indexes with powers.
Definition: variable_set.h:131
Tvariable_set * GetMonomialVariables(Tmonomial *f)
Gets the variables of a monomial.
Definition: monomial.c:153
A scaled product of powers of variables.
Definition: monomial.h:32
double UpperLimit(Tinterval *i)
Gets the uppser limit.
Definition: interval.c:87
void GenerateScaledParabolaEquation(double s, unsigned int vx, unsigned int vy, Tequation *eq)
Construtor. Generates a scaled parabola equation.
Definition: equation.c:1366
unsigned int GetNumTermsInLinearConstraint(TLinearConstraint *lc)
Number of variables in a linear constraint.
void ResetEquation(Tequation *eq)
Reset equation information.
Definition: equation.c:442
void GetEquationBounds(Tinterval *bounds, Tequation *eq)
Returns the right-hand side of the equation in the form of an interval.
Definition: equation.c:1154
void GenerateScaledSaddleEquation(double s, unsigned int vx, unsigned int vy, unsigned int vz, Tequation *eq)
Construtor. Generates a scaled saddle equation.
Definition: equation.c:1398
unsigned int VariableSetSize(Tvariable_set *vs)
Gets the number of elements of a variable set.
Definition: variable_set.c:442
A box.
Definition: box.h:83
double GetEquationValue(Tequation *eq)
Gets the right-hand value of the equation.
Definition: equation.c:1149
unsigned int FixVariableInEquation(double epsilon, unsigned int nv, double b, Tequation *eq)
Turns a variable into a constant.
Definition: equation.c:461
void VarAccumulateEquations(Tequation *eqn, unsigned int v, Tequation *eq)
Adds an equation scaled with a variable to another equation.
Definition: equation.c:377
void GetLinearConstraintError(Tinterval *error, TLinearConstraint *lc)
Gets the right-hand side interval for the linear constraint.
#define MEM_DUP(_var, _n, _type)
Duplicates a previously allocated memory space.
Definition: defines.h:414
void PrintInterval(FILE *f, Tinterval *i)
Prints an interval.
Definition: interval.c:1001
#define NO_UINT
Used to denote an identifier that has not been initialized.
Definition: defines.h:435
void AddVariable2Monomial(unsigned int fn, unsigned int varid, unsigned int p, Tmonomial *f)
Adds a power variable to the monomial.
Definition: monomial.c:171
double IntervalCenter(Tinterval *i)
Gets the interval center.
Definition: interval.c:129
boolean CleanInfEquation(Tequation *eq_in, Tinterval *varValues, boolean *changed, Tequation *eq_out)
Removes the monomials that evaluate to inf.
Definition: equation.c:752
boolean CircleEquation(Tequation *eq)
Identify circle equations.
Definition: equation.c:1068
void AddCt2LinearConstraint(double ct, TLinearConstraint *lc)
Adds a constant term to the linear constraint.
unsigned int FindMonomial(Tmonomial *f, Tequation *eq)
Searches for a given monomial in the equation.
Definition: equation.c:1561
void EquationFromLinearConstraint(TLinearConstraint *lc, Tequation *eq)
Defines a new equation from a linear constraint.
Definition: equation.c:106
unsigned int type
Definition: equation.h:237
double GetMonomialCt(Tmonomial *f)
Gets the scale factor of a monomial.
Definition: monomial.c:136
unsigned int MonomialOrder(Tmonomial *f)
Gets the order of a monomial.
Definition: monomial.c:91
void PrintMonomials(FILE *f, char **varNames, Tequation *eq)
Prints an equation as a set if monomials.
Definition: equation.c:1692
boolean BilinearEquation(Tequation *eq)
Identify bilinear equations.
Definition: equation.c:1049
void EvaluateMonomialInt(Tinterval *varValues, Tinterval *i_out, Tmonomial *f)
Evaluates a monomial for a given set of ranges for the variables.
Definition: monomial.c:210
#define MAX_TERMS_SIMP
Maximum number of terms to be used in the simplifications.
Definition: equation.h:31
boolean SphereEquation(Tequation *eq)
Identify sphere equations.
Definition: equation.c:1082
void NewInterval(double lower, double upper, Tinterval *i)
Constructor.
Definition: interval.c:47
#define DERIVED_EQ
One of the possible type of equations.
Definition: equation.h:174
#define INF
Infinite.
Definition: defines.h:70
void PrintMonomial(FILE *file, boolean first, char **varNames, Tmonomial *f)
Prints a monomial.
Definition: monomial.c:255
double GetLinearConstraintCoefficient(unsigned int i, TLinearConstraint *lc)
Gets the a particular linear constraint coefficient.
void AddCt2Monomial(double k, Tmonomial *f)
Scales a monomial.
Definition: monomial.c:158
void GetOriginalVarRelation(unsigned int nvo, TLinearConstraint *lc, Tmapping *m)
Gets the relation for a variable in the original set with the variables in the simple set...
Definition: csmapping.c:112
void ProductEquations(Tequation *eq1, Tequation *eq2, Tequation *eqOut)
Product of two equations.
Definition: equation.c:398
boolean PolynomialEquation(Tequation *eq)
Idetify polynomial equations.
Definition: equation.c:1134
Defines a interval.
Definition: interval.h:33
void CopyMonomial(Tmonomial *f_dst, Tmonomial *f_orig)
Copy constructor.
Definition: monomial.c:96
void InitMonomial(Tmonomial *f)
Constructor.
Definition: monomial.c:17
double IntervalSize(Tinterval *i)
Gets the uppser limit.
Definition: interval.c:96
void RewriteEquation2Orig(Tmapping *map, Tequation *eqOut, Tequation *eq)
Applies the un-simplification mapping to an equation.
Definition: equation.c:321
void PurgeEquation(Tequation *eq)
Removes monomial with small constant.
Definition: equation.c:51
void AccumulateEquations(Tequation *eqn, double ct, Tequation *eq)
Adds a scaled equation to another equation.
Definition: equation.c:366
unsigned int GetNumMonomials(Tequation *eq)
Number of monomials in an equation.
Definition: equation.c:1592
double value
Definition: equation.h:243
unsigned int GetEquationType(Tequation *eq)
Gets the equation type.
Definition: equation.c:1144
boolean QuadraticMonomial(Tmonomial *f)
Checks if a monomial is quadratic: K*x^2, with K a constant.
Definition: monomial.c:64
void NormalizeEquation(Tequation *eq)
Normalizes an equation.
Definition: equation.c:703
Tvariable_set * GetEquationVariables(Tequation *eq)
Gets the set of variables equation used in the equation.
Definition: equation.c:1178
unsigned int GetEquationOrder(Tequation *eq)
Gets the equation order.
Definition: equation.c:1173
void DeleteMonomial(Tmonomial *f)
Destructor.
Definition: monomial.c:289
boolean LinearEquation(Tequation *eq)
Identify linear equations.
Definition: equation.c:1036
void GenerateDotProductEquation(unsigned int v1x, unsigned int v1y, unsigned int v1z, unsigned int v2x, unsigned int v2y, unsigned int v2z, unsigned int vc, double c, Tequation *eq)
Construtor. Generates the equation of the dot product of two unitary vectors.
Definition: equation.c:1526
unsigned int GetEquationCmp(Tequation *eq)
Gets the type of relational operator of the equation.
Definition: equation.c:1139
void IntervalOffset(Tinterval *i, double offset, Tinterval *i_out)
Interval offset.
Definition: interval.c:622
void InitVarSet(Tvariable_set *vs)
Constructor.
Definition: variable_set.c:70
boolean SaddleEquation(Tequation *eq)
Identify scaled saddle equations.
Definition: equation.c:1096