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