OpenStructure
Loading...
Searching...
No Matches
vec_mat_predicates.hh
Go to the documentation of this file.
1//------------------------------------------------------------------------------
2// This file is part of the OpenStructure project <www.openstructure.org>
3//
4// Copyright (C) 2008-2020 by the OpenStructure authors
5//
6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License as published by the Free
8// Software Foundation; either version 3.0 of the License, or (at your option)
9// any later version.
10// This library is distributed in the hope that it will be useful, but WITHOUT
11// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13// details.
14//
15// You should have received a copy of the GNU Lesser General Public License
16// along with this library; if not, write to the Free Software Foundation, Inc.,
17// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18//------------------------------------------------------------------------------
19#ifndef OST_GEOM_VEC_MAT_PREDICATES_HH
20#define OST_GEOM_VEC_MAT_PREDICATES_HH
21#include <boost/test/unit_test.hpp>
22#include <boost/version.hpp>
23#if BOOST_VERSION<105900
24#include <boost/test/floating_point_comparison.hpp>
25#else
26#include <boost/test/tools/floating_point_comparison.hpp>
27#endif
28#include <ost/geom/geom.hh>
29
30
31/*
32 This file contains several predicates to check for equality of vectors and
33 matrices. Usage:
34
35 BOOST_CHECK(vec2_is_close(geom::Vec2(1,2), geom::Vec2(1, 2)));
36 */
37
38template<class V>
39boost::test_tools::predicate_result vec_is_close(const V& v1, const V& v2,
40 Real tolerance,
41 unsigned int dim)
42{
43 std::string labels[]={"x","y","z","w"};
44 bool flag=true;
45 boost::test_tools::predicate_result res( false );
46#if BOOST_VERSION<105900
47 boost::test_tools::close_at_tolerance<Real> close_test(boost::test_tools::percent_tolerance(tolerance));
48#else
49 boost::math::fpc::close_at_tolerance<Real> close_test(boost::math::fpc::percent_tolerance(tolerance));
50#endif
51 for(unsigned int i=0;i<dim;++i){
52 if(v1[i]==0.0){
53 if(!boost::test_tools::check_is_small(v2[i],tolerance)){
54 flag=false;
55 res.message() << "Value for " << labels[i] << " differs: ( " << v1[i] << " != " << v2[i] << " ). ";
56 }
57 }else if (v2[i]==0.0){
58 if(!boost::test_tools::check_is_small(v1[i],tolerance)){
59 flag=false;
60 res.message() << "Value for "<< labels[i] << " differs: ( " << v1[i] << " != " << v2[i] << " ). ";
61 }
62 }else{
63 if(!close_test(v1[i],v2[i])){
64 flag=false;
65 res.message() << "Value for " << labels[i] << " differs: ( " << v1[i] << " != " << v2[i] << " ). ";
66 }
67 }
68 }
69 if(flag){
70 return true;
71 }else{
72 return res;
73 }
74}
75
76boost::test_tools::predicate_result vec2_is_close(const geom::Vec2& v1,
77 const geom::Vec2& v2,
78 Real tolerance=geom::EPSILON)
79{
80 return vec_is_close<geom::Vec2>(v1,v2,tolerance,2);
81}
82
83boost::test_tools::predicate_result vec3_is_close(const geom::Vec3& v1,
84 const geom::Vec3& v2,
85 Real tolerance=geom::EPSILON)
86{
87 return vec_is_close<geom::Vec3>(v1,v2,tolerance,3);
88}
89
90boost::test_tools::predicate_result vec4_is_close(const geom::Vec4& v1,
91 const geom::Vec4& v2,
92 Real tolerance=geom::EPSILON)
93{
94 return vec_is_close<geom::Vec4>(v1,v2,tolerance,4);
95}
96
97template<class M>
98boost::test_tools::predicate_result mat_is_close(const M& m1, const M& m2,
99 Real tolerance,
100 unsigned int dim)
101{
102 bool flag=true;
103 boost::test_tools::predicate_result res( false );
104#if BOOST_VERSION<105900
105 boost::test_tools::close_at_tolerance<Real> close_test(boost::test_tools::percent_tolerance(tolerance));
106#else
107 boost::math::fpc::close_at_tolerance<Real> close_test(boost::math::fpc::percent_tolerance(tolerance));
108#endif
109 for(unsigned int i=0;i<dim;++i){
110 for(unsigned int j=0;j<dim;++j){
111 if(m1(i,j)==0.0){
112 if(!boost::test_tools::check_is_small(m2(i,j),tolerance)){
113 flag=false;
114 res.message() << "Value for (" << i << "," << j << ") differs: (" << m1(i,j) << "!=" << m2(i,j) << "). ";
115 }
116 }else if (m2(i,j)==0.0){
117 if(!boost::test_tools::check_is_small(m1(i,j),tolerance)){
118 flag=false;
119 res.message() << "Value for (" << i << "," << j << ") differs: (" << m1(i,j) << "!=" << m2(i,j) << "). ";
120 }
121 }else{
122 if(!close_test(m1(i,j),m2(i,j))){
123 flag=false;
124 res.message() << "Value for (" << i << "," << j << ") differs: (" << m1(i,j) << "!=" << m2(i,j) << "). ";
125 }
126 }
127 }
128 }
129 if(flag){
130 return true;
131 }else{
132 return res;
133 }
134}
135
136boost::test_tools::predicate_result mat2_is_close(const geom::Mat2& m1,
137 const geom::Mat2& m2,
138 Real tolerance=geom::EPSILON)
139{
140 return mat_is_close<geom::Mat2>(m1,m2,tolerance,2);
141}
142
143boost::test_tools::predicate_result mat3_is_close(const geom::Mat3& m1,
144 const geom::Mat3& m2,
145 Real tolerance=geom::EPSILON)
146{
147 return mat_is_close<geom::Mat3>(m1,m2,tolerance,3);
148}
149
150boost::test_tools::predicate_result mat4_is_close(const geom::Mat4& m1,
151 const geom::Mat4& m2,
152 Real tolerance=geom::EPSILON)
153{
154 return mat_is_close<geom::Mat4>(m1,m2,tolerance,4);
155}
156
157#endif
Three dimensional vector class, using Real precision.
Definition vec3.hh:48
float Real
Definition base.hh:44
static const Real EPSILON
Definition constants.hh:28
boost::test_tools::predicate_result mat_is_close(const M &m1, const M &m2, Real tolerance, unsigned int dim)
boost::test_tools::predicate_result mat2_is_close(const geom::Mat2 &m1, const geom::Mat2 &m2, Real tolerance=geom::EPSILON)
boost::test_tools::predicate_result mat4_is_close(const geom::Mat4 &m1, const geom::Mat4 &m2, Real tolerance=geom::EPSILON)
boost::test_tools::predicate_result vec_is_close(const V &v1, const V &v2, Real tolerance, unsigned int dim)
boost::test_tools::predicate_result vec3_is_close(const geom::Vec3 &v1, const geom::Vec3 &v2, Real tolerance=geom::EPSILON)
boost::test_tools::predicate_result vec2_is_close(const geom::Vec2 &v1, const geom::Vec2 &v2, Real tolerance=geom::EPSILON)
boost::test_tools::predicate_result vec4_is_close(const geom::Vec4 &v1, const geom::Vec4 &v2, Real tolerance=geom::EPSILON)
boost::test_tools::predicate_result mat3_is_close(const geom::Mat3 &m1, const geom::Mat3 &m2, Real tolerance=geom::EPSILON)