basic_algebra.c
Go to the documentation of this file.
1 #include "basic_algebra.h"
2 
3 #include "defines.h"
4 #include "geom.h"
5 
6 #include <math.h>
7 
15 CBLAS_INLINE double GeneralDotProduct(unsigned int s,double *v1,double *v2)
16 {
17  #ifdef _CBLAS
18  return(cblas_ddot(s,v1,1,v2,1));
19  #else
20  unsigned int i;
21  double dp;
22 
23  dp=0.0;
24  for(i=0;i<s;i++)
25  dp+=(v1[i]*v2[i]);
26  return(dp);
27  #endif
28 }
29 
30 CBLAS_INLINE void ScaleVector(double f,unsigned int s,double *v)
31 {
32  #ifdef _CBLAS
33  cblas_dscal(s,f,v,1);
34  #else
35  unsigned int i;
36 
37  for(i=0;i<s;i++)
38  v[i]*=f;
39  #endif
40 }
41 
42 CBLAS_INLINE void ScaleVector2(double f,unsigned int s,double *v,double *vout)
43 {
44  #ifdef _CBLAS
45  cblas_dcopy(s,v,1,vout,1);
46  cblas_dscal(s,f,vout,1);
47  #else
48  unsigned int i;
49 
50  for(i=0;i<s;i++)
51  vout[i]=v[i]*f;
52  #endif
53 }
54 
55 CBLAS_INLINE void AccumulateVector(unsigned int s,double *v1,double *v2)
56 {
57  #ifdef _CBLAS
58  cblas_daxpy(s,1.0,v1,1,v2,1);
59  #else
60  unsigned int i;
61 
62  for(i=0;i<s;i++)
63  v2[i]+=v1[i];
64  #endif
65 }
66 
67 CBLAS_INLINE void SumVector(unsigned int s,double *v1,double *v2,double *v)
68 {
69  #ifdef _CBLAS
70  /* If v==v2 and we copy v1 on v, v2 will be lost */
71  if (v==v2)
72  cblas_daxpy(s,1.0,v1,1,v,1);
73  else
74  {
75  cblas_dcopy(s,v1,1,v,1);
76  cblas_daxpy(s,1.0,v2,1,v,1);
77  }
78  #else
79  unsigned int i;
80 
81  for(i=0;i<s;i++)
82  v[i]=(v1[i]+v2[i]);
83  #endif
84 }
85 
86 CBLAS_INLINE void SumVectorScale(unsigned int s,double *v1,double w,double *v2,double *v)
87 {
88  #ifdef _CBLAS
89  /* If v==v2 and we copy v1 on v, v2 will be lost */
90  if (v==v2)
91  {
92  cblas_dscal(s,w,v2,1);
93  cblas_daxpy(s,1.0,v1,1,v,1); /* v=v+v1=w*v2+v1 */
94  }
95  else
96  {
97  cblas_dcopy(s,v1,1,v,1);
98  cblas_daxpy(s,w,v2,1,v,1);
99  }
100  #else
101  unsigned int i;
102 
103  for(i=0;i<s;i++)
104  v[i]=(v1[i]+w*v2[i]);
105  #endif
106 }
107 
108 void CosVector(unsigned int s,double *v,double *co)
109 {
110  unsigned int i;
111 
112  for(i=0;i<s;i++)
113  co[i]=cos(v[i]);
114 }
115 
116 void SinVector(unsigned int s,double *v,double *si)
117 {
118  unsigned int i;
119 
120  for(i=0;i<s;i++)
121  si[i]=sin(v[i]);
122 }
123 
124 unsigned int MaxVectorElement(unsigned int m,double *v)
125 {
126  if (m==0)
127  return(NO_UINT);
128  else
129  {
130  unsigned int i;
131  unsigned int me;
132  double ma;
133 
134  me=0;
135  ma=v[0];
136  for(i=1;i<m;i++)
137  {
138  if (v[i]>ma)
139  {
140  ma=v[i];
141  me=i;
142  }
143  }
144  return(me);
145  }
146 }
147 
148 double MaxVector(unsigned int m,double *v)
149 {
150  if (m==0)
151  return(0.0);
152  else
153  {
154  unsigned int i;
155  double ma;
156 
157  ma=v[0];
158  for(i=1;i<m;i++)
159  {
160  if (v[i]>ma)
161  ma=v[i];
162  }
163  return(ma);
164  }
165 }
166 
167 unsigned int MinVectorElement(unsigned int m,double *v)
168 {
169  if (m==0)
170  return(NO_UINT);
171  else
172  {
173  unsigned int i;
174  unsigned int me;
175  double mi;
176 
177  me=0;
178  mi=v[0];
179  for(i=1;i<m;i++)
180  {
181  if (v[i]<mi)
182  {
183  mi=v[i];
184  me=i;
185  }
186  }
187  return(me);
188  }
189 }
190 
191 double MinVector(unsigned int m,double *v)
192 {
193  if (m==0)
194  return(0.0);
195  else
196  {
197  unsigned int i;
198  double mi;
199 
200  mi=v[0];
201  for(i=1;i<m;i++)
202  {
203  if (v[i]<mi)
204  mi=v[i];
205  }
206  return(mi);
207  }
208 }
209 
210 void Vector2Range(double l,double u,double mode,
211  unsigned int m,double *v)
212 {
213  if (m>0)
214  {
215  unsigned int i;
216  double mi,ma,val;
217  double s;
218 
219  if (l>u)
220  Error("Lower can not be higher than upper in Vector2Range");
221  s=u-l;
222  if (s<ZERO)
223  Error("Null range in Vector2Range");
224 
225  mi=pow(v[0],mode);
226  ma=mi;
227  for(i=1;i<m;i++)
228  {
229  val=pow(v[i],mode);
230 
231  if (val<mi)
232  mi=val;
233  else
234  {
235  if (val>ma)
236  ma=val;
237  }
238  }
239 
240  if ((ma-mi)<ZERO)
241  Error("Constant vector in Vector2Range");
242 
243  for(i=0;i<m;i++)
244  {
245  val=pow(v[i],mode);
246  v[i]=(val-mi)/(ma-mi)*s+l;
247  }
248  }
249 }
250 
251 CBLAS_INLINE void SubtractVector(unsigned int s,double *v1,double *v2)
252 {
253  #ifdef _CBLAS
254  cblas_daxpy(s,-1.0,v2,1,v1,1);
255  #else
256  unsigned int i;
257 
258  for(i=0;i<s;i++)
259  v1[i]-=v2[i];
260  #endif
261 }
262 
263 /* We always inline DifferenceVector because it is used by other functions below */
264 inline void DifferenceVector(unsigned int s,double *v1,double *v2,double *v)
265 {
266  #ifdef _CBLAS
267  /* If v==v2 and we copy v1 on v, v2 will be lost */
268  if (v==v2)
269  {
270  cblas_dscal(s,-1.0,v2,1);
271  cblas_daxpy(s,1.0,v1,1,v,1); /* v=v+v1=-v2+v1 */
272  }
273  else
274  {
275  cblas_dcopy(s,v1,1,v,1);
276  cblas_daxpy(s,-1.0,v2,1,v,1);
277  }
278  #else
279  unsigned int i;
280 
281  for(i=0;i<s;i++)
282  v[i]=(v1[i]-v2[i]);
283  #endif
284 }
285 
286 void DifferenceVectorSubset(unsigned int s,
287  boolean *subset,
288  double *v1,double *v2,double *v)
289 {
290  if (subset==NULL)
291  DifferenceVector(s,v1,v2,v);
292  else
293  {
294  unsigned int i;
295 
296  for(i=0;i<s;i++)
297  {
298  if (subset[i])
299  v[i]=(v1[i]-v2[i]);
300  else
301  v[i]=0.0;
302  }
303  }
304 }
305 
306 void DifferenceVectorTopology(unsigned int s,unsigned int *tp,
307  double *v1,double *v2,double *v)
308 {
309  if (tp==NULL)
310  DifferenceVector(s,v1,v2,v);
311  else
312  {
313  unsigned int i;
314  double d;
315 
316  for(i=0;i<s;i++)
317  {
318  d=v1[i]-v2[i];
319  if (tp[i]==TOPOLOGY_S)
320  PI2PI(d);
321  v[i]=d;
322  }
323  }
324 }
325 void DifferenceVectorTopologySubset(unsigned int s,unsigned int *tp,
326  boolean *subset,
327  double *v1,double *v2,double *v)
328 {
329  if (subset==NULL)
330  DifferenceVectorTopology(s,tp,v1,v2,v);
331  else
332  {
333  if (tp==NULL)
334  DifferenceVectorSubset(s,subset,v1,v2,v);
335  else
336  {
337  unsigned int i;
338  double d;
339 
340  for(i=0;i<s;i++)
341  {
342  if (subset[i])
343  {
344  d=v1[i]-v2[i];
345  if (tp[i]==TOPOLOGY_S)
346  PI2PI(d);
347  v[i]=d;
348  }
349  else
350  v[i]=0.0;
351  }
352  }
353  }
354 }
355 
356 CBLAS_INLINE double Norm(unsigned int s,double *v)
357 {
358  #ifdef _CBLAS
359  return(cblas_dnrm2(s,v,1));
360  #else
361  unsigned int i;
362  double n;
363 
364  n=0.0;
365  for(i=0;i<s;i++)
366  n+=(v[i]*v[i]);
367  return(sqrt(n));
368  #endif
369 }
370 
371 CBLAS_INLINE double NormWithStride(unsigned int s,unsigned int st,double *v)
372 {
373  #ifdef _CBLAS
374  return(cblas_dnrm2(s,v,st));
375  #else
376  unsigned int i,j;
377  double n;
378 
379  n=0.0;
380  for(i=0,j=0;i<s;i++,j+=st)
381  n+=(v[j]*v[j]);
382  return(sqrt(n));
383  #endif
384 }
385 
386 /* We inline SquaredDistance in all the cases, not just if CBLAS is present
387  because it is used in functions below */
388 inline double SquaredDistance(unsigned int s,double *v1,double *v2)
389 {
390  double n;
391 
392  #ifdef _NO_CBLAS
393  /* Not clear if this is more efficient than the naive implementation.
394  So, this is not used right now. */
395  n=cblas_ddot(s,v1,1,v1,1)
396  -2.0*cblas_ddot(s,v1,1,v2,1)
397  +cblas_ddot(s,v2,1,v2,1);
398  #else
399  unsigned int i;
400  double v;
401 
402  n=0;
403  for(i=0;i<s;i++)
404  {
405  v=v1[i]-v2[i];
406  n+=(v*v);
407  }
408  #endif
409 
410  return(n);
411 }
412 
413 double SquaredDistanceSubset(unsigned int s,boolean *subset,double *v1,double *v2)
414 {
415  double n;
416 
417  if (subset==NULL)
418  n=SquaredDistance(s,v1,v2);
419  else
420  {
421  unsigned int i;
422  double v;
423 
424  n=0;
425  for(i=0;i<s;i++)
426  {
427  if (subset[i])
428  {
429  v=v1[i]-v2[i];
430  n+=(v*v);
431  }
432  }
433  }
434  return(n);
435 }
436 
437 /* We inline Distance in all the cases, not just if CBLAS is present */
438 inline double Distance(unsigned int s,double *v1,double *v2)
439 {
440  return(sqrt(SquaredDistance(s,v1,v2)));
441 }
442 
443 double SquaredDistanceTopology(unsigned int s,unsigned int *tp,
444  double *v1,double *v2)
445 {
446  double n;
447 
448  /* We in-line the DistanceTopology function, for efficiency reasons. */
449  if (tp==NULL)
450  n=SquaredDistance(s,v1,v2);
451  else
452  {
453  unsigned int i;
454  double v;
455 
456  n=0.0;
457  for(i=0;i<s;i++)
458  {
459  v=v1[i]-v2[i];
460  if ((tp[i]==TOPOLOGY_S)&&((v<-M_PI)||(v>M_PI)))
461  PI2PI(v);
462  n+=(v*v);
463  }
464  }
465  return(n);
466 }
467 
468 double SquaredDistanceTopologyMin(double t2,unsigned int s,unsigned int *tp,
469  double *v1,double *v2)
470 {
471  unsigned int i;
472  double n,v;
473 
474  n=0.0;
475  if (tp==NULL)
476  {
477  /* This is the Distance function inlined (and modified) here for
478  efficiency (avoid an additonal function call) */
479  for(i=0;((i<s)&&(n<t2));i++)
480  {
481  v=v1[i]-v2[i];
482  n+=(v*v);
483  }
484  }
485  else
486  {
487  for(i=0;((i<s)&&(n<t2));i++)
488  {
489  v=v1[i]-v2[i];
490  if ((tp[i]==TOPOLOGY_S)&&((v<-M_PI)||(v>M_PI)))
491  PI2PI(v);
492  n+=(v*v);
493  }
494  }
495  return(n);
496 }
497 
498 double DistanceTopology(unsigned int s,unsigned int *tp,
499  double *v1,double *v2)
500 {
501  double n;
502 
503  if (tp==NULL)
504  n=SquaredDistance(s,v1,v2);
505  else
506  {
507  unsigned int i;
508  double v;
509 
510  n=0.0;
511  for(i=0;i<s;i++)
512  {
513  v=v1[i]-v2[i];
514  if ((tp[i]==TOPOLOGY_S)&&((v<-M_PI)||(v>M_PI)))
515  PI2PI(v);
516  n+=(v*v);
517  }
518  }
519  return(sqrt(n));
520 }
521 
522 double DistanceTopologySubset(unsigned int s,unsigned int *tp,
523  boolean *subset,
524  double *v1,double *v2)
525 {
526  double n;
527 
528  if (subset==NULL)
529  n=SquaredDistanceTopology(s,tp,v1,v2);
530  else
531  {
532  if (tp==NULL)
533  n=SquaredDistanceSubset(s,subset,v1,v2);
534  else
535  {
536  unsigned int i;
537  double v;
538 
539  n=0.0;
540  for(i=0;i<s;i++)
541  {
542  if (subset[i])
543  {
544  v=v1[i]-v2[i];
545  if ((tp[i]==TOPOLOGY_S)&&((v<-M_PI)||(v>M_PI)))
546  PI2PI(v);
547  n+=(v*v);
548  }
549  }
550  }
551  }
552  return(sqrt(n));
553 }
554 
555 
556 double DistanceTopologyMin(double t,unsigned int s,unsigned int *tp,
557  double *v1,double *v2)
558 {
559  unsigned int i;
560  double n,v,t2;
561 
562  n=0.0;
563  t2=t*t;
564  if (tp==NULL)
565  {
566  /* This is the SquaredDistance function inlined and modified for
567  efficiency (avoid an additonal function call) */
568  for(i=0;(i<s)&&(n<t2);i++)
569  {
570  v=v1[i]-v2[i];
571  n+=(v*v);
572  }
573  }
574  else
575  {
576  for(i=0;(i<s)&&(n<t2);i++)
577  {
578  v=v1[i]-v2[i];
579  if ((tp[i]==TOPOLOGY_S)&&((v<-M_PI)||(v>M_PI)))
580  PI2PI(v);
581  n+=(v*v);
582  }
583  }
584  return(sqrt(n));
585 }
586 
587 boolean CrossTopologyBorder(unsigned int s,unsigned int *tp,double *v1,double *v2)
588 {
589  return(Distance(s,v1,v2)>DistanceTopology(s,tp,v1,v2));
590 }
591 
592 CBLAS_INLINE void Normalize(unsigned int s,double *v)
593 {
594  double n;
595 
596  #ifdef _CBLAS
597  n=cblas_dnrm2(s,v,1);
598  if (n>1e-6)
599  cblas_dscal(s,1.0/n,v,1);
600  else
601  Error("Normalizing a null vector");
602  #else
603  unsigned int i;
604 
605  n=Norm(s,v);
606  if (n>1e-6) /* avoid division by (almost) zero */
607  {
608  for(i=0;i<s;i++)
609  v[i]/=n;
610  }
611  else
612  Error("Normalizing a null vector");
613  #endif
614 }
615 
616 double Mean(unsigned int s,double *v)
617 {
618  unsigned int i;
619  double m;
620 
621  m=0.0;
622  for(i=0;i<s;i++)
623  m+=v[i];
624 
625  return(m/((double)s));
626 }
627 
628 double StdDev(unsigned int s,double m,double *v)
629 {
630  unsigned int i;
631  double sd,d;
632 
633  sd=0.0;
634  for(i=0;i<s;i++)
635  {
636  d=v[i]-m;
637  sd+=(d*d);
638  }
639 
640  if (s>1)
641  return(sqrt(sd/((double)s-1)));
642  else
643  return(sqrt(sd));
644 }
645 
646 void ArrayPi2Pi(unsigned int n,unsigned int *t,double *a)
647 {
648  unsigned int i;
649  double *b;
650 
651  b=a;
652  for(i=0;i<n;i++,b++)
653  {
654  if (t[i]==TOPOLOGY_S)
655  PI2PI(*b);
656  }
657 }
658 
659 CBLAS_INLINE void GetRow(unsigned int k,unsigned int r,unsigned int c,double *m,double *v)
660 {
661  #ifdef _CBLAS
662  cblas_dcopy(c,&(m[RC2INDEX(k,0,r,c)]),(ROW_MAJOR?1:r),v,1);
663  #else
664  unsigned int i;
665 
666  for(i=0;i<c;i++)
667  v[i]=m[RC2INDEX(k,i,r,c)];
668  #endif
669 }
670 
671 CBLAS_INLINE void GetColumn(unsigned int k,unsigned int r,unsigned int c,double *m,double *v)
672 {
673  #ifdef _CBLAS
674  cblas_dcopy(r,&(m[RC2INDEX(0,k,r,c)]),(ROW_MAJOR?c:1),v,1);
675  #else
676  unsigned int i;
677 
678  for(i=0;i<r;i++)
679  v[i]=m[RC2INDEX(i,k,r,c)];
680  #endif
681 }
682 
683 CBLAS_INLINE void SetRow(double *v,unsigned int k,unsigned int r,unsigned int c,double *m)
684 {
685  #ifdef _CBLAS
686  cblas_dcopy(c,v,1,&(m[RC2INDEX(k,0,r,c)]),(ROW_MAJOR?1:r));
687  #else
688  unsigned int i;
689 
690  for(i=0;i<c;i++)
691  m[RC2INDEX(k,i,r,c)]=v[i];
692  #endif
693 }
694 
695 CBLAS_INLINE void SetColumn(double *v,unsigned int k,unsigned int r,unsigned int c,double *m)
696 {
697  #ifdef _CBLAS
698  cblas_dcopy(r,v,1,&(m[RC2INDEX(0,k,r,c)]),(ROW_MAJOR?c:1));
699  #else
700  unsigned int i;
701 
702  for(i=0;i<r;i++)
703  m[RC2INDEX(i,k,r,c)]=v[i];
704  #endif
705 }
706 
707 CBLAS_INLINE double RowSquaredNorm(unsigned int k,unsigned int r,unsigned int c,double *m)
708 {
709  double s;
710  unsigned int i;
711 
712  #ifdef _CBLAS
713  i=RC2INDEX(k,0,r,c);
714  s=cblas_ddot(c,&(m[i]),(ROW_MAJOR?1:r),&(m[i]),(ROW_MAJOR?1:r));
715  #else
716  double v;
717 
718  s=0.0;
719  for(i=0;i<c;i++)
720  {
721  v=m[RC2INDEX(k,i,r,c)];
722  s+=(v*v);
723  }
724  #endif
725  return(s);
726 }
727 
728 CBLAS_INLINE double ColumnSquaredNorm(unsigned int k,unsigned int r,unsigned int c,double *m)
729 {
730  double s;
731  unsigned int i;
732 
733  #ifdef _CBLAS
734  i=RC2INDEX(0,k,r,c);
735  s=cblas_ddot(r,&(m[i]),(ROW_MAJOR?c:1),&(m[i]),(ROW_MAJOR?c:1));
736  #else
737  double v;
738 
739  s=0.0;
740  for(i=0;i<r;i++)
741  {
742  v=m[RC2INDEX(i,k,r,c)];
743  s+=(v*v);
744  }
745  #endif
746  return(s);
747 }
748 
749 CBLAS_INLINE void MatrixVectorProduct(unsigned int r,unsigned int c,double *A,double *b,double *o)
750 {
751  #ifdef _CBLAS
752  cblas_dgemv((ROW_MAJOR?CblasRowMajor:CblasColMajor),CblasNoTrans,r,c,1.0,A,(ROW_MAJOR?c:r),b,1,0.0,o,1);
753  #else
754  unsigned int i,j;
755 
756  for(i=0;i<r;i++)
757  {
758  o[i]=0.0;
759  for(j=0;j<c;j++)
760  o[i]+=(A[RC2INDEX(i,j,r,c)]*b[j]);
761  }
762  #endif
763 }
764 
765 CBLAS_INLINE void TMatrixVectorProduct(unsigned int r,unsigned int c,double *A,double *b,double *o)
766 {
767  #ifdef _CBLAS
768  cblas_dgemv((ROW_MAJOR?CblasRowMajor:CblasColMajor),CblasTrans,r,c,1.0,A,(ROW_MAJOR?c:r),b,1,0.0,o,1);
769  #else
770  unsigned int i,j;
771 
772  for(i=0;i<c;i++)
773  {
774  o[i]=0.0;
775  for(j=0;j<r;j++)
776  o[i]+=(A[RC2INDEX(j,i,r,c)]*b[j]);
777  }
778  #endif
779 }
780 
781 CBLAS_INLINE void TMatrixVectorStrideProduct(unsigned int r,unsigned int c,double *A,unsigned int s,double *b,double *o)
782 {
783  #ifdef _CBLAS
784  cblas_dgemv((ROW_MAJOR?CblasRowMajor:CblasColMajor),CblasTrans,r,c,1.0,A,(ROW_MAJOR?c:r),b,s,0.0,o,1);
785  #else
786  unsigned int i,j;
787 
788  for(i=0;i<c;i++)
789  {
790  o[i]=0.0;
791  for(j=0;j<r;j++)
792  o[i]+=(A[RC2INDEX(j,i,r,c)]*b[j*s]);
793  }
794  #endif
795 }
796 
797 CBLAS_INLINE void MatrixMatrixProduct(unsigned int ra,unsigned int ca,double *A,
798  unsigned int cb,double *B,double *C)
799 {
800  #ifdef _CBLAS
801  /* A is ra x ca
802  B is ca x cb
803  C is ra x cb */
804  cblas_dgemm((ROW_MAJOR?CblasRowMajor:CblasColMajor),CblasNoTrans,CblasNoTrans,
805  ra,cb,ca,1.0,A,(ROW_MAJOR?ca:ra),B,(ROW_MAJOR?cb:ca),0.0,C,(ROW_MAJOR?cb:ra));
806  #else
807  unsigned int i,j,k;
808 
809  /* A * B */
810  for(i=0;i<ra;i++)
811  {
812  for(j=0;j<cb;j++)
813  {
814  C[RC2INDEX(i,j,ra,cb)]=0.0;
815  for(k=0;k<ca;k++)
816  C[RC2INDEX(i,j,ra,cb)]+=(A[RC2INDEX(i,k,ra,ca)]*B[RC2INDEX(k,j,ca,cb)]);
817  }
818  }
819  #endif
820 }
821 
822 CBLAS_INLINE void TMatrixMatrixProduct(unsigned int ra,unsigned int ca,double *A,
823  unsigned int cb,double *B,double *C)
824 {
825  #ifdef _CBLAS
826  /* A^t is ca x ra
827  B is ra x cb
828  C is ca x cb */
829  cblas_dgemm((ROW_MAJOR?CblasRowMajor:CblasColMajor),CblasTrans,CblasNoTrans,
830  ca,cb,ra,1.0,A,(ROW_MAJOR?ca:ra),B,(ROW_MAJOR?cb:ra),0.0,C,(ROW_MAJOR?cb:ca));
831  #else
832  unsigned int i,j,k;
833 
834  /* A^t * B */
835  for(i=0;i<ca;i++)
836  {
837  for(j=0;j<cb;j++)
838  {
839  C[RC2INDEX(i,j,ca,cb)]=0.0;
840  for(k=0;k<ra;k++)
841  C[RC2INDEX(i,j,ca,cb)]+=(A[RC2INDEX(k,i,ra,ca)]*B[RC2INDEX(k,j,ra,cb)]);
842  }
843  }
844  #endif
845 }
846 
847 double MinCosinusBetweenSubSpaces(unsigned int m,unsigned int k,double *T1,double *T2)
848 {
849  unsigned int i;
850  double c,cm;
851  double *proj;
852  #ifndef _CBLAS
853  unsigned int s,j;
854  #endif
855 
856  NEW(proj,k,double);
857 
858  cm=1; /*minimal cosinus*/
859  for(i=0;i<k;i++)
860  {
861  #ifdef _CBLAS
862  #if (ROW_MAJOR)
863  TMatrixVectorStrideProduct(m,k,T1,k,&(T2[i]),proj);
864  #else
865  TMatrixVectorProduct(m,k,T1,&(T2[i*m]),proj);
866  #endif
867  #else
868  for(j=0;j<k;j++)
869  {
870  proj[j]=0;
871  for(s=0;s<m;s++)
872  proj[j]+=(T1[RC2INDEX(s,j,m,k)]*T2[RC2INDEX(s,i,m,k)]);
873  }
874  #endif
875  /* Assuming vector of T1 and T2 orthonormal, c is the cosinus of
876  the i-th vector of basis T2 with respect to the subspace defined
877  by T1. Note that in the projection the angle can not be larger than
878  pi/2 and, therefore, the cosinus in in [0,1]*/
879  c=Norm(k,proj);
880 
881  /* We search for the minimum cosinus = maximum angle. This is a measure
882  of the difference between the two subspaces.*/
883  if (c<cm) cm=c;
884  }
885 
886  free(proj);
887 
888  return(cm);
889 }
890 
891 CBLAS_INLINE void SubMatrixFromMatrix(unsigned int nr1,unsigned int nc1,double *m1,
892  unsigned int nri,unsigned int nci,
893  unsigned int nr,unsigned int nc,double *m)
894 {
895  #ifdef _CBLAS
896  unsigned int i,j,k;
897  #if (ROW_MAJOR)
898  if (nr1<nc1)
899  {
900  /* copy row by row */
901  for(j=0,i=0,k=RC2INDEX(nri,nci,nr,nc);j<nr1;j++,i+=nc1,k+=nc)
902  cblas_dcopy(nc1,&(m1[i]),1,&(m[k]),1);
903  }
904  else
905  {
906  /* copy column by column */
907  for(i=0,k=RC2INDEX(nri,nci,nr,nc);i<nc1;i++,k++)
908  cblas_dcopy(nr1,&(m1[i]),nc1,&(m[k]),nc);
909  }
910  #else
911  if (nr1<nc1)
912  {
913  /* copy row by row */
914  for(i=0,k=RC2INDEX(nri,nci,nr,nc);i<nr1;i++,k++)
915  cblas_dcopy(nc1,&(m1[i]),nr1,&(m[k]),nr);
916  }
917  else
918  {
919  /* copy column by column */
920  for(j=0,i=0,k=RC2INDEX(nri,nci,nr,nc);j<nc1;j++,i+=nr1,k+=nr)
921  cblas_dcopy(nr1,&(m1[i]),1,&(m[k]),1);
922  }
923  #endif
924  #else
925  unsigned int i,j,k,l;
926 
927  for(i=0,k=nri;i<nr1;i++,k++)
928  {
929  for(j=0,l=nci;j<nc1;j++,l++)
930  m[RC2INDEX(k,l,nr,nc)]=m1[RC2INDEX(i,j,nr1,nc1)];
931  }
932  #endif
933 }
934 
935 CBLAS_INLINE void SubMatrixFromTMatrix(unsigned int nr1,unsigned int nc1,double *m1,
936  unsigned int nri,unsigned int nci,
937  unsigned int nr,unsigned int nc,double *m)
938 {
939  #ifdef _CBLAS
940  unsigned int i,j,k;
941  #if (ROW_MAJOR)
942  if (nc1<nr1)
943  {
944  /* copy row by row (of the transposed) */
945  for(i=0,k=RC2INDEX(nri,nci,nr,nc);i<nc1;i++,k+=nc)
946  cblas_dcopy(nr1,&(m1[i]),nc1,&(m[k]),1);
947  }
948  else
949  {
950  /* copy column by column (of the transposed) */
951  for(j=0,i=0,k=RC2INDEX(nri,nci,nr,nc);j<nr1;j++,i+=nc1,k++)
952  cblas_dcopy(nc1,&(m1[i]),1,&(m[k]),nc);
953  }
954  #else
955  if (nc1<nr1)
956  {
957  /* copy row by row (of the transposed) */
958  for(j=0,i=0,k=RC2INDEX(nri,nci,nr,nc);j<nc1;j++,i+=nr1,k++)
959  cblas_dcopy(nr1,&(m1[i]),1,&(m[k]),nr);
960  }
961  else
962  {
963  /* copy column by column (of the transposed) */
964  for(i=0,k=RC2INDEX(nri,nci,nr,nc);i<nr1;i++,k+=nr)
965  cblas_dcopy(nc1,&(m1[i]),nr1,&(m[k]),1);
966  }
967  #endif
968  #else
969  unsigned int i,j,k,l;
970 
971  for(i=0,k=nri;i<nc1;i++,k++)
972  {
973  for(j=0,l=nci;j<nr1;j++,l++)
974  m[RC2INDEX(k,l,nr,nc)]=m1[RC2INDEX(j,i,nr1,nc1)];
975  }
976  #endif
977 }
978 
979 void PrintVector(FILE *f,char *label,unsigned int n,double *v)
980 {
981  unsigned int i;
982 
983  if (label!=NULL)
984  fprintf(f,"%s=",label);
985  fprintf(f,"[ ");
986  for(i=0;i<n;i++)
987  fprintf(f,"%.16f ",v[i]);
988  fprintf(f,"];\n");
989 }
990 
991 void SaveVector(FILE *f,unsigned int n,double *v)
992 {
993  unsigned int i;
994 
995  for(i=0;i<n;i++)
996  fprintf(f,"%.16f\n",v[i]);
997 }
998 
999 
1000 void PrintMatrix(FILE *f,char *label,unsigned int r,unsigned int c,double *m)
1001 {
1002  unsigned int i,j;
1003 
1004  if (label!=NULL)
1005  fprintf(f,"%s=",label);
1006  fprintf(f,"[ ");
1007  for(i=0;i<r;i++)
1008  {
1009  for(j=0;j<c;j++)
1010  fprintf(f,"%.16f ",m[RC2INDEX(i,j,r,c)]);
1011  fprintf(f,"\n");
1012  }
1013  fprintf(f,"];\n");
1014 }
1015 
1016 void PrintTMatrix(FILE *f,char *label,unsigned int r,unsigned int c,double *m)
1017 {
1018  unsigned int i,j;
1019 
1020  if (label!=NULL)
1021  fprintf(f,"%s=",label);
1022  fprintf(f,"[ ");
1023  for(i=0;i<c;i++)
1024  {
1025  for(j=0;j<r;j++)
1026  fprintf(f,"%.16f ",m[RC2INDEX(j,i,r,c)]);
1027  fprintf(f,"\n");
1028  }
1029  fprintf(f,"];\n");
1030 }
double MaxVector(unsigned int m, double *v)
Value of the maximum element of a vector.
CBLAS_INLINE void ScaleVector(double f, unsigned int s, double *v)
Scales a vector.
Definition: basic_algebra.c:30
double SquaredDistanceTopologyMin(double t2, unsigned int s, unsigned int *tp, double *v1, double *v2)
Computes the squared distance of two points.
Definition of basic functions.
double DistanceTopologySubset(unsigned int s, unsigned int *tp, boolean *subset, double *v1, double *v2)
Computes the distance of two points along a subset of components.
double SquaredDistanceSubset(unsigned int s, boolean *subset, double *v1, double *v2)
Computes the squared distance of two points along some components.
CBLAS_INLINE void SetRow(double *v, unsigned int k, unsigned int r, unsigned int c, double *m)
Sets a row of a matrix.
double DistanceTopology(unsigned int s, unsigned int *tp, double *v1, double *v2)
Computes the distance of two points.
CBLAS_INLINE void TMatrixVectorStrideProduct(unsigned int r, unsigned int c, double *A, unsigned int s, double *b, double *o)
Product of a transposed matrix and a vector.
#define NEW(_var, _n, _type)
Allocates memory space.
Definition: defines.h:385
#define RC2INDEX(i, j, nr, nc)
Index in a vector of a matrix element.
Definition: basic_algebra.h:81
void ArrayPi2Pi(unsigned int n, unsigned int *t, double *a)
Applies PI2PI to an array.
void SinVector(unsigned int s, double *v, double *si)
Sine on a vector.
double MinVector(unsigned int m, double *v)
Value of the minimum element of a vector.
CBLAS_INLINE void TMatrixMatrixProduct(unsigned int ra, unsigned int ca, double *A, unsigned int cb, double *B, double *C)
C = A^t * B.
CBLAS_INLINE double Norm(unsigned int s, double *v)
Computes the norm of a vector.
CBLAS_INLINE void SumVector(unsigned int s, double *v1, double *v2, double *v)
Adds two vectors.
Definition: basic_algebra.c:67
#define PI2PI(a)
Forces an angle go be in [-pi,pi].
Definition: defines.h:205
void DifferenceVectorTopology(unsigned int s, unsigned int *tp, double *v1, double *v2, double *v)
Substracts two vectors.
CBLAS_INLINE double RowSquaredNorm(unsigned int k, unsigned int r, unsigned int c, double *m)
Computes the squared norm of a row of a matrix.
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 Normalize(unsigned int s, double *v)
Normalizes a vector.
void Error(const char *s)
General error function.
Definition: error.c:80
void DifferenceVectorTopologySubset(unsigned int s, unsigned int *tp, boolean *subset, double *v1, double *v2, double *v)
Substracts two vectors along some of its components.
#define ZERO
Floating point operations giving a value below this constant (in absolute value) are considered 0...
Definition: defines.h:37
void SaveVector(FILE *f, unsigned int n, double *v)
Saves a vector.
double SquaredDistance(unsigned int s, double *v1, double *v2)
Computes the squared distance of two points.
#define CBLAS_INLINE
Inline BLAS-based functions.
Definition: basic_algebra.h:48
double Distance(unsigned int s, double *v1, double *v2)
Computes the distance of two points.
CBLAS_INLINE void ScaleVector2(double f, unsigned int s, double *v, double *vout)
Scales a vector.
Definition: basic_algebra.c:42
void PrintVector(FILE *f, char *label, unsigned int n, double *v)
Prints a vector.
unsigned int MaxVectorElement(unsigned int m, double *v)
Index of the maximum element of a vector.
CBLAS_INLINE double GeneralDotProduct(unsigned int s, double *v1, double *v2)
Computes the dot product of two general vectors.
Definition: basic_algebra.c:15
void DifferenceVectorSubset(unsigned int s, boolean *subset, double *v1, double *v2, double *v)
Substracts two vectors along some of its components.
CBLAS_INLINE void MatrixVectorProduct(unsigned int r, unsigned int c, double *A, double *b, double *o)
Product of a matrix and a vector.
Definitions of constants and macros used in several parts of the cuik library.
void DifferenceVector(unsigned int s, double *v1, double *v2, double *v)
Substracts two vectors.
boolean CrossTopologyBorder(unsigned int s, unsigned int *tp, double *v1, double *v2)
Determines if the line between two points crosses the topology boder.
double MinCosinusBetweenSubSpaces(unsigned int m, unsigned int k, double *T1, double *T2)
Computes the cosinus of the maximum angle between two lineal sub-spaces.
void Vector2Range(double l, double u, double mode, unsigned int m, double *v)
Scales a vector to a given range.
#define M_PI
Pi.
Definition: defines.h:83
CBLAS_INLINE void TMatrixVectorProduct(unsigned int r, unsigned int c, double *A, double *b, double *o)
Product of a transposed matrix and a vector.
CBLAS_INLINE double ColumnSquaredNorm(unsigned int k, unsigned int r, unsigned int c, double *m)
Computes the squared norm of a column of a matrix.
double StdDev(unsigned int s, double m, double *v)
Computes the standard deviation.
#define NO_UINT
Used to denote an identifier that has not been initialized.
Definition: defines.h:435
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 CosVector(unsigned int s, double *v, double *co)
Cosine on a vector.
CBLAS_INLINE void SubtractVector(unsigned int s, double *v1, double *v2)
Substracts a vector from another vector.
double SquaredDistanceTopology(unsigned int s, unsigned int *tp, double *v1, double *v2)
Computes the squared distance of two points.
CBLAS_INLINE void SubMatrixFromMatrix(unsigned int nr1, unsigned int nc1, double *m1, unsigned int nri, unsigned int nci, unsigned int nr, unsigned int nc, double *m)
Defines a submatrix in a matrix.
unsigned int MinVectorElement(unsigned int m, double *v)
Index of the minimum element of a vector.
double DistanceTopologyMin(double t, unsigned int s, unsigned int *tp, double *v1, double *v2)
Computes the distance of two points, if it is below a given threshold.
void PrintMatrix(FILE *f, char *label, unsigned int r, unsigned int c, double *m)
Prints a matrix.
CBLAS_INLINE void SubMatrixFromTMatrix(unsigned int nr1, unsigned int nc1, double *m1, unsigned int nri, unsigned int nci, unsigned int nr, unsigned int nc, double *m)
Defines a submatrix in a matrix.
CBLAS_INLINE double NormWithStride(unsigned int s, unsigned int st, double *v)
Computes the norm of a vector.
CBLAS_INLINE void MatrixMatrixProduct(unsigned int ra, unsigned int ca, double *A, unsigned int cb, double *B, double *C)
C = A * B.
CBLAS_INLINE void GetRow(unsigned int k, unsigned int r, unsigned int c, double *m, double *v)
Gets a row from a matrix.
void PrintTMatrix(FILE *f, char *label, unsigned int r, unsigned int c, double *m)
Prints a transposed matrix.
CBLAS_INLINE void SetColumn(double *v, unsigned int k, unsigned int r, unsigned int c, double *m)
Sets a column of a matrix.
double Mean(unsigned int s, double *v)
Computes the mean.
#define TOPOLOGY_S
One of the possible topologies.
Definition: defines.h:139
CBLAS_INLINE void GetColumn(unsigned int k, unsigned int r, unsigned int c, double *m, double *v)
Gets a column from a matrix.