DMRITool  v0.1.1-139-g860d86b4
Diffusion MRI Tool
utlNDArrayFunctions.h
Go to the documentation of this file.
1 
11 #ifndef __utlNDArrayFunctions_h
12 #define __utlNDArrayFunctions_h
13 
14 
15 #include "utlCoreMacro.h"
16 #include "utlSTDHeaders.h"
17 #include "utlExpression.h"
18 #include "utlCore.h"
19 #include "utlBlas.h"
20 #include "utlLapack.h"
21 #include "utlMath.h"
22 #include "utlTypeinfo.h"
23 
24 // #include "utlNDArray.h"
25 
29 namespace utl
30 {
31 
32 
33 template < class T, unsigned int Dim >
34 class NDArray;
35 
36 template < class T, unsigned int Dim >
37 class NDArrayBase;
38 
40 template <class T1, class T2, unsigned Dim1, unsigned Dim2>
41 inline bool
42 IsSameShape( const NDArray<T1,Dim1>& arr1, const NDArray<T2,Dim2>& arr2 )
43 {
44  if (Dim1!=Dim2)
45  return false;
46  else
47  return arr1.IsSameShape(arr2);
48 }
49 
50 /**************************************************************************************/
51 /* Conversion */
52 /**************************************************************************************/
53 
54 template <class T, unsigned int Dim, class EType>
57 {
58  NDArray<T,Dim> mat(expr);
59  return mat;
60 }
61 
65 template <class T, unsigned int Dim, class EType>
66 utl_shared_ptr< NDArray<T,Dim> >
68 {
69  utl_shared_ptr< NDArray<T,Dim> > mat(new NDArray<T,Dim>(expr) );
70  return mat;
71 }
72 
74 template <class T, class EType>
75 utl_shared_ptr< NDArray<T,1> >
77 {
78  utl_shared_ptr< NDArray<T,1> > vec (new NDArray<T,1>(expr));
79  return vec;
80 }
81 
83 template <class T, class EType>
84 utl_shared_ptr< NDArray<T,2> >
86 {
87  utl_shared_ptr< NDArray<T,2> > mat(new NDArray<T,2>(expr));
88  return mat;
89 }
90 
91 template <class T>
92 std::vector<T>
94 {
95  std::vector<T> v(vec.Size());
96  for ( int i = 0; i < vec.Size(); i += 1 )
97  v[i] = vec[i];
98  return v;
99 }
100 
101 template <class T>
103 StdVectorToUtlVector ( const std::vector<T>& vec )
104 {
105  utl::NDArray<T,1> v(vec.size());
106  for ( int i = 0; i < vec.size(); ++i )
107  v[i] = vec[i];
108  return v;
109 }
110 
111 
112 template <class T>
115 {
116  utlAssert(in.Columns()==3 || in.Rows()==3, "wrong dimension");
117  NDArray<T,2> out(in);
118  if (in.Columns()==3)
119  {
120  for ( int i = 0; i < in.Rows(); i += 1 )
121  utl::spherical2Cartesian(in(i,0), in(i,1), in(i,2), out(i,0), out(i,1), out(i,2));
122  }
123  else
124  {
125  for ( int i = 0; i < in.Columns(); i += 1 )
126  utl::spherical2Cartesian(in(0,i), in(1,i), in(2,i), out(0,i), out(1,i), out(2,i));
127  }
128  return out;
129 }
130 
131 template <class T>
134 {
135  utlAssert(in.Columns()==3 || in.Rows()==3, "wrong dimension");
136  NDArray<T,2> out(in);
137  if (in.Columns()==3)
138  {
139  for ( int i = 0; i < in.Rows(); i += 1 )
140  utl::cartesian2Spherical(in(i,0), in(i,1), in(i,2), out(i,0), out(i,1), out(i,2));
141  }
142  else
143  {
144  for ( int i = 0; i < in.Columns(); i += 1 )
145  utl::cartesian2Spherical(in(0,i), in(1,i), in(2,i), out(0,i), out(1,i), out(2,i));
146  }
147  return out;
148 }
149 
150 template <class T>
152 FlipOrientations ( const NDArray<T,2>& in, const std::vector<int>& flip )
153 {
154  utlAssert(in.Columns()==3 || in.Rows()==3, "wrong dimension");
155  utlAssert(flip.size()==3, "flip should have 3 elements");
156  NDArray<T,2> out(in);
157  if (in.Columns()==3)
158  {
159  for ( int i = 0; i < in.Rows(); i += 1 )
160  {
161  for ( int j = 0; j < 3; ++j )
162  out(i,j)= flip[j]? -in(i,j) : in(i,j);
163  }
164  }
165  else
166  {
167  for ( int i = 0; i < in.Columns(); i += 1 )
168  {
169  for ( int j = 0; j < 3; ++j )
170  out(j,i)= flip[j]? -in(j,i) : in(j,i);
171  }
172  }
173  return out;
174 }
175 
192 template <class T>
193 inline void
195 {
196  unsigned int const* shape = tensor.GetShape();
197 
198  utlException(shape[0]!=3 || shape[1]!=3 || shape[2]!=3 || shape[3]!=3, "It should be in 3D space");
199 
200  constexpr double s2 = utl::SQRT2;
201  mat.ReSize(6,6);
202 
203  mat(0,0)=tensor(0,0,0,0), mat(0,1)=tensor(0,0,1,1), mat(0,2)=tensor(0,0,2,2), mat(0,3)=s2*tensor(0,0,0,1), mat(0,4)=s2*tensor(0,0,0,2), mat(0,5)=s2*tensor(0,0,1,2);
204  mat(1,0)=tensor(1,1,0,0), mat(1,1)=tensor(1,1,1,1), mat(1,2)=tensor(1,1,2,2), mat(1,3)=s2*tensor(1,1,0,1), mat(1,4)=s2*tensor(1,1,0,2), mat(1,5)=s2*tensor(1,1,1,2);
205  mat(2,0)=tensor(2,2,0,0), mat(2,1)=tensor(2,2,1,1), mat(2,2)=tensor(2,2,2,2), mat(2,3)=s2*tensor(2,2,0,1), mat(2,4)=s2*tensor(2,2,0,2), mat(2,5)=s2*tensor(2,2,1,2);
206  mat(3,0)=s2*tensor(0,1,0,0), mat(3,1)=s2*tensor(0,1,1,1), mat(3,2)=s2*tensor(0,1,2,2), mat(3,3)=2.0*tensor(0,1,0,1), mat(3,4)=2.0*tensor(0,1,0,2), mat(3,5)=2.0*tensor(0,1,1,2);
207  mat(4,0)=s2*tensor(0,2,0,0), mat(4,1)=s2*tensor(0,2,1,1), mat(4,2)=s2*tensor(0,2,2,2), mat(4,3)=2.0*tensor(0,2,0,1), mat(4,4)=2.0*tensor(0,2,0,2), mat(4,5)=2.0*tensor(0,2,1,2);
208  mat(5,0)=s2*tensor(1,2,0,0), mat(5,1)=s2*tensor(1,2,1,1), mat(5,2)=s2*tensor(1,2,2,2), mat(5,3)=2.0*tensor(1,2,0,1), mat(5,4)=2.0*tensor(1,2,0,2), mat(5,5)=2.0*tensor(1,2,1,2);
209 }
210 
211 template <class T>
212 inline void
214 {
215  utlException(mat.Rows()!=6 || mat.Cols()!=6, "Mat should be in 6x6 matrix");
216  tensor.ReSize(3,3,3,3);
217 
218  constexpr double si2 = utl::SQRT1_2;
219 
220  tensor(0,0,0,0)=mat(0,0);
221  tensor(0,0,0,1)=si2*mat(0,3); tensor(0,0,1,0)=tensor(0,0,0,1);
222  tensor(0,0,0,2)=si2*mat(0,4); tensor(0,0,2,0)=tensor(0,0,0,2);
223  tensor(0,0,1,1)=mat(0,1);
224  tensor(0,0,1,2)=si2*mat(0,5); tensor(0,0,2,1)=tensor(0,0,1,2);
225  tensor(0,0,2,2)=mat(0,2);
226  tensor(0,1,0,0)=si2*mat(3,0); tensor(1,0,0,0)=tensor(0,1,0,0);
227  tensor(0,1,0,1)=0.5*mat(3,3); tensor(1,0,0,1)=tensor(0,1,0,1); tensor(0,1,1,0)=tensor(0,1,0,1); tensor(1,0,1,0)=tensor(0,1,0,1);
228  tensor(0,1,0,2)=0.5*mat(3,4); tensor(0,1,2,0)=tensor(0,1,0,2); tensor(1,0,0,2)=tensor(0,1,0,2); tensor(1,0,2,0)=tensor(0,1,0,2);
229  tensor(0,1,1,1)=si2*mat(3,1); tensor(1,0,1,1)=tensor(0,1,1,1);
230  tensor(0,1,1,2)=0.5*mat(3,5); tensor(1,0,1,2)=tensor(0,1,1,2); tensor(0,1,2,1)=tensor(0,1,1,2); tensor(1,0,2,1)=tensor(0,1,1,2);
231  tensor(0,1,2,2)=si2*mat(3,2); tensor(1,0,2,2)=tensor(0,1,2,2);
232  tensor(0,2,0,0)=si2*mat(4,0); tensor(2,0,0,0)=tensor(0,2,0,0);
233  tensor(0,2,0,1)=0.5*mat(4,3); tensor(0,2,1,0)=tensor(0,2,0,1); tensor(2,0,0,1)=tensor(0,2,0,1); tensor(2,0,1,0)=tensor(0,2,0,1);
234  tensor(0,2,0,2)=0.5*mat(4,4); tensor(2,0,0,2)=tensor(0,2,0,2); tensor(0,2,2,0)=tensor(0,2,0,2); tensor(2,0,2,0)=tensor(0,2,0,2);
235  tensor(0,2,1,1)=si2*mat(4,1); tensor(2,0,1,1)=tensor(0,2,1,1);
236  tensor(0,2,1,2)=0.5*mat(4,5); tensor(2,0,1,2)=tensor(0,2,1,2); tensor(0,2,2,1)=tensor(0,2,1,2); tensor(2,0,2,1)=tensor(0,2,1,2);
237  tensor(0,2,2,2)=si2*mat(4,2); tensor(2,0,2,2)=tensor(0,2,2,2);
238  tensor(1,1,0,0)=mat(1,0);
239  tensor(1,1,0,1)=si2*mat(1,3); tensor(1,1,1,0)=tensor(1,1,0,1);
240  tensor(1,1,0,2)=si2*mat(1,4); tensor(1,1,2,0)=tensor(1,1,0,2);
241  tensor(1,1,1,1)=mat(1,1);
242  tensor(1,1,1,2)=si2*mat(1,5); tensor(1,1,2,1)=tensor(1,1,1,2);
243  tensor(1,1,2,2)=mat(1,2);
244  tensor(1,2,0,0)=si2*mat(5,0); tensor(2,1,0,0)=tensor(1,2,0,0);
245  tensor(1,2,0,1)=0.5*mat(5,3); tensor(2,1,0,1)=tensor(1,2,0,1); tensor(1,2,1,0)=tensor(1,2,0,1); tensor(2,1,1,0)=tensor(1,2,0,1);
246  tensor(1,2,0,2)=0.5*mat(5,4); tensor(2,1,0,2)=tensor(1,2,0,2); tensor(1,2,2,0)=tensor(1,2,0,2); tensor(2,1,2,0)=tensor(1,2,0,2);
247  tensor(1,2,1,1)=si2*mat(5,1); tensor(2,1,1,1)=tensor(1,2,1,1);
248  tensor(1,2,1,2)=0.5*mat(5,5); tensor(2,1,1,2)=tensor(1,2,1,2); tensor(1,2,2,1)=tensor(1,2,1,2); tensor(2,1,2,1)=tensor(1,2,1,2);
249  tensor(1,2,2,2)=si2*mat(5,2); tensor(2,1,2,2)=tensor(1,2,2,2);
250  tensor(2,2,0,0)=mat(2,0);
251  tensor(2,2,0,1)=si2*mat(2,3); tensor(2,2,1,0)=tensor(2,2,0,1);
252  tensor(2,2,0,2)=si2*mat(2,4); tensor(2,2,2,0)=tensor(2,2,0,2);
253  tensor(2,2,1,1)=mat(2,1);
254  tensor(2,2,1,2)=si2*mat(2,5); tensor(2,2,2,1)=tensor(2,2,1,2);
255  tensor(2,2,2,2)=mat(2,2);
256 }
257 
258 
259 /**************************************************************************************/
260 /* Print */
261 /**************************************************************************************/
262 
263 template <class T>
264 inline void
265 PrintUtlMatrix(const NDArray<T,2>& mat, const std::string& str="", const char* separate=" ", std::ostream& os=std::cout)
266 {
267  utl::PrintMatrix<NDArray<T,2> >(mat, mat.Rows(), mat.Columns(), str, separate, os);
268 }
269 
270 template <class T>
271 inline void
272 PrintUtlVector(const NDArray<T,1>& vec, const std::string& str="", const char* separate=" ", std::ostream& os=std::cout, bool showStats=true)
273 {
274  PrintContainer(vec.Begin(), vec.End(), str, separate, os, showStats);
275 }
276 
277 template <class T, unsigned int Dim>
278 inline void
279 PrintUtlNDArray(const NDArrayBase<T,Dim>& arr, const std::string& str="", const char* separate=" ", std::ostream& os=std::cout)
280 {
281  arr.Print(os<< str, separate );
282 }
283 
284 template <class T=double>
286 Eye(const int n, const T val=1.0)
287 {
288  utl::NDArray<T,2> mat(n,n);
289  mat.Fill(0.0);
290  mat.FillDiagonal(val);
291  return mat;
292 }
293 
294 template <class T=double>
296 Ones(const int n)
297 {
298  utl::NDArray<T,1> mat(n);
299  mat.Fill(1.0);
300  return mat;
301 }
302 
303 template <class T=double>
305 Ones(const int n, const int m)
306 {
307  utl::NDArray<T,2> mat(n, m);
308  mat.Fill(1.0);
309  return mat;
310 }
311 
312 template< typename T, unsigned int Dim >
313 std::ostream &
314 operator<<(std::ostream & os, const NDArray<T,Dim> & arr)
315 {
316  arr.Print(os<< "utl::NDArray<T,Dim>" );
317  return os;
318 }
319 
320 template< typename T >
321 std::ostream &
322 operator<<(std::ostream & os, const NDArray<T,1> & arr)
323 {
324  utl::PrintContainer(arr.Begin(), arr.End(), "utl::NDArray<T,1>", " ", os);
325  return os;
326 }
327 
328 template< typename T >
329 std::ostream &
330 operator<<(std::ostream & os, const NDArray< T,2 > & arr)
331 {
332  utl::PrintUtlMatrix(arr, "utl::NDArray<T,2>", " ", os);
333  return os;
334 }
335 
336 /**************************************************************************************/
337 /* Blas and Lapack functions */
338 /**************************************************************************************/
339 
361 
362 
382 
424 
425 
448 __utl_syrk_Matrix(T, syrk_UtlMatrix, Utl, utl::NDArray<T UTL_COMMA 2>, Rows, Cols, GetData, ReSize);
449 
477 
488 
498 template <class T> inline void
499 syev_UtlMatrix ( const NDArray<T,2>& mat, NDArray<T,1>& eigenValues, NDArray<T,2>& eigenVectors)
500 {
501  utlException(mat.Rows()!=mat.Cols(), "The matrix should be symmetric");
502  char JOBZ='V', UPLO='U';
503  int N = mat.Rows(),INFO=0, LWORK=-1;
504 
505  eigenVectors = mat;
506  eigenValues.ReSize(N);
507 
508  // T query;
509  // utl::syev<T>(&JOBZ,&UPLO,&N,eigenVectors.GetData(), &N, eigenValues.GetData(),&query,&LWORK,&INFO);
510  // LWORK=static_cast<int>(query);
511 
512  // T *const WORK = new T[LWORK];
513  // utl::syev<T>(&JOBZ,&UPLO,&N,eigenVectors.GetData(), &N, eigenValues.GetData(),WORK,&LWORK,&INFO);
514  // delete[] WORK;
515 
516  INFO = utl::syev<T>(LAPACK_COL_MAJOR, JOBZ,UPLO,N,eigenVectors.GetData(), N, eigenValues.GetData());
517  utlGlobalException(INFO, "LAPACK library function dsyev_() returned error code INFO=" << INFO);
518 }
519 
529 template <class T> inline void
530 syevd_UtlMatrix ( const NDArray<T,2>& mat, NDArray<T,1>& eigenValues, NDArray<T,2>& eigenVectors)
531 {
532  utlException(mat.Rows()!=mat.Cols(), "The matrix should be symmetric");
533  char JOBZ='V', UPLO='U';
534  int N = mat.Rows(),INFO=0, LWORK=-1, LIWORK=-1;
535 
536  eigenVectors = mat;
537  eigenValues.ReSize(N);
538 
539  // T query;
540  // int queryI;
541  // utl::syevd<T>(&JOBZ,&UPLO,&N,eigenVectors.GetData(), &N, eigenValues.GetData(),&query,&LWORK,&queryI,&LIWORK,&INFO);
542  // LWORK=static_cast<int>(query);
543  // LIWORK=static_cast<int>(queryI);
544 
545  // T *const WORK = new T[LWORK];
546  // int *const IWORK = new int[LIWORK];
547  // utl::syevd<T>(&JOBZ,&UPLO,&N,eigenVectors.GetData(), &N, eigenValues.GetData(),WORK,&LWORK,IWORK,&LIWORK,&INFO);
548  // delete[] WORK;
549  // delete[] IWORK;
550 
551  INFO = utl::syevd<T>(LAPACK_COL_MAJOR, JOBZ,UPLO,N,eigenVectors.GetData(), N, eigenValues.GetData());
552  utlGlobalException(INFO, "LAPACK library function dsyevd_() returned error code INFO=" << INFO);
553 }
554 
555 
565 template <class T> inline void
566 gesvd_UtlMatrix(const NDArray<T,2>& mat, NDArray<T,2>& U, NDArray<T,1>& s, NDArray<T,2>& V, char format='S' )
567 {
568  utlException(format!='S' && format!='A', "wrong format. format should be 'A' or 'S' ");
569  int M=mat.Rows(), N=mat.Cols(), INFO=0;
570  int min_MN = utl::min(M,N), LDVT;
571  s.ReSize(min_MN);
572  if (format=='S')
573  {
574  U.ReSize(min_MN, M);
575  V.ReSize(N, min_MN);
576  LDVT = min_MN;
577  }
578  else
579  {
580  U.ReSize(M, M);
581  V.ReSize(N, N);
582  LDVT = N;
583  }
584  char formatU=format, formatV=format;
585  int LDA=M, LDU=M, LWORK=-1;
586  NDArray<T,2> matTmp;
587  matTmp = mat.GetTranspose();
588 
589  // T query;
590  // utl::gesvd<T>(&formatU, &formatV, &M, &N, matTmp.GetData(), &LDA, s.GetData(), U.GetData(), &LDU, V.GetData(), &LDVT, &query, &LWORK, &INFO);
591  // LWORK=static_cast<int>(query);
592 
593  // T* WORK = new T[LWORK];
594  // // dgesdd_(&format, &M, &N, matTmp.GetData(), &LDA, s.GetData(), U.GetData(), &LDU, V.GetData(), &LDVT, WORK, &LWORK, IWORK, &INFO);
595  // utl::gesvd<T>(&formatU, &formatV, &M, &N, matTmp.GetData(), &LDA, s.GetData(), U.GetData(), &LDU, V.GetData(), &LDVT, WORK, &LWORK, &INFO);
596  // delete[] WORK;
597 
598  T* superb = new T[min_MN];
599  INFO=utl::gesvd<T>(LAPACK_COL_MAJOR, formatU, formatV, M, N, matTmp.GetData(), LDA, s.GetData(), U.GetData(), LDU, V.GetData(), LDVT, superb);
600  delete[] superb;
601  U = U.GetTranspose();
602  // U.TransposeInplace();
603 
604  utlGlobalException(INFO, "LAPACK library function dgesvd_() returned error code INFO=" << INFO);
605 }
606 
619 template <class T> inline void
621 {
622  utlException(format!='S' && format!='A', "wrong format. format should be 'A' or 'S' ");
623  int M=mat.Rows(), N=mat.Cols(), INFO=0;
624  int min_MN = utl::min(M,N), LDVT;
625  s.ReSize(min_MN);
626  if (format=='S')
627  {
628  U.ReSize(min_MN, M);
629  V.ReSize(N, min_MN);
630  LDVT = min_MN;
631  }
632  else
633  {
634  U.ReSize(M, M);
635  V.ReSize(N, N);
636  LDVT = N;
637  }
638  char formatU=format, formatV=format;
639  int LDA=M, LDU=M, LWORK;
640  NDArray<T,2> matTmp;
641  matTmp = mat.GetTranspose();
642 
643  // int* IWORK = new int[8*min_MN];
644  // T query;
645  // LWORK=-1;
646  // utl::gesdd<T>(&format, &M, &N, matTmp.GetData(), &LDA, s.GetData(), U.GetData(), &LDU, V.GetData(), &LDVT, &query, &LWORK, IWORK, &INFO);
647  // // dgesvd_(&formatU, &formatV, &M, &N, matTmp.GetData(), &LDA, s.GetData(), U.GetData(), &LDU, V.GetData(), &LDVT, &query, &LWORK, &INFO);
648  // LWORK=static_cast<int>(query);
649 
650  // // LWORK = min_MN*(6+4*min_MN)+utl::max(M,N);
651  // T* WORK = new T[LWORK];
652  // utl::gesdd<T>(&format, &M, &N, matTmp.GetData(), &LDA, s.GetData(), U.GetData(), &LDU, V.GetData(), &LDVT, WORK, &LWORK, IWORK, &INFO);
653  // // dgesvd_(&formatU, &formatV, &M, &N, matTmp.GetData(), &LDA, s.GetData(), U.GetData(), &LDU, V.GetData(), &LDVT, WORK, &LWORK, &INFO);
654  // delete[] WORK;
655  // delete[] IWORK;
656 
657  INFO=utl::gesdd(LAPACK_COL_MAJOR, format, M, N, matTmp.GetData(), LDA, s.GetData(), U.GetData(), LDU, V.GetData(), LDVT);
658  U = U.GetTranspose();
659  // U.TransposeInplace();
660 
661  utlGlobalException(INFO, "LAPACK library function dgesdd_() returned error code INFO=" << INFO);
662 }
663 
664 /**************************************************************************************/
665 /* Products */
666 /**************************************************************************************/
667 
672 template <class T, unsigned int Dim>
673 inline T
675 {
676  utlSAException(v1.Size() != v2.Size())(v1.Size())(v2.Size()).msg("vector sizes mismatch");
677  return utl::cblas_dot<T>(v1.Size(), v1.GetData(), 1, v2.GetData(), 1);
678 }
679 
681 template <class T, unsigned int Dim>
682 inline T
683 DotProduct ( const NDArray<T,Dim>& v1, const NDArray<T,Dim>& v2 )
684 {
685  utlSAException(v1.Size() != v2.Size())(v1.Size())(v2.Size()).msg("vector sizes mismatch");
686  return InnerProduct(v1, v2);
687 }
688 
689 template <unsigned int Dim>
690 inline std::complex<double>
691 DotProduct( const NDArray<std::complex<double>,Dim>& v1, const NDArray<std::complex<double>,Dim>& v2 )
692 {
693  utlSAException(v1.Size() != v2.Size())(v1.Size())(v2.Size()).msg("vector sizes mismatch");
694  std::complex<double> result;
695  cblas_zdotu_sub(v1.Size(),v1.GetData(),1,v2.GetData(),1, &result);
696  return result;
697 }
698 
699 template <class T>
700 inline void
701 InnerProduct ( const NDArray<T,2>& mat, const NDArray<T,1>& vec, NDArray<T, 1>& result )
702 {
703  utlSAException(vec.Size()!=mat.Cols())(mat.Cols())(vec.Size()).msg("wrong size");
704  utl::ProductUtlMv(mat, vec, result);
705 }
706 
707 template <class T>
708 inline void
709 InnerProduct ( const NDArray<T,1>& vec, const NDArray<T,2>& mat, NDArray<T, 1>& result )
710 {
711  utlSAException(vec.Size()!=mat.Rows())(mat.Rows())(vec.Size()).msg("wrong size");
712  utl::ProductUtlvM(vec, mat, result);
713 }
714 
715 template <class T>
716 inline void
717 InnerProduct ( const NDArray<T,4>& tensor, const NDArray<T,2>& matrix, NDArray<T, 2>& result )
718 {
719  unsigned int const* shapeT = tensor.GetShape();
720  unsigned int const* shapeM = matrix.GetShape();
721  utlSAException(shapeT[2]!=shapeM[0] || shapeT[3]!=shapeM[1])
722  (shapeT[2])(shapeM[0])(shapeT[3])(shapeM[1]).msg("sizes do not match");
723 
724  result.ReSize(shapeT[0], shapeT[1]);
725 
726  NDArray<T,2> mat;
727  int nn=0;
728  for ( int i = 0; i < shapeT[0]; ++i )
729  {
730  for ( int j = 0; j < shapeT[1]; ++j )
731  {
732  mat = tensor.GetRefSubMatrix(i, j);
733  result[nn] = utl::InnerProduct(mat, matrix);
734  nn++;
735  }
736  }
737 }
738 
739 
740 template <class T>
741 inline void
742 InnerProduct ( const NDArray<T,2>& matrix, const NDArray<T,4>& tensor, NDArray<T, 2>& result )
743 {
744  unsigned int const* shapeT = tensor.GetShape();
745  unsigned int const* shapeM = matrix.GetShape();
746  utlSAException(shapeT[0]!=shapeM[0] || shapeT[1]!=shapeM[1])
747  (shapeT[0])(shapeM[0])(shapeT[1])(shapeM[1]).msg("sizes do not match");
748 
749  result.ReSize(shapeT[2], shapeT[3]);
750 
751  int nn=0;
752  for ( int k = 0; k < shapeT[2]; ++k )
753  {
754  for ( int l = 0; l < shapeT[3]; ++l )
755  {
756  result[nn]=0;
757  int off=0;
758  for ( int i = 0; i < shapeT[0]; ++i )
759  {
760  for ( int j = 0; j < shapeT[1]; ++j )
761  {
762  result[nn] += tensor(i,j,k,l) * matrix[off];
763  off++;
764  }
765  }
766  nn++;
767  }
768  }
769 }
770 
771 template <class T>
772 inline void
773 OuterProduct ( const NDArrayBase<T,2>& mat1, const NDArrayBase<T,2>& mat2, NDArray<T, 4>& tensor )
774 {
775  unsigned size[4];
776  unsigned const* shape1 = mat1.GetShape();
777  unsigned const* shape2 = mat2.GetShape();
778  size[0]=shape1[0], size[1]=shape1[1];
779  size[2]=shape2[0], size[3]=shape2[1];
780  tensor.ReSize(size);
781 
782  int off1=0;
783  int off0=0;
784  for ( int i = 0; i < size[0]; ++i )
785  {
786  for ( int j = 0; j < size[1]; ++j )
787  {
788  int off2=0;
789  for ( int k = 0; k < size[2]; ++k )
790  {
791  for ( int l = 0; l < size[3]; ++l )
792  {
793  tensor[off0] = mat1[off1] * mat2[off2];
794  off2++;
795  off0++;
796  }
797  }
798  off1++;
799  }
800  }
801 }
802 
803 template <class T>
804 void
805 OuterProduct ( const NDArray<T,1>& v1, const NDArray<T,1>& v2, NDArray<T,2>& mat )
806 {
807  bool isComplex = std::is_same<T, std::complex<double>>::value ||std::is_same<T, std::complex<float>>::value;
808  mat.ReSize(v1.Size(), v2.Size());
809  for ( int i = 0; i < v1.Size(); ++i )
810  for ( int j = 0; j < v2.Size(); ++j )
811  {
812  if (isComplex)
813  mat(i,j) = v1[i]*std::conj(v2[j]);
814  else
815  mat(i,j) = v1[i]*v2[j];
816  }
817 }
818 
819 // use CrossProduct in utlMath.h
820 // template <class T>
821 // void
822 // CrossProduct ( const NDArray<T,1>& v1, const NDArray<T,1>& v2, NDArray<T,1>& v3 )
823 // {
824 // utlException(v1.Size()!=3, "wrong size");
825 // utlException(v2.Size()!=3, "wrong size");
826 // v3.ReSize(3);
827 // v3[0]=v1[1]*v2[2] - v1[2]*v2[1];
828 // v3[1]=v1[2]*v2[0] - v1[0]*v2[2];
829 // v3[2]=v1[0]*v2[1] - v1[1]*v2[0];
830 // }
831 
832 template <class T>
835 {
836  double norm1, norm2;
837  utl::NDArray<T,1> tmp1, tmp2;
838  tmp1 = v1-v0; norm1 = tmp1.GetTwoNorm();
839  tmp2 = v1+v0; norm2 = tmp2.GetTwoNorm();
840  if (norm1 > norm2)
841  return tmp2;
842  else
843  return tmp1;
844 }
845 
846 template< typename T >
847 inline NDArray<T,2>
848 operator*(const NDArray<T,2>& mat1, const NDArray<T,2>& mat2)
849 {
850  utlSAException(mat1.Cols()!=mat2.Rows())(mat1.Cols())(mat2.Rows()).msg("wrong size");
851  NDArray<T,2> result;
852  utl::ProductUtlMM(mat1, mat2, result);
853  return result;
854 }
855 
856 template<typename T>
857 inline NDArray<std::complex<T>,2>
858 operator*(const NDArray<T,2>& mat1, const NDArray<std::complex<T>,2>& mat2)
859 {
860  utlSAException(mat1.Cols()!=mat2.Rows())(mat1.Cols())(mat2.Rows()).msg("wrong size");
861  NDArray<std::complex<T>,2> result, tmp;
862  tmp=mat1;
863  utl::ProductUtlMM(tmp, mat2, result);
864  return result;
865 }
866 
867 template<typename T>
868 inline NDArray<std::complex<T>,2>
869 operator*(const NDArray<std::complex<T>,2>& mat1, const NDArray<T,2>& mat2)
870 {
871  utlSAException(mat1.Cols()!=mat2.Rows())(mat1.Cols())(mat2.Rows()).msg("wrong size");
872  NDArray<std::complex<T>,2> result, tmp;
873  tmp=mat2;
874  utl::ProductUtlMM(mat1, tmp, result);
875  return result;
876 }
877 
878 template< typename T >
879 inline NDArray<T,1>
880 operator*(const NDArray<T,2>& mat, const NDArray<T,1>& vec)
881 {
882  utlSAException(vec.Size()!=mat.Cols())(mat.Cols())(vec.Size()).msg("wrong size");
883  NDArray<T,1> result;
884  utl::ProductUtlMv(mat, vec, result);
885  return result;
886 }
887 
888 template< typename T >
889 inline NDArray<T,1>
890 operator*(const NDArray<T,1>& vec, const NDArray<T,2>& mat)
891 {
892  utlSAException(vec.Size()!=mat.Rows())(mat.Rows())(vec.Size()).msg("wrong size");
893  NDArray<T,1> result;
894  utl::ProductUtlvM(vec, mat, result);
895  return result;
896 }
897 
898 template<typename T, typename EType >
899 inline NDArray<T,1>
901 {
902  utl_shared_ptr<NDArray<T,2> > mat = ToMatrix<T>(expr);
903  return vec* (*mat);
904 }
905 
908 template <class T>
909 inline NDArray<T,2>
910 InverseMatrix( const NDArray<T,2>& mat, const double eps=1e-10 )
911 {
912  utlSAException(mat.Rows()!=mat.Cols())(mat.Rows())(mat.Cols()).msg("the matrix should be symmetric");
913  int n = mat.Rows();
914  NDArray<T,2> result(n,n);
915  utlException(n==0, "matrix cannot be empty");
916  if (n>=1 && n <=4)
917  {
918  utl::InverseSmallMatrix(mat, result, n);
919  }
920  else
921  {
922  getri_UtlMatrix(mat, result);
923  }
924  return result;
925 }
926 
929 template <class T>
930 inline NDArray<T,2>
931 InverseSymmericMatrix( const NDArray<T,2>& mat, const double eps=1e-10 )
932 {
933  utlSAException(mat.Rows()!=mat.Cols())(mat.Rows())(mat.Cols()).msg("the matrix should be symmetric");
934  int n = mat.Rows();
935  NDArray<T,2> result;
936  if (n<=4)
937  result = InverseMatrix(mat, eps);
938  else
939  {
940  result = mat;
941  char uplo='U';
942  int lwork=-1, INFO=0;
943  int* ipiv= new int[n];
944 
945  // T *query, *work;
946  // query = new T[1];
947  // utl::sytrf<T>(&uplo,&n,result.GetData(),&n,ipiv,query,&lwork,&INFO);
948  // lwork=static_cast<INTT>(*query);
949  // delete[] query;
950  // work = new T[lwork];
951  // utl::sytrf<T>(&uplo,&n,result.GetData(),&n,ipiv,work,&lwork,&INFO);
952  // delete[] work;
953  // work = new T[2*n];
954  // utl::sytri<T>(&uplo,&n,result.GetData(),&n,ipiv,work,&INFO);
955  // delete[] work;
956 
957  utl::sytrf<T>(LAPACK_COL_MAJOR, uplo,n,result.GetData(),n,ipiv);
958  INFO=utl::sytri<T>(LAPACK_COL_MAJOR, uplo,n,result.GetData(),n,ipiv);
959  delete[] ipiv;
960 
961  utlGlobalException(INFO>0, "The matrix is singular and its inverse could not be computed. \
962  LAPACK library function sytrid_() returned error code INFO=" << INFO);
963  utlGlobalException(INFO<0, "LAPACK library function sytrid_() returned error code INFO=" << INFO);
964 
965  T* data = result.GetData();
966  for ( int i = 0; i < n; ++i )
967  for ( int j = 0; j < i; ++j )
968  data[j*n+i] = data[i*n+j];
969  }
970  return result;
971 }
972 
975 template <class T>
976 inline NDArray<T,2>
977 PInverseSymmericMatrix( const NDArray<T,2>& mat, const double eps=1e-10 )
978 {
979  utlSAException(mat.Rows()!=mat.Cols())(mat.Rows())(mat.Cols()).msg("the matrix should be symmetric");
980  int N = mat.Rows();
981  NDArray<T,2> result;
982  NDArray<T,2> eigenVectors, tmp, S(N,N,0.0);
983  NDArray<T,1> eigenValues, v;
984  mat.EigenDecompositionSymmetricMatrix(eigenValues, eigenVectors);
985  for (unsigned i=0; i<N; ++i)
986  {
987  if ( std::abs(eigenValues[i])>eps )
988  S(i,i) = 1.0/eigenValues[i];
989  else
990  S(i,i)=0.0;
991  }
992  utl::ProductUtlMtM(eigenVectors, S, tmp);
993  utl::ProductUtlMM(tmp, eigenVectors, result);
994  return result;
995 }
996 
998 template <class T>
999 inline NDArray<T,2>
1000 PInverseMatrix( const NDArray<T,2>& mat, const double eps=1e-10 )
1001 {
1002  NDArray<T,2> U,V, tmp, result;
1003  NDArray<T,1> uVec, vVec;
1005  mat.SVD(U, S, V, 'S');
1006 
1007  NDArray<T,2> diag(S.Size(), S.Size(),0.0);
1008  for ( int i = 0; i < S.Size(); i += 1 )
1009  {
1010  if ( std::abs(S[i])>eps )
1011  diag(i,i) = 1.0/S[i];
1012  else
1013  diag(i,i) = 0.0;
1014  }
1015  utl::ProductUtlMM(V, diag, tmp);
1016  utl::ProductUtlMMt(tmp, U, result);
1017  return result;
1018 }
1019 
1020 template <class T>
1022 ConnectUtlVector ( const NDArray<T,1>& m1, const NDArray<T,1>& m2 )
1023 {
1024  NDArray<T,1> result(m1.Size()+m2.Size());
1025  int m1Size = m1.Size();
1026  for ( int i = 0; i < m1Size; i += 1 )
1027  result[i] = m1[i];
1028  for ( int i = 0; i < m2.Size(); i += 1 )
1029  result[i+m1Size] = m2[i];
1030  return result;
1031 }
1032 
1033 template <class T>
1035 ConnectUtlMatrix ( const NDArray<T,2>& m1, const NDArray<T,2>& m2, const bool isConnectRow )
1036 {
1037  if (isConnectRow)
1038  {
1039  utlException(m1.Columns()!=m2.Columns(), "wrong column size! m1.Columns()="<<m1.Columns()<<", m2.Columns()"<<m2.Columns());
1040  NDArray<T,2> result(m1.Rows()+m2.Rows(), m1.Columns());
1041  int m1Rows = m1.Rows();
1042  for ( int j = 0; j < m1.Columns(); j += 1 )
1043  {
1044  for ( int i = 0; i < m1.Rows(); i += 1 )
1045  result(i,j) = m1(i,j);
1046  for ( int i = 0; i < m2.Rows(); i += 1 )
1047  result(i+m1Rows,j) = m2(i,j);
1048  }
1049  return result;
1050  }
1051  else
1052  {
1053  utlException(m1.Rows()!=m2.Rows(), "wrong row size! m1.Rows()="<<m1.Rows()<<", m2.Rows()"<<m2.Rows());
1054  NDArray<T,2> result(m1.Rows(), m1.Columns()+m2.Columns());
1055  int m1Columns = m1.Columns();
1056  for ( int i = 0; i < m1.Rows(); i += 1 )
1057  {
1058  for ( int j = 0; j < m1.Columns(); j += 1 )
1059  result(i,j) = m1(i,j);
1060  for ( int j = 0; j < m2.Columns(); j += 1 )
1061  result(i,j+m1Columns) = m2(i,j);
1062  }
1063  return result;
1064  }
1065 }
1066 
1067 template <class T, unsigned Dim>
1069 Real ( const NDArray<std::complex<T>, Dim >& mat )
1070 {
1071  NDArray<T, Dim> result(mat.GetShape());
1072  for ( int i = 0; i < mat.Size(); ++i )
1073  result[i] = std::real(mat[i]);
1074  return result;
1075 }
1076 
1077 template <class T, unsigned Dim>
1079 Imag ( const NDArray<std::complex<T>, Dim >& mat )
1080 {
1081  NDArray<T, Dim> result(mat.GetShape());
1082  for ( int i = 0; i < mat.Size(); ++i )
1083  result[i] = std::imag(mat[i]);
1084  return result;
1085 }
1086 
1087 
1089 template <class T, unsigned Dim>
1091 ComplexCombine ( const NDArray<T,Dim>& arrReal, const NDArray<T,Dim>& arrImg )
1092 {
1093  utlException(!IsSameShape(arrReal, arrImg), "should have the same shape");
1094  typedef std::complex<T> VT;
1095  NDArray<VT, Dim> result(arrReal.GetShape());
1096  for ( int i = 0; i < result.Size(); ++i )
1097  result[i] = VT(arrReal[i], arrImg[i]);
1098  return result;
1099 }
1100 
1102 template <class T, unsigned Dim>
1103 NDArray<std::complex<T>, Dim>
1104 ComplexCombine ( const T val, const NDArray<T,Dim>& arrImg )
1105 {
1106  typedef std::complex<T> VT;
1107  NDArray<VT, Dim> result(arrImg.GetShape());
1108  for ( int i = 0; i < result.Size(); ++i )
1109  result[i] = VT(val, arrImg[i]);
1110  return result;
1111 }
1112 
1114 template <class T, unsigned Dim>
1115 NDArray<std::complex<T>, Dim>
1116 ComplexCombine ( const NDArray<T,Dim>& arrReal, const T val )
1117 {
1118  typedef std::complex<T> VT;
1119  NDArray<VT, Dim> result(arrReal.GetShape());
1120  for ( int i = 0; i < result.Size(); ++i )
1121  result[i] = VT(arrReal[i], val);
1122  return result;
1123 }
1124 
1125 
1126 template <class T>
1127 void
1128 GetEqualityConstraintProjection ( const NDArray<T,2>& Aeq, const NDArray<T,1>& beq, const NDArray<T,2>& QInverse,
1129  NDArray<T,2>& projMatrix, NDArray<T,1>& projVector )
1130 {
1131  int n = QInverse.Rows();
1132  utlException(Aeq.Rows()!=n, "wrong size! Aeq.rows()="<<Aeq.Rows()<<", n="<<n);
1133  NDArray<T,2> AeqT=Aeq.GetTranspose();
1134  projMatrix.ReSize(n,n);
1135  projMatrix.SetIdentity();
1136  NDArray<T,2> tmp, tmp2, tmp3;
1137  ProductUtlMM(AeqT, QInverse, Aeq, tmp2);
1138  tmp = PInverseSymmericMatrix(tmp2);
1139  ProductUtlMM( QInverse, Aeq, tmp, tmp2);
1140  ProductUtlMM( tmp2, AeqT, tmp3);
1141  projMatrix -= tmp3;
1142 
1143  ProductUtlMv( tmp2, beq, projVector);
1144 }
1145 
1151 template <class T>
1153 GetMeanOfRotationMatrix(const std::vector<NDArray<T,2> >& matrixVec, const utl::NDArray<T,1>& weights)
1154 {
1155  int N = matrixVec.size();
1156  utlSAException(N==0)(N).msg("wrong size");
1157  utlSAException(weights.Size()!=N)(N)(weights.Size()).msg("wrong size");
1158 
1159  NDArray<T,2> mat(3,3), tangentVec(3,3), matTmp(3,3);
1160  mat.Fill(0.0);
1161  mat.FillDiagonal(1.0);
1162 
1163  double eps=1e-4;
1164  double normVec=1.0;
1165 
1166  do
1167  {
1168  tangentVec.Fill(0.0);
1169  for ( int i = 0; i < N; ++i )
1170  {
1171  utl::ProductUtlMtM(mat, matrixVec[i], matTmp);
1172  matTmp = matTmp.LogM() ;
1173  tangentVec += matTmp % weights[i];
1174  }
1175 
1176  mat = mat * tangentVec.ExpM();
1177  normVec = tangentVec.GetTwoNorm();
1178  } while ( normVec>eps );
1179 
1180  return mat;
1181 }
1182 
1183 template <class T>
1185 GetMeanOfRotationMatrix(const std::vector<NDArray<T,2> >& matrixVec)
1186 {
1187  int N = matrixVec.size();
1188  utlSAException(N==0)(N).msg("wrong size");
1189  utl::NDArray<T,1> weights(N, 1.0/N);
1190  GetMeanOfRotationMatrix(matrixVec, weights);
1191 }
1192 
1199 template <class T>
1200 void
1201 RotationMatrixToAxisAngle(const NDArray<T,2>& rotMat, NDArray<T,1>& axis, double& theta)
1202 {
1203  utlSAException(rotMat.Rows()!=3 || rotMat.Cols()!=3)
1204  (rotMat.Rows())(rotMat.Cols()).msg("wrong size of rotMat");
1205  axis.ReSize(3);
1206 
1207  theta = std::acos((rotMat(0,0)+rotMat(1,1)+rotMat(2,2)-1.0)/2.0);
1208  // double thetaSin = std::sin(theta);
1209 
1210  axis[0]= rotMat(2,1)-rotMat(1,2);
1211  axis[1]= rotMat(0,2)-rotMat(2,0);
1212  axis[2]= rotMat(1,0)-rotMat(0,1);
1213 
1214  double normAxis = axis.GetTwoNorm();
1215  if (normAxis>1e-3)
1216  axis /= normAxis;
1217  else
1218  {
1219  NDArray<T,2> U, V, matTmp=utl::Eye<T>(3)-rotMat;
1220  NDArray<T,1> S;
1221  matTmp.SVD(U, S, V);
1222  axis = V.GetColumn(2);
1223  }
1224 }
1225 
1232 template <class T>
1233 void
1234 AxisAngleToRotationMatrix(const NDArray<T,1>& axis, const double theta, NDArray<T,2>& rotMat)
1235 {
1236  NDArray<T,1> v(axis);
1237  double norm = v.GetTwoNorm();
1238  utlException(norm<1e-8, "norm is too small");
1239  v /= norm;
1240 
1241  double c=std::cos(theta), s=std::sin(theta);
1242  double t=1.0-c;
1243 
1244  rotMat.ReSize(3,3);
1245  rotMat(0,0) = t*v[0]*v[0] + c; rotMat(0,1) = t*v[0]*v[1] - v[2]*s; rotMat(0,2) = t*v[0]*v[2] + v[1]*s;
1246  rotMat(1,0) = t*v[0]*v[1] + v[2]*s; rotMat(1,1) = t*v[1]*v[1] + c; rotMat(1,2) = t*v[1]*v[2] - v[0]*s;
1247  rotMat(2,0) = t*v[0]*v[2] - v[1]*s; rotMat(2,1) = t*v[1]*v[2] + v[0]*s; rotMat(2,2) = t*v[2]*v[2] + c;
1248 }
1250 template <class T>
1252 MeanDirector ( const std::vector<utl::NDArray<T,1> >& dirVec, const bool isUnitNorm=true)
1253 {
1254  int N = dirVec.size();
1255  utlException(N==0, "empty dirVec");
1256 
1257  int dim = dirVec[0].Size();
1258  utl::NDArray<T,2> mat(dim, dim), eigenVectors, matTmp;
1259  utl::NDArray<T,1> dir, eigenValues, meanV(dim);
1260  mat.Fill(0.0);
1261  for ( int i = 0; i < N; ++i )
1262  {
1263  dir = dirVec[i];
1264  utlSAException(dir.Size()!=dim)(dim)(dir.Size()).msg("wrong size of dir");
1265  utl::OuterProduct(dir, dir, matTmp);
1266  mat += matTmp;
1267  }
1268 
1269  if (mat.GetTwoNorm()>1e-10)
1270  {
1271  mat.EigenDecompositionSymmetricMatrix(eigenValues, eigenVectors);
1272  meanV = eigenVectors.GetRow(dim-1);
1273  if (isUnitNorm)
1274  return meanV;
1275  else
1276  return meanV % eigenValues[dim-1];
1277  }
1278  else
1279  {
1280  meanV.Fill(0.0);
1281  return meanV;
1282  }
1283 }
1284 
1285 }
1286 
1289 #endif
NDArray is a N-Dimensional array class (row-major, c version)
Definition: utlFunctors.h:131
void InverseSmallMatrix(const TMatrixType &mat, TMatrixType &result, const int row)
Definition: utlMath.h:1213
NDArray<T,1> is a vector class which uses blas mkl.
Definition: utlVector.h:36
void PrintContainer(IteratorType v1, IteratorType v2, const std::string &str="", const char *separate=" ", std::ostream &os=std::cout, bool showStats=true)
Definition: utlCore.h:1068
bool gemm_UtlMatrixTimesMatrix(const bool bATrans, const bool bBTrans, const T alpha, const utl::NDArray< T, 2 > &A, const utl::NDArray< T, 2 > &B, const T beta, utl::NDArray< T, 2 > &C)
typename remove_complex< T >::type remove_complex_t
Definition: utlTypeinfo.h:67
#define __utl_geev_Matrix(T, FuncName, RowMajorMatrixName, GetRowsFuncName, GetColsFuncName, MatrixGetDataFuncName, VectorName, VectorGetDataFuncName, ReSizeFuncName)
geev_VnlMatrix Calculate non-symmetric eigen-decomposition. Define 3 functions. 1) calculate only eig...
Definition: utlLapack.h:355
bool IsSameShape(const NDArray< T1, Dim1 > &arr1, const NDArray< T2, Dim2 > &arr2)
void GetRow(const int index, T *vec) const
Definition: utlMatrix.h:266
utl::NDArray< T, 2 > GetMeanOfRotationMatrix(const std::vector< NDArray< T, 2 > > &matrixVec, const utl::NDArray< T, 1 > &weights)
base class for expression
Definition: utlExpression.h:36
bool ReSize(const SizeType s0, const SizeType s1, const SizeType s2, const SizeType s3)
Created "07-04-2016.
void syevd_UtlMatrix(const NDArray< T, 2 > &mat, NDArray< T, 1 > &eigenValues, NDArray< T, 2 > &eigenVectors)
dsyevd_UtlMatrix eigen-decomposition for symmetric matrix. dsyevd is faster than dsyev http://www...
NDArray< T, 2 > operator*(const NDArray< T, 2 > &mat1, const NDArray< T, 2 > &mat2)
void Print(std::ostream &os, const char *separate=" ") const
Definition: utlNDArray.h:1135
NDArray< T, 2 > SetIdentity()
Definition: utlMatrix.h:181
bool IsSameShape(const EType &src) const
Definition: utlNDArray.h:771
void gesdd_UtlMatrix(const NDArray< T, 2 > &mat, NDArray< T, 2 > &U, NDArray< utl::remove_complex_t< T >, 1 > &s, NDArray< T, 2 > &V, char format='S')
dgesdd_UtlMatrix dgesdd is faster than dgesvd. http://www.netlib.org/lapack/explore-html/db/db4/dgesd...
void Convert4To2Tensor(const utl::NDArray< T, 4 > &tensor, utl::NDArray< T, 2 > &mat)
Iterator Begin()
Definition: utlNDArray.h:582
void PrintUtlNDArray(const NDArrayBase< T, Dim > &arr, const std::string &str="", const char *separate=" ", std::ostream &os=std::cout)
void PrintUtlMatrix(const NDArray< T, 2 > &mat, const std::string &str="", const char *separate=" ", std::ostream &os=std::cout)
void SVD(NDArray< T, 2 > &U, NDArray< ScalarValueType, 1 > &S, NDArray< T, 2 > &V, char format='S') const
SVD.
Definition: utlMatrix.h:378
NDArray< T, 2 > ConnectUtlMatrix(const NDArray< T, 2 > &m1, const NDArray< T, 2 > &m2, const bool isConnectRow)
static constexpr double SQRT1_2
Definition: utlConstants.h:33
SizeType Columns() const
Definition: utlMatrix.h:137
#define utlException(cond, expout)
Definition: utlCoreMacro.h:548
NDArray< T, 2 > GetTranspose(const T scale=1.0) const
Definition: utlMatrix.h:205
void spherical2Cartesian(const T r, const T theta, const T phi, T &x, T &y, T &z)
Definition: utlCore.h:1602
SizeType Rows() const
Definition: utlMatrix.h:136
NDArray< T, 1 > DifferenceOfDirection(const NDArray< T, 1 > v1, const NDArray< T, 1 > &v0)
NDArray<T,2> is a row-major matrix.
Definition: utlMatrix.h:37
double GetTwoNorm() const
Definition: utlNDArray.h:1013
void RotationMatrixToAxisAngle(const NDArray< T, 2 > &rotMat, NDArray< T, 1 > &axis, double &theta)
NDArray< T, 1 > StdVectorToUtlVector(const std::vector< T > &vec)
NDArray< T, 2 > CartesianToSpherical(const NDArray< T, 2 > &in)
NDArray< T, 2 > FlipOrientations(const NDArray< T, 2 > &in, const std::vector< int > &flip)
NDArray< T, 2 > PInverseSymmericMatrix(const NDArray< T, 2 > &mat, const double eps=1e-10)
void gesvd_UtlMatrix(const NDArray< T, 2 > &mat, NDArray< T, 2 > &U, NDArray< T, 1 > &s, NDArray< T, 2 > &V, char format='S')
dgesvd_UtlMatrix
void AxisAngleToRotationMatrix(const NDArray< T, 1 > &axis, const double theta, NDArray< T, 2 > &rotMat)
const T & min(const T &a, const T &b)
Return the minimum between a and b.
Definition: utlCore.h:257
void ProductUtlvM(const utl::NDArray< T, 1 > &b, const utl::NDArray< T, 2 > &A, utl::NDArray< T, 1 > &c, const double alpha=1.0, const double beta=0.0)
utl::NDArray< T, 1 > Ones(const int n)
utl::NDArray< T, 1 > MeanDirector(const std::vector< utl::NDArray< T, 1 > > &dirVec, const bool isUnitNorm=true)
std::shared_ptr< NDArray< T, 1 > > ToVector(const Expr< EType, typename EType::ValueType > &expr)
bool gemv_UtlMatrixTimesVector(const bool bATrans, const T alpha, const utl::NDArray< T, 2 > &A, const utl::NDArray< T, 1 > &X, const T beta, utl::NDArray< T, 1 > &Y)
void ProductUtlMM(const utl::NDArray< T, 2 > &A, const utl::NDArray< T, 2 > &B, utl::NDArray< T, 2 > &C, const double alpha=1.0, const double beta=0.0)
NDArray< T, 2 > InverseMatrix(const NDArray< T, 2 > &mat, const double eps=1e-10)
int gesdd(int matrix_order, char JOBZ, int M, int N, T *A, int LDA, T *S, T *U, int LDU, T *VT, int LDVT)
T abs(const T x)
template version of the fabs function
Base class for utl::NDArray.
Definition: utlMatrix.h:22
double DotProduct(const TVector1 &v1, const TVector2 &v2, const int N1)
Definition: utlMath.h:1332
#define utlGlobalException(cond, expout)
Definition: utlCoreMacro.h:372
utl::NDArray< T, 2 > Eye(const int n, const T val=1.0)
NDArray< T, 2 > & FillDiagonal(const T val)
Definition: utlMatrix.h:155
#define __utl_gemv_MatrixTimesVector(T, FuncName, FuncHelperName, RowMajorMatrixName, GetRowsFuncName, GetColsFuncName, MatrixGetDataFuncName, VectorName, GetSizeFuncName, VectorGetDataFuncName, ReSizeFuncName)
Definition: utlBlas.h:551
void getri_UtlMatrix(const utl::NDArray< T, 2 > &mat, utl::NDArray< T, 2 > &result)
geev_UtlMatrix calculate inverse of a general matrix via LU decomposition.
Definition: utl.h:90
NDArray< T, Dim > Real(const NDArray< std::complex< T >, Dim > &mat)
#define __utl_syrk_Matrix(T, FuncName, FuncHelperName, RowMajorMatrixName, GetRowsFuncName, GetColsFuncName, GetDataFuncName, ReSizeFuncName)
macro for syrk and row-major matrix
Definition: utlBlas.h:646
void Fill(const T &value)
Definition: utlNDArray.h:922
std::vector< T > UtlVectorToStdVector(const NDArray< T, 1 > &vec)
void GetEqualityConstraintProjection(const NDArray< T, 2 > &Aeq, const NDArray< T, 1 > &beq, const NDArray< T, 2 > &QInverse, NDArray< T, 2 > &projMatrix, NDArray< T, 1 > &projVector)
SizeType Cols() const
Definition: utlMatrix.h:138
std::shared_ptr< NDArray< T, Dim > > ToNDArray(const Expr< EType, typename EType::ValueType > &expr)
void syrk_UtlMatrix(const bool trans, const T alpha, const utl::NDArray< T, 2 > &A, const T beta, utl::NDArray< T, 2 > &C)
syrk_UtlMatrix
NDArray< T, 2 > PInverseMatrix(const NDArray< T, 2 > &mat, const double eps=1e-10)
#define utlSAException(expr)
Definition: utlCoreMacro.h:543
void EigenDecompositionSymmetricMatrix(NDArray< T, 1 > &eigenValues, NDArray< T, 2 > &eigenVectors) const
Eigen-decomposition for symmetric matrix.
Definition: utlMatrix.h:396
void OuterProduct(const TVector1 &v1, const int N1, const TVector2 &v2, const int N2, TMatrix &mat)
Definition: utlMath.h:1299
#define __utl_gemm_MatrixTimesMatrix(T, FuncName, FuncHelperName, RowMajorMatrixName, GetRowsFuncName, GetColsFuncName, GetDataFuncName, ReSizeFuncName)
Definition: utlBlas.h:433
void cblas_zdotu_sub(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotu)
Iterator End()
Definition: utlNDArray.h:602
NDArray< T, Dim > Imag(const NDArray< std::complex< T >, Dim > &mat)
NDArray< T, 2 > InverseSymmericMatrix(const NDArray< T, 2 > &mat, const double eps=1e-10)
NDArray< T, 2 > SphericalToCartesian(const NDArray< T, 2 > &in)
void GetColumn(const int index, T *vec) const
Definition: utlMatrix.h:277
NDArray< T, 2 > GetRefSubMatrix(const int i, const int j) const
std::shared_ptr< NDArray< T, 2 > > ToMatrix(const Expr< EType, typename EType::ValueType > &expr)
#define utlAssert(cond, expout)
Definition: utlCoreMacro.h:550
NDArray< T, 2 > LogM()
Definition: utlMatrix.h:537
#define __utl_getri_Matrix(T, FuncName, RowMajorMatrixName, GetRowsFuncName, GetColsFuncName, MatrixGetDataFuncName, ReSizeFuncName)
Definition: utlLapack.h:321
bool gevm_UtlVectorTimesMatrix(const bool bATrans, const T alpha, const utl::NDArray< T, 1 > &X, const utl::NDArray< T, 2 > &A, const T beta, utl::NDArray< T, 1 > &Y)
void cartesian2Spherical(const T x, const T y, const T z, T &r, T &theta, T &phi)
Definition: utlCore.h:1579
double InnerProduct(const TVector1 &v1, const TVector2 &v2, const int N1)
Definition: utlMath.h:1322
void ProductUtlMtM(const utl::NDArray< T, 2 > &A, const utl::NDArray< T, 2 > &B, utl::NDArray< T, 2 > &C, const double alpha=1.0, const double beta=0.0)
void ProductUtlMMt(const utl::NDArray< T, 2 > &A, const utl::NDArray< T, 2 > &B, utl::NDArray< T, 2 > &C, const double alpha=1.0, const double beta=0.0)
const ShapeType GetShape() const
Definition: utlNDArray.h:330
void PrintUtlVector(const NDArray< T, 1 > &vec, const std::string &str="", const char *separate=" ", std::ostream &os=std::cout, bool showStats=true)
NDArray< T, 1 > ConnectUtlVector(const NDArray< T, 1 > &m1, const NDArray< T, 1 > &m2)
NDArray< std::complex< T >, Dim > ComplexCombine(const NDArray< T, Dim > &arrReal, const NDArray< T, Dim > &arrImg)
macros for utlCore
void geev_UtlMatrix(const utl::NDArray< T, 2 > &mat, utl::NDArray< T, 1 > &valReal, utl::NDArray< T, 1 > &valImg, utl::NDArray< T, 2 > &vecRealR, utl::NDArray< T, 2 > &vecImgR, utl::NDArray< T, 2 > &vecRealL, utl::NDArray< T, 2 > &vecImgL)
geev_UtlMatrix calculate non-symmetric eigen-decomposition.
SizeType Size() const
Definition: utlNDArray.h:321
bool ReSize(const SizeType rows, const SizeType cols)
Definition: utlMatrix.h:140
NDArray< T, Dim > Eval(const Expr< EType, typename EType::ValueType > &expr)
bool ReSize(const SizeType size)
Definition: utlVector.h:167
static constexpr double SQRT2
Definition: utlConstants.h:31
#define __utl_gevm_MatrixTimesVector(T, FuncName, FuncHelperName, RowMajorMatrixName, GetRowsFuncName, GetColsFuncName, MatrixGetDataFuncName, VectorName, GetSizeFuncName, VectorGetDataFuncName, ReSizeFuncName)
Definition: utlBlas.h:593
void ProductUtlMv(const utl::NDArray< T, 2 > &A, const utl::NDArray< T, 1 > &b, utl::NDArray< T, 1 > &c, const double alpha=1.0, const double beta=0.0)
NDArray<T,4> is a 4th order tensor.
void Convert2To4Tensor(const utl::NDArray< T, 2 > &mat, utl::NDArray< T, 4 > &tensor)
void syev_UtlMatrix(const NDArray< T, 2 > &mat, NDArray< T, 1 > &eigenValues, NDArray< T, 2 > &eigenVectors)
dsyev_VnlMatrix eigen-decomposition for symmetric matrix. http://www.netlib.org/lapack/explore-html/d...