1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library 2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra. 3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> 5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla 7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed 8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "main.h" 11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include <Eigen/Geometry> 12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include <Eigen/LU> 13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include <Eigen/SVD> 14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/* this test covers the following files: 16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Geometry/OrthoMethods.h 17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath*/ 18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar> void orthomethods_3() 20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename NumTraits<Scalar>::Real RealScalar; 22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<Scalar,3,3> Matrix3; 23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<Scalar,3,1> Vector3; 24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<Scalar,4,1> Vector4; 26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Vector3 v0 = Vector3::Random(), 28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath v1 = Vector3::Random(), 29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath v2 = Vector3::Random(); 30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // cross product 32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_MUCH_SMALLER_THAN(v1.cross(v2).dot(v1), Scalar(1)); 33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_MUCH_SMALLER_THAN(v1.dot(v1.cross(v2)), Scalar(1)); 34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_MUCH_SMALLER_THAN(v1.cross(v2).dot(v2), Scalar(1)); 35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_MUCH_SMALLER_THAN(v2.dot(v1.cross(v2)), Scalar(1)); 362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang VERIFY_IS_MUCH_SMALLER_THAN(v1.cross(Vector3::Random()).dot(v1), Scalar(1)); 37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Matrix3 mat3; 38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mat3 << v0.normalized(), 39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath (v0.cross(v1)).normalized(), 40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath (v0.cross(v1).cross(v0)).normalized(); 41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY(mat3.isUnitary()); 422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang mat3.setRandom(); 442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang VERIFY_IS_APPROX(v0.cross(mat3*v1), -(mat3*v1).cross(v0)); 452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang VERIFY_IS_APPROX(v0.cross(mat3.lazyProduct(v1)), -(mat3.lazyProduct(v1)).cross(v0)); 46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // colwise/rowwise cross product 48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mat3.setRandom(); 49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Vector3 vec3 = Vector3::Random(); 50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Matrix3 mcross; 51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath int i = internal::random<int>(0,2); 52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mcross = mat3.colwise().cross(vec3); 53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(mcross.col(i), mat3.col(i).cross(vec3)); 542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang VERIFY_IS_MUCH_SMALLER_THAN((mat3.adjoint() * mat3.colwise().cross(vec3)).diagonal().cwiseAbs().sum(), Scalar(1)); 562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang VERIFY_IS_MUCH_SMALLER_THAN((mat3.adjoint() * mat3.colwise().cross(Vector3::Random())).diagonal().cwiseAbs().sum(), Scalar(1)); 572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang VERIFY_IS_MUCH_SMALLER_THAN((vec3.adjoint() * mat3.colwise().cross(vec3)).cwiseAbs().sum(), Scalar(1)); 592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang VERIFY_IS_MUCH_SMALLER_THAN((vec3.adjoint() * Matrix3::Random().colwise().cross(vec3)).cwiseAbs().sum(), Scalar(1)); 602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mcross = mat3.rowwise().cross(vec3); 62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(mcross.row(i), mat3.row(i).cross(vec3)); 63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // cross3 65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Vector4 v40 = Vector4::Random(), 66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath v41 = Vector4::Random(), 67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath v42 = Vector4::Random(); 68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath v40.w() = v41.w() = v42.w() = 0; 69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath v42.template head<3>() = v40.template head<3>().cross(v41.template head<3>()); 70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(v40.cross3(v41), v42); 712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang VERIFY_IS_MUCH_SMALLER_THAN(v40.cross3(Vector4::Random()).dot(v40), Scalar(1)); 72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // check mixed product 74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<RealScalar, 3, 1> RealVector3; 75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RealVector3 rv1 = RealVector3::Random(); 76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(v1.cross(rv1.template cast<Scalar>()), v1.cross(rv1)); 77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(rv1.template cast<Scalar>().cross(v1), rv1.cross(v1)); 78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar, int Size> void orthomethods(int size=Size) 81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename NumTraits<Scalar>::Real RealScalar; 83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<Scalar,Size,1> VectorType; 84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<Scalar,3,Size> Matrix3N; 85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<Scalar,Size,3> MatrixN3; 86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<Scalar,3,1> Vector3; 87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VectorType v0 = VectorType::Random(size); 89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // unitOrthogonal 91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_MUCH_SMALLER_THAN(v0.unitOrthogonal().dot(v0), Scalar(1)); 92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(v0.unitOrthogonal().norm(), RealScalar(1)); 93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (size>=3) 95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath v0.template head<2>().setZero(); 97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath v0.tail(size-2).setRandom(); 98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_MUCH_SMALLER_THAN(v0.unitOrthogonal().dot(v0), Scalar(1)); 100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(v0.unitOrthogonal().norm(), RealScalar(1)); 101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // colwise/rowwise cross product 104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Vector3 vec3 = Vector3::Random(); 105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath int i = internal::random<int>(0,size-1); 106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Matrix3N mat3N(3,size), mcross3N(3,size); 108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mat3N.setRandom(); 109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mcross3N = mat3N.colwise().cross(vec3); 110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(mcross3N.col(i), mat3N.col(i).cross(vec3)); 111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MatrixN3 matN3(size,3), mcrossN3(size,3); 113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath matN3.setRandom(); 114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mcrossN3 = matN3.rowwise().cross(vec3); 115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(mcrossN3.row(i), matN3.row(i).cross(vec3)); 116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid test_geo_orthomethods() 119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(int i = 0; i < g_repeat; i++) { 121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_1( orthomethods_3<float>() ); 122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_2( orthomethods_3<double>() ); 123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_4( orthomethods_3<std::complex<double> >() ); 124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_1( (orthomethods<float,2>()) ); 125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_2( (orthomethods<double,2>()) ); 126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_1( (orthomethods<float,3>()) ); 127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_2( (orthomethods<double,3>()) ); 128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_3( (orthomethods<float,7>()) ); 129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_4( (orthomethods<std::complex<double>,8>()) ); 130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_5( (orthomethods<float,Dynamic>(36)) ); 131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_6( (orthomethods<double,Dynamic>(35)) ); 132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 134