mequation.c
Go to the documentation of this file.
1 #include "mequation.h"
2 
3 #include "error.h"
4 #include "basic_algebra.h"
5 
6 #include <string.h>
7 #include <math.h>
8 
9 
29 
31 {
32 #if (0)
33  unsigned int nRot,nTrans;
34 
35  me->neq=0;
36  nRot=1;
37  nTrans=1;
38 #else
39  unsigned int i,nRot,nTrans;
40  boolean ctAllTrans;
41  unsigned int dof[6]={0,0,0,0,0,0};
42 
43  for(i=0;i<me->n;i++)
44  UpdateUsedDOF(dof,me->ts[i]);
45 
46  nRot=(dof[RX]+dof[RY]+dof[RZ]);
47  nTrans=(dof[TX]+dof[TY]+dof[TZ]);
48 
49  /* Check if all ct transforms are translations */
50  ctAllTrans=TRUE;
51  for(i=0;((ctAllTrans)&&(i<me->n));i++)
52  ctAllTrans=(!HasCtRotTransSeq(me->ts[i]));
53 
54  me->neq=0;
55  if ((ctAllTrans)&&(nRot>0)&&(nTrans==0))
56  {
57  /* Check if all rotations are aligned -> plannar mechanism */
58  if (dof[RX]==nRot)
59  {
60  me->r[me->neq]=AXIS_Y;me->c[me->neq]=AXIS_Z;me->neq++;
61  me->r[me->neq]=AXIS_Y;me->c[me->neq]=AXIS_H;me->neq++;
62  me->r[me->neq]=AXIS_Z;me->c[me->neq]=AXIS_H;me->neq++;
63  me->r[me->neq]=AXIS_Y;me->c[me->neq]=AXIS_Y;me->neq++;
64  }
65  if (dof[RY]==nRot)
66  {
67  me->r[me->neq]=AXIS_X;me->c[me->neq]=AXIS_Z;me->neq++;
68  me->r[me->neq]=AXIS_X;me->c[me->neq]=AXIS_H;me->neq++;
69  me->r[me->neq]=AXIS_Z;me->c[me->neq]=AXIS_H;me->neq++;
70  me->r[me->neq]=AXIS_X;me->c[me->neq]=AXIS_X;me->neq++;
71  }
72  if (dof[RZ]==nRot)
73  {
74  me->r[me->neq]=AXIS_X;me->c[me->neq]=AXIS_Y;me->neq++;
75  me->r[me->neq]=AXIS_X;me->c[me->neq]=AXIS_H;me->neq++;
76  me->r[me->neq]=AXIS_Y;me->c[me->neq]=AXIS_H;me->neq++;
77  me->r[me->neq]=AXIS_X;me->c[me->neq]=AXIS_X;me->neq++;
78  }
79  }
80 #endif
81 
82  /* If none of the special cases -> general case */
83  /* Ct equations also define equations (ct equations) */
84  if (me->neq==0)
85  {
86  me->r[0]=AXIS_X; me->c[0]=AXIS_Y;
87  me->r[1]=AXIS_X; me->c[1]=AXIS_Z;
88  me->r[2]=AXIS_Y; me->c[2]=AXIS_Z;
89  me->r[3]=AXIS_X; me->c[3]=AXIS_H;
90  me->r[4]=AXIS_Y; me->c[4]=AXIS_H;
91  me->r[5]=AXIS_Z; me->c[5]=AXIS_H;
92  me->r[6]=AXIS_X; me->c[6]=AXIS_X;
93  me->r[7]=AXIS_Y; me->c[7]=AXIS_Y;
94  me->r[8]=AXIS_Z; me->c[8]=AXIS_Z;
95  me->neq=9;
96  }
97 }
98 
100 {
101  me->n=1;
102  me->simp=FALSE;
103  NEW(me->ts,me->n,TTransSeq*);
104  NEW(me->ts[0],1,TTransSeq);
105  InitTransSeq(me->ts[0]);
106  HTransformIdentity(&(me->rhs));
107  AddCtTrans2TransSeq(&(me->rhs),me->ts[0]);
108 
109  me->neq=0;
111 }
112 
113 void CopyMEquation(TMequation *me_dst,TMequation *me_src)
114 {
115  unsigned int i;
116 
117  me_dst->n=me_src->n;
118  me_dst->simp=me_src->simp;
119  NEW(me_dst->ts,me_dst->n,TTransSeq*);
120  for(i=0;i<me_dst->n;i++)
121  {
122  NEW(me_dst->ts[i],1,TTransSeq);
123  CopyTransSeq(me_dst->ts[i],me_src->ts[i]);
124  }
125  HTransformCopy(&(me_dst->rhs),&(me_src->rhs));
126  me_dst->neq=me_src->neq;
127  for(i=0;i<me_dst->neq;i++)
128  {
129  me_dst->r[i]=me_src->r[i];
130  me_dst->c[i]=me_src->c[i];
131  }
132 }
133 
135 {
136  if (me->n>1)
137  Error("Reseting a non-basic matrix equation.");
138 
139  ResetTransSeq(me->ts[0]);
140  HTransformIdentity(&(me->rhs));
141  me->neq=0;
142  me->simp=FALSE;
143 }
144 
146 {
147  return(me->neq==0);
148 }
149 
150 unsigned int MEquationSize(TMequation *me)
151 {
152  unsigned int i,s,l;
153 
154  s=0;
155  for(i=0;i<me->n;i++)
156  {
157  l=TransSeqSize(me->ts[i]);
158  if (l>s) s=l;
159  }
160  return(s);
161 }
162 
164 {
165  unsigned int dof[6]={0,0,0,0,0,0};
166  unsigned int i;
167 
168  for(i=0;i<me->n;i++)
169  UpdateUsedDOF(dof,me->ts[i]);
170 
171  return((dof[RX]+dof[RY]+dof[RZ])>0);
172 }
173 
175 {
176  unsigned int i;
177 
178  if (me->neq==0)
179  Error("Modifying an empty matrix equation");
180 
181  me->simp=TRUE;
182 
183  me->neq=3;
184  for(i=0;i<3;i++)
185  {
186  me->r[i]=i;
187  me->c[i]=AXIS_H;
188  }
189 }
190 
191 boolean VarIncludedinMEquation(unsigned int v,TMequation *me)
192 {
193  unsigned int i;
194  boolean found;
195 
196  found=FALSE;
197  i=0;
198  while((!found)&&(i<me->n))
199  {
200  found=VarIncludedinTransSeq(v,me->ts[i]);
201  i++;
202  }
203  return(found);
204 }
205 
206 void AddDispTrans2MEquation(int s,unsigned int v,
207  double *vect,TMequation *me)
208 {
209  AddDispTrans2TransSeq(s,v,vect,me->ts[0]);
210 }
211 
212 void AddVarTrans2MEquation(unsigned int t,int s,unsigned int v,TMequation *me)
213 {
214  if (me->n>1)
215  Error("Adding terms to a non-basic matrix equation.");
216  if (me->simp)
217  Error("Adding terms an already simplified matrix equation.");
218 
219  AddVarTrans2TransSeq(t,s,v,me->ts[0]);
220 
222 }
223 
224 void AddPatchTrans2MEquation(unsigned int t,int s,unsigned int u,unsigned int v,
225  double **p,TMequation *me)
226 {
227  if (me->n>1)
228  Error("Adding terms to a non-basic matrix equation.");
229  if (me->simp)
230  Error("Adding terms an already simplified matrix equation.");
231 
232  AddPatchTrans2TransSeq(t,s,u,v,p,me->ts[0]);
233 
235 }
236 
237 
239 {
240  if (me->n>1)
241  Error("Adding terms to a non-basic matrix equation.");
242  if (me->simp)
243  Error("Adding terms an already simplified matrix equation.");
244 
245  AddCtTrans2TransSeq(t,me->ts[0]);
246 
248 }
249 
251 {
252  int i;
253  unsigned int n;
254  TTrans taux;
255 
256  if (me->n>1)
257  Error("Adding terms to a non-basic matrix equation.");
258 
259  if (me->simp)
260  Error("Adding terms an already simplified matrix equation.");
261 
262  n=TransSeqSize(ts);
263  if (n>0)
264  {
265  if (s<0)
266  {
267  for(i=n-1;i>=0;i--)
268  {
269  TransInvert(&taux,GetElementFromTransSeq(i,ts));
270  AddTrans2TransSeq(&taux,me->ts[0]);
271  DeleteTrans(&taux);
272  }
273  }
274  else
275  {
276  for(i=0;i<n;i++)
278  }
280  }
281 }
282 
284 {
285  return(me->neq);
286 }
287 
288 void ShiftVariablesInMEquation(unsigned int nv,TMequation *me)
289 {
290  unsigned int i;
291 
292  for(i=0;i<me->n;i++)
293  ShiftVariablesInTransSeq(nv,me->ts[i]);
294 }
295 
296 unsigned int FixVarInMEquation(unsigned int nv,double v,TMequation *me)
297 {
298  unsigned int i;
299  TTransSeq **tsOrig;
300  unsigned int nOrig;
301  unsigned int r;
302  THTransform ctt;
303 
304  tsOrig=me->ts;
305  nOrig=me->n;
306 
307  NEW(me->ts,me->n,TTransSeq *);
308  me->n=0;
309 
310  for(i=0;i<nOrig;i++)
311  {
312  if (FixVarInTransSeq(nv,v,&ctt,tsOrig[i]))
313  {
314  /* tsOrig[i] is now constant */
315  HTransformSubstract(&(me->rhs),&ctt,&(me->rhs));
316  DeleteTransSeq(tsOrig[i]);
317  }
318  else
319  {
320  /* non-ct tsOrig[i] -> just add it to tne new equation */
321  me->ts[me->n]=tsOrig[i];
322  me->n++;
323  }
324  HTransformDelete(&ctt);
325  }
326  free(tsOrig);
327 
328  if (me->n==0)
329  {
330  /* The hole matrix equation is ct */
331  if (HTransformIsZero(&(me->rhs)))
332  r=1; /* ct and holds */
333  else
334  r=2; /* ct and does not hold */
335  }
336  else
337  r=0; /* normal case */
338 
339  me->simp=FALSE;
340  SimplifyMEquation(me);
341 
342  return(r);
343 }
344 
345 void ReplaceVarInMEquation(unsigned int nv,unsigned int nvNew,TMequation *me)
346 {
347  unsigned int i;
348 
349  for(i=0;i<me->n;i++)
350  ReplaceVarInTransSeq(nv,nvNew,me->ts[i]);
351 }
352 
354 {
355  return(me->simp);
356 }
357 
359 {
360  if (me->simp)
361  Error("Re-simplifying a matrix equation?");
362 
363  me->simp=TRUE;
364 
365  if ((me->neq>0)&&(me->n==1))
366  SimplifyTransSeq(me->ts[0]);
367 
369 }
370 
371 void DeriveMEquation(unsigned int v,TMequation *dme,TMequation *me)
372 {
373  if (!me->simp)
374  Error("Deriving a non simplified equation");
375 
376  if (me->neq==0)
377  //InitMEquation(dme);
378  Error("Deriving an empty equation?");
379  else
380  {
381  unsigned int i,k,n;
382  TTransSeq **ts;
383 
384  dme->n=0;
385  dme->simp=TRUE; /* == me->simp */
386  for(i=0;i<me->n;i++)
387  {
388  DeriveTransSeq(v,&n,&ts,me->ts[i]);
389  if (n>0)
390  {
391  k=dme->n+n;
392  if (dme->n==0)
393  { NEW(dme->ts,k,TTransSeq*); }
394  else
395  { MEM_EXPAND(dme->ts,k,TTransSeq*); }
396  memcpy(&(dme->ts[dme->n]),ts,sizeof(TTransSeq*)*n);
397  free(ts);
398  dme->n=k;
399  }
400  }
401  if (dme->n==0)
402  dme->ts=NULL;
403 
404  HTransformZero(&(dme->rhs));
405 
406  dme->neq=me->neq;
407  for(i=0;i<me->neq;i++)
408  {
409  dme->r[i]=me->r[i];
410  dme->c[i]=me->c[i];
411  }
412  }
413 }
414 
415 unsigned int EvaluateMEquation(double *v,double *r,TMequation *me)
416 {
417  if (me->neq>0)
418  {
419  unsigned int i,j;
420  THTransform a;
421 
422  for(j=0;j<me->neq;j++)
423  r[j]=-HTransformGetElement(me->r[j],me->c[j],&(me->rhs));
424 
425  for(i=0;i<me->n;i++)
426  {
427  EvaluateTransSeq(v,&a,me->ts[i]);
428  for(j=0;j<me->neq;j++)
429  r[j]+=HTransformGetElement(me->r[j],me->c[j],&a);
430 
431  HTransformDelete(&a);
432  }
433  }
434  return(me->neq);
435 }
436 
437 void EvaluateMEquationXVectors(double *v,unsigned int n,double *p,
438  double *r,TMequation *me)
439 {
440  if (me->neq>0)
441  {
442  unsigned int i,k;
443  THTransform a;
444  double p1[3];
445 
446  /* The rhs is not used since this function is only used
447  for derivatives (rhs=0)*/
448 
449  /* Initialize the result to zero */
450  for(i=0;i<n;i++)
451  {
452  for(k=0;k<3;k++)
453  r[3*i+k]=0;
454  }
455 
456  /* Sum for all the terms in the matrix equation */
457  for(i=0;i<me->n;i++)
458  {
459  EvaluateTransSeq(v,&a,me->ts[i]);
460 
461  /* Now apply the matrix to all vectors */
462  for(k=0;k<n;k++)
463  {
464  HTransformApply(&(p[3*k]),p1,&a);
465  AccumulateVector(3,p1,&(r[3*k]));
466  }
467 
468  HTransformDelete(&a);
469  }
470  }
471 }
472 
473 void PrintMEquation(FILE *f,char **varNames,TMequation *me)
474 {
475  unsigned int i;
476 
477  fprintf(f," ");
478  for(i=0;i<me->n;i++)
479  {
480  PrintTransSeq(f,varNames,me->ts[i]);
481  if (i<(me->n-1))
482  fprintf(f,"+");
483  }
484  fprintf(f,"=");
485  if (HTransformIsIdentity(&(me->rhs)))
486  fprintf(f,"Id;\n");
487  else
488  fprintf(f,"Z;\n");
489 }
490 
491 
493 {
494  unsigned int i;
495 
496  if (me->ts!=NULL)
497  {
498  for(i=0;i<me->n;i++)
499  {
500  DeleteTransSeq(me->ts[i]);
501  free(me->ts[i]);
502  }
503  free(me->ts);
504  }
505  HTransformDelete(&(me->rhs));
506 }
#define AXIS_X
One of the dimension of R^3.
Definition: htransform.h:83
unsigned int EvaluateMEquation(double *v, double *r, TMequation *me)
Evaluates a matrix equation.
Definition: mequation.c:415
#define FALSE
FALSE.
Definition: boolean.h:30
void CopyTransSeq(TTransSeq *ts_dst, TTransSeq *ts_src)
Constructor.
Definition: trans_seq.c:457
boolean FixVarInTransSeq(unsigned int nv, double v, THTransform *ctt, TTransSeq *ts)
Set a variable to a constant value.
Definition: trans_seq.c:723
void HTransformApply(double *p_in, double *p_out, THTransform *t)
Multiply a homogeneous transform and a vector.
Definition: htransform.c:782
#define NEW(_var, _n, _type)
Allocates memory space.
Definition: defines.h:385
void SetTranslationMEquation(TMequation *me)
Sets a matrix equation as a translation equation.
Definition: mequation.c:174
unsigned int MEquationSize(TMequation *me)
Size of the matrix equation.
Definition: mequation.c:150
boolean SimplifiedMEquation(TMequation *me)
Identifies simplified equations.
Definition: mequation.c:353
void AddPatchTrans2TransSeq(unsigned int t, int s, unsigned int u, unsigned int v, double **p, TTransSeq *ts)
Adds a Parametrized-Patch transform to a transform sequence.
Definition: trans_seq.c:615
void UpdateUsedDOF(unsigned int *dof, TTransSeq *ts)
Determines the dof used in a transform sequence.
Definition: trans_seq.c:645
A homgeneous transform in R^3.
void ShiftVariablesInTransSeq(unsigned int nv, TTransSeq *ts)
Adjust variable indices after removing a variable.
Definition: trans_seq.c:705
#define AXIS_Y
One of the dimension of R^3.
Definition: htransform.h:91
void PrintMEquation(FILE *f, char **varNames, TMequation *me)
Prints a Transform sequence to a file.
Definition: mequation.c:473
#define RZ
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:75
void HTransformZero(THTransform *t)
Constructor.
Definition: htransform.c:75
void ReplaceVarInTransSeq(unsigned int nv, unsigned int nvNew, TTransSeq *ts)
Replaces a variable.
Definition: trans_seq.c:831
CBLAS_INLINE void AccumulateVector(unsigned int s, double *v1, double *v2)
Adds a vector to another vectors.
Definition: basic_algebra.c:55
CBLAS_INLINE void HTransformSubstract(THTransform *t1, THTransform *t2, THTransform *t3)
Substraction of two homogeneous transforms.
Definition: htransform.c:472
void RecomputeScalarEquations(TMequation *me)
Recomputes the scalar equations derived from a metrix one.
Definition: mequation.c:30
void EvaluateTransSeq(double *v, THTransform *r, TTransSeq *ts)
Evaluates the transform sequence.
Definition: trans_seq.c:997
TTransSeq ** ts
Definition: mequation.h:46
#define RY
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:67
#define TRUE
TRUE.
Definition: boolean.h:21
void Error(const char *s)
General error function.
Definition: error.c:80
void InitTransSeq(TTransSeq *ts)
Constructor.
Definition: trans_seq.c:450
#define TZ
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:51
boolean VarIncludedinMEquation(unsigned int v, TMequation *me)
Checks if the matrix equation includes a given variable.
Definition: mequation.c:191
#define AXIS_H
The homogeneous dimension in R^3.
Definition: htransform.h:108
boolean VarIncludedinTransSeq(unsigned int v, TTransSeq *ts)
Determines if the sequence includes a given variable.
Definition: trans_seq.c:630
Matrix equation.
Definition: mequation.h:42
void DeleteMEquation(TMequation *me)
Destructor.
Definition: mequation.c:492
unsigned int r[MAX_EQ_MATRIX]
Definition: mequation.h:52
Error and warning functions.
void AddVarTrans2MEquation(unsigned int t, int s, unsigned int v, TMequation *me)
Adds a variable transform to the matrix equation.
Definition: mequation.c:212
void PrintTransSeq(FILE *f, char **varNames, TTransSeq *ts)
Prints a transform sequence to a file.
Definition: trans_seq.c:1074
void AddTrans2TransSeq(TTrans *t, TTransSeq *ts)
Adds a transform to a transform sequence.
Definition: trans_seq.c:514
unsigned int TransSeqSize(TTransSeq *ts)
Number of elements in the transform sequence.
Definition: trans_seq.c:501
double HTransformGetElement(unsigned int i, unsigned int j, THTransform *t)
Gets an element in a homogeneous transform.
Definition: htransform.c:329
void DeleteTrans(TTrans *t)
Destructor.
Definition: trans_seq.c:421
void DeleteTransSeq(TTransSeq *ts)
Destructor.
Definition: trans_seq.c:1288
#define AXIS_Z
One of the dimension of R^3.
Definition: htransform.h:99
#define TX
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:35
A step in a transform sequence.
Definition: trans_seq.h:136
void AddDispTrans2MEquation(int s, unsigned int v, double *vect, TMequation *me)
Adds a displacement along a vector.
Definition: mequation.c:206
void ResetTransSeq(TTransSeq *ts)
Semi-destructor.
Definition: trans_seq.c:472
void AddTransSeq2MEquation(int s, TTransSeq *ts, TMequation *me)
Concatenates a transform sequence to the matrix equation.
Definition: mequation.c:250
boolean HasCtRotTransSeq(TTransSeq *ts)
Checks if the tranform sequence includes contant rotations.
Definition: trans_seq.c:489
unsigned int FixVarInMEquation(unsigned int nv, double v, TMequation *me)
Set a variable to a constant value.
Definition: mequation.c:296
unsigned int n
Definition: mequation.h:45
TTrans * GetElementFromTransSeq(unsigned int i, TTransSeq *ts)
Returns an element from a transform sequence.
Definition: trans_seq.c:506
A sequence of transforms.
Definition: trans_seq.h:319
void AddPatchTrans2MEquation(unsigned int t, int s, unsigned int u, unsigned int v, double **p, TMequation *me)
Adds a Parametrized-Patch transform to a matrix equation.
Definition: mequation.c:224
void AddVarTrans2TransSeq(unsigned int t, int s, unsigned int v, TTransSeq *ts)
Adds a variable transform to the sequence.
Definition: trans_seq.c:578
void ReplaceVarInMEquation(unsigned int nv, unsigned int nvNew, TMequation *me)
Replaces a variable.
Definition: mequation.c:345
void ResetMEquation(TMequation *me)
Resets the information stored in the matrix equation.
Definition: mequation.c:134
unsigned int c[MAX_EQ_MATRIX]
Definition: mequation.h:53
void AddCtTrans2MEquation(THTransform *t, TMequation *me)
Adds a constant transform to a matrix equation.
Definition: mequation.c:238
boolean IsEmptyMEquation(TMequation *me)
Identify empty matrix equations.
Definition: mequation.c:145
#define RX
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:59
void CopyMEquation(TMequation *me_dst, TMequation *me_src)
Copy constructor.
Definition: mequation.c:113
void DeriveMEquation(unsigned int v, TMequation *dme, TMequation *me)
Derives a matrix equation.
Definition: mequation.c:371
Definition of the matrix equation operations.
void SimplifyMEquation(TMequation *me)
Tries to reduce the complexity of the matrix equation.
Definition: mequation.c:358
void InitMEquation(TMequation *me)
Construtor.
Definition: mequation.c:99
void AddDispTrans2TransSeq(int s, unsigned int v, double *vect, TTransSeq *ts)
Adds a displacement transform to the sequence.
Definition: trans_seq.c:601
void HTransformDelete(THTransform *t)
Destructor.
Definition: htransform.c:887
#define MEM_EXPAND(_var, _n, _type)
Expands a previously allocated memory space.
Definition: defines.h:404
void DeriveTransSeq(unsigned int v, unsigned int *n, TTransSeq ***tsd, TTransSeq *ts)
Derive a sequence of transforms.
Definition: trans_seq.c:868
void TransInvert(TTrans *ti, TTrans *t)
Invert a transform.
Definition: trans_seq.c:141
boolean HasRotations(TMequation *me)
Cheks if a matrix equation includes rotations.
Definition: mequation.c:163
void ShiftVariablesInMEquation(unsigned int nv, TMequation *me)
Adjust variable indices after removina a variable.
Definition: mequation.c:288
void AddCtTrans2TransSeq(THTransform *t, TTransSeq *ts)
Adds a constant transform to the sequence.
Definition: trans_seq.c:550
void EvaluateMEquationXVectors(double *v, unsigned int n, double *p, double *r, TMequation *me)
Equation x vector evaluation.
Definition: mequation.c:437
void HTransformCopy(THTransform *t_dst, THTransform *t_src)
Copy constructor.
Definition: htransform.c:83
boolean simp
Definition: mequation.h:43
unsigned int neq
Definition: mequation.h:50
boolean HTransformIsZero(THTransform *t)
Identify the zero matrix.
Definition: htransform.c:97
void HTransformIdentity(THTransform *t)
Constructor.
Definition: htransform.c:69
unsigned int NumberScalarEquations(TMequation *me)
Number of scaler equations defined by a matrix equation.
Definition: mequation.c:283
void SimplifyTransSeq(TTransSeq *ts)
Reduces the complexity of the tranform sequence.
Definition: trans_seq.c:846
THTransform rhs
Definition: mequation.h:48
#define TY
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:43
boolean HTransformIsIdentity(THTransform *t)
Identify the identity matrix.
Definition: htransform.c:91