Visual Servoing Platform  version 3.1.0
vpMatrix_cholesky.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Matrix Cholesky decomposition.
33  *
34  * Authors:
35  * Filip Novotny
36  *
37  *****************************************************************************/
38 
39 #include <visp3/core/vpConfig.h>
40 
41 #include <visp3/core/vpColVector.h>
42 #include <visp3/core/vpMath.h>
43 #include <visp3/core/vpMatrix.h>
44 
45 // Exception
46 #include <visp3/core/vpException.h>
47 #include <visp3/core/vpMatrixException.h>
48 
49 // Debug trace
50 #include <visp3/core/vpDebug.h>
51 
52 #if (VISP_HAVE_OPENCV_VERSION >= 0x020101) // Require opencv >= 2.1.1
53 #include <opencv2/core/core.hpp>
54 #endif
55 
56 #ifdef VISP_HAVE_LAPACK
57 #ifdef VISP_HAVE_LAPACK_BUILT_IN
58 typedef long int integer;
59 #else
60 typedef int integer;
61 #endif
62 
63 extern "C" void dpotrf_(char *uplo, integer *n, double *a, integer *lda, integer *info);
64 extern "C" int dpotri_(char *uplo, integer *n, double *a, integer *lda, integer *info);
65 #endif
66 
106 {
107 #ifdef VISP_HAVE_LAPACK
108  return inverseByCholeskyLapack();
109 #elif (VISP_HAVE_OPENCV_VERSION >= 0x020101)
110  return inverseByCholeskyOpenCV();
111 #else
112  throw(vpException(vpException::fatalError, "Cannot inverse matrix by "
113  "Cholesky. Install Lapack or "
114  "OpenCV 3rd party"));
115 #endif
116 }
117 
118 #ifndef DOXYGEN_SHOULD_SKIP_THIS
119 
120 #ifdef VISP_HAVE_LAPACK
121 
157 vpMatrix vpMatrix::inverseByCholeskyLapack() const
158 {
159  if (rowNum != colNum) {
160  throw(vpMatrixException(vpMatrixException::matrixError, "Cannot inverse a non-square matrix (%ux%u) by Cholesky",
161  rowNum, colNum));
162  }
163 
164  integer rowNum_ = (integer)this->getRows();
165  integer lda = (integer)rowNum_; // lda is the number of rows because we don't use a submatrix
166  integer info;
167 
168  vpMatrix A = *this;
169  dpotrf_((char *)"L", &rowNum_, A.data, &lda, &info);
170 
171  if (info != 0)
172  throw(vpException(vpException::fatalError, "Cannot inverse by Cholesky with Lapack: error in dpotrf_()"));
173 
174  dpotri_((char *)"L", &rowNum_, A.data, &lda, &info);
175  if (info != 0) {
176  std::cout << "cholesky:dpotri_:error" << std::endl;
178  }
179 
180  for (unsigned int i = 0; i < A.getRows(); i++)
181  for (unsigned int j = 0; j < A.getCols(); j++)
182  if (i > j)
183  A[i][j] = A[j][i];
184 
185  return A;
186 }
187 #endif
188 
189 #if (VISP_HAVE_OPENCV_VERSION >= 0x020101)
190 
226 vpMatrix vpMatrix::inverseByCholeskyOpenCV() const
227 {
228  if (rowNum != colNum) {
229  throw(
230  vpException(vpException::fatalError, "Cannot inverse a non square matrix (%ux%u) by Cholesky", rowNum, colNum));
231  }
232 
233  cv::Mat M(rowNum, colNum, CV_64F, this->data);
234  cv::Mat Minv = M.inv(cv::DECOMP_CHOLESKY);
235 
236  vpMatrix A(rowNum, colNum);
237  memcpy(A.data, Minv.data, (size_t)(8 * Minv.rows * Minv.cols));
238 
239  return A;
240 }
241 #endif
242 
243 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:104
error that can be emited by ViSP classes.
Definition: vpException.h:71
unsigned int getRows() const
Definition: vpArray2D.h:156
Type * data
Address of the first element of the data array.
Definition: vpArray2D.h:84
unsigned int getCols() const
Definition: vpArray2D.h:146
unsigned int rowNum
Number of rows in the array.
Definition: vpArray2D.h:74
vpMatrix inverseByCholesky() const
unsigned int colNum
Number of columns in the array.
Definition: vpArray2D.h:76
error that can be emited by the vpMatrix class and its derivates