add solver.hpp

This commit is contained in:
Stefan Tröger
2013-05-01 19:25:23 +02:00
committed by Stefan Tröger
parent b1d7dbe2f0
commit bf447d3a7c
7 changed files with 1021 additions and 253 deletions

View File

@@ -25,12 +25,12 @@
#include "geometry.hpp"
#include <boost/math/special_functions/fpclassify.hpp>
using boost::math::isnormal;
using boost::math::isfinite;
namespace dcm {
//the calculations( same as we always calculate directions we can outsource the work to this functions)
namespace parallel_detail {
namespace orientation_detail {
template<typename Kernel, typename T>
inline typename Kernel::number_type calc(T d1,
@@ -38,19 +38,18 @@ inline typename Kernel::number_type calc(T d1,
Direction dir) {
switch(dir) {
case Same:
case equal:
return (d1-d2).norm();
case Opposite:
case opposite:
return (d1+d2).norm();
case Both:
if(d1.dot(d2) >= 0) {
return (d1-d2).norm();
}
return (d1+d2).norm();
default:
assert(false);
case parallel:
return d1.dot(d2) - d1.norm()*d2.norm();
case perpendicular:
return d1.dot(d2);
default:
assert(false);
}
return 0;
return 0;
};
@@ -62,21 +61,21 @@ inline typename Kernel::number_type calcGradFirst(T d1,
typename Kernel::number_type res;
switch(dir) {
case Same:
case equal:
res = ((d1-d2).dot(dd1) / (d1-d2).norm());
break;
case Opposite:
case opposite:
res= ((d1+d2).dot(dd1) / (d1+d2).norm());
break;
case Both:
if(d1.dot(d2) >= 0) {
res = (((d1-d2).dot(dd1) / (d1-d2).norm()));
break;
}
res = (((d1+d2).dot(dd1) / (d1+d2).norm()));
case parallel:
res = dd1.dot(d2) - d1.dot(dd1)/d1.norm()*d2.norm();
break;
case perpendicular:
res = dd1.dot(d2);
break;
}
if((isnormal)(res)) return res;
if(isfinite(res)) return res;
return 0;
};
@@ -88,21 +87,20 @@ inline typename Kernel::number_type calcGradSecond(T d1,
typename Kernel::number_type res;
switch(dir) {
case Same:
case equal:
res = ((d1-d2).dot(-dd2) / (d1-d2).norm());
break;
case Opposite:
case opposite:
res = ((d1+d2).dot(dd2) / (d1+d2).norm());
break;
case Both:
if(d1.dot(d2) >= 0) {
res = (((d1-d2).dot(-dd2) / (d1-d2).norm()));
break;
}
res = (((d1+d2).dot(dd2) / (d1+d2).norm()));
case parallel:
res = d1.dot(dd2) - d2.dot(dd2)/d2.norm()*d1.norm();
break;
case perpendicular:
res = d1.dot(dd2);
break;
}
if((isnormal)(res)) return res;
if((isfinite)(res)) return res;
return 0;
};
@@ -113,14 +111,18 @@ inline void calcGradFirstComp(T d1,
Direction dir) {
switch(dir) {
case Same:
case equal:
grad = (d1-d2) / (d1-d2).norm();
return;
case Opposite:
case opposite:
grad = (d1+d2) / (d1+d2).norm();
return;
case Both:
assert(false);
case parallel:
grad = d2 - d1/d1.norm()*d2.norm();
return;
case perpendicular:
grad = d2;
return;
}
};
@@ -131,85 +133,198 @@ inline void calcGradSecondComp(T d1,
Direction dir) {
switch(dir) {
case Same:
case equal:
grad = (d2-d1) / (d1-d2).norm();
return;
case Opposite:
case opposite:
grad = (d2+d1) / (d1+d2).norm();
return;
case Both:
assert(false);
case parallel:
grad = d1 - d2/d2.norm()*d1.norm();
return;
case perpendicular:
grad = d1;
return;
}
};
}
template< typename Kernel >
struct Parallel::type< Kernel, tag::line3D, tag::line3D > : public dcm::PseudoScale<Kernel> {
struct Orientation::type< Kernel, tag::direction3D, tag::direction3D > : public dcm::PseudoScale<Kernel> {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
Direction value;
option_type value;
//template definition
Scalar calculate(Vector& param1, Vector& param2) {
return parallel_detail::calc<Kernel>(param1.template tail<3>(), param2.template tail<3>(), value);
};
Scalar calculateGradientFirst(Vector& param1, Vector& param2, Vector& dparam1) {
return parallel_detail::calcGradFirst<Kernel>(param1.template tail<3>(), param2.template tail<3>(), dparam1.template tail<3>(), value);
};
Scalar calculateGradientSecond(Vector& param1, Vector& param2, Vector& dparam2) {
return parallel_detail::calcGradSecond<Kernel>(param1.template tail<3>(), param2.template tail<3>(), dparam2.template tail<3>(), value);
};
void calculateGradientFirstComplete(Vector& param1, Vector& param2, Vector& gradient) {
gradient.template head<3>().setZero();
parallel_detail::calcGradFirstComp<Kernel>(param1.template tail<3>(), param2.template tail<3>(), gradient.template tail<3>(), value);
};
void calculateGradientSecondComplete(Vector& param1, Vector& param2, Vector& gradient) {
gradient.template head<3>().setZero();
parallel_detail::calcGradSecondComp<Kernel>(param1.template tail<3>(), param2.template tail<3>(), gradient.template tail<3>(), value);
};
//template definition
Scalar calculate(Vector& param1, Vector& param2) {
return orientation_detail::calc<Kernel>(param1, param2, value);
};
Scalar calculateGradientFirst(Vector& param1, Vector& param2, Vector& dparam1) {
return orientation_detail::calcGradFirst<Kernel>(param1, param2, dparam1, value);
};
Scalar calculateGradientSecond(Vector& param1, Vector& param2, Vector& dparam2) {
return orientation_detail::calcGradSecond<Kernel>(param1, param2, dparam2, value);
};
void calculateGradientFirstComplete(Vector& param1, Vector& param2, Vector& gradient) {
gradient.template head<3>().setZero();
orientation_detail::calcGradFirstComp<Kernel>(param1, param2, gradient, value);
};
void calculateGradientSecondComplete(Vector& param1, Vector& param2, Vector& gradient) {
gradient.template head<3>().setZero();
orientation_detail::calcGradSecondComp<Kernel>(param1, param2, gradient, value);
};
};
template< typename Kernel >
struct Orientation::type< Kernel, tag::line3D, tag::line3D > : public dcm::PseudoScale<Kernel> {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
option_type value;
//template definition
Scalar calculate(Vector& param1, Vector& param2) {
return orientation_detail::calc<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
value);
};
Scalar calculateGradientFirst(Vector& param1, Vector& param2, Vector& dparam1) {
return orientation_detail::calcGradFirst<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
dparam1.template segment<3>(3),
value);
};
Scalar calculateGradientSecond(Vector& param1, Vector& param2, Vector& dparam2) {
return orientation_detail::calcGradSecond<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
dparam2.template segment<3>(3),
value);
};
void calculateGradientFirstComplete(Vector& param1, Vector& param2, Vector& gradient) {
gradient.template head<3>().setZero();
orientation_detail::calcGradFirstComp<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
gradient.template segment<3>(3),
value);
};
void calculateGradientSecondComplete(Vector& param1, Vector& param2, Vector& gradient) {
gradient.template head<3>().setZero();
orientation_detail::calcGradSecondComp<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
gradient.template segment<3>(3),
value);
};
};
template< typename Kernel >
struct Orientation::type< Kernel, tag::line3D, tag::plane3D > : public Orientation::type< Kernel, tag::line3D, tag::line3D > {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
option_type value;
option_type getValue() {
if(value==parallel)
return perpendicular;
if(value==perpendicular)
return parallel;
return value;
};
template< typename Kernel >
struct Parallel::type< Kernel, tag::cylinder3D, tag::cylinder3D > : public dcm::PseudoScale<Kernel>{
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
Direction value;
Scalar calculate(Vector& param1, Vector& param2) {
return parallel_detail::calc<Kernel>(param1.template segment<3>(3), param2.template segment<3>(3), value);
};
Scalar calculateGradientFirst(Vector& param1, Vector& param2, Vector& dparam1) {
return parallel_detail::calcGradFirst<Kernel>(param1.template segment<3>(3), param2.template segment<3>(3),
dparam1.template segment<3>(3), value);
};
Scalar calculateGradientSecond(Vector& param1, Vector& param2, Vector& dparam2) {
return parallel_detail::calcGradSecond<Kernel>(param1.template segment<3>(3), param2.template segment<3>(3),
dparam2.template segment<3>(3), value);
};
void calculateGradientFirstComplete(Vector& param1, Vector& param2, Vector& gradient) {
gradient.template head<3>().setZero();
parallel_detail::calcGradFirstComp<Kernel>(param1.template segment<3>(3), param2.template segment<3>(3),
gradient.template segment<3>(3), value);
};
void calculateGradientSecondComplete(Vector& param1, Vector& param2, Vector& gradient) {
gradient.template head<3>().setZero();
parallel_detail::calcGradSecondComp<Kernel>(param1.template segment<3>(3), param2.template segment<3>(3),
gradient.template segment<3>(3), value);
};
//template definition
Scalar calculate(Vector& param1, Vector& param2) {
return orientation_detail::calc<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
getValue());
};
Scalar calculateGradientFirst(Vector& param1, Vector& param2, Vector& dparam1) {
return orientation_detail::calcGradFirst<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
dparam1.template segment<3>(3),
getValue());
};
Scalar calculateGradientSecond(Vector& param1, Vector& param2, Vector& dparam2) {
return orientation_detail::calcGradSecond<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
dparam2.template segment<3>(3),
getValue());
};
void calculateGradientFirstComplete(Vector& param1, Vector& param2, Vector& gradient) {
gradient.template head<3>().setZero();
orientation_detail::calcGradFirstComp<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
gradient.template segment<3>(3),
getValue());
};
void calculateGradientSecondComplete(Vector& param1, Vector& param2, Vector& gradient) {
gradient.template head<3>().setZero();
orientation_detail::calcGradSecondComp<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
gradient.template segment<3>(3),
getValue());
};
};
template< typename Kernel >
struct Parallel::type< Kernel, tag::line3D, tag::plane3D > : public Parallel::type<Kernel, tag::line3D, tag::line3D> {};
struct Orientation::type< Kernel, tag::line3D, tag::cylinder3D > : public Orientation::type< Kernel, tag::line3D, tag::line3D > {};
template< typename Kernel >
struct Parallel::type< Kernel, tag::plane3D, tag::plane3D > : public Parallel::type<Kernel, tag::line3D, tag::line3D> {};
struct Orientation::type< Kernel, tag::plane3D, tag::plane3D > : public Orientation::type< Kernel, tag::line3D, tag::line3D > {};
template< typename Kernel >
struct Orientation::type< Kernel, tag::plane3D, tag::cylinder3D > : public Orientation::type<Kernel, tag::line3D, tag::plane3D> {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
using Orientation::type<Kernel, tag::line3D, tag::plane3D>::value;
//template definition
Scalar calculate(Vector& param1, Vector& param2) {
return Orientation::type<Kernel, tag::line3D, tag::plane3D>::calculate(param1, param2);
};
Scalar calculateGradientFirst(Vector& param1, Vector& param2, Vector& dparam1) {
return Orientation::type<Kernel, tag::line3D, tag::plane3D>::calculateGradientFirst(param1, param2, dparam1);
};
Scalar calculateGradientSecond(Vector& param1, Vector& param2, Vector& dparam2) {
return Orientation::type<Kernel, tag::line3D, tag::plane3D>::calculateGradientSecond(param1, param2, dparam2);
};
void calculateGradientFirstComplete(Vector& param1, Vector& param2, Vector& gradient) {
Orientation::type<Kernel, tag::line3D, tag::plane3D>::calculateGradientFirstComplete(param1, param2, gradient);
};
void calculateGradientSecondComplete(Vector& param1, Vector& param2, Vector& gradient) {
Orientation::type<Kernel, tag::line3D, tag::plane3D>::calculateGradientSecondComplete(param1, param2, gradient);
gradient(6)=0;
};
};
template< typename Kernel >
struct Orientation::type< Kernel, tag::cylinder3D, tag::cylinder3D > : public Orientation::type< Kernel, tag::line3D, tag::line3D > {
typedef typename Kernel::VectorMap Vector;
void calculateGradientFirstComplete(Vector& param1, Vector& param2, Vector& gradient) {
gradient.template head<3>().setZero();
orientation_detail::calcGradFirstComp<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
gradient.template segment<3>(3),
Orientation::type< Kernel, tag::line3D, tag::line3D >::value);
gradient(6) = 0;
};
void calculateGradientSecondComplete(Vector& param1, Vector& param2, Vector& gradient) {
gradient.template head<3>().setZero();
orientation_detail::calcGradSecondComp<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
gradient.template segment<3>(3),
Orientation::type< Kernel, tag::line3D, tag::line3D >::value);
gradient(6) = 0;
};
};
}
#endif //GCM_ANGLE
#endif