equations.c
Go to the documentation of this file.
1 #include "equations.h"
2 
3 #include "defines.h"
4 #include "error.h"
5 #include "geom.h"
6 
7 #include <math.h>
8 
28 
41 
51 void CopyEquationInfo(TequationInfo *ei_dst,TequationInfo *ei_src);
52 
69  TequationInfo *ei);
85 void ErrorDueToVariable(unsigned int m,double *c,Tinterval *is,double *ev,TequationInfo *ei);
86 
107 boolean LinearizeSaddleEquation(double epsilon,
108  unsigned int safeSimplex,
109  Tbox *b,
110  TSimplex *lp,TequationInfo *ei);
111 
112 
131 boolean LinearizeBilinealMonomialEquation(double epsilon,
132  double lr2tm,
133  unsigned int safeSimplex,
134  Tbox *b,
135  TSimplex *lp,TequationInfo *ei);
136 
154 boolean LinearizeParabolaEquation(double epsilon,
155  unsigned int safeSimplex,
156  Tbox *b,
157  TSimplex *lp,TequationInfo *ei);
158 
177 boolean LinearizeCircleEquation(double epsilon,
178  unsigned int safeSimplex,
179  Tbox *b,
180  TSimplex *lp,TequationInfo *ei);
181 
200 boolean LinearizeSphereEquation(double epsilon,
201  unsigned int safeSimplex,
202  Tbox *b,
203  TSimplex *lp,TequationInfo *ei);
204 
224 boolean LinearizeGeneralEquationInt(unsigned int cmp,
225  double epsilon,
226  unsigned int safeSimplex,
227  Tbox *b,
228  double *c,
229  TSimplex *lp,
230  TequationInfo *ei);
248 boolean LinearizeGeneralEquation(double epsilon,
249  unsigned int safeSimplex,
250  Tbox *b,
251  TSimplex *lp,TequationInfo *ei);
252 
262 
280 void AddEquationInt(Tequation *equation,Tequations *eqs);
281 
282 /*******************************************************************************/
283 
285 {
286  unsigned int i,j,nf;
287  Tvariable_set *vars,*varsf;
288  Tmonomial *f;
289  unsigned int s;
290  Tinterval bounds;
291  double v;
292 
293  NEW(ei->equation,1,Tequation);
294  CopyEquation(ei->equation,eq);
295 
296  if (GetNumMonomials(eq)==0)
297  {
299  ei->n=0;
300  ei->lc=NULL;
301  ei->Jacobian=NULL;
302  ei->Hessian=NULL;
303  }
304  else
305  {
306  if (LinearEquation(eq))
308  else
309  {
310  if (ParabolaEquation(eq))
312  else
313  {
314  if (SaddleEquation(eq))
316  else
317  {
318  if (BilinealMonomialEquation(eq))
320  else
321  {
322  if (CircleEquation(eq))
324  else
325  {
326  if (SphereEquation(eq))
328  else
330  }
331  }
332  }
333  }
334  }
335 
336  vars=GetEquationVariables(eq);
337  ei->n=VariableSetSize(vars);
338 
339  if (ei->EqType==LINEAR_EQUATION)
340  {
341  /* Define a LinearConstraint from the Linear equation.
342  The linear constraint is the structure to be directly added to the simplex */
343 
344  NEW(ei->lc,1,TLinearConstraint);
346  v=GetEquationValue(eq);
347  NewInterval(v,v,&bounds);
348  SimplexExpandBounds(GetEquationCmp(eq),&bounds);
349  SetLinearConstraintError(&bounds,ei->lc);
350 
351  nf=GetNumMonomials(eq);
352  for(i=0;i<nf;i++)
353  {
354  f=GetMonomial(i,eq);
355  varsf=GetMonomialVariables(f);
356  s=VariableSetSize(varsf);
357  if (s!=1) /* The ct terms of the equation are all in the right-hand part */
358  Error("Non-linear equation disguised as linear (SetEquationInfo)");
359 
361  }
362 
363  ei->Jacobian=NULL;
364  ei->Hessian=NULL;
365  }
366  else
367  {
368  /*Compute the Jacobain/Hessian to be used in the linear approximation*/
369 
370  NEW(ei->Jacobian,ei->n,Tequation *);
371  for(i=0;i<ei->n;i++)
372  {
373  NEW(ei->Jacobian[i],1,Tequation);
374  DeriveEquation(GetVariableN(i,vars),ei->Jacobian[i],eq);
375  }
376 
377  NEW(ei->Hessian,ei->n,Tequation **);
378  for(i=0;i<ei->n;i++)
379  {
380  NEW(ei->Hessian[i],ei->n,Tequation*);
381  for(j=0;j<i;j++)
382  ei->Hessian[i][j]=NULL;
383  for(j=i;j<ei->n;j++)
384  {
385  NEW(ei->Hessian[i][j],1,Tequation);
386  DeriveEquation(GetVariableN(j,vars),ei->Hessian[i][j],ei->Jacobian[i]);
387  }
388  }
389  ei->lc=NULL;
390  }
391  }
392 }
393 
395 {
396  return(ei->equation);
397 }
398 
400 {
401  unsigned int i,j;
402 
403  NEW(ei_dst->equation,1,Tequation);
404  CopyEquation(ei_dst->equation,ei_src->equation);
405 
406  ei_dst->n=ei_src->n;
407 
408  ei_dst->EqType=ei_src->EqType;
409 
410  if (ei_dst->EqType==EMPTY_EQUATION)
411  {
412  ei_dst->lc=NULL;
413  ei_dst->Jacobian=NULL;
414  ei_dst->Hessian=NULL;
415  }
416  else
417  {
418  if (ei_dst->EqType==LINEAR_EQUATION)
419  {
420  NEW(ei_dst->lc,1,TLinearConstraint);
421  CopyLinearConstraint(ei_dst->lc,ei_src->lc);
422 
423  ei_dst->Jacobian=NULL;
424  ei_dst->Hessian=NULL;
425  }
426  else
427  {
428  NEW(ei_dst->Jacobian,ei_dst->n,Tequation *);
429  for(i=0;i<ei_dst->n;i++)
430  {
431  NEW(ei_dst->Jacobian[i],1,Tequation);
432  CopyEquation(ei_dst->Jacobian[i],ei_src->Jacobian[i]);
433  }
434 
435  if (ei_src->Hessian==NULL)
436  ei_dst->Hessian=NULL;
437  else
438  {
439  NEW(ei_dst->Hessian,ei_dst->n,Tequation **);
440  for(i=0;i<ei_dst->n;i++)
441  {
442  NEW(ei_dst->Hessian[i],ei_dst->n,Tequation*);
443 
444  for(j=0;j<ei_dst->n;j++)
445  ei_dst->Hessian[i][j]=NULL;
446  for(j=i;j<ei_dst->n;j++)
447  {
448  NEW(ei_dst->Hessian[i][j],1,Tequation);
449  CopyEquation(ei_dst->Hessian[i][j],ei_src->Hessian[i][j]);
450  }
451  }
452  }
453  ei_dst->lc=NULL;
454  }
455  }
456 }
457 
459  TLinearConstraint *lc,
460  TequationInfo *ei)
461 {
462  double d;
463  Tinterval a,h;
464  unsigned int i,j,k;
465  Tvariable_set *vars;
466  Tinterval *is,z,half;
467  unsigned int m;
468  Tinterval *cInt,error,dfc,o;
469  double v;
470 
471  if (ei->Hessian==NULL)
472  Error("Hessian required in GetFirstOrderApproximationToEquation");
473 
474  m=GetBoxNIntervals(b);
475  is=GetBoxIntervals(b);
476 
477  /* f(x) = f(c) + df(c) (x-c) + E2 */
478  /* with E2 a quadratic error term */
479  /* f(x) = df(c) x + f(c) - df(c) c + E2 */
480  /* f(c) and df(c) are evaluated UP and DOWN
481  to avoid missing solutions */
482  /* f(x) = [df(c)_l df(c)_u] x + [f(c)_l f(c)_u] - [df(c)_l df(c)_u] c + E2 */
483  /* f(x) = df(c)_l x + [0 df(c)_u-df(c)_l] x + [f(c)_l f(c)_u] - [df(c)_l df(c)_u] c + E2 */
484  /* We accumulate all the intervals into one error term */
485  /* Error = [0 df(c)_u-df(c)_l] x + [f(c)_l f(c)_u] - [df(c)_l df(c)_u] c + E2 */
486  /* Error = [0 df(c)_u-df(c)_l] x + [f(c)_l f(c)_u] + [-df(c)_u -df(c)_l] c + E2 */
487  /* f(x) = df(c)_l x + Error */
488 
489 
490  /* To take into account floating point errors, we perform interval evaluation of the
491  equations but on punctual intervals (defined from the given points). */
492 
493  NewInterval(-ZERO,ZERO,&z);
494  NewInterval(0.5-ZERO,0.5+ZERO,&half);
495 
496  vars=GetEquationVariables(ei->equation);
497 
498  #if (_DEBUG>5)
499  printf(" First order approx to equation at [ ");
500  for(i=0;i<ei->n;i++)
501  {
502  k=GetVariableN(i,vars);
503  printf("%f ",c[k]);
504  }
505  printf("]\n");
506  #endif
507 
508  NEW(cInt,m,Tinterval);
509  for(i=0;i<ei->n;i++)
510  {
511  k=GetVariableN(i,vars);
512  NewInterval(c[k]-ZERO,c[k]+ZERO,&(cInt[k]));
513  }
514 
515  /* This function (GetFirstOrderApproximationToEquation) is typically used within cuik
516  and in cuik, equations typically do not include cos/sin -> do not cache their
517  evaluation.
518  The same applies to the all the uses of EvaluateEquationInt below. */
519  EvaluateEquationInt(cInt,&error,ei->equation);
520  v=GetEquationValue(ei->equation);
521 
522  /* The coefficients and value of the equations can be affected by some noise
523  due to floating point roundings when operating them. We add a small
524  range (1e-11) to compensate for those possible errors. */
525  NewInterval(-v-ZERO,-v+ZERO,&o);
526 
527  IntervalAdd(&error,&o,&error);
528 
530 
531  for(i=0;i<ei->n;i++)
532  {
533  k=GetVariableN(i,vars);
534 
535  EvaluateEquationInt(cInt,&dfc,ei->Jacobian[i]);
536  v=GetEquationValue(ei->Jacobian[i]);
537  /* The coefficients and value of the equations can be affected by some noise
538  due to floating point roundings when operating them. We add a small
539  range (1e-11) to compensate for those possible errors. */
540  NewInterval(-v-ZERO,-v+ZERO,&o);
541 
542  IntervalAdd(&dfc,&o,&dfc);
543 
544  d=LowerLimit(&dfc);
545 
546  IntervalOffset(&dfc,-d,&a);
547  IntervalProduct(&a,&(is[k]),&a);
548  IntervalAdd(&error,&a,&error);
549 
550  IntervalInvert(&dfc,&a);
551  IntervalScale(&a,c[k],&a);
552  IntervalAdd(&error,&a,&error);
553 
554  AddTerm2LinearConstraint(k,d,lc);
555  }
556 
557  /* Now we bound the error using interval arithmetics */
558  /* Error= 0.5 * \sum_{i,j} r[i] H_{i,j} r[j] */
559 
560  /* The interval-based bound is exact as far as the Hessian is ct (i.e., we only
561  have quadratic functions) and if there are not repeated variables in the
562  error expression ( 0.5 * \sum_{i,j} r[i] H_{i,j} r[j]). This is the case
563  of the circle, vector product and scalar product that appear in our problems.
564  In other cases we could over-estimate the error (this delays the convergence,
565  but does not avoid it)
566  */
567 
568  /* We re-use the cInt vector previously allocated. This is not a problem since cInt
569  is not used any more and the size of cInt (num var in the problem) is larger than
570  ei->n (number of variables in the current equation) */
571  for(i=0;i<ei->n;i++)
572  {
573  k=GetVariableN(i,vars);
574  IntervalOffset(&(is[k]),-c[k],&(cInt[i]));
575  IntervalAdd(&(cInt[i]),&z,&(cInt[i]));
576  }
577 
578  for(i=0;i<ei->n;i++)
579  {
580  /* The Hessian is symmetric so we only evaluate the upper triangular part
581  (In this way we already have the 0.5 scale factor in the error,
582  except for the diagonal)*/
583  for(j=i;j<ei->n;j++)
584  {
585  if (i==j)
586  {
587  IntervalPow(&(cInt[i]),2,&a); /* r[i]^2 */
588  IntervalProduct(&a,&half,&a);
589  }
590  else
591  IntervalProduct(&(cInt[i]),&(cInt[j]),&a); /* r[i]*r[j] */
592  //IntervalAdd(&a,&z,&a);
593 
594  EvaluateEquationInt(is,&h,ei->Hessian[i][j]);
595  IntervalOffset(&h,-GetEquationValue(ei->Hessian[i][j]),&h);
596  //IntervalAdd(&h,&z,&h);
597 
598  IntervalProduct(&a,&h,&a);
599 
600  IntervalAdd(&error,&a,&error);
601  }
602  }
603 
604  free(cInt);
605 
606  /* If one of the input ranges infinite, we override the computed error
607  (probably have overflow....) */
608  if (GetBoxMaxSizeVarSet(vars,b)<INF)
609  IntervalInvert(&error,&error);
610  else
611  NewInterval(-INF,INF,&error);
612 
613  SetLinearConstraintError(&error,lc);
614 }
615 
616 void ErrorDueToVariable(unsigned int m,double *c,Tinterval *is,
617  double *ev,TequationInfo *ei)
618 {
619  if (ei->EqType==EMPTY_EQUATION)
620  Error("ErrorDueToVariable on an empty equation");
621 
622  if (ei->EqType!=LINEAR_EQUATION)
623  {
624  Tvariable_set *vars;
625  unsigned int i,k;
626  Tinterval error;
627  Tinterval *r,a,h;
628  unsigned int j;
629 
630  if (ei->Hessian==NULL)
631  Error("Hessian required in ErrorDueToVariable");
632 
633  /*
634  Error= 1/2 * \sum_{i,j} r[i] * H_{i,j} * r[j] ->
635  Error= \sum{i} Error(i)
636  with
637  Error(i)= 1/2 * r[i] * \sum_{j} H_{i,j}* r[j]
638 
639  The output of this function is ev[i]=Error(i) (defined as above)
640  */
641 
642  vars=GetEquationVariables(ei->equation);
643 
644  NEW(r,ei->n,Tinterval);
645 
646  for(i=0;i<ei->n;i++)
647  {
648  k=GetVariableN(i,vars);
649  IntervalOffset(&(is[k]),-c[k],&(r[i]));
650  }
651 
652  for(i=0;i<ei->n;i++)
653  {
654  NewInterval(0,0,&error);
655  for(j=i;j<ei->n;j++)
656  {
657  if (i==j)
658  {
659  IntervalPow(&(r[i]),2,&a);
660  IntervalScale(&a,0.5,&a);
661  }
662  else
663  IntervalProduct(&(r[i]),&(r[j]),&a);
664 
665  EvaluateEquationInt(is,&h,ei->Hessian[i][j]);
666  IntervalOffset(&h,-GetEquationValue(ei->Hessian[i][j]),&h);
667 
668  IntervalProduct(&a,&h,&a);
669 
670  IntervalAdd(&error,&a,&error);
671  }
672 
673  ev[i]=IntervalSize(&error);
674  }
675 
676  free(r);
677  }
678 }
679 
681 {
682  unsigned int i,j;
683 
685  free(ei->equation);
686 
687  if (ei->EqType!=EMPTY_EQUATION)
688  {
689  if (ei->EqType==LINEAR_EQUATION)
690  {
692  free(ei->lc);
693  }
694  else
695  {
696  for(i=0;i<ei->n;i++)
697  {
698  DeleteEquation(ei->Jacobian[i]);
699  free(ei->Jacobian[i]);
700  }
701  free(ei->Jacobian);
702 
703  if (ei->Hessian!=NULL)
704  {
705  for(i=0;i<ei->n;i++)
706  {
707  for(j=i;j<ei->n;j++)
708  {
709  DeleteEquation(ei->Hessian[i][j]);
710  free(ei->Hessian[i][j]);
711  }
712  free(ei->Hessian[i]);
713  }
714  free(ei->Hessian);
715  }
716  }
717  }
718 }
719 
721 {
722  unsigned int i;
723 
724  eqs->neq=0; /* Total equations */
725 
726  eqs->s=0; /* System equation */
727  eqs->c=0; /* Coordinate equations */
728  eqs->d=0; /* Dummy equations */
729  eqs->e=0; /* Equality equations */
730 
731  eqs->polynomial=TRUE;
732  eqs->scalar=TRUE;
733 
734  /* Scalar equations */
735  eqs->n=0;
736  eqs->m=INIT_NUM_EQUATIONS;
737  NEW(eqs->equation,eqs->m,TequationInfo *);
738 
739  for(i=0;i<eqs->m;i++)
740  eqs->equation[i]=NULL;
741 
742  /* Matrix equations */
743  eqs->nm=0;
744  eqs->mm=INIT_NUM_EQUATIONS;
745  NEW(eqs->mequation,eqs->mm,TMequation *);
746 
747  for(i=0;i<eqs->mm;i++)
748  eqs->mequation[i]=NULL;
749 
750  /* The cached information about non-empty EQU equations: initially empty. */
751  eqs->nsEQU=0;
752  eqs->eqEQU=NULL;
753 }
754 
755 void CopyEquations(Tequations *eqs_dst,Tequations *eqs_src)
756 {
757  unsigned int i;
758 
759  eqs_dst->neq=eqs_src->neq;
760 
761  eqs_dst->s=eqs_src->s;
762  eqs_dst->c=eqs_src->c;
763  eqs_dst->d=eqs_src->d;
764  eqs_dst->e=eqs_src->e;
765 
766  eqs_dst->polynomial=eqs_src->polynomial;
767  eqs_dst->scalar=eqs_src->scalar;
768 
769  eqs_dst->m=eqs_src->m;
770  eqs_dst->n=eqs_src->n;
771  NEW(eqs_dst->equation,eqs_dst->m,TequationInfo *);
772  for(i=0;i<eqs_src->m;i++)
773  {
774  if (eqs_src->equation[i]!=NULL)
775  {
776  NEW(eqs_dst->equation[i],1,TequationInfo);
777  CopyEquationInfo(eqs_dst->equation[i],eqs_src->equation[i]);
778  }
779  else
780  eqs_dst->equation[i]=NULL;
781  }
782 
783  eqs_dst->mm=eqs_src->mm;
784  eqs_dst->nm=eqs_src->nm;
785  NEW(eqs_dst->mequation,eqs_dst->mm,TMequation *);
786  for(i=0;i<eqs_src->mm;i++)
787  {
788  if (eqs_src->mequation[i]!=NULL)
789  {
790  NEW(eqs_dst->mequation[i],1,TMequation);
791  CopyMEquation(eqs_dst->mequation[i],eqs_src->mequation[i]);
792  }
793  else
794  eqs_dst->mequation[i]=NULL;
795  }
796 
797  /* The cached information is not copied */
798  eqs_dst->nsEQU=0;
799  eqs_dst->eqEQU=NULL;
800 }
801 
803 {
804  unsigned int i;
805 
806  for(i=0;i<eqs1->m;i++)
807  {
808  if (eqs1->equation[i]!=NULL)
810  }
811  for(i=0;i<eqs1->mm;i++)
812  {
813  if (eqs1->mequation[i]!=NULL)
814  AddMatrixEquation(eqs1->mequation[i],eqs);
815  }
816  /* Remove the cached information, if any */
817  eqs->nsEQU=0;
818  if (eqs->eqEQU!=NULL)
819  free(eqs->eqEQU);
820 }
821 
822 boolean UsedVarInNonDummyEquations(unsigned int nv,Tequations *eqs)
823 {
824  Tequation *eq;
825  boolean found;
826  unsigned int i;
827 
828  i=0;
829  found=FALSE;
830  while((i<eqs->n)&&(!found))
831  {
832  eq=GetOriginalEquation(eqs->equation[i]);
833  if (GetEquationType(eq)!=DUMMY_EQ)
834  found=VarIncluded(nv,GetEquationVariables(eq));
835  if (!found) i++;
836  }
837  i=0;
838  while((i<eqs->nm)&&(!found))
839  {
840  found=VarIncludedinMEquation(nv,eqs->mequation[i]);
841  if (!found) i++;
842  }
843 
844  return(found);
845 }
846 
847 boolean UsedVarInEquations(unsigned int nv,Tequations *eqs)
848 {
849  boolean found;
850  unsigned int i;
851 
852  i=0;
853  found=FALSE;
854  while((i<eqs->n)&&(!found))
855  {
857  if (!found) i++;
858  }
859  i=0;
860  while((i<eqs->nm)&&(!found))
861  {
862  found=VarIncludedinMEquation(nv,eqs->mequation[i]);
863  if (!found) i++;
864  }
865 
866  return(found);
867 }
868 
869 void RemoveEquationsWithVar(double epsilon,unsigned int nv,Tequations *eqs)
870 {
871  Tequation *eq;
872  Tequations newEqs;
873  unsigned int j,i;
874  boolean found;
875 
876  i=0;
877  found=FALSE;
878  while((i<eqs->nm)&&(!found))
879  {
880  found=VarIncludedinMEquation(nv,eqs->mequation[i]);
881  if (!found) i++;
882  }
883  if (found)
884  Error("Removing a variable used in matrix equations");
885 
886  InitEquations(&newEqs);
887  for(j=0;j<eqs->n;j++)
888  {
889 
890  eq=GetOriginalEquation(eqs->equation[j]);
891  if (!VarIncluded(nv,GetEquationVariables(eq)))
892  {
893  /*The equations with the given variables are not included in the new set*/
894  /*The given variables is to be removed from the problem (it is not used
895  any more!). Removing a variable causes a shift in all the variable
896  indexes above the removed one. This effect can be easily simulated
897  by fixing the variable-to-be-removed for the equations to be kept in
898  the new set. */
899  FixVariableInEquation(epsilon,nv,1,eq);
900  AddEquation(eq,&newEqs);
901  }
902  }
903 
904  for(i=0;i<eqs->nm;i++)
906 
907  DeleteEquations(eqs);
908  CopyEquations(eqs,&newEqs); /* cached infor empty in copy */
909  DeleteEquations(&newEqs);
910 }
911 
912 boolean ReplaceVariableInEquations(double epsilon,
913  unsigned int nv,TLinearConstraint *lc,
914  Tequations *eqs)
915 {
916  boolean hold;
917  unsigned int j,r;
918  Tequations newEqs;
919  Tequation *eqn;
920  unsigned int nTerms,nvNew;
921  Tinterval error;
922  double ct;
923 
924 
925  if ((!eqs->scalar)||(!eqs->polynomial))
926  {
927  /* Matrix or trigonometric equations allow limited replacements */
928 
930  if (nTerms>1)
931  Error("Wrong variable replacement for matrix/trigonometric equations in ReplaceVariableInEquations: can not use general replacements");
932  if (nTerms==0)
933  nvNew=NO_UINT; /* replace nv by a ct */
934  else
935  {
936  /* nvNew is the other variable in the 'lc' */
937  nvNew=GetLinearConstraintVariable(0,lc); /* replace nv by a var */
938  if (nvNew==nv)
939  Error("Self-replacement in ReplaceVariableInEquations");
940  }
941 
942  GetLinearConstraintError(&error,lc);
943  if (IntervalSize(&error)>ZERO)
944  Error("Wrong variable replacement for matrix/trigonometric equations in ReplaceVariableInEquations: the replacement must be constant");
945  ct=-IntervalCenter(&error);
946 
947  if ((nvNew!=NO_UINT)&&(fabs(ct)>ZERO))
948  Error("Wrong variable replacement for matrix/trigonometric equations in ReplaceVariableInEquations: replacement can not have offset");
949  }
950 
951  hold=TRUE;
952  InitEquations(&newEqs);
953 
954  for(j=0;((hold)&(j<eqs->nm));j++)
955  {
956  if (nvNew==NO_UINT)
957  r=FixVarInMEquation(nv,ct,eqs->mequation[j]);
958  else
959  {
960  ReplaceVarInMEquation(nv,nvNew,eqs->mequation[j]);
961  r=0;
962  }
963  if (r==0) /* normal that holds -> include in the new set */
964  AddMatrixEquation(eqs->mequation[j],&newEqs);
965  else
966  hold=(r==1); /* no need to add ct that holds. if not holds -> error */
967  }
968 
969  for(j=0;((hold)&&(j<eqs->n));j++)
970  {
971  eqn=GetOriginalEquation(eqs->equation[j]);
972 
973  r=ReplaceVariableInEquation(epsilon,nv,lc,eqn);
974 
975  if (r==2)
976  hold=FALSE; /*the equation became ct and does not hold -> the whole system fails*/
977  else
978  {
979  if (r==0)
980  AddEquation(eqn,&newEqs);
981 
982  /*if r==1, a ct equation that holds -> no need to add it to the new set*/
983  }
984  }
985 
986  DeleteEquations(eqs);
987  CopyEquations(eqs,&newEqs); /* cache information to empty */
988  DeleteEquations(&newEqs);
989 
990  return(hold);
991 }
992 
994 {
995  unsigned int i,j,jMin,nfi,neq,neqn,meq;
996  Tequation *eqi;
997  Tequations newEqs;
998  boolean changes;
999  Tequation *localMin; /* simplest equation when operation eqi with
1000  the rest of equations */
1001  unsigned int nmMin,nvMin,nm,nv;
1002 
1003  /*We try to get the simplest possible set of equations
1004  Simple equation = as less number of monomials as possible*/
1005 
1006  changes=FALSE;
1007 
1008  neq=NScalarEquations(eqs); /* Only affects the scalar equations */
1009  InitEquations(&newEqs);
1010  #if (_DEBUG>5)
1011  printf("Gaussian process:\n");
1012  #endif
1013  for(i=0;i<neq;i++)
1014  {
1015  eqi=GetOriginalEquation(eqs->equation[i]);
1016 
1017  if ((GetEquationCmp(eqi)!=EQU)||(GetEquationType(eqi)==DUMMY_EQ))
1018  AddEquation(eqi,&newEqs);
1019  else
1020  {
1021  nfi=GetNumMonomials(eqi);
1022 
1023  /* We try to simplify eqi linearly operating it with the
1024  already simplified equations and the equations still to be
1025  simplified. */
1026  neqn=NScalarEquations(&newEqs); /* only scalar but...*/
1027  meq=neqn+(neq-i-1); /* equations already processed and equations pending to be processed */
1028 
1029  /* For large systems, Gaussian elimination is very time consuming.
1030  Try to parallelize it if possible */
1031  NEW(localMin,meq,Tequation);
1032 
1033  /* See what is the best (i.e., the simplest equation) we can get operating
1034  equation 'i' with all other equations (the already 'simplified' and those
1035  still to be simplified) */
1036  #pragma omp parallel for private(j) schedule(dynamic)
1037  for(j=0;j<meq;j++)
1038  {
1039  /* private variables for the thread */
1040  unsigned int k;
1041  Tequation *eqj;
1042  Tmonomial *fi,*fj;
1043  unsigned int r;
1044  double ct;
1045  Tequation eqNew;
1046  unsigned int nmNew,nvNew,nmLocalMin,nvLocalMin;
1047 
1048  /* Initialize the 'simplest' equation with eqi and see
1049  if we can improve from this point */
1050  CopyEquation(&(localMin[j]),eqi);
1051  nmLocalMin=GetNumMonomials(&(localMin[j]));
1052  nvLocalMin=GetEquationNumVariables(&(localMin[j]));
1053 
1054  if (j<neqn)
1055  /* equations already simplified */
1056  eqj=GetOriginalEquation(newEqs.equation[j]);
1057  else
1058  /* equations still to be processed (with index larger than 'i') */
1059  eqj=GetOriginalEquation(eqs->equation[i+1+(j-neqn)]);
1060 
1061  if ((GetEquationCmp(eqj)==EQU)&&(GetEquationType(eqj)!=DUMMY_EQ))
1062  {
1063  /* eqi = alpha_k * m_k + ...
1064  with m_k a 'monomial' we have eqj = beta_k + m_k
1065  if eqj also includes m_k we perform the operation
1066  eq = eqi - eqj * alpha_k/beta_k
1067  This elimiates monomial (alpha_k * m_k) from eqi and
1068  possibly produces a simple eqi (assuming that the
1069  above operation do not introduces additional terms).
1070  */
1071  for(k=0;k<nfi;k++)
1072  {
1073  fi=GetMonomial(k,eqi);
1074  r=FindMonomial(fi,eqj);
1075 
1076  if (r!=NO_UINT)
1077  {
1078  /*If the monomial of eqi is also in eqj*/
1079  fj=GetMonomial(r,eqj);
1080  ct=-GetMonomialCt(fi)/GetMonomialCt(fj);
1081 
1082  CopyEquation(&eqNew,eqi);
1083  AccumulateEquations(eqj,ct,&eqNew);
1084 
1085  nmNew=GetNumMonomials(&eqNew);
1086  nvNew=GetEquationNumVariables(&eqNew);
1087 
1088  /*If the equation after operation has less monomials than
1089  the minimal equation we have up to now -> we have a new
1090  minimal */
1091 
1092  if ((nmNew<nmLocalMin)||
1093  ((nmNew==nmLocalMin)&&(nvNew<nvLocalMin)))
1094  {
1095  #if (_DEBUG>5)
1096  printf("\n Original eq: ");
1097  PrintEquation(stdout,NULL,eqi);
1098  printf(" Original ct: %f\n",ct);
1099  printf(" Accumulated eq: ");
1100  PrintEquation(stdout,NULL,eqj);
1101  printf(" Result: ");
1102  PrintEquation(stdout,NULL,&eqNew);
1103  #endif
1104 
1105  DeleteEquation(&(localMin[j]));
1106  CopyEquation(&(localMin[j]),&eqNew);
1107  nmLocalMin=nmNew;
1108  nvLocalMin=nvNew;
1109  }
1110  DeleteEquation(&eqNew);
1111  }
1112  }
1113  }
1114  }
1115  /* End of the parallel execution */
1116 
1117  /* find the simplest equation among the equation in localMin */
1118  nmMin=GetNumMonomials(eqi);
1119  nvMin=GetEquationNumVariables(eqi);
1120  jMin=NO_UINT; /* it can be the case that no option is better than
1121  the original variable */
1122  for(j=0;j<meq;j++)
1123  {
1124  nm=GetNumMonomials(&(localMin[j]));
1125  nv=GetEquationNumVariables(&(localMin[j]));
1126 
1127  if ((nm<nmMin)||
1128  ((nm==nmMin)&&(nv<nvMin)))
1129  {
1130  jMin=j;
1131  nmMin=nm;
1132  nvMin=nv;
1133  }
1134  }
1135  if (jMin!=NO_UINT)
1136  {
1137  /* We managed to simplify equation 'i' */
1138  AddEquation(&(localMin[jMin]),&newEqs);
1139  changes=TRUE;
1140  }
1141  else
1142  AddEquation(eqi,&newEqs);
1143 
1144  /* Release memory */
1145  #pragma omp parallel for private(j) schedule(dynamic)
1146  for(j=0;j<meq;j++)
1147  DeleteEquation(&(localMin[j]));
1148  free(localMin);
1149  }
1150  }
1151 
1152  /* The matrix equations are directly copied to the new set */
1153  for(i=0;i<eqs->nm;i++)
1154  AddMatrixEquation(eqs->mequation[i],&newEqs);
1155 
1156  /* Delete the previous set and keep the new one */
1157  DeleteEquations(eqs);
1158  CopyEquations(eqs,&newEqs); /* cache information reseted */
1159  DeleteEquations(&newEqs);
1160 
1161  return(changes);
1162 }
1163 
1164 unsigned int NEquations(Tequations *eqs)
1165 {
1166  return(eqs->neq);
1167 }
1168 
1169 unsigned int NScalarEquations(Tequations *eqs)
1170 {
1171  return(eqs->n);
1172 }
1173 
1174 unsigned int NSystemEquations(Tequations *eqs)
1175 {
1176  return(eqs->s);
1177 }
1178 
1179 unsigned int NCoordEquations(Tequations *eqs)
1180 {
1181  return(eqs->c);
1182 }
1183 
1184 unsigned int NDummyEquations(Tequations *eqs)
1185 {
1186  return(eqs->d);
1187 }
1188 
1189 unsigned int NEqualityEquations(Tequations *eqs)
1190 {
1191  return(eqs->e);
1192 }
1193 
1195 {
1196  return(eqs->neq-eqs->e);
1197 }
1198 
1200 {
1201  return(eqs->polynomial);
1202 }
1203 
1205 {
1206  return(eqs->scalar);
1207 }
1208 
1209 boolean IsSystemEquation(unsigned int i,Tequations *eqs)
1210 {
1211  if (i>=eqs->neq)
1212  Error("Index out of range in IsSystemEquation");
1213 
1214  if (i<eqs->n)
1216  else
1217  return(TRUE);
1218 }
1219 
1220 boolean IsCoordEquation(unsigned int i,Tequations *eqs)
1221 {
1222  if (i>=eqs->neq)
1223  Error("Index out of range in IsCoordEquation");
1224 
1225  return((i<eqs->n)&&
1227 }
1228 
1229 boolean IsDummyEquation(unsigned int i,Tequations *eqs)
1230 {
1231  if (i>=eqs->neq)
1232  Error("Index out of range in IsDummyEquation");
1233 
1234  return((i<eqs->n)&&
1236 }
1237 
1238 unsigned int GetEquationTypeN(unsigned int i,Tequations *eqs)
1239 {
1240  if (i>=eqs->neq)
1241  Error("Index out of range in GetEquationTypeN");
1242 
1243  if (eqs->equation[i]==NULL)
1244  return(NOTYPE_EQ);
1245  else
1246  {
1247  if (i<eqs->n)
1248  return(GetEquationType(GetOriginalEquation(eqs->equation[i])));
1249  else
1250  return(SYSTEM_EQ);
1251  }
1252 }
1253 
1254 boolean HasEquation(Tequation *equation,Tequations *eqs)
1255 {
1256  boolean found;
1257  unsigned int i;
1258 
1259  i=0;
1260  found=FALSE;
1261  while((i<eqs->n)&&(!found))
1262  {
1263  found=(CmpEquations(equation,GetOriginalEquation(eqs->equation[i]))==0);
1264  if (!found) i++;
1265  }
1266  return(found);
1267 }
1268 
1269 unsigned int CropEquation(unsigned int ne,
1270  unsigned int varType,
1271  double epsilon,double rho,
1272  Tbox *b,
1273  Tvariables *vs,
1274  Tequations *eqs)
1275 {
1276  unsigned int status;
1277  TequationInfo *ei;
1278  unsigned int cmp;
1279  Tequation *eq;
1280  Tvariable_set *vars;
1281 
1282  double val,alpha,beta;
1283  Tvariable_set *varsf;;
1284  Tinterval x_new,y_new,z_new;
1285  unsigned int nx,ny,nz;
1286  unsigned int m,i,j,k;
1287  Tinterval *is,bounds,range;
1288  Tbox bNew;
1289  Tinterval *isNew;
1290  boolean reduced;
1291  double l,u,c;
1292  unsigned int full;
1293 
1294  if (ne>=eqs->neq)
1295  Error("Index out of range in CropEquation");
1296 
1297  if (ne>=eqs->n)
1298  Error("CropEquation can only be used with scalar equations");
1299 
1300  ei=eqs->equation[ne];
1301 
1302  eq=GetOriginalEquation(ei);
1303 
1304  status=NOT_REDUCED_BOX;
1305 
1306  cmp=GetEquationCmp(eq);
1307  val=GetEquationValue(eq);
1308  m=GetBoxNIntervals(b);
1309  is=GetBoxIntervals(b);
1310  vars=GetEquationVariables(eq);
1311 
1312  #if (_DEBUG>6)
1313  printf("\n Croping Equation: %u\n",ne);
1314  #endif
1315 
1316  /* Trivial consistancy check: Interval evaluation must hold */
1317  EvaluateEquationInt(is,&range,eq);
1318  GetEquationBounds(&bounds,eq);
1319 
1320  #if (_DEBUG>6)
1321  printf(" Whole box test:\n");
1322  printf(" Left vs Right hand side: ");
1323  PrintInterval(stdout,&range);
1324  printf(" ");
1325  PrintInterval(stdout,&bounds);
1326  printf("\n");
1327  #endif
1328  if (!Intersect(&bounds,&range))
1329  {
1330  status=EMPTY_BOX;
1331  #if (_DEBUG>6)
1332  printf(" No intersection -> Empty box.\n");
1333  #endif
1334  }
1335  /* Stronger cuts based on EvaluateEquationInt could be implemented.
1336  Iterate considering only half of the interval for each variable (first
1337  the lower part, then the upper one) to check is any half can be
1338  trivially discarded. Repeat while there is any reduction.
1339  All this is done without bisection -> avoid branching. This
1340  technique to avoid branching can be used also at higher levels. */
1341  if (status!=EMPTY_BOX)
1342  {
1343  #if (_DEBUG>6)
1344  printf(" Half range tests:\n");
1345  #endif
1346  CopyBox(&bNew,b);
1347  isNew=GetBoxIntervals(&bNew);
1348  reduced=FALSE; /* eventually */
1349  do {
1350  status=NOT_REDUCED_BOX; /* at this loop, so far */
1351  for(i=0;((status!=EMPTY_BOX)&&(i<ei->n));i++)
1352  {
1353  k=GetVariableN(i,vars);
1354  l=LowerLimit(&(isNew[k]));
1355  u=UpperLimit(&(isNew[k]));
1356  c=IntervalCenter(&(isNew[k]));
1357  #if (_DEBUG>6)
1358  printf(" Variable %u/%u -> [%f %f %f] \n",k,ei->n,l,c,u);
1359  #endif
1360  /* If the range is not too tiny */
1361  if (((c-l)>=epsilon)&&((u-c)>=epsilon))
1362  {
1363  full=0; /* binary flags to detect which of the halves is full */
1364  for(j=0;j<2;j++)
1365  {
1366  if (j==0)
1367  NewInterval(l,c,&(isNew[k])); /* lower half */
1368  else
1369  NewInterval(c,u,&(isNew[k])); /* upper half */
1370  #if (_DEBUG>6)
1371  printf(" Considering range - [%f %f] (%u %u)\n",LowerLimit(&(isNew[k])),UpperLimit(&(isNew[k])),full,status);
1372  #endif
1373  EvaluateEquationInt(isNew,&range,eq);
1374  if (Intersect(&bounds,&range))
1375  {
1376  full|=(1<<j);
1377  #if (_DEBUG>6)
1378  printf(" Range is full (%u %u)\n",full,status);
1379  #endif
1380  }
1381  #if (_DEBUG>6)
1382  else
1383  printf(" Range is empty (%u %u)\n",full,status);
1384  #endif
1385  }
1386  #if (_DEBUG>6)
1387  printf(" Full flag %u (%u)\n",full,status);
1388  #endif
1389  switch(full)
1390  {
1391  case 3:
1392  /* keep both halves (restore original interval) */
1393  NewInterval(l,u,&(isNew[k]));
1394  break;
1395  case 2:
1396  /* keep upper half */
1397  NewInterval(c,u,&(isNew[k]));
1398  status=REDUCED_BOX;
1399  reduced=TRUE;
1400  break;
1401  case 1:
1402  /* keep lower half */
1403  NewInterval(l,c,&(isNew[k]));
1404  status=REDUCED_BOX;
1405  reduced=TRUE;
1406  break;
1407  case 0:
1408  /* keep no half */
1409  status=EMPTY_BOX;
1410  break;
1411  }
1412  }
1413  }
1414  } while (status==REDUCED_BOX);
1415  if (reduced)
1416  {
1417  for(i=0;i<m;i++)
1418  CopyInterval(&(is[i]),&(isNew[i]));
1419  }
1420  DeleteBox(&bNew);
1421  }
1422 
1423  /* If the box is not already empty -> crop using the linear approximation (or special functions). */
1424  if ((status==NOT_REDUCED_BOX)&&(cmp==EQU))
1425  {
1426  #if (_DEBUG>6)
1427  printf(" Eq: ");
1428  PrintEquation(stdout,NULL,eq);
1429  printf(" Input ranges: ");
1430  for(i=0;i<ei->n;i++)
1431  {
1432  k=GetVariableN(i,vars);
1433  printf(" v[%u]=",k);PrintInterval(stdout,&(is[k]));printf(" ");
1434  }
1435  printf("\n");
1436  #endif
1437 
1438 
1439  /* Special equations cropped with special functions that get tighter bounds
1440  (they use non-linear functions) */
1441  switch(ei->EqType)
1442  {
1443  case LINEAR_EQUATION:
1444  status=CropLinearConstraint(epsilon,varType,b,vs,ei->lc);
1445  break;
1446 
1447  case PARABOLA_EQUATION:
1448  /* x^2 + \alpha y = \beta */
1451  alpha=GetMonomialCt(GetMonomial(1,eq));
1452  beta=GetEquationValue(eq);
1453 
1454  if (((IntervalSize(&(is[nx]))>=epsilon)||
1455  (IntervalSize(&(is[ny]))>=epsilon))&&
1456  (IntervalSize(&(is[nx]))<INF))
1457  {
1458  if (RectangleParabolaClipping(&(is[nx]),alpha,beta,&(is[ny]),&x_new,&y_new))
1459  {
1460  status=REDUCED_BOX;
1461 
1462  if (GetVariableTypeN(nx,vs)&varType)
1463  CopyInterval(&(is[nx]),&x_new);
1464 
1465  if (GetVariableTypeN(ny,vs)&varType)
1466  CopyInterval(&(is[ny]),&y_new);
1467  }
1468  else
1469  status=EMPTY_BOX;
1470  }
1471  break;
1472 
1473  case SADDLE_EQUATION:
1474  /* x*y + \alpha z = \beta */
1475  varsf=GetMonomialVariables(GetMonomial(0,eq));
1476  alpha=GetMonomialCt(GetMonomial(1,eq));
1477  beta=GetEquationValue(eq);
1478 
1479  nx=GetVariableN(0,varsf);
1480  ny=GetVariableN(1,varsf);
1482 
1483  if (((IntervalSize(&(is[nx]))>=epsilon)||
1484  (IntervalSize(&(is[ny]))>=epsilon)||
1485  (IntervalSize(&(is[nz]))>=epsilon))&&
1486  (IntervalSize(&(is[nx]))<INF)&&
1487  (IntervalSize(&(is[ny]))<INF))
1488  {
1489  if (BoxSaddleClipping(&(is[nx]),&(is[ny]),alpha,beta,&(is[nz]),
1490  &x_new,&y_new,&z_new))
1491  {
1492  status=REDUCED_BOX;
1493 
1494  if (GetVariableTypeN(nx,vs)&varType)
1495  CopyInterval(&(is[nx]),&x_new);
1496 
1497  if (GetVariableTypeN(ny,vs)&varType)
1498  CopyInterval(&(is[ny]),&y_new);
1499 
1500  if (GetVariableTypeN(nz,vs)&varType)
1501  CopyInterval(&(is[nz]),&z_new);
1502  }
1503  else
1504  status=EMPTY_BOX;
1505  }
1506  break;
1507 
1509  /* xy=\beta is transformed to xy + \alpha z= \beta with z=[0,0]*/
1510  nx=GetVariableN(0,vars);
1511  ny=GetVariableN(1,vars);
1512 
1513  if (((IntervalSize(&(is[nx]))>=epsilon)||
1514  (IntervalSize(&(is[ny]))>=epsilon))&&
1515  (IntervalSize(&(is[nx]))<INF)&&
1516  (IntervalSize(&(is[ny]))<INF))
1517  {
1518  Tinterval r;
1519 
1520  NewInterval(-ZERO,+ZERO,&r);
1521 
1522  if (BoxSaddleClipping(&(is[nx]),&(is[ny]),1.0,val,&r,
1523  &x_new,&y_new,&z_new))
1524  {
1525  status=REDUCED_BOX;
1526 
1527  if (GetVariableTypeN(nx,vs)&varType)
1528  CopyInterval(&(is[nx]),&x_new);
1529 
1530  if (GetVariableTypeN(ny,vs)&varType)
1531  CopyInterval(&(is[ny]),&y_new);
1532  }
1533  else
1534  status=EMPTY_BOX;
1535  }
1536  break;
1537 
1538  case CIRCLE_EQUATION:
1539  /* x^2 + y^2 = val */
1540  nx=GetVariableN(0,vars);
1541  ny=GetVariableN(1,vars);
1542 
1543  if ((IntervalSize(&(is[nx]))>=epsilon)||
1544  (IntervalSize(&(is[ny]))>=epsilon))
1545  {
1546  if (RectangleCircleClipping(val,
1547  &(is[nx]),&(is[ny]),
1548  &x_new,&y_new))
1549  {
1550  status=REDUCED_BOX;
1551 
1552  if (GetVariableTypeN(nx,vs)&varType)
1553  CopyInterval(&(is[nx]),&x_new);
1554 
1555  if (GetVariableTypeN(ny,vs)&varType)
1556  CopyInterval(&(is[ny]),&y_new);
1557  }
1558  else
1559  status=EMPTY_BOX;
1560  }
1561  break;
1562 
1563  case SPHERE_EQUATION:
1564  /* x^2 + y^2 + z^2 = val */
1565  nx=GetVariableN(0,vars);
1566  ny=GetVariableN(1,vars);
1567  nz=GetVariableN(2,vars);
1568 
1569  if ((IntervalSize(&(is[nx]))>=epsilon)||
1570  (IntervalSize(&(is[ny]))>=epsilon)||
1571  (IntervalSize(&(is[nz]))>=epsilon))
1572  {
1573  if (BoxSphereClipping(val,
1574  &(is[nx]),&(is[ny]),&(is[nz]),
1575  &x_new,&y_new,&z_new))
1576  {
1577  status=REDUCED_BOX;
1578 
1579  if (GetVariableTypeN(nx,vs)&varType)
1580  CopyInterval(&(is[nx]),&x_new);
1581 
1582  if (GetVariableTypeN(ny,vs)&varType)
1583  CopyInterval(&(is[ny]),&y_new);
1584 
1585  if (GetVariableTypeN(nz,vs)&varType)
1586  CopyInterval(&(is[nz]),&z_new);
1587  }
1588  else
1589  status=EMPTY_BOX;
1590  }
1591  break;
1592 
1593  case GENERAL_EQUATION:
1594  /* When simplifying systems it is quite common to introduce equations
1595  of type x^2=ct or x*y=ct. We treat them as special cases and taking into
1596  accound the non-linealities -> stronger crop
1597  Here we treat the case x^2=ct.
1598  The case x*y=ct is treated as a BILINEAL_MONOMIAL_EQUATION above
1599  (We differentiate this type of equations because they require not only
1600  a different crop but also a different linalization).
1601  */
1602  if ((PolynomialEquation(eq))&&
1603  (GetNumMonomials(eq)==1)&&
1604  (GetMonomialCt(GetMonomial(0,eq))==1))
1605  {
1606  Tinterval r;
1607 
1608  if (VariableSetSize(vars)==1) /*only one variable in the equation*/
1609  {
1610  /* Only one variable included in the equation-> x^2=ct
1611  (the linal case x=ct is treated above (LINEAL_EQUATION) */
1612  /* ax^2=ct is transformed to x^2+y=ct with y=[0,0] */
1613  nx=GetVariableN(0,vars);
1614 
1615  if ((IntervalSize(&(is[nx]))>=epsilon)&&
1616  (IntervalSize(&(is[nx]))<INF)&&
1617  (GetVariableTypeN(nx,vs)&varType))
1618  {
1619  NewInterval(-ZERO,+ZERO,&r);
1620 
1621  if (RectangleParabolaClipping(&(is[nx]),1.0,val,&r,&x_new,&y_new))
1622  {
1623  status=REDUCED_BOX;
1624  CopyInterval(&(is[nx]),&x_new);
1625  }
1626  else
1627  status=EMPTY_BOX;
1628  }
1629  }
1630  else
1631  Error("Three variables in a single monomial?");
1632  }
1633  else
1634  {
1635  double *c; /*central point*/
1636  TLinearConstraint lc;
1637 
1638  NEW(c,m,double);
1639 
1640  do {
1641  /*possible improvement -> use a random point inside the ranges
1642  this will cut increase the crop */
1643  for(i=0;i<ei->n;i++)
1644  {
1645  k=GetVariableN(i,vars);
1646  c[k]=IntervalCenter(&(is[k]));
1647  }
1648 
1650 
1651  GetLinearConstraintError(&bounds,&lc);
1652  SimplexExpandBounds(cmp,&bounds);
1653  SetLinearConstraintError(&bounds,&lc);
1654 
1655  status=CropLinearConstraint(epsilon,varType,b,vs,&lc);
1656 
1658 
1659  } while(status==REDUCED_BOX);
1660 
1661  free(c);
1662  }
1663  break;
1664 
1665  default:
1666  Error("Unknown equation type in CropEquation");
1667  }
1668  }
1669  #if (_DEBUG>6)
1670  else
1671  {
1672  if (cmp!=EQU)
1673  printf(" Inequalities are not cropped\n");
1674  }
1675  if (status!=EMPTY_BOX)
1676  {
1677  printf(" Output ranges: ");
1678  for(i=0;i<ei->n;i++)
1679  {
1680  k=GetVariableN(i,vars);
1681  printf(" v[%u]=",k);PrintInterval(stdout,&(is[k]));printf(" ");
1682  }
1683  printf("\n ");
1684  }
1685  #endif
1686 
1687  return(status);
1688 }
1689 
1691 {
1692  unsigned int t;
1693 
1694  if (eqs->n==eqs->m)
1695  {
1696  unsigned int i,k;
1697 
1698  k=eqs->m;
1699  MEM_DUP(eqs->equation,eqs->m,TequationInfo *);
1700  for(i=k;i<eqs->m;i++)
1701  eqs->equation[i]=NULL;
1702  }
1703 
1704  NEW(eqs->equation[eqs->n],1,TequationInfo);
1705  SetEquationInfo(equation,eqs->equation[eqs->n]);
1706 
1707  t=GetEquationType(equation);
1708  if (t==SYSTEM_EQ) eqs->s++;
1709  if (t==COORD_EQ) eqs->c++;
1710  if (t==DUMMY_EQ) eqs->d++;
1711  if (GetEquationCmp(equation)==EQU) eqs->e++;
1712  eqs->polynomial=((eqs->polynomial)&&(PolynomialEquation(equation)));
1713 
1714  eqs->n++;
1715  eqs->neq++;
1716 
1717  /* Remove the cached information, if any */
1718  eqs->nsEQU=0;
1719  if (eqs->eqEQU!=NULL)
1720  free(eqs->eqEQU);
1721 }
1722 
1723 void AddEquation(Tequation *equation,Tequations *eqs)
1724 {
1725  if ((GetEquationType(equation)==NOTYPE_EQ)||(GetEquationCmp(equation)==NOCMP))
1726  Error("Adding an equation with unknown type of cmp");
1727 
1728  NormalizeEquation(equation);
1729 
1730  if ((GetNumMonomials(equation)>0)&&(!HasEquation(equation,eqs)))
1731  {
1732  int j;
1733  TequationInfo *s;
1734 
1735  AddEquationInt(equation,eqs);
1736 
1737  j=eqs->n-1;
1738  while((j>0)&&(CmpEquations(GetOriginalEquation(eqs->equation[j-1]),
1739  GetOriginalEquation(eqs->equation[j]))==1))
1740  {
1741  s=eqs->equation[j-1];
1742  eqs->equation[j-1]=eqs->equation[j];
1743  eqs->equation[j]=s;
1744 
1745  j--;
1746  }
1747  }
1748 }
1749 
1751 {
1752  if ((GetEquationType(equation)==NOTYPE_EQ)||(GetEquationCmp(equation)==NOCMP))
1753  Error("Adding an equation with unknown type of cmp");
1754 
1755  AddEquationInt(equation,eqs);
1756 }
1757 
1758 
1760 {
1761  unsigned int k;
1762 
1763  eqs->scalar=FALSE;
1764  if (HasRotations(equation))
1765  eqs->polynomial=FALSE;
1766 
1767  if (eqs->nm==eqs->mm)
1768  {
1769  unsigned int i;
1770 
1771  k=eqs->mm;
1772  MEM_DUP(eqs->mequation,eqs->mm,TMequation*);
1773  for(i=k;i<eqs->mm;i++)
1774  eqs->mequation[i]=NULL;
1775  }
1776  NEW(eqs->mequation[eqs->nm],1,TMequation);
1777  CopyMEquation(eqs->mequation[eqs->nm],equation);
1778  eqs->nm++;
1779 
1780  k=NumberScalarEquations(equation);
1781  eqs->neq+=k;
1782  eqs->s+=k;
1783  eqs->e+=k;
1784 
1785  /* Remove the cached information, if any */
1786  eqs->nsEQU=0;
1787  if (eqs->eqEQU!=NULL)
1788  free(eqs->eqEQU);
1789 }
1790 
1792 {
1793  if (n<eqs->n)
1794  return(GetOriginalEquation(eqs->equation[n]));
1795  else
1796  return(NULL);
1797 }
1798 
1799 Tequation *GetEquation(unsigned int n,Tequations *eqs)
1800 {
1801  if (!eqs->scalar)
1802  Error("GetEquation can only be used with scalar equations");
1803 
1804  if (n<eqs->n)
1805  return(GetOriginalEquation(eqs->equation[n]));
1806  else
1807  return(NULL);
1808 }
1809 
1810 boolean LinearizeSaddleEquation(double epsilon,unsigned int safeSimplex,Tbox *b,
1811  TSimplex *lp,TequationInfo *ei)
1812 {
1813  Tvariable_set *varsf;
1814  unsigned int nx,ny,nz;
1815  double x_min,x_max;
1816  double y_min,y_max;
1817  double *c;
1818  boolean full;
1819  Tequation *eq;
1820  Tinterval *is;
1821  unsigned int m;
1822 
1823  m=GetBoxNIntervals(b);
1824  is=GetBoxIntervals(b);
1825  eq=GetOriginalEquation(ei);
1826 
1827  /* x*y + \alpha z = \beta where \alpha can be zero.
1828  In this case the z variable is not used. */
1829  varsf=GetMonomialVariables(GetMonomial(0,eq));
1830 
1831  nx=GetVariableN(0,varsf);
1832  ny=GetVariableN(1,varsf);
1834 
1835  x_min=LowerLimit(&(is[nx]));
1836  x_max=UpperLimit(&(is[nx]));
1837 
1838  y_min=LowerLimit(&(is[ny]));
1839  y_max=UpperLimit(&(is[ny]));
1840 
1841  if ((x_min<-epsilon)&&(x_max>epsilon))
1842  {
1843  double px[4]={x_min,x_min,x_max,x_max};
1844  double py[4]={y_min,y_max,y_min,y_max};
1845  unsigned int cmp[4]={LEQ,GEQ,GEQ,LEQ};
1846 
1847  unsigned int i;
1848 
1849  NEW(c,m,double);
1850 
1851  full=TRUE;
1852  for(i=0;((full)&&(i<4));i++)
1853  {
1854  c[nx]=px[i];
1855  c[ny]=py[i];
1856  c[nz]=0; /*This is actually not used in any case*/
1857 
1858  full=LinearizeGeneralEquationInt(cmp[i],epsilon,safeSimplex,b,c,lp,ei);
1859  }
1860  free(c);
1861  }
1862  else
1863  full=LinearizeGeneralEquation(epsilon,safeSimplex,b,lp,ei);
1864 
1865  return(full);
1866 }
1867 
1868 boolean LinearizeBilinealMonomialEquation(double epsilon,double lr2tm,
1869  unsigned int safeSimplex,Tbox *b,
1870  TSimplex *lp,TequationInfo *ei)
1871 {
1872  Tvariable_set *varsf;
1873  unsigned int nx,ny;
1874  double x_min,x_max;
1875  double y_min,y_max;
1876  double *c;
1877  boolean full;
1878  Tequation *eq;
1879  Tinterval *is;
1880  unsigned int m;
1881  double val;
1882 
1883  m=GetBoxNIntervals(b);
1884  is=GetBoxIntervals(b);
1885  eq=GetOriginalEquation(ei);
1886 
1887  /* x*y = \beta */
1888  varsf=GetMonomialVariables(GetMonomial(0,eq));
1889 
1890  nx=GetVariableN(0,varsf);
1891  ny=GetVariableN(1,varsf);
1892 
1893  x_min=LowerLimit(&(is[nx]));
1894  x_max=UpperLimit(&(is[nx]));
1895 
1896  y_min=LowerLimit(&(is[ny]));
1897  y_max=UpperLimit(&(is[ny]));
1898 
1899  val=GetEquationValue(eq);
1900  if (fabs(val)<epsilon)
1901  {
1902  /* x*y=0 -> a constraint for each corner*/
1903  double px[4]={x_min,x_min,x_max,x_max};
1904  double py[4]={y_min,y_max,y_min,y_max};
1905  unsigned int cmp[4]={LEQ,GEQ,GEQ,LEQ};
1906 
1907  unsigned int i;
1908 
1909  NEW(c,m,double);
1910 
1911  full=TRUE;
1912  for(i=0;((full)&&(i<4));i++)
1913  {
1914  /* Only consider corners outside the curbe */
1915  if (fabs(px[i]*py[i]-val)>epsilon)
1916  {
1917  c[nx]=px[i];
1918  c[ny]=py[i];
1919 
1920  full=LinearizeGeneralEquationInt(cmp[i],epsilon,safeSimplex,b,c,lp,ei);
1921  }
1922  }
1923  free(c);
1924  }
1925  else
1926  {
1927  if (0) //(((x_max-x_min)<lr2tm)&&((y_max-y_min)<lr2tm))
1928  /* A small box in both dimensions */
1929  full=LinearizeGeneralEquation(epsilon,safeSimplex,b,lp,ei);
1930  else
1931  {
1932  /* x*y=beta beta!=0 -> one constraint for each corner*/
1933  /* we add epsilon to avoid numerical issues if the box intersects
1934  the curbe in one corner */
1935  double px[4]={x_min-epsilon,x_min-epsilon,x_max+epsilon,x_max+epsilon};
1936  double py[4]={y_min-epsilon,y_max+epsilon,y_min-epsilon,y_max+epsilon};
1937  unsigned int cmp[4]={LEQ,GEQ,GEQ,LEQ};
1938 
1939  unsigned int i;
1940 
1941  NEW(c,m,double);
1942 
1943  full=TRUE;
1944  for(i=0;((full)&&(i<4));i++)
1945  {
1946  /* Only consider corners outside the curbe */
1947  if (fabs(px[i]*py[i]-val)>epsilon)
1948  {
1949  c[nx]=px[i];
1950  c[ny]=py[i];
1951 
1952  full=LinearizeGeneralEquationInt(cmp[i],epsilon,safeSimplex,b,c,lp,ei);
1953  }
1954  }
1955 
1956  if ((x_max<0)||(x_min>0))
1957  {
1958  /* if the box is at one side of the Y axis -> one additional constraint
1959  tangent to the curbe */
1960  c[nx]=(x_max<0?-1.0:1.0)*sqrt(x_max*x_min);
1961  c[ny]=val/c[nx];
1962 
1963  full=LinearizeGeneralEquationInt((val>0?GEQ:LEQ),epsilon,safeSimplex,b,c,lp,ei);
1964  }
1965  free(c);
1966  }
1967 
1968  }
1969 
1970  return(full);
1971 }
1972 
1973 boolean LinearizeParabolaEquation(double epsilon,unsigned int safeSimplex,
1974  Tbox *b,
1975  TSimplex *lp,TequationInfo *ei)
1976 {
1977  unsigned int nx,ny;
1978  double x_min,x_max,x_c;
1979  double *c;
1980  boolean full;
1981  Tequation *eq;
1982  Tinterval *is;
1983  unsigned int m;
1984 
1985  m=GetBoxNIntervals(b);
1986  is=GetBoxIntervals(b);
1987  eq=GetOriginalEquation(ei);
1988 
1989  /* x^2 + \alpha y = \beta */
1992 
1993  x_min=LowerLimit(&(is[nx]));
1994  x_max=UpperLimit(&(is[nx]));
1995  x_c=IntervalCenter(&(is[nx]));
1996 
1997  NEW(c,m,double);
1998 
1999  {
2000  double px[3]={x_c,x_min,x_max};
2001  unsigned int cmp[3]={EQU,LEQ,LEQ};
2002  unsigned int i;
2003 
2004  full=TRUE;
2005  for(i=0;((full)&&(i<3));i++)
2006  {
2007  c[nx]=px[i];
2008  c[ny]=0; /*The value of 'y' is not used in the linealization*/
2009 
2010  full=LinearizeGeneralEquationInt(cmp[i],epsilon,safeSimplex,b,c,lp,ei);
2011  }
2012  }
2013 
2014  free(c);
2015 
2016  return(full);
2017 }
2018 
2019 boolean LinearizeCircleEquation(double epsilon,
2020  unsigned int safeSimplex,
2021  Tbox *b,
2022  TSimplex *lp,TequationInfo *ei)
2023 {
2024  Tequation *eq;
2025  Tvariable_set *vars;
2026  unsigned int nx,ny;
2027  double x_min,x_max,x_c;
2028  double y_min,y_max,y_c;
2029  double *c;
2030  double r2;
2031  /*At most 5 linearization points are selected (one
2032  for each box corner and one from the center of the
2033  interval x,y)*/
2034  double cx[5];
2035  double cy[5];
2036  unsigned int cmp[5];
2037  unsigned int i,nc;
2038  boolean full;
2039  Tinterval *is;
2040  unsigned int m;
2041  unsigned int cmpEq;
2042 
2043  m=GetBoxNIntervals(b);
2044  is=GetBoxIntervals(b);
2045  eq=GetOriginalEquation(ei);
2046  cmpEq=GetEquationCmp(eq);
2047 
2048  vars=GetEquationVariables(eq);
2049 
2050  r2=GetEquationValue(eq);
2051 
2052  nx=GetVariableN(0,vars);
2053  ny=GetVariableN(1,vars);
2054 
2055  x_min=LowerLimit(&(is[nx]));
2056  x_max=UpperLimit(&(is[nx]));
2057  x_c=IntervalCenter(&(is[nx]));
2058 
2059  y_min=LowerLimit(&(is[ny]));
2060  y_max=UpperLimit(&(is[ny]));
2061  y_c=IntervalCenter(&(is[ny]));
2062 
2063  NEW(c,m,double); /* space for the linealization point */
2064 
2065  /* for large input ranges (both in x and y) we add linealization constraints
2066  from the corners of the box*/
2067  nc=0;
2068  if (cmpEq!=GEQ)
2069  {
2070  /* Check which of the 4 box corners are out of the circle.
2071  For the external points we add a linealization point
2072  selected on the circle: intersection of the circle and a
2073  line from the origin to the corner (a normalization of
2074  point (x,y) to norm sqrt(r2))
2075  */
2076  double px[4]={x_min,x_min,x_max,x_max};
2077  double py[4]={y_min,y_max,y_min,y_max};
2078  double norm;
2079 
2080  for(i=0;i<4;i++)
2081  {
2082  ROUNDDOWN;
2083  norm=px[i]*px[i]+py[i]*py[i];
2084  ROUNDNEAR;
2085  if (norm>(r2+epsilon)) /*corner (clearly) out of the circle*/
2086  {
2087  norm=sqrt(r2/norm);
2088  cx[nc]=px[i]*norm;
2089  cy[nc]=py[i]*norm;
2090  cmp[nc]=LEQ;
2091  nc++;
2092  }
2093  }
2094  }
2095 
2096  /* A point selected from the center of x range is added always
2097  'y' is selected so that it is on the circle, if possible.
2098  If not, y is just the center of the y range
2099  */
2100  cx[nc]=x_c;
2101  cy[nc]=y_c;
2102  cmp[nc]=cmpEq;
2103  nc++;
2104 
2105  full=TRUE;
2106  for(i=0;((full)&&(i<nc));i++)
2107  {
2108  c[nx]=cx[i];
2109  c[ny]=cy[i];
2110 
2111  full=LinearizeGeneralEquationInt(cmp[i],epsilon,safeSimplex,b,c,lp,ei);
2112  }
2113 
2114  free(c);
2115 
2116  return(full);
2117 }
2118 
2119 boolean LinearizeSphereEquation(double epsilon,unsigned int safeSimplex,
2120  Tbox *b,
2121  TSimplex *lp,TequationInfo *ei)
2122 {
2123  Tequation *eq;
2124  Tvariable_set *vars;
2125  unsigned int nx,ny,nz;
2126  double x_min,x_max,x_c;
2127  double y_min,y_max,y_c;
2128  double z_min,z_max,z_c;
2129  double *c;
2130  double r2;
2131  /*At most 9 linearization points are selected (one
2132  for each box corner and one from the center of the
2133  interval x,y,z)*/
2134  double cx[9];
2135  double cy[9];
2136  double cz[9];
2137  unsigned int cmp[9];
2138  unsigned int i,nc;
2139  boolean full;
2140  Tinterval *is;
2141  unsigned int m;
2142  unsigned int cmpEq;
2143 
2144  m=GetBoxNIntervals(b);
2145  is=GetBoxIntervals(b);
2146  eq=GetOriginalEquation(ei);
2147  cmpEq=GetEquationCmp(eq);
2148 
2149  vars=GetEquationVariables(eq);
2150 
2151  r2=GetEquationValue(eq);
2152 
2153  nx=GetVariableN(0,vars);
2154  ny=GetVariableN(1,vars);
2155  nz=GetVariableN(2,vars);
2156 
2157  x_min=LowerLimit(&(is[nx]));
2158  x_max=UpperLimit(&(is[nx]));
2159  x_c=IntervalCenter(&(is[nx]));
2160 
2161  y_min=LowerLimit(&(is[ny]));
2162  y_max=UpperLimit(&(is[ny]));
2163  y_c=IntervalCenter(&(is[ny]));
2164 
2165  z_min=LowerLimit(&(is[nz]));
2166  z_max=UpperLimit(&(is[nz]));
2167  z_c=IntervalCenter(&(is[nz]));
2168 
2169  NEW(c,m,double); /* space for the linealization point */
2170 
2171  /* for large input ranges (both in x and y) we add linealization constraints
2172  from the corners of the box*/
2173  nc=0;
2174  if (cmpEq!=GEQ)
2175  {
2176  /* Check which of the 8 box corners are out of the sphere.
2177  For the external points we add a linealization point
2178  selected on the sphere: intersection of the sphere and a
2179  line from the origin to the corner (a normalization of
2180  point (x,y,z) to norm sqrt(r2))
2181  */
2182  double px[8]={x_min,x_min,x_min,x_min,x_max,x_max,x_max,x_max};
2183  double py[8]={y_min,y_min,y_max,y_max,y_min,y_min,y_max,y_max};
2184  double pz[8]={z_min,z_max,z_min,z_max,z_min,z_max,z_min,z_max};
2185  double norm;
2186 
2187  for(i=0;i<8;i++)
2188  {
2189  ROUNDDOWN;
2190  norm=px[i]*px[i]+py[i]*py[i]+pz[i]*pz[i];
2191  ROUNDNEAR;
2192  if (norm>(r2+epsilon)) /*corner (clearly) out of the sphere*/
2193  {
2194  norm=sqrt(r2/norm);
2195  cx[nc]=px[i]*norm;
2196  cy[nc]=py[i]*norm;
2197  cz[nc]=pz[i]*norm;
2198  cmp[nc]=LEQ;
2199  nc++;
2200  }
2201  }
2202  }
2203 
2204  /* A point selected from the center of x range is added always
2205  'y' is selected so that it is on the circle, if possible.
2206  If not, y is just eh center of the y range
2207  */
2208  cx[nc]=x_c;
2209  cy[nc]=y_c;
2210  cz[nc]=z_c;
2211  cmp[nc]=cmpEq;
2212  nc++;
2213 
2214  full=TRUE;
2215  for(i=0;((full)&&(i<nc));i++)
2216  {
2217  c[nx]=cx[i];
2218  c[ny]=cy[i];
2219  c[nz]=cz[i];
2220 
2221  full=LinearizeGeneralEquationInt(cmp[i],epsilon,safeSimplex,b,c,lp,ei);
2222  }
2223 
2224  free(c);
2225 
2226  return(full);
2227 }
2228 
2229 boolean LinearizeGeneralEquationInt(unsigned int cmp,
2230  double epsilon,
2231  unsigned int safeSimplex,
2232  Tbox *b,double *c,
2233  TSimplex *lp,TequationInfo *ei)
2234 {
2235  Tvariable_set *vars;
2236  TLinearConstraint lc;
2237  boolean full=TRUE;
2238 
2240 
2241  if (GetBoxMaxSizeVarSet(vars,b)<INF)
2242  {
2244 
2245  full=SimplexAddNewConstraint(epsilon,safeSimplex,&lc,cmp,GetBoxIntervals(b),lp);
2246 
2248  }
2249 
2250  return(full);
2251 }
2252 
2253 boolean LinearizeGeneralEquation(double epsilon,
2254  unsigned int safeSimplex,
2255  Tbox *b,
2256  TSimplex *lp,TequationInfo *ei)
2257 {
2258  Tequation *eq;
2259  unsigned int i,k;
2260  Tvariable_set *vars;
2261  double *c;
2262  boolean full;
2263  Tinterval *is;
2264  unsigned int m;
2265 
2266  m=GetBoxNIntervals(b);
2267  is=GetBoxIntervals(b);
2268 
2269  eq=GetOriginalEquation(ei);
2270 
2271  vars=GetEquationVariables(eq);
2272 
2273  NEW(c,m,double);
2274  for(i=0;i<ei->n;i++)
2275  {
2276  k=GetVariableN(i,vars);
2277  c[k]=IntervalCenter(&(is[k]));
2278  }
2279 
2280  full=LinearizeGeneralEquationInt(GetEquationCmp(eq),epsilon,safeSimplex,b,c,lp,ei);
2281 
2282  free(c);
2283 
2284  return(full);
2285 }
2286 
2287 boolean AddEquation2Simplex(unsigned int ne, /*eq identifier*/
2288  double lr2tm_q,double lr2tm_s,
2289  double epsilon,
2290  unsigned int safeSimplex,
2291  double rho,
2292  Tbox *b,
2293  Tvariables *vs,
2294  TSimplex *lp,
2295  Tequations *eqs)
2296 {
2297  boolean full;
2298 
2299  full=TRUE;
2300 
2301  if (!eqs->scalar)
2302  Error("AddEquation2Simplex can only be used with scalar equations");
2303 
2304  if (ne<eqs->n)/* No equation -> nothing done */
2305  {
2306  TequationInfo *ei;
2307  Tequation *eq;
2308  Tinterval r;
2309  double val;
2310  double s;
2311  boolean ctEq;
2312 
2313  ei=eqs->equation[ne];
2314  eq=GetOriginalEquation(ei);
2315 
2316  #if (_DEBUG>4)
2317  printf(" Adding equation %u of type %u to the simplex \n",ne,ei->EqType);
2318  printf(" ");
2319  PrintEquation(stdout,NULL,eq);
2320  #endif
2321 
2322  #if (_DEBUG>4)
2323  printf(" Cropping equation\n");
2324  #endif
2325 
2326  if (CropEquation(ne,ANY_TYPE_VAR,epsilon,rho,b,vs,eqs)==EMPTY_BOX)
2327  {
2328  #if ((!_USE_MPI)&&(_DEBUG>1))
2329  fprintf(stderr,"C");
2330  #endif
2331  full=FALSE;
2332  }
2333  else
2334  {
2335  /*There is no need to add constant equations to the simplex.
2336  Thus, we evaluate the equations and if the result is almost
2337  constant we just check if the equation holds or not.
2338  If not, the system has no solution.
2339  The same applies to inequalities that already hold
2340  */
2341 
2343  val=GetEquationValue(eq);
2344  IntervalOffset(&r,-val,&r);
2345 
2346  #if (_DEBUG>4)
2347  printf(" Defining constraints for equation\n");
2348  printf(" EvalIntEq (offset=%f): ",val);
2349  PrintInterval(stdout,&r);
2350  if (IntervalSize(&r)<INF)
2351  printf(" -> %g\n",IntervalSize(&r));
2352  else
2353  printf(" -> +inf\n");
2354  #endif
2355 
2356  ctEq=FALSE;
2357 
2358  switch(GetEquationCmp(eq))
2359  {
2360  case EQU:
2361  if ((safeSimplex>1)&&(IntervalSize(&r)<=(10*epsilon)))
2362  {
2363  /* We have an (almost) constant equation -> just check whether
2364  it holds or not but do not add it to the simplex */
2365  /* We allow for some numerical inestabilities: numerical values
2366  below epsilon are converted to zero when defining the linear
2367  constraints and, consequently, we have to admit epsilon-like
2368  errors
2369  */
2370  ctEq=TRUE;
2371  full=((IsInside(0.0,0.0,&r))||
2372  (fabs(LowerLimit(&r))<10*epsilon)||
2373  (fabs(UpperLimit(&r))<10*epsilon));
2374 
2375  }
2376  break;
2377 
2378  case LEQ:
2379  if (UpperLimit(&r)<0.0)
2380  {
2381  ctEq=TRUE;
2382  full=TRUE;
2383  }
2384  else
2385  {
2386  if (LowerLimit(&r)>0.0)
2387  {
2388  ctEq=TRUE;
2389  full=FALSE;
2390  }
2391  }
2392  break;
2393  case GEQ:
2394  if (UpperLimit(&r)<0.0)
2395  {
2396  ctEq=TRUE;
2397  full=FALSE;
2398  }
2399  else
2400  {
2401  if (LowerLimit(&r)>0.0)
2402  {
2403  ctEq=TRUE;
2404  full=TRUE;
2405  }
2406  }
2407  break;
2408  }
2409 
2410  #if (_DEBUG>4)
2411  if (ctEq)
2412  {
2413  printf(" Constant Equation\n");
2414  printf(" Eq eval:[%g %g] -> ",LowerLimit(&r),UpperLimit(&r));
2415  if (full)
2416  printf("ct full equation\n\n");
2417  else
2418  printf("ct empty equation\n\n");
2419  }
2420  #endif
2421 
2422  if (!ctEq)
2423  {
2424  Tequation eqClean;
2425  boolean changed;
2426 
2427  /* The equation is not constant, we proceed to add it into
2428  the simplex tableau, linearizing if needed.*/
2429 
2430  #if (_DEBUG>4)
2431  printf(" Cleaning equation of inf \n");
2432  #endif
2433  if (CleanInfEquation(eq,GetBoxIntervals(b),&changed,&eqClean))
2434  {
2435  TequationInfo *eiClean;
2436 
2437  if (changed)
2438  {
2439  #if (_DEBUG>4)
2440  printf(" The equation changed when cleaning inf \n");
2441  printf(" New equation:");
2442  PrintEquation(stdout,NULL,&eqClean);
2443  #endif
2444  NEW(eiClean,1,TequationInfo);
2445  SetEquationInfo(&eqClean,eiClean);
2447  }
2448  else
2449  {
2450  #if (_DEBUG>4)
2451  printf(" The equation remain the same when cleaning inf \n");
2452  #endif
2453  eiClean=ei;
2455  }
2456 
2457  /* Use a particular linear relaxation depending on the
2458  equation type */
2459  switch (ei->EqType)
2460  {
2461  case LINEAR_EQUATION:
2462  full=SimplexAddNewConstraint(epsilon,
2463  safeSimplex,
2464  ei->lc,
2465  GetEquationCmp(eq),
2466  GetBoxIntervals(b),lp);
2467  break;
2468 
2469  case SADDLE_EQUATION:
2470  if (s<lr2tm_s)
2471  full=LinearizeGeneralEquation(epsilon,safeSimplex,b,lp,eiClean);
2472  else
2473  full=LinearizeSaddleEquation(epsilon,safeSimplex,b,lp,eiClean);
2474  break;
2475 
2477  full=LinearizeBilinealMonomialEquation(epsilon,lr2tm_s,safeSimplex,b,lp,eiClean);
2478  break;
2479 
2480  case PARABOLA_EQUATION:
2481  if (s<lr2tm_q)
2482  full=LinearizeGeneralEquation(epsilon,safeSimplex,b,lp,eiClean);
2483  else
2484  full=LinearizeParabolaEquation(epsilon,safeSimplex,b,lp,eiClean);
2485  break;
2486 
2487  case CIRCLE_EQUATION:
2488  if (s<lr2tm_q)
2489  full=LinearizeGeneralEquation(epsilon,safeSimplex,b,lp,eiClean);
2490  else
2491  full=LinearizeCircleEquation(epsilon,safeSimplex,b,lp,eiClean);
2492  break;
2493 
2494  case SPHERE_EQUATION:
2495  if (s<lr2tm_q)
2496  full=LinearizeGeneralEquation(epsilon,safeSimplex,b,lp,eiClean);
2497  else
2498  full=LinearizeSphereEquation(epsilon,safeSimplex,b,lp,eiClean);
2499  break;
2500 
2501  case GENERAL_EQUATION:
2502  full=LinearizeGeneralEquation(epsilon,safeSimplex,b,lp,eiClean);
2503  break;
2504 
2505  default:
2506  Error("Unknown equation type in AddEquation2Simplex");
2507  }
2508 
2509  if (changed)
2510  {
2511  DeleteEquationInfo(eiClean);
2512  free(eiClean);
2513  }
2514  }
2515  #if (_DEBUG>4)
2516  else
2517  printf(" Useless equation after cleaning inf\n");
2518  #endif
2519 
2520  DeleteEquation(&eqClean);
2521  }
2522  #if ((!_USE_MPI)&&(_DEBUG>1))
2523  if (!full)
2524  fprintf(stderr,"A");
2525  #endif
2526  }
2527  }
2528 
2529  return(full);
2530 }
2531 
2532 void UpdateSplitWeight(unsigned int ne,double *splitDim,
2533  Tbox *b,Tequations *eqs)
2534 {
2535  unsigned int i,k;
2536  TequationInfo *ei;
2537  Tvariable_set *vars;
2538  double *c,*ev;
2539  Tinterval *is;
2540  unsigned int m;
2541 
2542  if (!eqs->scalar)
2543  Error("UpdateSplitWeight can only be used with scalar equations");
2544 
2545  if (ne<eqs->n)
2546  {
2547  m=GetBoxNIntervals(b);
2548  is=GetBoxIntervals(b);
2549 
2550  ei=eqs->equation[ne];
2551 
2552  if (ei->EqType!=LINEAR_EQUATION)
2553  {
2554  vars=GetEquationVariables(ei->equation);
2555 
2556  NEW(c,m,double);
2557  NEW(ev,m,double);
2558 
2559  for(i=0;i<ei->n;i++)
2560  {
2561  k=GetVariableN(i,vars);
2562  c[k]=IntervalCenter(&(is[k]));
2563  }
2564 
2565  ErrorDueToVariable(m,c,is,ev,ei);
2566 
2567  for(i=0;i<ei->n;i++)
2568  {
2569  k=GetVariableN(i,vars);
2570  splitDim[k]+=ev[i];
2571  }
2572 
2573  free(c);
2574  free(ev);
2575  }
2576  }
2577 }
2578 
2579 void EvaluateEqualityEquations(boolean systemOnly,double *v,double *r,Tequations *eqs)
2580 {
2581  unsigned int i,k,l;
2582  Tequation *eq;
2583 
2584  k=0;
2585  for(i=0;i<eqs->n;i++)
2586  {
2587  eq=GetOriginalEquation(eqs->equation[i]);
2588 
2589  if (GetEquationCmp(eq)==EQU)
2590  {
2591  if ((!systemOnly)||(GetEquationType(eq)==SYSTEM_EQ))
2592  r[k]=EvaluateWholeEquation(v,eq);
2593  else
2594  r[k]=0.0;
2595  k++;
2596  }
2597  }
2598 
2599  /* Evaluate the matrix equations (they are all equalities). */
2600  for(i=0;i<eqs->nm;i++)
2601  {
2602  l=EvaluateMEquation(v,&(r[k]),eqs->mequation[i]);
2603  k+=l;
2604  }
2605 }
2606 
2607 void EvaluateSubSetEqualityEquations(double *v,boolean *se,double *r,Tequations *eqs)
2608 {
2609  unsigned int i,j,k,l,s;
2610  Tequation *eq;
2611  double mv[MAX_EQ_MATRIX];
2612 
2613  k=0;
2614  s=0;
2615  for(i=0;i<eqs->n;i++)
2616  {
2617  eq=GetOriginalEquation(eqs->equation[i]);
2618  if (GetEquationCmp(eq)==EQU)
2619  {
2620  if (se[s])
2621  {
2622  r[k]=EvaluateWholeEquation(v,eq);
2623  k++;
2624  }
2625  s++;
2626  }
2627  }
2628  /* all matrix equations are equalities */
2629  for(i=0;i<eqs->nm;i++)
2630  {
2631  l=EvaluateMEquation(v,mv,eqs->mequation[i]);
2632  for(j=0;j<l;j++,s++)
2633  {
2634  if (se[s])
2635  {
2636  r[k]=mv[j];
2637  k++;
2638  }
2639  }
2640  }
2641 }
2642 
2644 {
2645  /* we have to be sure that this is not executed
2646  in parallel over the same eqs structure.
2647  Only need to be executed once (typically at
2648  the system initialization). */
2649  #pragma omp critical
2650  {
2651  if ((eqs->nsEQU==0)&&(eqs->n>0))
2652  {
2653  unsigned int i;
2654  Tequation *eq;
2655 
2656  /* We have at most 'n' equality scalar equations */
2657  NEW(eqs->eqEQU,eqs->n,Tequation*);
2658  for(i=0;i<eqs->n;i++)
2659  {
2660  eq=GetOriginalEquation(eqs->equation[i]);
2661 
2662  if (GetEquationCmp(eq)==EQU)
2663  {
2664  if (EmptyEquation(eq))
2665  eqs->eqEQU[eqs->nsEQU]=NULL;
2666  else
2667  eqs->eqEQU[eqs->nsEQU]=eq;
2668  eqs->nsEQU++;
2669  }
2670  }
2671  }
2672  }
2673 }
2674 
2675 void EvaluateEqualitySparseEquations(double *v,double *r,Tequations *eqs)
2676 {
2677  Tequation **eq;
2678  unsigned int i,k,l;
2679 
2680  /* The cache information is requiered */
2681  if ((eqs->nsEQU==0)&&(eqs->n>0))
2682  Error("User CacheScalarEQUInfo before calling EvaluateEqualitySparseEquations");
2683 
2684  /* Fast evaluation of the empty equations */
2685  eq=&(eqs->eqEQU[0]);
2686  for(k=0;k<eqs->nsEQU;k++,eq++)
2687  r[k]=(*eq?EvaluateWholeEquation(v,*eq):0.0);
2688 
2689  /* Evaluate the matrix equations (they are all equalities). */
2690  k=eqs->nsEQU;
2691  for(i=0;i<eqs->nm;i++)
2692  {
2693  l=EvaluateMEquation(v,&(r[k]),eqs->mequation[i]);
2694  k+=l;
2695  }
2696 }
2697 
2698 void EvaluateSubSetEqualitySparseEquations(double *v,boolean *se,double *r,Tequations *eqs)
2699 {
2700  Tequation **eq;
2701  unsigned int i,j,l,k,s;
2702  double mv[MAX_EQ_MATRIX];
2703 
2704  /* Cache the information (without taking into account 'se') */
2705  if ((eqs->nsEQU==0)&&(eqs->n>0))
2706  CacheScalarEQUInfo(eqs);
2707 
2708  /* Evaluate the selected scalar equality equations */
2709  k=0;
2710  eq=&(eqs->eqEQU[0]);
2711  for(i=0;i<eqs->nsEQU;i++,eq++)
2712  {
2713  if (se[i])
2714  {
2715  r[k]=(*eq?EvaluateWholeEquation(v,*eq):0.0);
2716  k++;
2717  }
2718  }
2719 
2720  /* Evaluate the matrix equations (they are all equalities). */
2721  s=eqs->nsEQU;
2722  for(i=0;i<eqs->nm;i++)
2723  {
2724  l=EvaluateMEquation(v,mv,eqs->mequation[i]);
2725  for(j=0;j<l;j++,s++)
2726  {
2727  if (se[s])
2728  {
2729  r[k]=mv[j];
2730  k++;
2731  }
2732  }
2733  }
2734 }
2735 
2736 void EvaluateEquationsXVectors(double *v,unsigned int ng,unsigned int *g,double *p,
2737  double *r,Tequations *eqs)
2738 {
2739  unsigned int i,s;
2740 
2741  if (eqs->n>0)
2742  Error("EvaluateEquationsXVectors can only be used on matrix-only equations");
2743 
2744  if (eqs->nm!=ng)
2745  Error("Num vectors-Equations missmatch in EvaluateEquationsXVectors");
2746 
2747  s=0;
2748  for(i=0;i<eqs->nm;i++)
2749  {
2750  EvaluateMEquationXVectors(v,g[i],&(p[3*s]),&(r[3*s]),eqs->mequation[i]);
2751  s+=g[i];
2752  }
2753 }
2754 
2755 void EvaluateInequalityEquations(double *v,double *r,Tequations *eqs)
2756 {
2757  unsigned int i,k;
2758  Tequation *eq;
2759  double e,rhs;
2760  unsigned int cmp;
2761 
2762  k=0;
2763  for(i=0;i<eqs->n;i++)
2764  {
2765  eq=GetOriginalEquation(eqs->equation[i]);
2766  cmp=GetEquationCmp(eq);
2767  if (cmp!=EQU)
2768  {
2769  e=EvaluateEquation(v,eq);
2770  rhs=GetEquationValue(eq);
2771  if (cmp==GEQ)
2772  r[k]=(e>=rhs?0.0:rhs-e);
2773  else
2774  r[k]=(e<=rhs?0.0:e-rhs);
2775  k++;
2776  }
2777  }
2778 }
2779 
2780 void DeriveEqualityEquations(unsigned int v,Tequations *deqs,Tequations *eqs)
2781 {
2782  unsigned int i;
2783  Tequation *eq;
2784  Tequation deq;
2785  TMequation dmeq;
2786 
2787  InitEquations(deqs);
2788  for(i=0;i<eqs->n;i++)
2789  {
2790  eq=GetOriginalEquation(eqs->equation[i]);
2791  if (GetEquationCmp(eq)==EQU)
2792  {
2793  DeriveEquation(v,&deq,eq);
2794  AddEquationInt(&deq,deqs); /* Adding even if empty */
2795  DeleteEquation(&deq);
2796  }
2797  }
2798  for(i=0;i<eqs->nm;i++)
2799  {
2800  DeriveMEquation(v,&dmeq,eqs->mequation[i]);
2801  AddMatrixEquation(&dmeq,deqs);
2802  DeleteMEquation(&dmeq);
2803  }
2804 }
2805 
2806 void PrintEquations(FILE *f,char **varNames,Tequations *eqs)
2807 {
2808  unsigned int i;
2809 
2810  if (eqs->s>0)
2811  {
2812  fprintf(f,"\n[SYSTEM EQS]\n");
2813  for(i=0;i<eqs->n;i++)
2814  {
2815  if (IsSystemEquation(i,eqs))
2816  {
2817  //fprintf(f,"%% %u\n",i);
2818  PrintEquation(f,varNames,GetOriginalEquation(eqs->equation[i]));
2819  }
2820  }
2821  if ((eqs->nm>0)&&(eqs->n>0))
2822  fprintf(f,"\n\n");
2823  for(i=0;i<eqs->nm;i++)
2824  PrintMEquation(f,varNames,eqs->mequation[i]);
2825  }
2826 
2827  if (eqs->c>0)
2828  {
2829  fprintf(f,"\n[COORD EQS]\n");
2830  for(i=0;i<eqs->n;i++)
2831  {
2832  if (IsCoordEquation(i,eqs))
2833  {
2834  //fprintf(f,"%% %u\n",i);
2835  PrintEquation(f,varNames,GetOriginalEquation(eqs->equation[i]));
2836  }
2837  }
2838  }
2839 
2840  if (eqs->d>0)
2841  {
2842  fprintf(f,"\n[DUMMY EQS]\n");
2843  for(i=0;i<eqs->n;i++)
2844  {
2845  if (IsDummyEquation(i,eqs))
2846  {
2847  //fprintf(f,"%% %u\n",i);
2848  PrintEquation(f,varNames,GetOriginalEquation(eqs->equation[i]));
2849  }
2850  }
2851  }
2852  for(i=0;i<eqs->n;i++)
2853  {
2854  if ((!IsSystemEquation(i,eqs))&&(!IsCoordEquation(i,eqs))&&(!IsDummyEquation(i,eqs)))
2855  {
2856  //fprintf(f,"%% %u\n",i);
2857  PrintEquation(f,varNames,GetOriginalEquation(eqs->equation[i]));
2858  }
2859  }
2860 }
2861 
2863 {
2864  unsigned int i;
2865 
2866  for(i=0;i<eqs->n;i++)
2867  {
2868  if (eqs->equation[i]!=NULL)
2869  {
2870  DeleteEquationInfo(eqs->equation[i]);
2871  free(eqs->equation[i]);
2872  }
2873  }
2874  free(eqs->equation);
2875 
2876  for(i=0;i<eqs->nm;i++)
2877  {
2878  if (eqs->mequation[i]!=NULL)
2879  {
2880  DeleteMEquation(eqs->mequation[i]);
2881  free(eqs->mequation[i]);
2882  }
2883  }
2884  free(eqs->mequation);
2885 
2886  /* Remove the cached information, if any */
2887  eqs->nsEQU=0;
2888  if (eqs->eqEQU!=NULL)
2889  free(eqs->eqEQU);
2890 }
unsigned int EvaluateMEquation(double *v, double *r, TMequation *me)
Evaluates a matrix equation.
Definition: mequation.c:415
boolean SimplexAddNewConstraint(double epsilon, unsigned int safeSimplex, TLinearConstraint *lc, unsigned int eq_type, Tinterval *is, TSimplex *s)
Adds a row (i.e., a constraint) to the simplex.
Definition: simplex.c:67
unsigned int c
Definition: equations.h:85
unsigned int e
Definition: equations.h:87
Set of variables of a cuiksystem.
Definition: variables.h:38
void DeleteLinearConstraint(TLinearConstraint *lc)
Destructor.
Tequation * GetScalarEquation(unsigned int n, Tequations *eqs)
Gets a scalar equation from the set.
Definition: equations.c:1791
double EvaluateWholeEquation(double *varValues, Tequation *eq)
Evaluates an equation in a given point.
Definition: equation.c:1726
void ReplaceVarInMEquation(unsigned int nv, unsigned int nvNew, TMequation *me)
Replaces a variable.
Definition: mequation.c:345
boolean Intersect(Tinterval *i1, Tinterval *i2)
Checks is a two intervals intersect.
Definition: interval.c:272
boolean HasRotations(TMequation *me)
Cheks if a matrix equation includes rotations.
Definition: mequation.c:163
Definition of basic functions.
#define SYSTEM_EQ
One of the possible type of equations.
Definition: equation.h:146
Tequation * GetEquation(unsigned int n, Tequations *eqs)
Gets an equation from the set.
Definition: equations.c:1799
Tmonomial * GetMonomial(unsigned int i, Tequation *eq)
Gets a monomial from an equation.
Definition: equation.c:1695
TMequation ** mequation
Definition: equations.h:98
void DeriveEquation(unsigned int nv, Tequation *d, Tequation *eq)
Derives an equation.
Definition: equation.c:1776
unsigned int NEquations(Tequations *eqs)
Number of equations in the set.
Definition: equations.c:1164
#define FALSE
FALSE.
Definition: boolean.h:30
boolean BilinealMonomialEquation(Tequation *eq)
Identify single bilineal monomial equations.
Definition: equation.c:1172
#define ROUNDDOWN
Sets the floating point operations in rounding down mode.
Definition: defines.h:219
unsigned int GetVariableTypeN(unsigned int n, Tvariables *vs)
Gets the type of a particular variable.
Definition: variables.c:123
boolean IsCoordEquation(unsigned int i, Tequations *eqs)
Identify coordenalization equations.
Definition: equations.c:1220
#define NEW(_var, _n, _type)
Allocates memory space.
Definition: defines.h:385
void EvaluateEquationInt(Tinterval *varValues, Tinterval *i_out, Tequation *eq)
Interval evaluation of an equation.
Definition: equation.c:1760
A linear constraint with an associated error.
Tequation *** Hessian
Definition: equations.h:63
void DeleteEquation(Tequation *eq)
Destructor.
Definition: equation.c:1859
void AddMatrixEquation(TMequation *equation, Tequations *eqs)
Adds a matrix equation to the set.
Definition: equations.c:1759
unsigned int NSystemEquations(Tequations *eqs)
Number of system equations in the set.
Definition: equations.c:1174
void MergeEquations(Tequations *eqs1, Tequations *eqs)
Copy constructor.
Definition: equations.c:802
unsigned int NCoordEquations(Tequations *eqs)
Number of coordenalization equations in the set.
Definition: equations.c:1179
TLinearConstraint * lc
Definition: equations.h:53
unsigned int mm
Definition: equations.h:96
void IntervalAdd(Tinterval *i1, Tinterval *i2, Tinterval *i_out)
Addition of two intervals.
Definition: interval.c:423
unsigned int GetEquationNumVariables(Tequation *eq)
Gets the number of variables equation used in the equation.
Definition: equation.c:1246
double EvaluateEquation(double *varValues, Tequation *eq)
Evaluates an equation in a given point.
Definition: equation.c:1744
void CopyEquation(Tequation *eq_dst, Tequation *eq_orig)
Copy constructor.
Definition: equation.c:216
void CopyEquations(Tequations *eqs_dst, Tequations *eqs_src)
Copy constructor.
Definition: equations.c:755
Tequation * equation
Definition: equations.h:48
#define EQU
In a Tequation, the equation relational operator is equal.
Definition: equation.h:202
#define DUMMY_EQ
One of the possible type of equations.
Definition: equation.h:164
void InitLinearConstraint(TLinearConstraint *lc)
Constructor.
void UpdateSplitWeight(unsigned int ne, double *splitDim, Tbox *b, Tequations *eqs)
Computes the linearization error induced by the variables of a given equation.
Definition: equations.c:2532
#define EMPTY_BOX
One of the possible results of reducing a box.
Definition: box.h:25
#define LINEAR_EQUATION
One of the possible type of equations.
Definition: equation.h:62
void GetFirstOrderApproximationToEquation(Tbox *b, double *c, TLinearConstraint *lc, TequationInfo *ei)
Gets a first order approximation to a given equation.
Definition: equations.c:458
#define COORD_EQ
One of the possible type of equations.
Definition: equation.h:155
void IntervalInvert(Tinterval *i, Tinterval *i_out)
Change of sign of a given interval.
Definition: interval.c:461
unsigned int neq
Definition: equations.h:82
Tequation ** Jacobian
Definition: equations.h:58
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.
unsigned int NInequalityEquations(Tequations *eqs)
Number of inequalities in the set.
Definition: equations.c:1194
#define TRUE
TRUE.
Definition: boolean.h:21
#define LEQ
In a Tequation, the equation relational operator is less equal.
Definition: equation.h:196
unsigned int CmpEquations(Tequation *eq1, Tequation *eq2)
Equation comparison.
Definition: equation.c:1251
void Error(const char *s)
General error function.
Definition: error.c:80
unsigned int EqType
Definition: equations.h:50
#define MAX_EQ_MATRIX
Max number of scalar equations in a matrix equation.
Definition: mequation.h:24
boolean AddEquation2Simplex(unsigned int ne, double lr2tm_q, double lr2tm_s, double epsilon, unsigned int safeSimplex, double rho, Tbox *b, Tvariables *vs, TSimplex *lp, Tequations *eqs)
Adds an equation to the simplex.
Definition: equations.c:2287
#define NOCMP
In a Tequation, the equation relational operator is not defined yet.
Definition: equation.h:208
boolean RectangleParabolaClipping(Tinterval *x, double alpha, double beta, Tinterval *y, Tinterval *x_new, Tinterval *y_new)
Clips a 2D box and a scaled parabola.
Definition: geom.c:473
#define INIT_NUM_EQUATIONS
Initial room for equations.
Definition: equations.h:30
void SimplexExpandBounds(unsigned int eq_type, Tinterval *b)
Expands an interval according to the equation type.
Definition: simplex.c:19
A simplex tableau structure.
Definition: simplex.h:73
unsigned int CropEquation(unsigned int ne, unsigned int varType, double epsilon, double rho, Tbox *b, Tvariables *vs, Tequations *eqs)
Equation-wise crop.
Definition: equations.c:1269
#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.
void CopyInterval(Tinterval *i_dst, Tinterval *i_org)
Copy constructor.
Definition: interval.c:59
Matrix equation.
Definition: mequation.h:42
void EvaluateSubSetEqualitySparseEquations(double *v, boolean *se, double *r, Tequations *eqs)
Evaluates a subset of the set of equality equations for sparse systems.
Definition: equations.c:2698
boolean polynomial
Definition: equations.h:89
unsigned int GetEquationTypeN(unsigned int i, Tequations *eqs)
Gets the type of a particular equation.
Definition: equations.c:1238
boolean VarIncluded(unsigned int id, Tvariable_set *vs)
Checks if a variable index is included in a set of variable indexes.
Definition: variable_set.c:183
#define GEQ
In a Tequation, the equation relational operator is great equal.
Definition: equation.h:190
unsigned int GetBoxNIntervals(Tbox *b)
Box dimensionality.
Definition: box.c:1016
boolean VarIncludedinMEquation(unsigned int v, TMequation *me)
Checks if the matrix equation includes a given variable.
Definition: mequation.c:191
boolean BoxSaddleClipping(Tinterval *x, Tinterval *y, double alpha, double beta, Tinterval *z, Tinterval *x_new, Tinterval *y_new, Tinterval *z_new)
Clips a 3D box and a scaled saddle.
Definition: geom.c:518
unsigned int GetVariableN(unsigned int n, Tvariable_set *vs)
Gets a variable identifier from a variable set.
Definition: variable_set.c:454
Error and warning functions.
void ErrorDueToVariable(unsigned int m, double *c, Tinterval *is, double *ev, TequationInfo *ei)
Computes the linealization error for a given equation for each variable involved in the equation...
Definition: equations.c:616
void PrintMEquation(FILE *f, char **varNames, TMequation *me)
Prints a Transform sequence to a file.
Definition: mequation.c:473
boolean LinearizeBilinealMonomialEquation(double epsilon, double lr2tm, unsigned int safeSimplex, Tbox *b, TSimplex *lp, TequationInfo *ei)
Produces a linear relaxation for a bilienal monomial equation.
Definition: equations.c:1868
void PrintEquation(FILE *f, char **varNames, Tequation *eq)
Prints an equation.
Definition: equation.c:1825
#define NOTYPE_EQ
One of the possible type of equations.
Definition: equation.h:182
void CopyLinearConstraint(TLinearConstraint *lc_dst, TLinearConstraint *lc_src)
Copy constructor.
#define SADDLE_EQUATION
One of the possible type of equations.
Definition: equation.h:89
double LowerLimit(Tinterval *i)
Gets the lower limit.
Definition: interval.c:79
void RemoveEquationsWithVar(double epsilon, unsigned int nv, Tequations *eqs)
Removes all equations that include a given variable.
Definition: equations.c:869
unsigned int NEqualityEquations(Tequations *eqs)
Number of equalities in the set.
Definition: equations.c:1189
boolean HasEquation(Tequation *equation, Tequations *eqs)
Checks if a given equation is already in the set.
Definition: equations.c:1254
void CopyEquationInfo(TequationInfo *ei_dst, TequationInfo *ei_src)
TequationInfo copy constructor.
Definition: equations.c:399
boolean IsSystemEquation(unsigned int i, Tequations *eqs)
Identify system equations.
Definition: equations.c:1209
Set of equations.
Definition: equations.h:81
An equation.
Definition: equation.h:237
Information associated with each scalar equation in the equation set.
Definition: equations.h:46
unsigned int NScalarEquations(Tequations *eqs)
Number of scalar equations in the set.
Definition: equations.c:1169
Definitions of constants and macros used in several parts of the cuik library.
boolean ParabolaEquation(Tequation *eq)
Identify scaled parabola equations.
Definition: equation.c:1184
boolean EmptyEquation(Tequation *eq)
Identify empty equations.
Definition: equation.c:1094
unsigned int n
Definition: equations.h:56
void EvaluateEqualitySparseEquations(double *v, double *r, Tequations *eqs)
Evaluates the set of equality equations for sparse systems.
Definition: equations.c:2675
void EvaluateEqualityEquations(boolean systemOnly, double *v, double *r, Tequations *eqs)
Evaluates all equality equations in the set.
Definition: equations.c:2579
void InitEquations(Tequations *eqs)
Constructor.
Definition: equations.c:720
boolean LinearizeSphereEquation(double epsilon, unsigned int safeSimplex, Tbox *b, TSimplex *lp, TequationInfo *ei)
Produces a linear relaxation for a sphere equation.
Definition: equations.c:2119
void CopyMEquation(TMequation *me_dst, TMequation *me_src)
Copy constructor.
Definition: mequation.c:113
void CopyBox(void *b_out, void *b_in)
Box copy operator.
Definition: box.c:160
A set of variable indexes with powers.
Definition: variable_set.h:139
Tvariable_set * GetMonomialVariables(Tmonomial *f)
Gets the variables of a monomial.
Definition: monomial.c:153
#define ROUNDNEAR
Sets the floating point operations in round near mode.
Definition: defines.h:225
A scaled product of powers of variables.
Definition: monomial.h:32
void CacheScalarEQUInfo(Tequations *eqs)
Collects information about scalar equality equations.
Definition: equations.c:2643
#define ANY_TYPE_VAR
Union of variables of any type.
Definition: variable.h:68
boolean PolynomialEquations(Tequations *eqs)
Identify polynomial system of equations.
Definition: equations.c:1199
double UpperLimit(Tinterval *i)
Gets the uppser limit.
Definition: interval.c:87
void ShiftVariablesInMEquation(unsigned int nv, TMequation *me)
Adjust variable indices after removina a variable.
Definition: mequation.c:288
void AddEquation(Tequation *equation, Tequations *eqs)
Adds an equation to the set.
Definition: equations.c:1723
unsigned int s
Definition: equations.h:84
unsigned int GetNumTermsInLinearConstraint(TLinearConstraint *lc)
Number of variables in a linear constraint.
boolean scalar
Definition: equations.h:90
void GetEquationBounds(Tinterval *bounds, Tequation *eq)
Returns the right-hand side of the equation in the form of an interval.
Definition: equation.c:1217
unsigned int VariableSetSize(Tvariable_set *vs)
Gets the number of elements of a variable set.
Definition: variable_set.c:449
A box.
Definition: box.h:83
double GetEquationValue(Tequation *eq)
Gets the right-hand value of the equation.
Definition: equation.c:1212
unsigned int FixVariableInEquation(double epsilon, unsigned int nv, double b, Tequation *eq)
Turns a variable into a constant.
Definition: equation.c:461
unsigned int FixVarInMEquation(unsigned int nv, double v, TMequation *me)
Set a variable to a constant value.
Definition: mequation.c:296
void GetLinearConstraintError(Tinterval *error, TLinearConstraint *lc)
Gets the right-hand side interval for the linear constraint.
boolean LinearizeGeneralEquationInt(unsigned int cmp, double epsilon, unsigned int safeSimplex, Tbox *b, double *c, TSimplex *lp, TequationInfo *ei)
Produces a linear relaxation for a general equation at a given point.
Definition: equations.c:2229
#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:1006
void EvaluateEquationsXVectors(double *v, unsigned int ng, unsigned int *g, double *p, double *r, Tequations *eqs)
Evaluates the matrix equations multiplied by some given vectors.
Definition: equations.c:2736
#define NO_UINT
Used to denote an identifier that has not been initialized.
Definition: defines.h:435
#define GENERAL_EQUATION
One of the possible type of equations.
Definition: equation.h:126
unsigned int n
Definition: equations.h:93
void IntervalScale(Tinterval *i1, double e, Tinterval *i_out)
Scales an interval.
Definition: interval.c:360
double IntervalCenter(Tinterval *i)
Gets the interval center.
Definition: interval.c:129
unsigned int CropLinearConstraint(double epsilon, unsigned int varType, Tbox *b, Tvariables *vs, TLinearConstraint *lc)
Reduce the ranges for.
boolean CleanInfEquation(Tequation *eq_in, Tinterval *varValues, boolean *changed, Tequation *eq_out)
Removes the monomials that evaluate to inf.
Definition: equation.c:763
boolean CircleEquation(Tequation *eq)
Identify circle equations.
Definition: equation.c:1131
boolean RectangleCircleClipping(double r2, Tinterval *x, Tinterval *y, Tinterval *x_new, Tinterval *y_new)
Clips a rectangle and a circle.
Definition: geom.c:347
unsigned int nm
Definition: equations.h:97
unsigned int NDummyEquations(Tequations *eqs)
Number of dummy equations in the set.
Definition: equations.c:1184
boolean LinearizeParabolaEquation(double epsilon, unsigned int safeSimplex, Tbox *b, TSimplex *lp, TequationInfo *ei)
Produces a linear relaxation for a parabola equation.
Definition: equations.c:1973
unsigned int FindMonomial(Tmonomial *f, Tequation *eq)
Searches for a given monomial in the equation.
Definition: equation.c:1672
#define PARABOLA_EQUATION
One of the possible type of equations.
Definition: equation.h:107
void EvaluateInequalityEquations(double *v, double *r, Tequations *eqs)
Error in inequalities.
Definition: equations.c:2755
boolean IsDummyEquation(unsigned int i, Tequations *eqs)
Identify dummy equations.
Definition: equations.c:1229
void EvaluateSubSetEqualityEquations(double *v, boolean *se, double *r, Tequations *eqs)
Evaluates a subset of the equality equations in the set.
Definition: equations.c:2607
boolean LinearizeGeneralEquation(double epsilon, unsigned int safeSimplex, Tbox *b, TSimplex *lp, TequationInfo *ei)
Produces a linear relaxation for a general equation at the central point of the sub-box defined by th...
Definition: equations.c:2253
double GetMonomialCt(Tmonomial *f)
Gets the scale factor of a monomial.
Definition: monomial.c:136
void DeleteBox(void *b)
Destructor.
Definition: box.c:1283
#define BILINEAL_MONOMIAL_EQUATION
One of the possible type of equations.
Definition: equation.h:98
boolean IsInside(double p, double tol, Tinterval *i)
Checks if a value is inside an interval.
Definition: interval.c:348
#define CIRCLE_EQUATION
One of the possible type of equations.
Definition: equation.h:80
Tequation ** eqEQU
Definition: equations.h:104
boolean ScalarEquations(Tequations *eqs)
Identifies scalar systems.
Definition: equations.c:1204
Tinterval * GetBoxIntervals(Tbox *b)
Returns a pointer to the array of intervals defining the box.
Definition: box.c:284
Tequation * GetOriginalEquation(TequationInfo *ei)
Returns the equation stored in a TequationInfo.
Definition: equations.c:394
boolean LinearizeSaddleEquation(double epsilon, unsigned int safeSimplex, Tbox *b, TSimplex *lp, TequationInfo *ei)
Produces a linear relaxation for a saddle equation.
Definition: equations.c:1810
unsigned int nsEQU
Definition: equations.h:100
void SetLinearConstraintError(Tinterval *error, TLinearConstraint *lc)
Sets a new righ-hand side error of the linear constraint.
TequationInfo ** equation
Definition: equations.h:94
void IntervalProduct(Tinterval *i1, Tinterval *i2, Tinterval *i_out)
Product of two intervals.
Definition: interval.c:389
unsigned int d
Definition: equations.h:86
void IntervalPow(Tinterval *i, unsigned int p, Tinterval *i_out)
Power of a given interval by a integer power factor.
Definition: interval.c:494
unsigned int m
Definition: equations.h:92
boolean SphereEquation(Tequation *eq)
Identify sphere equations.
Definition: equation.c:1145
void NewInterval(double lower, double upper, Tinterval *i)
Constructor.
Definition: interval.c:47
void SetEquationInfo(Tequation *e, TequationInfo *ei)
TequationInfo constructor.
Definition: equations.c:284
#define INF
Infinite.
Definition: defines.h:70
#define REDUCED_BOX
One of the possible results of reducing a box.
Definition: box.h:38
void DeleteEquations(Tequations *eqs)
Destructor.
Definition: equations.c:2862
void PrintEquations(FILE *f, char **varNames, Tequations *eqs)
Prints a set of equations.
Definition: equations.c:2806
boolean PolynomialEquation(Tequation *eq)
Idetify polynomial equations.
Definition: equation.c:1197
boolean BoxSphereClipping(double r2, Tinterval *x, Tinterval *y, Tinterval *z, Tinterval *x_new, Tinterval *y_new, Tinterval *z_new)
Clips a 3D box and a sphere.
Definition: geom.c:401
void AddEquationInt(Tequation *equation, Tequations *eqs)
Adds an equation to a set.
Definition: equations.c:1690
Defines a interval.
Definition: interval.h:33
void DeleteEquationInfo(TequationInfo *ei)
Destructor.
Definition: equations.c:680
double GetBoxMaxSizeVarSet(Tvariable_set *vars, Tbox *b)
Computes the size of the box.
Definition: box.c:639
double IntervalSize(Tinterval *i)
Gets the uppser limit.
Definition: interval.c:96
void DeriveEqualityEquations(unsigned int v, Tequations *deqs, Tequations *eqs)
Derives an equation set.
Definition: equations.c:2780
Definition of the Tequations type and the associated functions.
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:1703
boolean UsedVarInEquations(unsigned int nv, Tequations *eqs)
Checks if a variable is used in the set of equations.
Definition: equations.c:847
void DeriveMEquation(unsigned int v, TMequation *dme, TMequation *me)
Derives a matrix equation.
Definition: mequation.c:371
#define NOT_REDUCED_BOX
One of the possible results of reducing a box.
Definition: box.h:59
unsigned int GetEquationType(Tequation *eq)
Gets the equation type.
Definition: equation.c:1207
unsigned int NumberScalarEquations(TMequation *me)
Number of scaler equations defined by a matrix equation.
Definition: mequation.c:283
boolean GaussianElimination(Tequations *eqs)
Perform Gaussian elimination on the set of equations.
Definition: equations.c:993
#define EMPTY_EQUATION
One of the possible type of equations.
Definition: equation.h:53
void NormalizeEquation(Tequation *eq)
Normalizes an equation.
Definition: equation.c:714
void DeleteMEquation(TMequation *me)
Destructor.
Definition: mequation.c:492
Tvariable_set * GetEquationVariables(Tequation *eq)
Gets the set of variables equation used in the equation.
Definition: equation.c:1241
boolean LinearEquation(Tequation *eq)
Identify linear equations.
Definition: equation.c:1099
double GetBoxMinSizeVarSet(Tvariable_set *vars, Tbox *b)
Computes the minimum size of the box.
Definition: box.c:657
void EvaluateMEquationXVectors(double *v, unsigned int n, double *p, double *r, TMequation *me)
Equation x vector evaluation.
Definition: mequation.c:437
boolean UsedVarInNonDummyEquations(unsigned int nv, Tequations *eqs)
Checks if a variable is used in the set of equations.
Definition: equations.c:822
unsigned int GetEquationCmp(Tequation *eq)
Gets the type of relational operator of the equation.
Definition: equation.c:1202
boolean LinearizeCircleEquation(double epsilon, unsigned int safeSimplex, Tbox *b, TSimplex *lp, TequationInfo *ei)
Produces a linear relaxation for a circle equation.
Definition: equations.c:2019
void AddEquationNoSimp(Tequation *equation, Tequations *eqs)
Adds an equation to the set.
Definition: equations.c:1750
void IntervalOffset(Tinterval *i, double offset, Tinterval *i_out)
Interval offset.
Definition: interval.c:627
#define SPHERE_EQUATION
One of the possible type of equations.
Definition: equation.h:116
boolean ReplaceVariableInEquations(double epsilon, unsigned int nv, TLinearConstraint *lc, Tequations *eqs)
Replaces a variable with a linear expression.
Definition: equations.c:912
boolean SaddleEquation(Tequation *eq)
Identify scaled saddle equations.
Definition: equation.c:1159