samples.c
Go to the documentation of this file.
1 #include "samples.h"
2 
3 #include "filename.h"
4 #include "algebra.h"
5 #include "parameters.h"
6 #include "list.h"
7 #include "random.h"
8 
9 #include <stdlib.h>
10 #include <string.h>
11 #include <math.h>
12 
34 int cmpUInt(const void *a,const void *b);
35 
51 double PathLength(unsigned int *tp,unsigned int m,
52  unsigned int np,double **point);
53 
54 
68 void ShortcutSmooth(Tparameters *pr,Tstatistics *stime,
69  unsigned int *np,double ***point,TAtlasBase *w);
70 
92 void RandomSmooth(Tparameters *pr,unsigned int nCores,unsigned int maxIterations,
93  Tstatistics *stime,
94  unsigned int *np,double ***point,TAtlasBase *w);
95 
119 void GradientSmooth(Tparameters *pr,unsigned int nCores,unsigned int maxIterations,
120  Tstatistics *stime,
121  unsigned int *np,double ***point,TAtlasBase *w);
122 
123 
124 
136 void SaveSamplesInt(Tfilename *fpath,unsigned int nvs,
137  unsigned int ns,double **path);
138 
139 /********************************************************************/
140 /********************************************************************/
141 /********************************************************************/
142 
143 void InitSamples(unsigned int *ms,unsigned int *ns,double ***path)
144 {
145  *ms=INIT_NUM_SAMPLES;
146  *ns=0;
147  NEW((*path),*ms,double *);
148 }
149 
150 void AddSample2Samples(unsigned int nv,double *sample,
151  unsigned int nvs,boolean *systemVars,
152  unsigned int *ms,unsigned int *ns,double ***path)
153 {
154  unsigned int i,k;
155 
156  if (*ns==*ms)
157  MEM_DUP(*path,*ms,double *);
158 
159  NEW((*path)[*ns],nvs,double);
160  k=0;
161  for(i=0;i<nv;i++)
162  {
163  if ((systemVars==NULL)||(systemVars[i]))
164  {
165  (*path)[*ns][k]=sample[i];
166  k++;
167  }
168  }
169  (*ns)++;
170 }
171 
172 double ConnectSamplesChart(Tparameters *pr,unsigned int *tp,
173  Tbox *domain,
174  unsigned int m,unsigned int n,
175  double *s1,double *s2,
176  double md,boolean checkCollisions,
177  boolean *reached,boolean *collision,
178  double *lastSample,unsigned int *ns,double ***path,
179  TAtlasBase *w)
180 {
181  boolean blocked,validChart,first;
182  double dist;
183  double *s,*s_next,*s_goal,*t,*t_next,*t_goal;
184  unsigned int i,k,a,b;
185  double delta,step,epsilon,d,dtmp,d12,e,ce,r,nt;
186  unsigned int ms;
187  TJacobian sJ;
188  Tchart c;
189 
190  epsilon=GetParameter(CT_EPSILON,pr);
191  delta=GetParameter(CT_DELTA,pr);
192  k=(unsigned int)GetParameter(CT_N_DOF,pr);
193  e=GetParameter(CT_E,pr);
194  ce=GetParameter(CT_CE,pr);
195  r=GetParameter(CT_R,pr);
196 
197  CS_WD_GET_SIMP_JACOBIAN(pr,&sJ,w);
198  /* Assume that the CD is already initialized */
199 
200  GetJacobianSize(&a,&b,&sJ);
201  if (b!=m)
202  Error("Jacobian size missmatch in ConnectSamplesChart");
203 
204  if ((ns!=NULL)&&(path!=NULL))
205  InitSamples(&ms,ns,path);
206  else
207  ms=0;
208 
209  /* we keep track of the current sample in the path
210  and the previous one to compute the displacement
211  between them */
212  if (lastSample==NULL)
213  { NEW(s,m,double); }
214  else
215  s=lastSample;
216  memcpy(s,s1,m*sizeof(double)); /* current sample */
217  NEW(s_next,m,double); /* space for the next sample */
218  NEW(s_goal,m,double); /* goal sample projected to the current chart */
219  NEW(t,k,double); /* parameters for 's' */
220  NEW(t_next,k,double); /* parameters for 's_next' */
221  NEW(t_goal,k,double); /* parameters for 's_goal' */
222 
223  d=DistanceTopology(m,tp,s1,s2);
224  d12=d;
225  dist=0.0;
226  *reached=(d12<delta);
227  *collision=FALSE;
228  blocked=FALSE;
229 
230  while ((!*reached)&&(!blocked)&&(!*collision))
231  {
232  /* Initialize the chart at the current sample */
233  if (tp!=NULL)
234  ArrayPi2Pi(m,tp,s);
235 
236  //fprintf(stderr,"New chart\n");
237  if (InitChart(pr,TRUE,domain,tp,m,k,s,e,ce,r,&sJ,w,&c)!=0)
238  {
239  //fprintf(stderr," Blocked (error init chart)\n");
240  blocked=TRUE;
241  }
242  else
243  {
244  /* 's' is 0 in the new chart */
245  for(i=0;i<k;i++)
246  t[i]=0.0;
247 
248  /* Determine the advance direction */
249  DifferenceVectorTopology(m,tp,s2,s,s_goal);
250  AccumulateVector(m,s,s_goal);
251  Manifold2Chart(s_goal,NULL,t_goal,&c); /* without topology now */
252  nt=Norm(k,t_goal);
253  if (nt<1e-3)
254  {
255  //fprintf(stderr," Blocked (small projection)\n");
256  blocked=TRUE; /* it is not clear which direction to take */
257  }
258  else
259  {
260  //fprintf(stderr,"tg:%g\n",Norm(k,t_goal));
261  /* when far from the goal, we move the goal far enough to ensure
262  the creation of new charts, if necessary. */
263  if (DistanceTopology(m,tp,s2,s)>r)
264  ScaleVector(2.0*r/nt,k,t_goal); /* move the goal far enough */
265 
266  /* Move in the current chart as far as possible */
267  validChart=TRUE;
268  step=delta;
269  first=TRUE;
270  while ((validChart)&&(!*reached)&&(!blocked)&&(!*collision))
271  {
272  /* Define t_next from t and t_goal */
273  DifferenceVector(k,t_goal,t,t_next);
274  nt=Norm(k,t_next);
275  if (nt>step)
276  {
277  SumVectorScale(k,t,step/nt,t_next,t_next);
278  nt=step;
279  }
280  else
281  AccumulateVector(k,t,t_next);
282  //fprintf(stderr," New step-> dg:%g (%g) st:%g tn:%g tg:%g (%g)\n",nt,DistanceTopology(m,tp,s2,s),nt,Norm(k,t_next),Norm(k,t_goal),Distance(k,t_next,t_goal));
283 
284  if (0) //(Norm(k,t_next)>r) /* TO BE REMOVED */
285  {
286  //fprintf(stderr," Change chart (r)\n");
287  validChart=FALSE;
288  }
289  else
290  {
291  /* and project to the manifold to obtain q_next */
292  if (Chart2Manifold(pr,&sJ,t_next,NULL,s,s_next,&c)>e)
293  {
294  //fprintf(stderr," Change chart (e)\n");
295  validChart=FALSE;
296  }
297  else
298  {
299  if ((nt<epsilon)&&(DistanceTopology(m,tp,s_next,s2)>delta))
300  {
301  /* we reached the targed in tangent space but the projection does not correspond
302  to the actual goal. Try to advance generating a new chart. */
303  if (first)
304  {
305  /* Note that it is not worth to reduce the step since we are already taking
306  steps of size epsilon. */
307  //fprintf(stderr," Blocked (tangent vs ambient)\n");
308  blocked=TRUE;
309  }
310  else
311  {
312  //fprintf(stderr," Change chart (tangent vs ambient)\n");
313  validChart=FALSE;
314  }
315  }
316  else
317  {
318  if ((!PointInBoxTopology(NULL,FALSE,m,s_next,0,tp,domain))||
319  (!CS_WD_SIMP_INEQUALITIES_HOLD(pr,s_next,w)))
320  {
321  //fprintf(stderr," Blocked (out of domain)\n");
322  blocked=TRUE;
323  }
324  else
325  {
326  if (checkCollisions)
327  CS_WD_IN_COLLISION(*collision,pr,s_next,s,w);
328  if (*collision)
329  {
330  //fprintf(stderr," Blocked (collision)\n");
331  blocked=TRUE;
332  }
333  else
334  {
335  d=DistanceTopology(m,tp,s,s_next);
336  dtmp=dist+d;
337 
338  /* Sanity check to avoid infinite connections */
339  if ((dtmp>md)||(dtmp>2.0*d12)||(DistanceTopology(m,tp,s1,s_next)>1.5*d12))
340  {
341  /*
342  if (dtmp>md)
343  fprintf(stderr," Blocked (max dist reached)\n");
344  if (dtmp>2.0*d12)
345  fprintf(stderr," Blocked (path too long)\n");
346  if (DistanceTopology(m,tp,s1,s_next)>1.5*d12)
347  fprintf(stderr," Blocked (too far from origin)\n");
348  */
349  blocked=TRUE;
350  }
351  else
352  {
353  /* Check if it is time to define a new chart along the connection */
354  /* We do the check before copying s_next to s -> the new chart is
355  defined in the last good sample */
356  if (nt/d<(1.0-ce)) /* nt=actual step in tangent space (can be < step at the end) */
357  {
358  //fprintf(stderr," Change chart (ce)\n");
359  validChart=FALSE;
360  }
361  else
362  {
363  dist=dtmp;
364 
365  *reached=(DistanceTopology(m,tp,s_next,s2)<delta);
366  /*
367  fprintf(stderr," New sample (%g)\n",dist);
368  if (*reached)
369  fprintf(stderr," Reached\n");
370  */
371  /* since everything is ok, we will continue from the last point */
372  memcpy(t,t_next,k*sizeof(double));
373  memcpy(s,s_next,m*sizeof(double));
374 
375  /* t_next and s_next alredy backed up-> we can modify them */
376  if (tp!=NULL)
377  ArrayPi2Pi(m,tp,s_next);
378 
379  /* Here we have a new valid sample */
380  if ((ms>0)&&(!(*reached)))
381  AddSample2Samples(m,s_next,m,NULL,&ms,ns,path);
382 
383  first=FALSE; /* we already have one sample */
384  step=delta; /* the following steps will be normal size */
385  }
386  }
387  }
388  }
389  }
390  }
391  }
392  if ((!validChart)&&(first))
393  {
394  /* we already have a chart at the last 's' -> we need sample close to 's'
395  where to generate the new chart. This only happens on very curved
396  manifolds or close to singularities. */
397  step*=0.9;
398  if (step<epsilon)
399  {
400  //fprintf(stderr," Blocked (impossible)\n");
401  blocked=TRUE;
402  }
403  validChart=TRUE;
404  }
405  }
406  }
407  }
408  DeleteChart(&c);
409  }
410 
411  if (*reached)
412  dist+=d; /* epsilon/delta size */
413  else
414  {
415  if (ms>0)
416  {
417  DeleteSamples(*ns,*path);
418  ns=0;
419  }
420  }
421 
422  if (lastSample==NULL)
423  free(s);
424  free(s_next);
425  free(s_goal);
426  free(t);
427  free(t_next);
428  free(t_goal);
429  DeleteJacobian(&sJ);
430 
431  return(dist);
432 }
433 
434 double ConnectSamples(Tparameters *pr,unsigned int *tp,
435  Tbox *domain,
436  unsigned int m,unsigned int n,
437  double *s1,double *s2,
438  double md,boolean checkCollisions,
439  boolean *reached,boolean *collision,
440  double *lastSample,unsigned int *ns,double ***path,
441  TAtlasBase *w)
442 {
443  boolean blocked;
444  double c;
445  double *v,*s,*s_next,*s_tmp;
446  double delta,epsilon,d,small,d1, d_new;
447  unsigned int ms;
448 
449  delta=GetParameter(CT_DELTA,pr);
450  epsilon=GetParameter(CT_EPSILON,pr);
451  small=delta/50; // for delta=0.05 delta/50 gives the value used by Berenson
452  // Use 10 for RRT*, to avoid too irregular samples
453  if (tp!=NULL)
454  {
455  ArrayPi2Pi(m,tp,s1);
456  ArrayPi2Pi(m,tp,s2);
457  }
458 
459  if ((ns!=NULL)&&(path!=NULL))
460  InitSamples(&ms,ns,path);
461  else
462  ms=0;
463 
464  /* displacement from current sample to goal */
465  NEW(v,m,double);
466  /* we keep track of the current sample in the path
467  and the previous one to compute the displacement
468  between them */
469  if (lastSample==NULL)
470  { NEW(s,m,double); }
471  else
472  s=lastSample;
473  memcpy(s,s1,sizeof(double)*m);
474  NEW(s_next,m,double);
475  NEW(s_tmp,m,double);
476 
477  DifferenceVectorTopology(m,tp,s2,s,v);
478  d=Norm(m,v);
479  *reached=(d<delta);
480  *collision=FALSE;
481  blocked=FALSE;
482 
483  c=0;
484 
485  while ((!*reached)&&(!blocked)&&(!*collision))
486  {
487  if (d<delta+small)
488  memcpy(s_next,s2,m*sizeof(double));
489  else
490  {
491  SumVectorScale(m,s,delta/d,v,s_next);
492 
493  if (n==0)
494  blocked=FALSE;
495  else
496  blocked=(CS_WD_NEWTON_IN_SIMP(pr,s_next,w)==DIVERGED);
497  }
498 
499  if (!blocked)
500  {
501  memcpy(s_tmp,s_next,m*sizeof(double));
502  if (tp!=NULL)
503  ArrayPi2Pi(m,tp,s_tmp);
504  if ((!PointInBoxTopology(NULL,FALSE,m,s_tmp,0,tp,domain))||
505  (!CS_WD_SIMP_INEQUALITIES_HOLD(pr,s_tmp,w)))
506  blocked=TRUE;
507  else
508  {
509  if (checkCollisions)
510  CS_WD_IN_COLLISION(*collision,pr,s_next,s,w);
511  if (!*collision)
512  {
513  d1=DistanceTopology(m,tp,s,s_next);
514  if (d1<small) /* If stalled -> stop */
515  blocked=TRUE;
516  else
517  {
518  if ((c+d1)>md) /* If beyond the max displacement -> stop */
519  blocked=TRUE;
520  else
521  {
522  memcpy(s,s_next,sizeof(double)*m);
523  DifferenceVectorTopology(m,tp,s2,s,v);
524  d_new=Norm(m,v);
525  if(d_new>d)
526  blocked=TRUE;
527  else
528  {
529  c+=d1;
530  d=d_new;
531  *reached=(d<epsilon);
532  if ((ms>0)&&(!(*reached)))
533  AddSample2Samples(m,s_next,m,NULL,&ms,ns,path);
534  }
535  }
536  }
537  }
538  }
539  }
540  }
541  if (*reached)
542  c+=d; /* epsilon size */
543  else
544  {
545  if (ms>0)
546  {
547  DeleteSamples(*ns,*path);
548  ns=0;
549  }
550  }
551 
552  free(v);
553  if (lastSample==NULL)
554  free(s);
555  free(s_next);
556  free(s_tmp);
557 
558  return(c);
559 }
560 
561 double PathLength(unsigned int *tp,unsigned int m,
562  unsigned int np,double **point)
563 {
564  double l;
565  unsigned int s;
566 
567  l=0.0;
568  for(s=1;s<np;s++)
569  l+=DistanceTopology(m,tp,point[s-1],point[s]);
570 
571  return(l);
572 }
573 
574 int cmpUInt(const void *a,const void *b)
575 {
576  int out;
577 
578  out=0;
579 
580  if ((*(unsigned int *)a)<(*(unsigned int *)b))
581  out=-1;
582  else
583  {
584  if ((*(unsigned int *)a)>(*(unsigned int *)b))
585  out=+1;
586  }
587  return(out);
588 }
589 
591  unsigned int *np,double ***point,TAtlasBase *w)
592 {
593  unsigned int c,g,b,i,k,m,s,ne;
594  double ll,nl;
595  unsigned int newNS,lastNS,lastS;
596  boolean pathOk,collision,done;
597  double **newPath,**lastPath;
598  unsigned int *tp;
599  Tbox domain;
600 
601  CS_WD_GENERATE_SIMP_INITIAL_BOX(pr,&domain,w);
602  m=CS_WD_GET_SIMP_TOPOLOGY(pr,&tp,w);
603  ne=m-(unsigned int)GetParameter(CT_N_DOF,pr);
604  CS_WD_INIT_CD(pr,1,w);
605 
606  //fprintf(stderr,"Initial num steps: %u\n",*np);
607  c=0; /* current */
608  while(c<*np-1)
609  {
610  /* dichotomic search of the largest cut possible from l and up to the end of the path*/
611  /* 'g' and 'b' provide a lower/upper bound the index of the futhers step that can
612  be reached from 'l' without any collision. This searched index is 's' */
613  g=c+1; /* last known good step (step we can directly connect from 'c') */
614  b=*np-1; /* last bad step (step that can not be directly connected from 'c') */
615  s=g;
616  pathOk=FALSE;
617  lastPath=NULL;
618  done=FALSE;
619  while (!done)
620  {
621  s=(g+b)/2;
622  //fprintf(stderr,"[%u - %u - %u]\n",g,s,b);
623 
624  ll=PathLength(tp,m,s-c+1,&((*point)[c]));
625  nl=ConnectSamplesChart(pr,tp,&domain,m,ne,(*point)[c],(*point)[s],ll,
626  TRUE,&pathOk,&collision,NULL,
627  &newNS,&newPath,w);
628  if (pathOk)
629  {
630  /* keep the last valid path */
631  if (lastPath!=NULL)
632  {
633  for(i=0;i<lastNS;i++)
634  free(lastPath[i]);
635  free(lastPath);
636  }
637  lastNS=newNS;
638  lastPath=newPath;
639  lastS=s;
640 
641  //fprintf(stderr,"[%u %u] good\n",c,s);
642  if (s==g) /*[g,b] has size 0 or 1*/
643  done=TRUE;
644  else
645  g=s+1; /* the searched index is larger than 's' */
646  }
647  else
648  {
649  //fprintf(stderr,"[%u %u] blocked\n",c,s);
650  if (s==g) /*[g,b] has size 0 or 1*/
651  done=TRUE;
652  else
653  b=s-1; /* the searched index is lower than 's' */
654  }
655  }
656 
657  //fprintf(stderr,"Test %u->%u : steps %u->%u length %g->%g\n",c,lastS,lastS-c+1,lastNS,ll,nl);
658  if ((lastPath!=NULL)&&(c<lastS-1)&&(lastNS<lastS-c+1)&&(nl<ll)) /* replace only if theres is a minimum gap and the num
659  of steps of the new path is lower */
660  {
661  //fprintf(stderr,"Shorcut from %u to %u in %u steps (%u) ",c,lastS,lastNS,lastS-c+1);
662 
663  /* replace segment l->s with the new path */
664  for(i=c+1;i<lastS;i++)
665  free((*point)[i]);
666 
667  for(i=0,k=c+1;i<lastNS;i++,k++)
668  (*point)[k]=lastPath[i];
669  free(lastPath);
670 
671  for(i=lastS,k=c+1+lastNS;i<*np;i++,k++)
672  (*point)[k]=(*point)[i];
673 
674  *np=c+1+lastNS+(*np-lastS);
675  c=c+1+lastNS;
676 
677  fprintf(stderr,"Steps: %u Path length %g Time: %g\n",*np,
678  PathLength(tp,m,*np,*point),GetElapsedTime(stime));
679  }
680  else
681  /* continue from 'b' */
682  c=lastS;
683  }
684  free(tp);
685  DeleteBox(&domain);
686 }
687 
688 void RandomSmooth(Tparameters *pr,unsigned int nCores,unsigned int maxIterations,
689  Tstatistics *stime,
690  unsigned int *np,double ***point,TAtlasBase *w)
691 {
692  unsigned int s,n,i,n1,n2,k,ne;
693  double nl,pl;
694  unsigned int lns;
695  double **lpath;
696  unsigned int m;
697  Tbox domain;
698  unsigned int *tp;
699  double **newPoint;
700  unsigned int nnp;
701  boolean reached,collision;
702  unsigned int *step,*newStep,j,dnCores,*localLength,*newLocalLength,*newLocalNS;
703  unsigned int *first,*middle,*last;
704  boolean *localPathOK;
705  double ***newLocalPath;
706  unsigned int nCuts;
707 
708  CS_WD_GENERATE_SIMP_INITIAL_BOX(pr,&domain,w);
709  m=CS_WD_GET_SIMP_TOPOLOGY(pr,&tp,w);
710  ne=m-(unsigned int)GetParameter(CT_N_DOF,pr);
711  CS_WD_INIT_CD(pr,nCores,w);
712 
713  //l=PathLength(tp,m,*np,*point);
714 
715  if (nCores>1)
716  {
717  dnCores=2*nCores;
718  NEW(step,dnCores,unsigned int);
719  NEW(newStep,nCores,unsigned int);
720  NEW(first,nCores,unsigned int);
721  NEW(middle,nCores,unsigned int);
722  NEW(last,nCores,unsigned int);
723  NEW(localLength,nCores,unsigned int);
724  NEW(localPathOK,nCores,boolean);
725  NEW(newLocalLength,nCores,unsigned int);
726  NEW(newLocalNS,nCores,unsigned int);
727  NEW(newLocalPath,nCores,double**);
728  }
729 
730  n=(*np);
731  for (s=0;s<maxIterations*n;s++)
732  {
733  if (nCores>1)
734  {
735  /* Select the start/end of the tentative shortcuts (note that we can have repeated random numbers!) */
736  /* It is not convenient to process in parallel too many shorctus since then all shortcuts are
737  small which results in poor path improvement. */
738  nCuts=randomMax(nCores-2)+1;
739  for(j=0;j<2*nCuts;j++)
740  step[j]=randomMax(*np-1);
741  qsort(step,2*nCuts,sizeof(unsigned int),cmpUInt);
742 
743  /* Compute the possible shorcuts */
744  #pragma omp parallel for private(j,n1,n2,collision) schedule(static)
745  for(j=0;j<nCuts;j++)
746  {
747  n1=step[2*j];
748  n2=step[2*j+1];
749 
750  /*
751  The path is split in 'nCuts' different segments. For each
752  segment first[j] is the first element in the segment,
753  middle[j] is the element just after the segment to (potentially)
754  improve and last[j] is the last element included in the segment.
755  */
756  first[j]=n1+1;
757  middle[j]=n2+(n1<n2 ? 0:1); /* if n1==n2, n1 belongs to the previous segment, skip it */
758  last[j]=(j==nCuts-1?(*np)-1:step[2*j+2]);
759 
760  if (first[j]<middle[j])
761  {
762  /* We hava at least one point in the segment to optimize */
763  localLength[j]=PathLength(tp,m,n2-n1+1,&((*point)[n1]));
764  newLocalLength[j]=DEFAULT_CONNECT(pr,tp,&domain,m,ne,(*point)[n1],(*point)[n2],localLength[j],
765  TRUE,&(localPathOK[j]),&collision,NULL,
766  &(newLocalNS[j]),&(newLocalPath[j]),w);
767  }
768  else
769  {
770  localLength[j]=0;
771  newLocalLength[j]=0;
772  localPathOK[j]=FALSE;
773  }
774  }
775  /* New number of path steps taking into account the possible new shortcuts */
776  nnp=first[0];
777  for(j=0;j<nCuts;j++)
778  {
779  newStep[j]=nnp;
780 
781  if ((localPathOK[j])&&(newLocalLength[j]<localLength[j]))
782  nnp+=newLocalNS[j];
783  else
784  nnp+=(middle[j]-first[j]);
785 
786  /* now the connecting segments in betwen the possibly smoothed ones */
787  nnp+=(last[j]-middle[j])+1;
788  }
789 
790  NEW(newPoint,nnp,double*);
791 
792  /* The initial non-smoothed segment */
793  for(i=0;i<first[0];i++)
794  newPoint[i]=(*point)[i];
795 
796  /* now the possibly smoothed segments (in parallel since they store
797  different parts of the new path) */
798  #pragma omp parallel for private(i,j,k) schedule(static)
799  for(j=0;j<nCuts;j++)
800  {
801  k=newStep[j];
802  if ((localPathOK[j])&&(newLocalLength[j]<localLength[j]))
803  {
804  /* keep the new path segment */
805  for(i=0;i<newLocalNS[j];i++)
806  { newPoint[k]=newLocalPath[j][i]; k++; }
807 
808  /* delete the previous path segment */
809  for(i=step[2*j]+1;i<step[2*j+1];i++)
810  free((*point)[i]);
811  }
812  else
813  {
814  if (first[j]<middle[j])
815  {
816  /* Delete the new path segment, if any */
817  if (localPathOK[j])
818  DeleteSamples(newLocalNS[j],newLocalPath[j]);
819 
820  /* keep the previous path segment */
821  for(i=first[j];i<middle[j];i++)
822  { newPoint[k]=(*point)[i]; k++; }
823  }
824  }
825 
826  /* The non-smoothed segment till next step (or the tail
827  non-smoothed segment). */
828  for(i=middle[j];i<=last[j];i++)
829  { newPoint[k]=(*point)[i]; k++; }
830  }
831 
832  /* update the path */
833  free(*point);
834  *point=newPoint;
835  *np=nnp;
836  }
837  else
838  {
839  /* nCores==1 */
840  n1=randomMax(*np-2);
841  n2=n1+1+randomMax(*np-2-n1);
842 
843  pl=PathLength(tp,m,n2-n1+1,&((*point)[n1]));
844 
845  nl=DEFAULT_CONNECT(pr,tp,&domain,m,ne,(*point)[n1],(*point)[n2],pl,
846  TRUE,&reached,&collision,NULL,&lns,&lpath,w);
847  /*
848  if (reached)
849  fprintf(stderr,"Test %u->%u. pl:%g st:%u -> nl:%g nst:%u %s\n",n1,n2,pl,n2-n1+2,nl,lns,(((reached)&&(nl<pl))?"(*)":" "));
850  else
851  fprintf(stderr,"Test %u->%u. pl:%g st:%u failed \n",n1,n2,pl,n2-n1+1);
852  */
853  if ((reached)&&(nl<pl))
854  {
855  /* Replace the path segment with the new path */
856 
857  /* Concat the sequences in a temporary buffer */
858  nnp=n1+1+lns+(*np-n2); /* new number of points */
859  NEW(newPoint,nnp,double*);
860  k=0;
861  for(i=0;i<=n1;i++)
862  { newPoint[k]=(*point)[i]; k++; }
863 
864  for(i=0;i<lns;i++)
865  { newPoint[k]=lpath[i]; k++; }
866 
867  for(i=n1+1;i<n2;i++)
868  free((*point)[i]);
869 
870  for(i=n2;i<*np;i++)
871  { newPoint[k]=(*point)[i]; k++; }
872 
873  /* Replace the points by the new points */
874  free(*point);
875  *point=newPoint;
876  *np=nnp;
877  }
878  else
879  {
880  if (reached)
881  DeleteSamples(lns,lpath);
882  }
883  }
884 
885  /* Print info for debug only */
886  if (s%10==0)
887  fprintf(stderr,"Shortcut (%u/%u) Path steps: %u Path length %g Time: %g\n",
888  s,n*maxIterations,*np,PathLength(tp,m,*np,*point),GetElapsedTime(stime));
889  }
890 
891  if (nCores>1)
892  {
893  free(step);
894  free(newStep);
895  free(first);
896  free(middle);
897  free(last);
898  free(localLength);
899  free(localPathOK);
900  free(newLocalLength);
901  free(newLocalNS);
902  free(newLocalPath);
903  }
904 
905  DeleteBox(&domain);
906  free(tp);
907 }
908 
909 void GradientSmooth(Tparameters *pr,unsigned int nCores,unsigned int maxIterations,
910  Tstatistics *stime,
911  unsigned int *np,double ***point,TAtlasBase *w)
912 {
913  unsigned int i,k,m,n,it;
914  double delta,e,ce,r;
915  Tbox domain;
916  TJacobian sJ;
917  unsigned int *tp;
918  Tchart *c;
919  double **u;
920  double **newPoint;
921  boolean *stalled;
922 
923  k=(unsigned int)GetParameter(CT_N_DOF,pr);
924  delta=GetParameter(CT_DELTA,pr);
925  e=GetParameter(CT_E,pr);
926  ce=GetParameter(CT_CE,pr);
927  r=GetParameter(CT_R,pr);
928 
929  CS_WD_GENERATE_SIMP_INITIAL_BOX(pr,&domain,w);
930  CS_WD_GET_SIMP_JACOBIAN(pr,&sJ,w);
931  CS_WD_GET_SIMP_TOPOLOGY(pr,&tp,w);
932  CS_WD_INIT_CD(pr,nCores,w);
933 
934  GetJacobianSize(&n,&m,&sJ); /* 'n' not used */
935 
936  /* Apply gradient-based length reduction */
937  /* Allocate memory for the minimization process */
938  NEW(c,*np,Tchart);
939  NEW(newPoint,*np,double*);
940  NEW(u,*np,double*);
941  for(i=0;i<*np;i++)
942  {
943  NEW(u[i],k,double);
944  NEW(newPoint[i],m,double);
945  }
946  NEW(stalled,*np,boolean);
947  for(i=0;i<*np;i++)
948  stalled[i]=FALSE;
949 
950  for(it=0;it<maxIterations;it++)
951  {
952  #pragma omp parallel for private(i) schedule(dynamic) if(nCores>1)
953  for(i=1;i<*np-1;i++)
954  {
955  if (!stalled[i])
956  {
957  /* Define chart */
958  if (InitChart(pr,TRUE,&domain,tp,
959  m,k,(*point)[i],e,ce,r,
960  &sJ,w,&(c[i]))==0)
961  {
962  double cost,newCost;
963 
964  /* set u=-delta*T'*(2*x_i-x_{i-1}-x_{i+1}) */
965  memcpy(newPoint[i],(*point)[i],m*sizeof(double));
966  ScaleVector(2.0,m,newPoint[i]);
967  SubtractVector(m,newPoint[i],(*point)[i-1]);
968  SubtractVector(m,newPoint[i],(*point)[i+1]);
969  TMatrixVectorProduct(m,k,GetChartTangentSpace(&(c[i])),newPoint[i],u[i]);
970  //ScaleVector(-0.1*delta/Norm(k,u[i]),k,u[i]);
971  ScaleVector(-0.1*delta/Norm(k,u[i]),k,u[i]);
972 
973  cost=(DistanceTopology(m,tp,(*point)[i-1],(*point)[i])+
974  DistanceTopology(m,tp,(*point)[i],(*point)[i+1]));
975 
976  /* a loop to ensurue that the step is not too large */
977  do {
978  /* Chart to manifold with 'u' */
979  if (Chart2Manifold(pr,&sJ,u[i],tp,(*point)[i],newPoint[i],&(c[i]))>e)
980  stalled[i]=TRUE;
981  else
982  {
983  /* Test if collision or out of domain */
984  CS_WD_IN_COLLISION(stalled[i],pr,newPoint[i],NULL,w);
985  stalled[i]=((stalled[i])||
986  (!PointInBoxTopology(NULL,FALSE,m,newPoint[i],0.0,tp,&domain)));
987 
988  newCost=(DistanceTopology(m,tp,(*point)[i-1],newPoint[i])+
989  DistanceTopology(m,tp,newPoint[i],(*point)[i+1]));
990  }
991 
992  ScaleVector(0.5,k,u[i]);
993  } while ((!stalled[i])&&(newCost>cost));
994 
995  //fprintf(stderr,"er[%u]: %f\n",i,Distance(m,(*point)[i],newPoint[i]));
996 
997  /* Delete the chart */
998  DeleteChart(&(c[i]));
999  }
1000  else
1001  stalled[i]=TRUE;
1002  }
1003  }
1004 
1005  /* Update the path with the possibly new points */
1006  #pragma omp parallel for private(i)
1007  for(i=1;i<*np-1;i++)
1008  {
1009  if (!stalled[i])
1010  memcpy((*point)[i],newPoint[i],m*sizeof(double));
1011  }
1012 
1013  /* Print 'l' */
1014  fprintf(stderr,"Iteration %u Path length %g Time: %g\n",
1015  it,PathLength(tp,m,*np,*point),GetElapsedTime(stime));
1016  }
1017 
1018  for(i=0;i<*np;i++)
1019  {
1020  free(u[i]);
1021  free(newPoint[i]);
1022  }
1023  free(u);
1024  free(newPoint);
1025  free(c);
1026  free(stalled);
1027 
1028  DeleteBox(&domain);
1029  free(tp);
1030  DeleteJacobian(&sJ);
1031 }
1032 
1033 void SmoothSamples(Tparameters *pr,boolean parallel,int mode,unsigned int maxIterations,
1034  unsigned int ns,double **path,
1035  unsigned int *sns,double ***spath,TAtlasBase *w)
1036 {
1037  unsigned int i,m,np,mp;
1038  double **point;
1039  double *o,l,delta;
1040  unsigned int *tp;
1041  unsigned int sms;
1042  unsigned int nv,nvs;
1043  boolean *systemVars;
1044  Tstatistics stime;
1045  unsigned int nCores;
1046 
1047  if (ns<3)
1048  Error("Too small path in SmoothSamples (only paths with at least 3 samples are considered)");
1049 
1050  if (parallel)
1051  {
1052  #ifdef _OPENMP
1053  nCores=omp_get_max_threads();
1054  if (ns<nCores*3)
1055  nCores=1;
1056  #else
1057  nCores=1;
1058  #endif
1059  }
1060  else
1061  nCores=1;
1062 
1063  delta=GetParameter(CT_DELTA,pr);
1064 
1065  InitStatistics(nCores,0,&stime);
1066 
1067  m=CS_WD_GET_SIMP_TOPOLOGY(pr,&tp,w);
1068 
1069  mp=ns;
1070  np=ns;
1071 
1072  NEW(point,mp,double*);
1073  #pragma omp parallel for private(i) schedule(dynamic)
1074  for(i=0;i<np;i++)
1075  {
1076  double *od;
1077 
1078  /* recover the dummy variables from the system ones
1079  for the point in original system */
1080  CS_WD_REGENERATE_SOLUTION_POINT(pr,path[i],&od,w);
1081  /* Get the point in the simplified form */
1082  CS_WD_GENERATE_SIMPLIFIED_POINT(pr,od,&(point[i]),w);
1083 
1084  free(od);
1085  }
1086  /********************************************/
1087  /* Compute the initial lenght */
1088  l=PathLength(tp,m,np,point);
1089  fprintf(stderr,"Initial lenght : %g\n",l);
1090  fprintf(stderr,"Number of processing cores : %u\n",nCores);
1091 
1092  /* If the path is not densily sampled the Euclidean
1093  distance between samples is too far from the Geodesic
1094  one and then the smoothing is not meaningful */
1095  if ((l/(double)np)>2*delta)
1096  Error("The input path is not dense enough");
1097 
1098  switch(mode)
1099  {
1100  case SMOOTH_RANDOM:
1101  fprintf(stderr,"Smooth method : RANDOM\n");
1102  RandomSmooth(pr,nCores,maxIterations,&stime,&np,&point,w);
1103  break;
1104  case SMOOTH_GRADIENT:
1105  fprintf(stderr,"Smooth method : GRADIENT\n");
1106  GradientSmooth(pr,1,maxIterations,&stime,&np,&point,w);
1107  break;
1108  case SMOOTH_SHORTCUT:
1109  fprintf(stderr,"Smooth method : SHORTCUT\n");
1110  ShortcutSmooth(pr,&stime,&np,&point,w);
1111  break;
1112  default:
1113  Error("Unknown smoothing method in ");
1114  }
1115 
1116  fprintf(stderr,"Final lengtht %g\n",PathLength(tp,m,np,point));
1117 
1118  /********************************************/
1119  /* The minimization is done, now define the new optimized path */
1120  nv=CS_WD_GET_SYSTEM_VARS(&systemVars,w);
1121  nvs=0;
1122  for(i=0;i<nv;i++)
1123  {
1124  if (systemVars[i])
1125  nvs++;
1126  }
1127  sms=np;
1128  NEW(*spath,sms,double*);
1129  *sns=0;
1130  for(i=0;i<np;i++)
1131  {
1132  CS_WD_REGENERATE_ORIGINAL_POINT(pr,point[i],&o,w);
1133  AddSample2Samples(nv,o,nvs,systemVars,&sms,sns,spath);
1134  free(o);
1135  }
1136  free(systemVars);
1137 
1138  /********************************************/
1139  /* Release the data used to represent the path */
1140  for(i=0;i<np;i++)
1141  free(point[i]);
1142  free(point);
1143 
1144  free(tp);
1145 
1146  fprintf(stderr,"Optimization time: %g\n",GetElapsedTime(&stime));
1147  DeleteStatistics(&stime);
1148 }
1149 
1150 void ConcatSamples(unsigned int nvs,
1151  unsigned int ns1,double **path1,
1152  unsigned int ns2,double **path2,
1153  unsigned int *ns,double ***path)
1154 {
1155  unsigned int i;
1156 
1157  *ns=(ns1+ns2);
1158  NEW((*path),*ns,double*);
1159  for(i=0;i<ns1;i++)
1160  {
1161  NEW((*path)[i],nvs,double);
1162  memcpy((*path)[i],path1[i],nvs*sizeof(double));
1163  }
1164  for(i=0;i<ns2;i++)
1165  {
1166  NEW((*path)[ns1+i],nvs,double);
1167  memcpy((*path)[ns1+i],path2[i],nvs*sizeof(double));
1168  }
1169 }
1170 
1171 void ReverseConcatSamples(unsigned int nvs,
1172  unsigned int ns1,double **path1,
1173  unsigned int ns2,double **path2,
1174  unsigned int *ns,double ***path)
1175 {
1176  unsigned int i;
1177  signed int s;
1178 
1179  *ns=(ns1+ns2);
1180 
1181  NEW((*path),*ns,double*);
1182  for(i=0;i<ns1;i++)
1183  {
1184  NEW((*path)[i],nvs,double);
1185  memcpy((*path)[i],path1[i],nvs*sizeof(double));
1186  }
1187  s=ns2-1;
1188  for(i=0;i<ns2;i++)
1189  {
1190  NEW((*path)[ns1+i],nvs,double);
1191  memcpy((*path)[ns1+i],path2[s],nvs*sizeof(double));
1192  s--;
1193  }
1194 }
1195 
1196 void ReverseSamples(unsigned int ns,double **path)
1197 {
1198  if (ns>0)
1199  {
1200  unsigned int s,k;
1201  double *step;
1202 
1203  s=ns-1;
1204  k=0;
1205  while(s>k)
1206  {
1207  step=path[s];
1208  path[s]=path[k];
1209  path[k]=step;
1210  s--;
1211  k++;
1212  }
1213  }
1214 }
1215 
1216 unsigned int ReadOneSample(Tparameters *p,char *fname,unsigned int nvs,double **s)
1217 {
1218  unsigned int i;
1219  Tfilename fsamples;
1220  FILE *f;
1221  unsigned int r;
1222 
1223  NEW(*s,nvs,double);
1224 
1225  r=(unsigned int)(GetParameter(CT_REPRESENTATION,p));
1226  if (r==REP_JOINTS)
1227  CreateFileName(NULL,fname,NULL,JOINTS_EXT,&fsamples);
1228  else
1229  CreateFileName(NULL,fname,NULL,LINKS_EXT,&fsamples);
1230  f=fopen(GetFileFullName(&fsamples),"r");
1231  if (!f)
1232  Error("Could not open sample file");
1233 
1234  fprintf(stderr,"Reading samples from : %s\n",GetFileFullName(&fsamples));
1235  for(i=0;i<nvs;i++)
1236  {
1237  if (fscanf(f,"%lf",&((*s)[i]))!=1)
1238  Error("Sample in file with less values than system variables");
1239  }
1240  fclose(f);
1241 
1242  DeleteFileName(&fsamples);
1243 
1244  return(nvs);
1245 }
1246 
1247 unsigned int ReadTwoSamples(Tparameters *p,char *fname,unsigned int nvs,double **s1,double **s2)
1248 {
1249  unsigned int i;
1250  Tfilename fsamples;
1251  FILE *f;
1252  unsigned int r;
1253 
1254  NEW(*s1,nvs,double);
1255  NEW(*s2,nvs,double);
1256 
1257  r=(unsigned int)(GetParameter(CT_REPRESENTATION,p));
1258  if (r==REP_JOINTS)
1259  CreateFileName(NULL,fname,NULL,JOINTS_EXT,&fsamples);
1260  else
1261  CreateFileName(NULL,fname,NULL,LINKS_EXT,&fsamples);
1262  f=fopen(GetFileFullName(&fsamples),"r");
1263  if (!f)
1264  Error("Could not open sample file");
1265 
1266  fprintf(stderr,"Reading samples from : %s\n",GetFileFullName(&fsamples));
1267  for(i=0;i<nvs;i++)
1268  {
1269  if (fscanf(f,"%lf",&((*s1)[i]))!=1)
1270  Error("Sample in file with less values than system variables");
1271  }
1272  for(i=0;i<nvs;i++)
1273  {
1274  if (fscanf(f,"%lf",&((*s2)[i]))!=1)
1275  Error("Sample in file with less values than system variables");
1276  }
1277  fclose(f);
1278 
1279  DeleteFileName(&fsamples);
1280 
1281  return(nvs);
1282 }
1283 
1284 void SaveSamplesInt(Tfilename *fpath,unsigned int nvs,
1285  unsigned int ns,double **path)
1286 {
1287  Tbox bp;
1288  unsigned int i,j;
1289  FILE *f;
1290 
1291  f=fopen(GetFileFullName(fpath),"w");
1292  if (!f)
1293  Error("Could not open file to store the solution path on mainfold");
1294 
1295  fprintf(stderr,"Writing solution path to : %s\n",GetFileFullName(fpath));
1296 
1297  fprintf(f,"%u\n",ns);
1298  for(i=0;i<ns;i++)
1299  {
1300  for(j=0;j<nvs;j++)
1301  fprintf(f,"%.12f ",path[i][j]);
1302 
1303  fprintf(f,"\n");
1304  }
1305 
1306  /*We will also write the path in the form of boxes (for animation)*/
1307  for(i=0;i<ns;i++)
1308  {
1309  InitBoxFromPoint(nvs,path[i],&bp);
1310  PrintBox(f,&bp);
1311  DeleteBox(&bp);
1312  }
1313 
1314  fclose(f);
1315 }
1316 
1317 
1318 void SaveSamples(char *fname,boolean smooth,unsigned int nvs,
1319  unsigned int ns,double **path)
1320 {
1321  Tfilename fpath;
1322 
1323  if (smooth)
1324  CreateFileName(NULL,fname,"_spath",SOL_EXT,&fpath);
1325  else
1326  CreateFileName(NULL,fname,"_path",SOL_EXT,&fpath);
1327 
1328  SaveSamplesInt(&fpath,nvs,ns,path);
1329 
1330  DeleteFileName(&fpath);
1331 }
1332 
1333 void SaveSamplesN(char *fname,boolean smooth,unsigned int n,unsigned int nvs,
1334  unsigned int ns,double **path)
1335 {
1336  Tfilename fpath;
1337  char s[100];
1338 
1339  if (smooth)
1340  sprintf(s,"_spath_%u",n);
1341  else
1342  sprintf(s,"_path_%u",n);
1343 
1344  CreateFileName(NULL,fname,s,SOL_EXT,&fpath);
1345 
1346  SaveSamplesInt(&fpath,nvs,ns,path);
1347 
1348  DeleteFileName(&fpath);
1349 }
1350 
1351 
1352 boolean LoadSamples(Tfilename fname, unsigned int *nvs,
1353  unsigned int *ns,double ***path)
1354 {
1355  FILE *f;
1356  Tlist lb;
1357  Tbox *b;
1358  Titerator i;
1359  unsigned int k;
1360 
1361  f=fopen(GetFileFullName(&fname),"r");
1362  if (f)
1363  {
1364  /*Load the path from a _path.sol file */
1365  fprintf(stderr,"Loading solution path from : %s\n",GetFileFullName(&fname));
1366 
1367  /* We take advantage that the sample list is stored as a box list to read it */
1368  ReadListOfBoxes(GetFileFullName(&fname),&lb);
1369 
1370  *ns=ListSize(&lb);
1371  NEW(*path,*ns,double *);
1372  InitIterator(&i,&lb);
1373  First(&i);
1374  k=0;
1375  while(!EndOfList(&i))
1376  {
1377  b=(Tbox *)GetCurrent(&i);
1378  if (k==0)
1379  *nvs=GetBoxNIntervals(b);
1380  else
1381  {
1382  if (*nvs!=GetBoxNIntervals(b))
1383  Error("Incongruent size of step in path");
1384  }
1385  NEW((*path)[k],*nvs,double);
1386  GetBoxCenter(NULL,(*path)[k],b);
1387  Advance(&i);
1388  k++;
1389  }
1390  fclose(f);
1391  DeleteListOfBoxes(&lb);
1392 
1393  return(TRUE);
1394  }
1395  else
1396  return(FALSE);
1397 }
1398 
1400  unsigned int xID,unsigned int yID,unsigned int zID,
1401  unsigned int ns,double **path)
1402 {
1403  unsigned int i;
1404  double *x,*y,*z;
1405  Tcolor pathColor;
1406  double cx,cy,cz;
1407  #if (RRT_PATH_NODES)
1408  double xc[2],yc[2],zc[2];
1409  Tcolor blue;
1410  #endif
1411 
1412  cx=GetParameter(CT_CUT_X,p);
1413  cy=GetParameter(CT_CUT_Y,p);
1414  cz=GetParameter(CT_CUT_Z,p);
1415 
1416  NEW(x,ns,double);
1417  NEW(y,ns,double);
1418  NEW(z,ns,double);
1419 
1420  for(i=0;i<ns;i++)
1421  {
1422  /* For the paths we only store system variables */
1423  x[i]=path[i][xID];
1424  y[i]=path[i][yID];
1425  z[i]=path[i][zID];
1426 
1427  if ((cx<0)&&(x[i]<cx))
1428  x[i]+=M_2PI;
1429  if ((cx>0)&&(x[i]>cx))
1430  x[i]-=M_2PI;
1431  if ((cy<0)&&(y[i]<cy))
1432  y[i]+=M_2PI;
1433  if ((cy>0)&&(y[i]>cy))
1434  y[i]-=M_2PI;
1435  if ((cz<0)&&(z[i]<cz))
1436  z[i]+=M_2PI;
1437  if ((cz>0)&&(z[i]>cz))
1438  z[i]-=M_2PI;
1439  }
1440 
1441  NewColor(0,1,0,&pathColor); /* green */
1442  StartNew3dObject(&pathColor,p3d);
1443  PlotVect3d(ns,x,y,z,p3d);
1444  Close3dObject(p3d);
1445  DeleteColor(&pathColor);
1446 
1447  #if (RRT_PATH_NODES)
1448  if (ns>2)
1449  {
1450  NewColor(0,0,1,&blue);
1451  StartNew3dObject(&blue,p3d);
1452  for(i=0;i<ns;i++)
1453  {
1454  xc[0]=x[i]-0.01;
1455  yc[0]=y[i];
1456  zc[0]=z[i];
1457 
1458  xc[1]=x[i]+0.01;
1459  yc[1]=y[i];
1460  zc[1]=z[i];
1461 
1462  PlotVect3d(2,xc,yc,zc,p3d);
1463 
1464  xc[0]=x[i];
1465  yc[0]=y[i]-0.01;
1466  zc[0]=z[i];
1467 
1468  xc[1]=x[i];
1469  yc[1]=y[i]+0.01;
1470  zc[1]=z[i];
1471 
1472  PlotVect3d(2,xc,yc,zc,p3d);
1473 
1474  xc[0]=x[i];
1475  yc[0]=y[i];
1476  zc[0]=z[i]-0.01;
1477 
1478  xc[1]=x[i];
1479  yc[1]=y[i];
1480  zc[1]=z[i]+0.01;
1481 
1482  PlotVect3d(2,xc,yc,zc,p3d);
1483  }
1484 
1485  DeleteColor(&blue);
1486  Close3dObject(p3d);
1487  }
1488  #endif
1489 
1490  free(x);
1491  free(y);
1492  free(z);
1493 }
1494 
1495 void DeleteSamples(unsigned int ns,double **path)
1496 {
1497  unsigned int i;
1498 
1499  for(i=0;i<ns;i++)
1500  free(path[i]);
1501  free(path);
1502 }
#define CT_R
Ball radius in atlas.
Definition: parameters.h:257
void ShortcutSmooth(Tparameters *pr, Tstatistics *stime, unsigned int *np, double ***point, TAtlasBase *w)
Fixed-cut based smoothing.
Definition: samples.c:590
void First(Titerator *i)
Moves an iterator to the first position of its associated list.
Definition: list.c:356
void PlotVect3d(unsigned int n, double *x, double *y, double *z, Tplot3d *p)
Adds a polyline to the current object.
Definition: plot3d.c:447
CBLAS_INLINE void ScaleVector(double f, unsigned int s, double *v)
Scales a vector.
Definition: basic_algebra.c:30
#define REP_JOINTS
One of the possible values of the REPRESENTATION parameter.
Definition: parameters.h:60
#define CT_EPSILON
Numerical tolerance.
Definition: parameters.h:194
#define FALSE
FALSE.
Definition: boolean.h:30
#define CS_WD_GENERATE_SIMPLIFIED_POINT(pr, p, r, wcs)
Generates a simplified point from an original one.
Definition: wcs.h:432
unsigned int ReadTwoSamples(Tparameters *p, char *fname, unsigned int nvs, double **s1, double **s2)
Reads two samples from a file.
Definition: samples.c:1247
double DistanceTopology(unsigned int s, unsigned int *tp, double *v1, double *v2)
Computes the distance of two points.
#define NEW(_var, _n, _type)
Allocates memory space.
Definition: defines.h:385
double ConnectSamplesChart(Tparameters *pr, unsigned int *tp, Tbox *domain, unsigned int m, unsigned int n, double *s1, double *s2, double md, boolean checkCollisions, boolean *reached, boolean *collision, double *lastSample, unsigned int *ns, double ***path, TAtlasBase *w)
Determines the connection between two points on the manifold.
Definition: samples.c:172
Data structure to hold the information about the name of a file.
Definition: filename.h:248
void ArrayPi2Pi(unsigned int n, unsigned int *t, double *a)
Applies PI2PI to an array.
#define SMOOTH_GRADIENT
One of the possible smoothing methods.
Definition: samples.h:57
unsigned int randomMax(unsigned int m)
Returns a random integer in the range [0,m].
Definition: random.c:77
void PlotSamples(Tparameters *p, Tplot3d *p3d, unsigned int xID, unsigned int yID, unsigned int zID, unsigned int ns, double **path)
Plots a 3D projection of a path.
Definition: samples.c:1399
void InitStatistics(unsigned int np, double v, Tstatistics *t)
Constructor.
Definition: statistics.c:21
CBLAS_INLINE double Norm(unsigned int s, double *v)
Computes the norm of a vector.
void DeleteJacobian(TJacobian *j)
Destructor.
Definition: jacobian.c:249
void DifferenceVectorTopology(unsigned int s, unsigned int *tp, double *v1, double *v2, double *v)
Substracts two vectors.
CBLAS_INLINE void AccumulateVector(unsigned int s, double *v1, double *v2)
Adds a vector to another vectors.
Definition: basic_algebra.c:55
void ReverseConcatSamples(unsigned int nvs, unsigned int ns1, double **path1, unsigned int ns2, double **path2, unsigned int *ns, double ***path)
Reverses and concats a path.
Definition: samples.c:1171
#define INIT_NUM_SAMPLES
Initial number of samples (or steps) in a path.
Definition: samples.h:28
Definition of the Tfilename type and the associated functions.
int cmpUInt(const void *a, const void *b)
Compares two unsigned in integers.
Definition: samples.c:574
#define TRUE
TRUE.
Definition: boolean.h:21
void GradientSmooth(Tparameters *pr, unsigned int nCores, unsigned int maxIterations, Tstatistics *stime, unsigned int *np, double ***point, TAtlasBase *w)
Gradient-based path smoothing.
Definition: samples.c:909
double Chart2Manifold(Tparameters *pr, TJacobian *sJ, double *t, unsigned int *tp, double *pInit, double *p, Tchart *c)
Returns the point in the manifold for a given set of parameteres.
Definition: chart.c:1066
void Error(const char *s)
General error function.
Definition: error.c:80
double PathLength(unsigned int *tp, unsigned int m, unsigned int np, double **point)
Length of a path formed by a set of samples.
Definition: samples.c:561
A color.
Definition: color.h:23
void GetJacobianSize(unsigned int *nr, unsigned int *nc, TJacobian *j)
Returns the size of the Jacobian.
Definition: jacobian.c:43
boolean ReadListOfBoxes(char *filename, Tlist *l)
Reads a list of boxes from a file.
Definition: box_list.c:286
A chart on a manifold.
Definition: chart.h:70
void RandomSmooth(Tparameters *pr, unsigned int nCores, unsigned int maxIterations, Tstatistics *stime, unsigned int *np, double ***point, TAtlasBase *w)
Random-based path smoothing.
Definition: samples.c:688
unsigned int GetBoxNIntervals(Tbox *b)
Box dimensionality.
Definition: box.c:992
void DeleteFileName(Tfilename *fn)
Destructor.
Definition: filename.c:205
boolean LoadSamples(Tfilename fname, unsigned int *nvs, unsigned int *ns, double ***path)
Reads a set of samples from file.
Definition: samples.c:1352
A 3D plot.
Definition: plot3d.h:54
#define CT_CUT_X
Limit of domain of the X dimension of 3d plots.
Definition: parameters.h:420
void DeleteListOfBoxes(Tlist *l)
Destructor.
Definition: box_list.c:353
unsigned int InitChart(Tparameters *pr, boolean simple, Tbox *domain, unsigned int *tp, unsigned int m, unsigned int k, double *p, double e, double eCurv, double r, TJacobian *sJ, TAtlasBase *w, Tchart *c)
Constructor.
Definition: chart.c:792
boolean EndOfList(Titerator *i)
Checks if an iterator is pointing at the end of the list.
Definition: list.c:445
#define CT_CUT_Z
Limit of domain of the Z dimension of 3d plots.
Definition: parameters.h:444
#define CS_WD_SIMP_INEQUALITIES_HOLD(pr, p, wcs)
Cheks if all inequalities hold.
Definition: wcs.h:207
A generic list.
Definition: list.h:46
void InitIterator(Titerator *i, Tlist *list)
Constructor.
Definition: list.c:284
void DifferenceVector(unsigned int s, double *v1, double *v2, double *v)
Substracts two vectors.
Definition of the Tlist type and the associated functions.
void SaveSamples(char *fname, boolean smooth, unsigned int nvs, unsigned int ns, double **path)
Saves a set of samples to a file.
Definition: samples.c:1318
#define CS_WD_NEWTON_IN_SIMP(pr, p, wcs)
Applies a Newton procedure to move a point towads the manifold.
Definition: wcs.h:488
#define SMOOTH_SHORTCUT
One of the possible smoothing methods.
Definition: samples.h:67
Statistics associated with a solving process.
Definition: statistics.h:28
double * GetChartTangentSpace(Tchart *c)
Gets the chart tangent space.
Definition: chart.c:970
A table of parameters.
void CreateFileName(char *path, char *name, char *suffix, char *ext, Tfilename *fn)
Constructor.
Definition: filename.c:22
#define CS_WD_GET_SIMP_JACOBIAN(pr, J, wcs)
Computes the Jacobian of the simplified system.
Definition: wcs.h:474
void ConcatSamples(unsigned int nvs, unsigned int ns1, double **path1, unsigned int ns2, double **path2, unsigned int *ns, double ***path)
Concats two path.
Definition: samples.c:1150
void DeleteChart(Tchart *c)
Destructor.
Definition: chart.c:2011
Type defining the equations on which the atlas is defined.
Definition: wcs.h:30
#define CS_WD_GET_SYSTEM_VARS(sv, wcs)
Gets the system variables.
Definition: wcs.h:238
char * GetFileFullName(Tfilename *fn)
Gets the file full name (paht+name+extension).
Definition: filename.c:151
#define M_2PI
2*Pi.
Definition: defines.h:100
#define SOL_EXT
File extension for solution files.
Definition: filename.h:137
#define CT_REPRESENTATION
Representation.
Definition: parameters.h:215
CBLAS_INLINE void TMatrixVectorProduct(unsigned int r, unsigned int c, double *A, double *b, double *o)
Product of a transposed matrix and a vector.
void SmoothSamples(Tparameters *pr, boolean parallel, int mode, unsigned int maxIterations, unsigned int ns, double **path, unsigned int *sns, double ***spath, TAtlasBase *w)
Path smoothing.
Definition: samples.c:1033
#define CS_WD_REGENERATE_ORIGINAL_POINT(pr, p, o, wcs)
Completes an original point from a simplified one.
Definition: wcs.h:279
double ConnectSamples(Tparameters *pr, unsigned int *tp, Tbox *domain, unsigned int m, unsigned int n, double *s1, double *s2, double md, boolean checkCollisions, boolean *reached, boolean *collision, double *lastSample, unsigned int *ns, double ***path, TAtlasBase *w)
Determines the connection between two points on the manifold.
Definition: samples.c:434
A box.
Definition: box.h:83
#define SMOOTH_RANDOM
One of the possible smoothing methods.
Definition: samples.h:47
#define JOINTS_EXT
File extension for files with samples represented by the joint values.
Definition: filename.h:187
#define MEM_DUP(_var, _n, _type)
Duplicates a previously allocated memory space.
Definition: defines.h:414
void * GetCurrent(Titerator *i)
Gets the element pointed by the iterator.
Definition: list.c:299
CBLAS_INLINE void SumVectorScale(unsigned int s, double *v1, double w, double *v2, double *v)
Adds two vectors with a scale.
Definition: basic_algebra.c:86
void InitBoxFromPoint(unsigned int dim, double *p, Tbox *b)
Initializes a box from a point.
Definition: box.c:43
CBLAS_INLINE void SubtractVector(unsigned int s, double *v1, double *v2)
Substracts a vector from another vector.
void DeleteSamples(unsigned int ns, double **path)
Deletes the space used by a set of samples.
Definition: samples.c:1495
unsigned int ReadOneSample(Tparameters *p, char *fname, unsigned int nvs, double **s)
Reads one sample from a file.
Definition: samples.c:1216
void DeleteBox(void *b)
Destructor.
Definition: box.c:1259
The Jacobian of a set of equations.
Definition: jacobian.h:23
#define CT_E
Chart error in atlas.
Definition: parameters.h:243
#define DEFAULT_CONNECT
Macro to easily switch the connection method.
Definition: samples.h:79
void SaveSamplesInt(Tfilename *fpath, unsigned int nvs, unsigned int ns, double **path)
Internal function to save a set of samples to a file.
Definition: samples.c:1284
double Manifold2Chart(double *p, unsigned int *tp, double *t, Tchart *c)
Returns the parametrization of a point.
Definition: chart.c:1036
double GetParameter(unsigned int n, Tparameters *p)
Gets the value for a particular parameter.
Definition: parameters.c:93
#define CS_WD_REGENERATE_SOLUTION_POINT(pr, p, r, wcs)
Compleates a solution point with the dummy variables.
Definition: wcs.h:417
#define CT_CUT_Y
Limit of domain of the Y dimension of 3d plots.
Definition: parameters.h:432
void DeleteColor(Tcolor *c)
Destructor.
Definition: color.c:93
#define CS_WD_IN_COLLISION(f, pr, s, sPrev, wcs)
Checks if a configuration is in collision.
Definition: wcs.h:319
List iterator.
Definition: list.h:61
#define CT_DELTA
Size of the steps in the path connecting two configurations.
Definition: parameters.h:282
#define CT_N_DOF
Dimensionality of the solution space for the mechanism at hand.
Definition: parameters.h:318
void GetBoxCenter(boolean *used, double *c, Tbox *b)
Returns the box center along the selected dimensions.
Definition: box.c:697
Auxiliary functions to deal with sets of samples.
void InitSamples(unsigned int *ms, unsigned int *ns, double ***path)
Initializes a set of samples.
Definition: samples.c:143
Definition of basic randomization functions.
#define CS_WD_INIT_CD(pr, mt, wcs)
Initializes the collision detector.
Definition: wcs.h:294
double GetElapsedTime(Tstatistics *t)
Elapsed time.
Definition: statistics.c:92
void PrintBox(FILE *f, Tbox *b)
Prints a box.
Definition: box.c:1118
void NewColor(double r, double g, double b, Tcolor *c)
Constructor.
Definition: color.c:14
unsigned int ListSize(Tlist *list)
Gets the number of elements in the list.
Definition: list.c:180
#define CS_WD_GENERATE_SIMP_INITIAL_BOX(pr, b, wcs)
Computes the global box for the simplified system.
Definition: wcs.h:460
Definition of the Tparameters type and the associated functions.
unsigned int StartNew3dObject(Tcolor *c, Tplot3d *p)
Start a composed object.
Definition: plot3d.c:157
void DeleteStatistics(Tstatistics *t)
Destructor.
Definition: statistics.c:274
void AddSample2Samples(unsigned int nv, double *sample, unsigned int nvs, boolean *systemVars, unsigned int *ms, unsigned int *ns, double ***path)
Adds a sample to a set of samples.
Definition: samples.c:150
#define DIVERGED
One of the possible outputs of the Newton iteration.
Definition: cuiksystem.h:111
#define LINKS_EXT
File extension for files with samples represented by the link poses.
Definition: filename.h:180
#define CT_CE
Chart error in atlas.
Definition: parameters.h:250
boolean Advance(Titerator *i)
Moves an iterator to the next position of its associated list.
Definition: list.c:373
#define CS_WD_GET_SIMP_TOPOLOGY(pr, tp, wcs)
Gets the simplified variable topology.
Definition: wcs.h:401
void Close3dObject(Tplot3d *p)
Closes a composed object.
Definition: plot3d.c:171
void SaveSamplesN(char *fname, boolean smooth, unsigned int n, unsigned int nvs, unsigned int ns, double **path)
Saves a set of samples to a file.
Definition: samples.c:1333
boolean PointInBoxTopology(boolean *used, boolean update, unsigned int n, double *v, double tol, unsigned int *tp, Tbox *b)
Checks if a point is included in a(sub-) box.
Definition: box.c:350
void ReverseSamples(unsigned int ns, double **path)
Reverses a set of samples.
Definition: samples.c:1196