[Bf-blender-cvs] [8159718] master: BLI: add SVD solver for mat3 (using eigen3).

Bastien Montagne noreply at git.blender.org
Fri Oct 9 21:30:07 CEST 2015


Commit: 8159718fafc57cfbc9da7f706e599a91caccfa42
Author: Bastien Montagne
Date:   Fri Oct 9 20:55:15 2015 +0200
Branches: master
https://developer.blender.org/rB8159718fafc57cfbc9da7f706e599a91caccfa42

BLI: add SVD solver for mat3 (using eigen3).

===================================================================

M	extern/Eigen3/CMakeLists.txt
M	extern/Eigen3/eigen3_capi.h
A	extern/Eigen3/intern/svd.cc
A	extern/Eigen3/intern/svd.h
M	source/blender/blenlib/BLI_math_solvers.h
M	source/blender/blenlib/intern/math_solvers.c

===================================================================

diff --git a/extern/Eigen3/CMakeLists.txt b/extern/Eigen3/CMakeLists.txt
index 9bbfc9a..e3b6388 100644
--- a/extern/Eigen3/CMakeLists.txt
+++ b/extern/Eigen3/CMakeLists.txt
@@ -34,8 +34,10 @@ set(SRC
 	eigen3_capi.h
 
 	intern/eigenvalues.cc
+	intern/svd.cc
 
 	intern/eigenvalues.h
+	intern/svd.h
 )
 
 blender_add_lib(extern_eigen3 "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/extern/Eigen3/eigen3_capi.h b/extern/Eigen3/eigen3_capi.h
index 16f2237..f8a7b3c 100644
--- a/extern/Eigen3/eigen3_capi.h
+++ b/extern/Eigen3/eigen3_capi.h
@@ -28,5 +28,6 @@
 #define __EIGEN3_C_API_H__
 
 #include "intern/eigenvalues.h"
+#include "intern/svd.h"
 
 #endif  /* __EIGEN3_C_API_H__ */
diff --git a/extern/Eigen3/intern/svd.cc b/extern/Eigen3/intern/svd.cc
new file mode 100644
index 0000000..e39a826
--- /dev/null
+++ b/extern/Eigen3/intern/svd.cc
@@ -0,0 +1,72 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2015 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ *                 Bastien Montagne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __EIGEN3_SVD_C_API_CC__
+#define __EIGEN3_SVD_C_API_CC__
+
+/* Eigen gives annoying huge amount of warnings here, silence them! */
+#ifdef __GNUC__
+#  pragma GCC diagnostic ignored "-Wlogical-op"
+#endif
+
+#include <Eigen/Core>
+#include <Eigen/SVD>
+
+#include "svd.h"
+
+using Eigen::JacobiSVD;
+
+using Eigen::NoQRPreconditioner;
+
+using Eigen::ComputeThinU;
+using Eigen::ComputeThinV;
+
+using Eigen::MatrixXf;
+using Eigen::VectorXf;
+using Eigen::Map;
+
+void EG3_svd_square_matrix(const int size, const float *matrix, float *r_U, float *r_S, float *r_V)
+{
+	/* Since our matrix is squared, we can use thinU/V. */
+	unsigned int flags = (r_U ? ComputeThinU : 0) | (r_V ? ComputeThinV : 0);
+
+	/* Blender and Eigen matrices are both column-major. */
+	JacobiSVD<MatrixXf, NoQRPreconditioner> svd(Map<MatrixXf>((float *)matrix, size, size), flags);
+
+	if (r_U) {
+		Map<MatrixXf>(r_U, size, size) = svd.matrixU();
+	}
+
+	if (r_S) {
+		Map<VectorXf>(r_S, size) = svd.singularValues();
+	}
+
+	if (r_V) {
+		Map<MatrixXf>(r_V, size, size) = svd.matrixV();
+	}
+}
+
+#endif  /* __EIGEN3_SVD_C_API_CC__ */
diff --git a/extern/Eigen3/eigen3_capi.h b/extern/Eigen3/intern/svd.h
similarity index 78%
copy from extern/Eigen3/eigen3_capi.h
copy to extern/Eigen3/intern/svd.h
index 16f2237..0ac5110 100644
--- a/extern/Eigen3/eigen3_capi.h
+++ b/extern/Eigen3/intern/svd.h
@@ -24,9 +24,17 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
-#ifndef __EIGEN3_C_API_H__
-#define __EIGEN3_C_API_H__
+#ifndef __EIGEN3_SVD_C_API_H__
+#define __EIGEN3_SVD_C_API_H__
 
-#include "intern/eigenvalues.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-#endif  /* __EIGEN3_C_API_H__ */
+void EG3_svd_square_matrix(const int size, const float *matrix, float *r_U, float *r_S, float *r_V);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* __EIGEN3_SVD_C_API_H__ */
diff --git a/source/blender/blenlib/BLI_math_solvers.h b/source/blender/blenlib/BLI_math_solvers.h
index ec9ba55..810c84c 100644
--- a/source/blender/blenlib/BLI_math_solvers.h
+++ b/source/blender/blenlib/BLI_math_solvers.h
@@ -46,6 +46,7 @@ extern "C" {
 
 bool BLI_eigen_solve_selfadjoint_m3(const float m3[3][3], float r_eigen_values[3], float r_eigen_vectors[3][3]);
 
+void BLI_svd_m3(const float m3[3][3], float r_U[3][3], float r_S[], float r_V[3][3]);
 
 /**************************** Inline Definitions ******************************/
 #if 0  /* None so far. */
diff --git a/source/blender/blenlib/intern/math_solvers.c b/source/blender/blenlib/intern/math_solvers.c
index 2f96271..d1dad9a 100644
--- a/source/blender/blenlib/intern/math_solvers.c
+++ b/source/blender/blenlib/intern/math_solvers.c
@@ -59,3 +59,16 @@ bool BLI_eigen_solve_selfadjoint_m3(const float m3[3][3], float r_eigen_values[3
 
 	return EG3_self_adjoint_eigen_solve(3, (const float *)m3, r_eigen_values, (float *)r_eigen_vectors);
 }
+
+/**
+ * \brief Compute the SVD (Singular Values Decomposition) of given 3D  matrix (m3 = USV*).
+ *
+ * \param m3 the matrix to decompose.
+ * \return r_U the computed left singular vector of \a m3 (NULL if not needed).
+ * \return r_S the computed singular values of \a m3 (NULL if not needed).
+ * \return r_V the computed right singular vector of \a m3 (NULL if not needed).
+ */
+void BLI_svd_m3(const float m3[3][3], float r_U[3][3], float r_S[3], float r_V[3][3])
+{
+	EG3_svd_square_matrix(3, (const float *)m3, (float *)r_U, (float *)r_S, (float *)r_V);
+}




More information about the Bf-blender-cvs mailing list