Institut de Robòtica i Informàtica Industrial
KRD Group

The CuikSuite Project

variable_set.c

Go to the documentation of this file.
00001 #include "variable_set.h"
00002 
00003 #include "defines.h"
00004 
00005 #include <string.h>
00006 #include <math.h>
00007 
00008 
00019 /*private function of adding a var to vs*/
00020 
00031 void AddVariableInt(unsigned int varid,unsigned int p,Tvariable_set *vs);
00032 
00033 void AddVariableInt(unsigned int varid,unsigned int p,Tvariable_set *vs)
00034 {  
00035   signed int j;
00036   unsigned int s;
00037 
00038   if (vs->nvars==vs->maxvars)
00039     {
00040       MEM_DUP(vs->var_id,vs->maxvars,unsigned int);
00041       MEM_EXPAND(vs->power,vs->maxvars,unsigned int);
00042     }
00043   
00044   vs->var_id[vs->nvars]=varid;
00045   vs->power[vs->nvars]=p;
00046   vs->nvars++;
00047 
00048   /* Keep variables in order from lower to upper ID */
00049   j=vs->nvars-1;
00050   while((j>0)&&(vs->var_id[j-1]>vs->var_id[j]))
00051     {
00052       s=vs->var_id[j-1];
00053       vs->var_id[j-1]=vs->var_id[j];
00054       vs->var_id[j]=s;
00055 
00056       s=vs->power[j-1];
00057       vs->power[j-1]=vs->power[j];
00058       vs->power[j]=s;
00059 
00060       j--;
00061     }
00062 }
00063 
00064 void InitVarSet(Tvariable_set *vs)
00065 {
00066   vs->nvars=0;
00067   vs->maxvars=INIT_NUM_VARIABLES;
00068   NEW(vs->var_id,vs->maxvars,unsigned int);
00069   NEW(vs->power,vs->maxvars,unsigned int);
00070 }
00071 
00072 void ResetVarSet(Tvariable_set *vs)
00073 {
00074   vs->nvars=0;
00075 }
00076 
00077 void CopyVarSet(Tvariable_set *vs_dst,Tvariable_set *vs_orig)
00078 {
00079   vs_dst->nvars=vs_orig->nvars;
00080 
00081   vs_dst->maxvars=vs_orig->maxvars; /*space for vars to be copied + some extra space for growing */
00082 
00083   NEW(vs_dst->var_id,vs_dst->maxvars,unsigned int);
00084   NEW(vs_dst->power,vs_dst->maxvars,unsigned int);
00085 
00086   memcpy(vs_dst->var_id,vs_orig->var_id,vs_dst->nvars*sizeof(unsigned int));
00087   memcpy(vs_dst->power,vs_orig->power,vs_dst->nvars*sizeof(unsigned int));
00088 }
00089 
00090 void ShiftVarIndexes(unsigned int nv,Tvariable_set *vs)
00091 {
00092   unsigned int i;
00093 
00094   for(i=0;i<vs->nvars;i++)
00095     {
00096       if (vs->var_id[i]==nv)
00097         Error("Remove the variable before shifting the var indexes for the remaining vars");
00098       if (vs->var_id[i]>nv)
00099         vs->var_id[i]--;
00100     }
00101 }
00102 
00103 unsigned int CmpVarSet(Tvariable_set *vs1,Tvariable_set *vs2)
00104 {
00105   unsigned int r;
00106   unsigned int i;
00107 
00108   if (vs1->nvars>vs2->nvars)
00109     r=2;
00110   else
00111     {
00112       if (vs2->nvars>vs1->nvars)
00113         r=1;
00114       else
00115         {
00116           i=0;
00117           while((i<vs1->nvars)&&
00118                 (vs1->var_id[i]==vs2->var_id[i])&&
00119                 (vs1->power[i]==vs2->power[i])) 
00120             i++;
00121   
00122           if (i==vs1->nvars)
00123             r=0;
00124           else
00125             {
00126               if (vs1->power[i]>vs2->power[i])
00127                 r=2;
00128               else
00129                 {
00130                   if (vs2->power[i]>vs1->power[i])
00131                     r=1;
00132                   else
00133                     {
00134                       if (vs1->var_id[i]>vs2->var_id[i])
00135                         r=1;
00136                       else
00137                         r=2;
00138                     }
00139                 }
00140             }
00141         }
00142     }
00143   return(r);
00144 }
00145 
00146 boolean EmptyVarSet(Tvariable_set *vs)
00147 {
00148   return(vs->nvars==0);
00149 }
00150 
00151 unsigned int GetPlaceinSet(unsigned int id,Tvariable_set *vs)
00152 { 
00153   boolean found=FALSE;
00154   unsigned int i;
00155 
00156   i=0;
00157   while((i<vs->nvars)&&(!found))
00158     {
00159       found=(id==vs->var_id[i]);
00160       if (!found) i++;
00161     }
00162     
00163   if (found)
00164     return(i);
00165   else
00166     return(NO_UINT); 
00167 }
00168 
00169 boolean VarIncluded(unsigned int id,Tvariable_set *vs)
00170 { 
00171   return((boolean)(GetPlaceinSet(id,vs)!=NO_UINT));
00172 }
00173 
00174 boolean Included(unsigned int id,unsigned int p,Tvariable_set *vs)
00175 {
00176   boolean found=FALSE;
00177   unsigned int i;
00178 
00179   i=0;
00180   while((i<vs->nvars)&&(!found))
00181     {
00182       found=((id==vs->var_id[i])&&(p==vs->power[i]));
00183       if (!found) i++;
00184     }
00185   
00186   return(found);
00187 }
00188 
00189 /*True if they share a variable with the SAME exponent */
00190 boolean VarSetIntersect(Tvariable_set *vs1,Tvariable_set *vs2)
00191 {
00192   boolean found=FALSE;
00193   unsigned int i;
00194   
00195   i=0;
00196   while((i<vs1->nvars)&&(!found))
00197     {
00198       found=Included(vs1->var_id[i],vs1->power[i],vs2);
00199       if (!found) i++;
00200     }
00201   return(found);
00202 }
00203 
00204 /* result of vs1 \ vs2  (variables with different exponent are taken as different) */
00205 /* observe that this operation is NOT inverse of the UnionVarSet */
00206 void SubstractVarSet(Tvariable_set *vs1,Tvariable_set *vs2,Tvariable_set *v_out) 
00207 {
00208   Tvariable_set v_aux;  
00209   unsigned int i;
00210 
00211   InitVarSet(&v_aux);
00212 
00213   for(i=0;i<vs1->nvars;i++)
00214     {
00215       if (!Included(vs1->var_id[i],vs1->power[i],vs2))
00216         AddVariableInt(vs1->var_id[i],vs1->power[i],&v_aux);
00217     }
00218   if ((v_out==vs1)||(v_out==vs2))
00219     DeleteVarSet(v_out);
00220 
00221   CopyVarSet(v_out,&v_aux);  
00222 
00223   DeleteVarSet(&v_aux);
00224 }
00225 
00226 /*result of v1+v2 : we want to keep all the variables and the maximum of the exponents
00227   in v1,v2 */
00228 void UnionVarSet(Tvariable_set *vs1,Tvariable_set *vs2,Tvariable_set *v_out)
00229 {
00230   Tvariable_set v_aux;
00231   unsigned int i,j,n;
00232   boolean found;
00233 
00234   CopyVarSet(&v_aux,vs1);
00235   n=v_aux.nvars;
00236 
00237   for(i=0;i<vs2->nvars;i++)
00238     {
00239       found=FALSE;
00240       j=0;
00241       while((j<n)&&(!found))
00242         {
00243           if (vs2->var_id[i]==v_aux.var_id[j])
00244               found=TRUE;
00245           else
00246             j++;
00247         }
00248       if (found)
00249         {
00250           if (vs2->power[i]>v_aux.power[j])
00251             v_aux.power[j]=vs2->power[i]; /*we keep the maximum order for this variable*/
00252         }
00253       else
00254         AddVariableInt(vs2->var_id[i],vs2->power[i],&v_aux);
00255     }
00256 
00257   if ((v_out==vs1)||(v_out==vs2))
00258     DeleteVarSet(v_out);
00259 
00260   CopyVarSet(v_out,&v_aux);  
00261 
00262   DeleteVarSet(&v_aux);
00263 }
00264 
00265 /*If already in the set, we just increse the exponent. We implement: (var_set)*x^p */
00266 void AddVariable2Set(unsigned int varid,unsigned int p,Tvariable_set *vs)
00267 {
00268   boolean found=FALSE;
00269   unsigned int i;
00270 
00271   i=0;
00272   while((i<vs->nvars)&&(!found))
00273     {
00274       found=(varid==vs->var_id[i]);
00275       if (!found) i++;
00276     }
00277   if (found)
00278     vs->power[i]+=p;
00279   else   
00280     AddVariableInt(varid,p,vs);
00281 }
00282 
00283 /*Independent of the exponent*/
00284 void RemoveVariableFromSet(unsigned int varid,Tvariable_set *vs)
00285 {
00286   boolean found=FALSE;
00287   unsigned int i,j;
00288 
00289   i=0;
00290   while((i<vs->nvars)&&(!found))
00291     {
00292       found=(varid==vs->var_id[i]);
00293       if (!found) i++;
00294     }
00295   if (found)
00296     {
00297       for(j=i+1;j<vs->nvars;j++)
00298         {
00299           vs->var_id[j-1]=vs->var_id[j];
00300           vs->power[j-1]=vs->power[j];
00301         }
00302       vs->nvars--;
00303     }
00304 }
00305 
00306 unsigned int VarSetOrder(Tvariable_set *vs)
00307 {
00308   unsigned int i,o;
00309   
00310   o=0;
00311   for(i=0;i<vs->nvars;i++)
00312     o+=vs->power[i];
00313     
00314 /*
00315   o=0;
00316   for(i=0;i<vs->nvars;i++)
00317     {
00318       if (vs->power[i]>o)
00319         o=vs->power[i];
00320     }
00321 */
00322   return(o);
00323 }
00324 
00325 unsigned int VariableSetSize(Tvariable_set *vs)
00326 {
00327   return(vs->nvars);
00328 }
00329 
00330 unsigned int GetVariableN(unsigned int n,Tvariable_set *vs)
00331 {
00332   if (n<vs->nvars)
00333     return(vs->var_id[n]);
00334   else
00335     {
00336       Error("Requested an element not included in VarSet");
00337       return(0);
00338     }
00339 }
00340 
00341 unsigned int *GetVariables(Tvariable_set *vs)
00342 {
00343   return(vs->var_id);
00344 }
00345 
00346 unsigned int GetVariablePowerN(unsigned int n,Tvariable_set *vs)
00347 {
00348   if (n<vs->nvars)
00349     return(vs->power[n]);
00350   else
00351     {
00352       Error("Requested an element not included in VarSet");
00353       return(0);
00354     }
00355 }
00356 
00357 unsigned int *GetPowers(Tvariable_set *vs)
00358 {
00359   return(vs->power);
00360 }
00361 
00362 double EvaluateVarSet(double *varValues,Tvariable_set *vs)
00363 {
00364   double f;
00365   unsigned int i;
00366 
00367   if (vs->nvars==0)
00368     Error("Should not evalute empty var sets");
00369 
00370   f=1.0;
00371   for(i=0;i<vs->nvars;i++)
00372     {
00373       if (vs->power[i]==1)
00374         f*=varValues[vs->var_id[i]];
00375       else
00376         f*=pow(varValues[vs->var_id[i]],(double)(vs->power[i]));
00377     }
00378 
00379   return(f);
00380 }
00381 
00382 void EvaluateVarSetInt(Tinterval *varValues,Tinterval *i_out,Tvariable_set *vs)
00383 {
00384   unsigned int i;
00385   Tinterval i_aux;
00386 
00387   if (vs->nvars==0)
00388     Error("Should not evalute empty var sets");
00389   
00390   NewInterval(1,1,i_out);
00391   for(i=0;i<vs->nvars;i++)
00392     {
00393       if (vs->power[i]==1)
00394         IntervalProduct(i_out,&(varValues[vs->var_id[i]]),i_out);
00395       else
00396         {
00397           IntervalPow(&(varValues[vs->var_id[i]]),vs->power[i],&i_aux);
00398           IntervalProduct(i_out,&i_aux,i_out);
00399         }
00400     }
00401 }
00402 
00403 unsigned int DeriveVarSet(unsigned int nv,Tvariable_set *dvs,Tvariable_set *vs)
00404 {
00405   unsigned int i,p; 
00406 
00407   dvs->maxvars=vs->maxvars; 
00408 
00409   NEW(dvs->var_id,dvs->maxvars,unsigned int);
00410   NEW(dvs->power,dvs->maxvars,unsigned int);
00411 
00412   dvs->nvars=0;
00413   p=0;
00414   for(i=0;i<vs->nvars;i++)
00415     {
00416       if (vs->var_id[i]==nv)
00417         {
00418           p=vs->power[i];
00419           if (vs->power[i]>1)
00420             {
00421               dvs->var_id[dvs->nvars]=vs->var_id[i];
00422               dvs->power[dvs->nvars]=p-1;
00423               dvs->nvars++;
00424             }
00425         }
00426       else
00427         {
00428           dvs->var_id[dvs->nvars]=vs->var_id[i];
00429           dvs->power[dvs->nvars]=vs->power[i];
00430           dvs->nvars++;
00431         }
00432     }
00433   return(p);
00434 }
00435 
00436 void PrintVarSet(FILE *f,char **varNames,Tvariable_set *vs)
00437 {
00438   unsigned int i; 
00439 
00440   if (vs->nvars>0)
00441     {
00442       for(i=0;i<vs->nvars;i++)
00443         {
00444           if (i>0) fprintf(f,"*");
00445 
00446           if (varNames!=NULL)
00447             { 
00448               char *n;
00449 
00450               n=varNames[vs->var_id[i]];
00451               PRINT_VARIABLE_NAME(f,n);
00452             }
00453           else
00454             fprintf(f,"v_%u",vs->var_id[i]);
00455 
00456           if (vs->power[i]>1)
00457             fprintf(f,"^%d",vs->power[i]);
00458         }
00459     }
00460 }
00461 
00462 void DeleteVarSet(Tvariable_set *vs)
00463 {
00464   free(vs->var_id);
00465   free(vs->power);
00466 }