linear_constraint.c
Go to the documentation of this file.
1 #include "linear_constraint.h"
2 
3 #include "defines.h"
4 #include "interval.h"
5 
6 #include <string.h>
7 #include <math.h>
8 
18 {
20  NEW(lc->ind,lc->max,unsigned int);
21  NEW(lc->val,lc->max,double);
23 }
24 
26 {
27  lc->n=0;
28  NewInterval(0,0,&(lc->error)); /*This is updated via intersections -> INF works */
29 }
30 
32 {
33  lc_dst->n=lc_src->n;
34  lc_dst->max=lc_src->max;
35  NEW(lc_dst->ind,lc_src->max,unsigned int);
36  NEW(lc_dst->val,lc_src->max,double);
37 
38  memcpy(lc_dst->ind,lc_src->ind,lc_dst->n*sizeof(unsigned int));
39  memcpy(lc_dst->val,lc_src->val,lc_dst->n*sizeof(double));
40 
41  CopyInterval(&(lc_dst->error),&(lc_src->error));
42 }
43 
45 {
46  return((LowerLimit(&(lc->error))!=-INF)||(UpperLimit(&(lc->error))!=+INF));
47 }
48 
50 {
51  return(lc->n);
52 }
53 
55 {
56  return(lc->val);
57 }
58 
60 {
61  if (i<lc->n)
62  return(lc->val[i]);
63  else
64  {
65  Error("Index out of range in GetLinearConstraintCoefficient");
66  return(0);
67  }
68 }
69 
71 {
72  return(lc->ind);
73 }
74 
75 unsigned int GetLinearConstraintVariable(unsigned int i,TLinearConstraint *lc)
76 {
77  if (i<lc->n)
78  return(lc->ind[i]);
79  else
80  {
81  Error("Index out of range in GetLinearConstraintCoefficient");
82  return(NO_UINT);
83  }
84 }
85 
87 {
88  CopyInterval(error,&(lc->error));
89 }
90 
92 {
93  return(IntervalSize(&(lc->error)));
94 }
95 
97 {
98  CopyInterval(&(lc->error),error);
99 }
100 
102 {
103  IntervalOffset(&(lc->error),-ct,&(lc->error));
104 }
105 
106 void AddTerm2LinearConstraint(unsigned int ind,double val,TLinearConstraint *lc)
107 {
108  if (val!=0.0)
109  {
110  boolean found;
111  unsigned int i;
112 
113  found=FALSE;
114  i=0;
115  while((!found)&&(i<lc->n))
116  {
117  found=(lc->ind[i]==ind);
118  if (!found) i++;
119  }
120  if (!found)
121  {
122  if (lc->n==lc->max) /* i==lc->n */
123  {
124  MEM_DUP(lc->ind,lc->max,unsigned int);
125  MEM_EXPAND(lc->val,lc->max,double);
126  }
127  lc->ind[lc->n]=ind;
128  lc->val[lc->n]=val;
129  lc->n++;
130  }
131  else
132  lc->val[i]+=val;
133  }
134 }
135 
137 {
138  unsigned int i,j;
139  boolean found;
140  double ct;
141 
142  found=FALSE;
143  i=0;
144  while((!found)&&(i<lc->n))
145  {
146  found=(lc->ind[i]==ind);
147  if (!found) i++;
148  }
149 
150  if (found)
151  {
152  ct=lc->val[i];
153  for(j=i+1;j<lc->n;j++)
154  {
155  lc->ind[j-1]=lc->ind[j];
156  lc->val[j-1]=lc->val[j];
157  }
158  lc->n--;
159  }
160  else
161  ct=0.0;
162 
163  return(ct);
164 }
165 
166 boolean LinearConstraintIncludes(unsigned int ind,TLinearConstraint *lc)
167 {
168  unsigned int i;
169  boolean found;
170 
171  found=FALSE;
172  i=0;
173  while((!found)&&(i<lc->n))
174  {
175  found=(lc->ind[i]==ind);
176  if (!found) i++;
177  }
178 
179  return(found);
180 }
181 
183 {
184  unsigned int i;
185 
186  for(i=0;i<lc->n;i++)
187  lc->val[i]=-lc->val[i];
188 
189  IntervalInvert(&(lc->error),&(lc->error));
190 }
191 
193 {
194  unsigned int i;
195  TLinearConstraint lc2;
196 
197  InitLinearConstraint(&lc2);
198 
199  for(i=0;i<lc->n;i++)
200  AddTerm2LinearConstraint(lc->ind[i],lc->val[i]*a,&lc2);
201 
202  IntervalScale(&(lc->error),a,&(lc2.error));
203 
205  CopyLinearConstraint(lc,&lc2);
207 }
208 
210 {
211  unsigned int i;
212 
213  IntervalAdd(&(lc1->error),&(lc2->error),&(lc2->error));
214 
215  for(i=0;i<lc1->n;i++)
216  AddTerm2LinearConstraint(lc1->ind[i],lc1->val[i],lc2);
217 }
218 
219 /*
220  This converts almost punctual ranges into points
221 
222  A> Variables in the LC with very narrow range can be removed from the LC and
223  added to the error term. This enhances the numerical robustness of the system.
224  This only makes sense if we do not convert a punctual
225  error term into a narrow interval since this would only displace the problem
226  from one variable (column variable) to another (row variable).
227 
228  B> If, due to numerical roundings, we end up with a LC with a extremely narrow error
229  term, we convert this error to a point. In theory this can lead to losing solutions
230  but in general too narrow ranges lead to numerical inestabilities.
231 */
233 {
234  TLinearConstraint lcInt;
235  Tinterval error,r;
236  unsigned int i,k;
237 
238  InitLinearConstraint(&lcInt);
239 
240  CopyInterval(&error,&(lc->error));
241 
242  for(i=0;i<lc->n;i++)
243  {
244  k=lc->ind[i];
245 
246  if ((fabs(lc->val[i])<=epsilon)||
247  (IntervalSize(&(is[k]))<=epsilon))
248  {
249  IntervalScale(&(is[k]),-lc->val[i],&r);
250  IntervalAdd(&r,&error,&error);
251  }
252  else
253  AddTerm2LinearConstraint(k,lc->val[i],&lcInt);
254  }
255 
256  CopyInterval(&(lcInt.error),&error);
257 
259  CopyLinearConstraint(lc,&lcInt);
260  DeleteLinearConstraint(&lcInt);
261 }
262 
264 {
265  boolean simplified;
266 
267  /* \sum k_i x_i = error */
268  /* for just one variable in the linear constraint */
269  /* k*x = error */
270  /* x= error/k */
271  *full=TRUE;
272  simplified=FALSE;
273 
274  if (lc->n==1)
275  {
276  Tinterval a,one;
277  unsigned int k;
278 
279  simplified=TRUE;
280 
281  NewInterval(1,1,&one);
282  /* The coefficients of the linear constraint can be affected by some noise
283  due to floating point roundings when operating them. We add a small
284  range (1e-11) to compensate for those possible errors. */
285  NewInterval(lc->val[0]-ZERO,lc->val[0]-ZERO,&a);
286  IntervalDivision(&one,&a,&a);
287  IntervalProduct(&a,&(lc->error),&a);
288 
289  k=lc->ind[0];
290 
291  *full=Intersection(&a,&(is[k]),&(is[k]));
292  }
293 
294  return(simplified);
295 }
296 
297 unsigned int CropLinearConstraint(double epsilon,unsigned int varType,Tbox *b,Tvariables *vs,
298  TLinearConstraint *lc)
299 {
300  #if (_DEBUG>6)
301  printf(" Cropping linear constraint: ");
302  PrintLinearConstraint(stdout,TRUE,NULL,lc);
303  #endif
304 
305  if ((lc->n==0)||(IntervalSize(&(lc->error))>=INF))
306  return(NOT_REDUCED_BOX);
307  else
308  {
309  Tinterval out,new_range,range,a,ct,one,zero;
310  unsigned int j,k,x_j;
311  unsigned int status;
312  Tinterval *is;
313  boolean haveInf;
314 
315  is=GetBoxIntervals(b);
316 
317  /* We have
318  \sum k_i x_i = error
319  \sum k_i x_i - k_j x_j + k_j x_j = error
320  k_j x_j= error - \sum(i!=k) k_i x_i
321  x_j = (error + \sum(i!=k) - k_i x_i))/k_j
322 
323  We evaluate the equation using interval arithmetics and then
324  we use the result
325  */
326 
327  status=NOT_REDUCED_BOX;
328 
329  for(j=0;((j<lc->n)&&(status!=EMPTY_BOX));j++)
330  {
331  x_j=lc->ind[j];
332 
333  /* if still makes sense to crop the range x_j */
334  if ((GetVariableTypeN(x_j,vs)&varType)&&
335  (IntervalSize(&(is[x_j]))>=10*epsilon))
336  {
337  #if (_DEBUG>6)
338  printf(" Cropping var v[%u] with range ",x_j);
339  PrintInterval(stdout,&(is[x_j]));
340  printf(" (%f)\n",IntervalSize(&(is[x_j])));
341  #endif
342 
343  CopyInterval(&out,&(lc->error));
344 
345  /* The linear constraint error can be affected by some noise
346  due to floating point roundings when operating them. We add a small
347  range (1e-11) to compensate for those possible errors. */
348  NewInterval(-ZERO,ZERO,&zero);
349  IntervalAdd(&out,&zero,&out);
350 
351  haveInf=FALSE; /* if one of the ranges other than 'x_j' is infinite
352  it is not worth th reduce x_j */
353 
354  for(k=0;((!haveInf)&&(k<lc->n));k++)
355  {
356  if (k!=j)
357  {
358  if (IntervalSize(&(is[lc->ind[k]]))<INF)
359  {
360  /* The coefficients of the linear constraint can be affected by some noise
361  due to floating point roundings when operating them. We add a small
362  range (1e-11) to compensate for those possible errors. */
363  NewInterval(-lc->val[k]-ZERO,-lc->val[k]+ZERO,&ct);
364  IntervalProduct(&(is[lc->ind[k]]),&ct,&a);
365  IntervalAdd(&out,&a,&out);
366  }
367  else
368  haveInf=TRUE;
369  }
370  }
371 
372  if (!haveInf)
373  {
374 
375  #if (_DEBUG>6)
376  printf(" %.12f*v[%u]=",lc->val[j],x_j);
377  PrintInterval(stdout,&out);
378  printf(" (%f)\n",IntervalSize(&out));
379  #endif
380 
381  /* The coefficients of the linear constraint can be affected by some noise
382  due to floating point roundings when operating them. We add a small
383  range (1e-11) to compensate for those possible errors. */
384  NewInterval(lc->val[j]-ZERO,lc->val[j]+ZERO,&ct);
385 
386  if (fabs(lc->val[j])<=10*epsilon)
387  {
388  /* We have a very small coefficient. Since the coeficient is used to divide,
389  we have to avoid a "division by zero" numerical error. In these cases
390  we just check if the linear constraint holds, i.e., if
391  ct*range_var intersects with the linear constraint error.
392  */
393  IntervalProduct(&ct,&(is[x_j]),&range);
394 
395  #if (_DEBUG>6)
396  printf(" Small constant. Avoid division by zero\n");
397  printf(" Forward range: ");
398  PrintInterval(stdout,&range);
399  printf(" (%f)\n",IntervalSize(&range));
400 
401  Intersection(&range,&out,&new_range);
402  printf(" Intersection range: ");
403  PrintInterval(stdout,&new_range);
404  printf(" (%f)\n",IntervalSize(&new_range));
405  #endif
406 
407  if (!Intersection(&range,&out,&new_range))
408  status=EMPTY_BOX;
409  }
410  else
411  {
412  NewInterval(1-ZERO,1+ZERO,&one);
413  IntervalDivision(&one,&ct,&ct);
414  IntervalProduct(&ct,&out,&range);
415 
416  #if (_DEBUG>6)
417  printf(" Temptative new range v[%u]: ",x_j);
418  PrintInterval(stdout,&range);
419  printf(" (%f)\n",IntervalSize(&range));
420  #endif
421 
422  if (Intersection(&(is[x_j]),&range,&new_range))
423  {
424  double s1,s2;
425 
426  #if (_DEBUG>6)
427  printf(" New range v[%u]: ",x_j);
428  PrintInterval(stdout,&new_range);
429  printf(" (%f)\n",IntervalSize(&new_range));
430  #endif
431 
432  s1=IntervalSize(&(is[x_j]));
433  s2=IntervalSize(&new_range);
434  if (s2<(s1-ZERO))
435  {
436  CopyInterval(&(is[x_j]),&new_range);
437  status=REDUCED_BOX;
438  }
439  }
440  else
441  status=EMPTY_BOX;
442  }
443  }
444  }
445  }
446 
447  return(status);
448  }
449 }
450 
451 /*
452  We compare the linear constraints using the angle between them (i.e., between
453  the vectors defining the hyperplane of the constraint).
454  The output "scale" gives ct so tath lc1*scale=lc2
455 */
456 boolean CmpLinearConstraints(double *scaleOne2Two,TLinearConstraint *lc1,TLinearConstraint *lc2)
457 {
458  boolean equal;
459 
460  equal=FALSE;
461 
462  if (lc1->n==lc2->n)
463  {
464  unsigned int j,l;
465  double n1,n2,n12,c;
466 
467  n12=0;
468  equal=TRUE;
469  j=0;
470  while((equal)&&(j<lc1->n))
471  {
472  /* look for ind[j] in lc */
473  equal=FALSE;
474  l=0;
475  while((!equal)&&(l<lc2->n))
476  {
477  equal=(lc1->ind[j]==lc2->ind[l]);
478  if (equal)
479  n12+=(lc1->val[j]*lc2->val[l]);
480  else
481  l++;
482  }
483  j++;
484  }
485 
486  if(equal)
487  {
488  n1=0.0;
489  n2=0.0;
490  for(j=0;j<lc1->n;j++)
491  {
492  n1+=(lc1->val[j]*lc1->val[j]);
493  n2+=(lc2->val[j]*lc2->val[j]);
494  }
495  n1=sqrt(n1);
496  n2=sqrt(n2);
497 
498  /* If the cosinus between the to normals defining the constrain planes
499  is close to one, then the constraints are almost equivalent (up to the
500  error than can be cleverly merged) */
501  c=n12/(n1*n2); /*cosinus -> [-1,1]*/
502  equal=((fabs(c-1.0)<=ZERO)||(fabs(c+1.0)<=ZERO));
503 
504  if (equal)
505  {
506  /*This scale converts lc1 into lc2*/
507 
508  /*define scale: the cosinus (known to be close to -1 or to 1) gives
509  the sign and the norms the magnituge*/
510  *scaleOne2Two=(c<0?-1.0:1.0)*n2/n1;
511 
512  /*Could also be c*n2/n1 because c is very close to one*/
513  }
514  }
515  }
516  return(equal);
517 }
518 
519 double EvaluateLinearConstraint(double *varValues,TLinearConstraint *lc)
520 {
521  double v;
522  unsigned int kk;
523 
524  v=0;
525  for(kk=0;kk<lc->n;kk++)
526  v+=(lc->val[kk]*varValues[lc->ind[kk]]);
527 
528  return(v);
529 }
530 
532 {
533  unsigned int kk;
534  Tinterval a,r;
535 
536  NewInterval(0,0,i_out);
537  for(kk=0;kk<lc->n;kk++)
538  {
539  /* The coefficients of the linear constraint can be affected by some noise
540  due to floating point roundings when operating them. We add a small
541  range (1e-11) to compensate for those possible errors. */
542  NewInterval(lc->val[kk]-ZERO,lc->val[kk]+ZERO,&a);
543  IntervalProduct(&(varValues[lc->ind[kk]]),&a,&r);
544  IntervalAdd(&r,i_out,i_out);
545  }
546 }
547 
548 void PrintLinearConstraint(FILE *f,boolean eq,char **varName,TLinearConstraint *lc)
549 {
550  unsigned int kk;
551  Tinterval e;
552 
553  for(kk=0;kk<lc->n;kk++)
554  {
555  if (lc->val[kk]==1)
556  {
557  if (kk>0)
558  fprintf(f,"+");
559  }
560  else
561  {
562  if (lc->val[kk]==-1)
563  fprintf(f,"-");
564  else
565  fprintf(f,"%+.12g*",lc->val[kk]);
566  }
567 
568  if (varName==NULL)
569  fprintf(f,"v_%u",lc->ind[kk]);
570  else
571  fprintf(f,"%s",varName[lc->ind[kk]]);
572 
573  }
574  if (eq)
575  {
576  fprintf(f," = ");
577  PrintInterval(f,&(lc->error));
578  fprintf(f," (s:%g)",IntervalSize(&(lc->error)));
579  }
580  else
581  {
582  if (IntervalSize(&(lc->error))<ZERO)
583  {
584  double c;
585 
586  c=IntervalCenter(&(lc->error));
587  if ((c!=0.0)||(lc->n==0))
588  fprintf(f," %+.12g",-c);
589  }
590  else
591  {
592  IntervalInvert(&(lc->error),&e);
593  fprintf(f," + ");
594  PrintInterval(f,&e);
595  }
596  }
597  fprintf(f,"\n");
598 }
599 
601 {
602  unsigned int i;
603 
604  fprintf(f,"%u %u ",lc->n,lc->max);
605 
606  for(i=0;i<lc->n;i++)
607  fprintf(f,"%u %f ",lc->ind[i],lc->val[i]);
608 
609  fprintf(f," %f %f ",LowerLimit(&(lc->error)),UpperLimit(&(lc->error)));
610 }
611 
613 {
614  unsigned int i;
615  double l,u;
616 
617  fscanf(f,"%u %u",&(lc->n),&(lc->max));
618  NEW(lc->ind,lc->max,unsigned int);
619  NEW(lc->val,lc->max,double);
620 
621  for(i=0;i<lc->n;i++)
622  {
623  fscanf(f,"%u",&(lc->ind[i]));
624  fscanf(f,"%lf",&(lc->val[i]));
625  }
626  fscanf(f,"%lf",&l);
627  fscanf(f,"%lf",&u);
628  NewInterval(l,u,&(lc->error));
629 }
630 
631 
633 {
634  free(lc->ind);
635  free(lc->val);
636  DeleteInterval(&(lc->error));
637 }
638 
639 
void AddLinearConstraints(TLinearConstraint *lc1, TLinearConstraint *lc2)
Adds one linear constraint to another.
boolean Intersection(Tinterval *i1, Tinterval *i2, Tinterval *i_out)
Computes the intersection of two intervals.
Definition: interval.c:285
Set of variables of a cuiksystem.
Definition: variables.h:38
#define INIT_NUM_TERMS_LC
Initial room for terms in a linear constraint.
void CleanLinearConstraint(double epsilon, Tinterval *is, TLinearConstraint *lc)
Removes terms in the linear constraint that give too small ranges.
#define FALSE
FALSE.
Definition: boolean.h:30
void InitLinearConstraint(TLinearConstraint *lc)
Constructor.
void DeleteLinearConstraint(TLinearConstraint *lc)
Destructor.
unsigned int GetVariableTypeN(unsigned int n, Tvariables *vs)
Gets the type of a particular variable.
Definition: variables.c:123
#define NEW(_var, _n, _type)
Allocates memory space.
Definition: defines.h:385
A linear constraint with an associated error.
double * GetLinearConstraintCoefficients(TLinearConstraint *lc)
Gets the linear constraint coefficients.
void IntervalAdd(Tinterval *i1, Tinterval *i2, Tinterval *i_out)
Addition of two intervals.
Definition: interval.c:423
void SaveLinearConstraint(FILE *f, TLinearConstraint *lc)
Saves the linear constraint into a file.
#define EMPTY_BOX
One of the possible results of reducing a box.
Definition: box.h:25
void IntervalInvert(Tinterval *i, Tinterval *i_out)
Change of sign of a given interval.
Definition: interval.c:461
#define TRUE
TRUE.
Definition: boolean.h:21
void EvaluateLinearConstraintInt(Tinterval *varValues, Tinterval *i_out, TLinearConstraint *lc)
Interval evaluation of a linear constraint.
boolean SimplifyLinearConstraint(boolean *full, Tinterval *is, TLinearConstraint *lc)
Apply linear constraints to reduce the ranges of the problem variables.
void Error(const char *s)
General error function.
Definition: error.c:80
void PrintLinearConstraint(FILE *f, boolean eq, char **varName, TLinearConstraint *lc)
Prints a linear constraint.
#define ZERO
Floating point operations giving a value below this constant (in absolute value) are considered 0...
Definition: defines.h:37
void CopyInterval(Tinterval *i_dst, Tinterval *i_org)
Copy constructor.
Definition: interval.c:59
boolean CmpLinearConstraints(double *scaleOne2Two, TLinearConstraint *lc1, TLinearConstraint *lc2)
Compares two linear constraints.
void CopyLinearConstraint(TLinearConstraint *lc_dst, TLinearConstraint *lc_src)
Copy constructor.
boolean BoundedLinearConstraint(TLinearConstraint *lc)
Test if the constraint is bounded.
double LowerLimit(Tinterval *i)
Gets the lower limit.
Definition: interval.c:79
unsigned int * ind
unsigned int GetLinearConstraintVariable(unsigned int i, TLinearConstraint *lc)
Gets the a particular variable index.
Definitions of constants and macros used in several parts of the cuik library.
void InvertLinearConstraint(TLinearConstraint *lc)
Changes the sign of a linear constraint.
void DeleteInterval(Tinterval *i)
Destructor.
Definition: interval.c:1021
double UpperLimit(Tinterval *i)
Gets the uppser limit.
Definition: interval.c:87
double RemoveTermFromLinearConstraint(unsigned int ind, TLinearConstraint *lc)
Removes a variable from a linear constraint.
boolean LinearConstraintIncludes(unsigned int ind, TLinearConstraint *lc)
Checks if a variable is included in a linear constraint.
void LoadLinearConstraint(FILE *f, TLinearConstraint *lc)
Constructor. Loads the linear constraint from a file.
void IntervalDivision(Tinterval *num, Tinterval *den, Tinterval *i_out)
Interval division.
Definition: interval.c:556
unsigned int CropLinearConstraint(double epsilon, unsigned int varType, Tbox *b, Tvariables *vs, TLinearConstraint *lc)
Reduce the ranges for.
A box.
Definition: box.h:83
void SetLinearConstraintError(Tinterval *error, TLinearConstraint *lc)
Sets a new righ-hand side error of the linear constraint.
void AddCt2LinearConstraint(double ct, TLinearConstraint *lc)
Adds a constant term to the linear constraint.
#define MEM_DUP(_var, _n, _type)
Duplicates a previously allocated memory space.
Definition: defines.h:414
void PrintInterval(FILE *f, Tinterval *i)
Prints an interval.
Definition: interval.c:1006
void ScaleLinearConstraint(double a, TLinearConstraint *lc)
Scales a linear constraint.
#define NO_UINT
Used to denote an identifier that has not been initialized.
Definition: defines.h:435
unsigned int GetNumTermsInLinearConstraint(TLinearConstraint *lc)
Number of variables in a linear constraint.
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
void GetLinearConstraintError(Tinterval *error, TLinearConstraint *lc)
Gets the right-hand side interval for the linear constraint.
double EvaluateLinearConstraint(double *varValues, TLinearConstraint *lc)
Evaluates a linear combination for a given point.
double GetLinearConstraintErrorSize(TLinearConstraint *lc)
Gets the size of the right-hand side interval for the linear constraint.
Tinterval * GetBoxIntervals(Tbox *b)
Returns a pointer to the array of intervals defining the box.
Definition: box.c:284
#define MEM_EXPAND(_var, _n, _type)
Expands a previously allocated memory space.
Definition: defines.h:404
void IntervalProduct(Tinterval *i1, Tinterval *i2, Tinterval *i_out)
Product of two intervals.
Definition: interval.c:389
void NewInterval(double lower, double upper, Tinterval *i)
Constructor.
Definition: interval.c:47
#define INF
Infinite.
Definition: defines.h:70
#define REDUCED_BOX
One of the possible results of reducing a box.
Definition: box.h:38
unsigned int * GetLinearConstraintVariables(TLinearConstraint *lc)
Gets the linear constraint variables.
Defines a interval.
Definition: interval.h:33
Definition of the TLinearConstraint type and the associated functions.
double IntervalSize(Tinterval *i)
Gets the uppser limit.
Definition: interval.c:96
void AddTerm2LinearConstraint(unsigned int ind, double val, TLinearConstraint *lc)
Adds a scaled variable to the linear constraint.
#define NOT_REDUCED_BOX
One of the possible results of reducing a box.
Definition: box.h:59
double GetLinearConstraintCoefficient(unsigned int i, TLinearConstraint *lc)
Gets the a particular linear constraint coefficient.
void ResetLinearConstraint(TLinearConstraint *lc)
Resets a linear constraint.
void IntervalOffset(Tinterval *i, double offset, Tinterval *i_out)
Interval offset.
Definition: interval.c:627
Definition of the Tinterval type and the associated functions.