From 22e9ae481216c127835d74d79aee73f88842120d Mon Sep 17 00:00:00 2001 From: Rohit Ranjan Date: Tue, 14 Apr 2020 08:24:44 +0530 Subject: [PATCH] extend arithmetic functions to support for differentials --- .../boost/astronomy/coordinate/arithmetic.hpp | 1095 ++++++++++++++++- .../coordinate/base_differential.hpp | 52 - test/coordinate/cartesian_differential.cpp | 113 ++ test/coordinate/spherical_differential.cpp | 110 ++ .../spherical_equatorial_differential.cpp | 110 ++ 5 files changed, 1405 insertions(+), 75 deletions(-) diff --git a/include/boost/astronomy/coordinate/arithmetic.hpp b/include/boost/astronomy/coordinate/arithmetic.hpp index 10e7bc78..0c6a62c1 100644 --- a/include/boost/astronomy/coordinate/arithmetic.hpp +++ b/include/boost/astronomy/coordinate/arithmetic.hpp @@ -13,6 +13,8 @@ #include #include +#include +#include namespace boost { namespace astronomy { namespace coordinate { @@ -120,6 +122,401 @@ auto cross >(result); } +//!Returns the cross product of differential1(cartesian differential) and differential2 +template +< + template class Differential2, + typename ...Args1, + typename ...Args2 +> +auto cross +( + cartesian_differential const& differential1, + Differential2 const& differential2 +) +{ + /*!both the coordinates/vector are first converted into + cartesian coordinate system then cross product of both cartesian + vectors is converted into cartesian differential type and returned*/ + + /*checking types if it is not subclass of + base_representaion then compile time erorr is generated*/ + //BOOST_STATIC_ASSERT_MSG((boost::astronomy::detail::is_base_template_of + // < + // boost::astronomy::coordinate::base_representation, + // Representation1 + // >::value), + // "First argument type is expected to be a representation class"); + //BOOST_STATIC_ASSERT_MSG((boost::astronomy::detail::is_base_template_of + // < + // boost::astronomy::coordinate::base_representation, + // Representation2 + // >::value), + // "Second argument type is expected to be a representation class"); + + /*converting both coordinates/vector into cartesian system*/ + + typedef cartesian_differential differential1_type; + typedef Differential2 differential2_type; + + bg::model::point + < + typename std::conditional + < + sizeof(typename differential2_type::type) >= + sizeof(typename differential1_type::type), + typename differential2_type::type, + typename differential1_type::type + >::type, + 3, + bg::cs::cartesian + > tempPoint1, tempPoint2, result; + + auto cartesian1 = make_cartesian_differential(differential1); + auto cartesian2 = make_cartesian_differential(differential2); + + typedef decltype(cartesian1) cartesian1_type; + typedef decltype(cartesian2) cartesian2_type; + + + bg::transform(differential1.get_differential(), tempPoint1); + bg::transform(differential2.get_differential(), tempPoint2); + + + bg::set<0>(result, (bg::get<1>(tempPoint1)*bg::get<2>(tempPoint2)) - + ((bg::get<2>(tempPoint1)* + bu::conversion_factor(typename cartesian1_type::quantity3::unit_type(), + typename cartesian1_type::quantity2::unit_type()))* + (bg::get<1>(tempPoint2)* + bu::conversion_factor(typename cartesian2_type::quantity2::unit_type(), + typename cartesian2_type::quantity3::unit_type())))); + + bg::set<1>(result, (bg::get<2>(tempPoint1)*bg::get<0>(tempPoint2)) - + ((bg::get<0>(tempPoint1)* + bu::conversion_factor(typename cartesian1_type::quantity1::unit_type(), + typename cartesian1_type::quantity3::unit_type()))* + (bg::get<2>(tempPoint2)* + bu::conversion_factor(typename cartesian2_type::quantity3::unit_type(), + typename cartesian2_type::quantity1::unit_type())))); + + bg::set<2>(result, (bg::get<0>(tempPoint1)*bg::get<1>(tempPoint2)) - + ((bg::get<1>(tempPoint1)* + bu::conversion_factor(typename cartesian1_type::quantity2::unit_type(), + typename cartesian1_type::quantity1::unit_type()))* + (bg::get<0>(tempPoint2)* + bu::conversion_factor(typename cartesian2_type::quantity1::unit_type(), + typename cartesian2_type::quantity2::unit_type())))); + + + return + cartesian_differential + < + typename cartesian1_type::type, + bu::quantity::type + >, + bu::quantity::type + >, + bu::quantity::type + > + >(result); +} + + +//!Returns the cross product of differential1(spherical differential) and differential2 +template +< + template class Differential2, + typename ...Args1, + typename ...Args2 +> +auto cross +( + spherical_differential const& differential1, + Differential2 const& differential2 +) +{ + /*!both the coordinates/vector are first converted into + cartesian coordinate system then cross product of both cartesian + vectors is converted into spherical differential system type and returned*/ + + /*checking types if it is not subclass of + base_representaion then compile time erorr is generated*/ + //BOOST_STATIC_ASSERT_MSG((boost::astronomy::detail::is_base_template_of + // < + // boost::astronomy::coordinate::base_representation, + // Representation1 + // >::value), + // "First argument type is expected to be a representation class"); + //BOOST_STATIC_ASSERT_MSG((boost::astronomy::detail::is_base_template_of + // < + // boost::astronomy::coordinate::base_representation, + // Representation2 + // >::value), + // "Second argument type is expected to be a representation class"); + + /*converting both coordinates/vector into cartesian system*/ + + typedef spherical_differential differential1_type; + typedef Differential2 differential2_type; + + bg::model::point + < + typename std::conditional + < + sizeof(typename differential2_type::type) >= + sizeof(typename differential1_type::type), + typename differential2_type::type, + typename differential1_type::type + >::type, + 3, + bg::cs::cartesian + > tempPoint1, tempPoint2, result; + + auto cartesian1 = make_cartesian_differential(differential1); + auto cartesian2 = make_cartesian_differential(differential2); + + typedef decltype(cartesian1) cartesian1_type; + typedef decltype(cartesian2) cartesian2_type; + + + bg::transform(differential1.get_differential(), tempPoint1); + bg::transform(differential2.get_differential(), tempPoint2); + + + bg::set<0>( + tempPoint2, + bg::get<0>(tempPoint2)* + bu::conversion_factor(typename cartesian2_type::quantity1::unit_type(), + typename cartesian2_type::quantity1::unit_type()) + ); + bg::set<1>( + tempPoint2, + bg::get<1>(tempPoint2)* + bu::conversion_factor(typename cartesian2_type::quantity2::unit_type(), + typename cartesian2_type::quantity1::unit_type()) + ); + bg::set<2>( + tempPoint2, + bg::get<2>(tempPoint2)* + bu::conversion_factor(typename cartesian2_type::quantity3::unit_type(), + typename cartesian2_type::quantity1::unit_type()) + ); + + result = bg::cross_product(tempPoint1,tempPoint2); + return + spherical_differential + < + typename differential1_type::type, + typename differential1_type::quantity1, + typename differential1_type::quantity2, + bu::quantity::type + > + >(result); +} + +//!Returns the cross product of differential1(spherical equatorial differential) and differential2 +template +< + template class Differential2, + typename ...Args1, + typename ...Args2 +> +auto cross +( + spherical_equatorial_differential const& differential1, + Differential2 const& differential2 +) +{ + /*!both the coordinates/vector are first converted into + cartesian coordinate system then cross product of both cartesian + vectors is converted into spherical equatorial differential system type and returned*/ + + /*checking types if it is not subclass of + base_representaion then compile time erorr is generated*/ + //BOOST_STATIC_ASSERT_MSG((boost::astronomy::detail::is_base_template_of + // < + // boost::astronomy::coordinate::base_representation, + // Representation1 + // >::value), + // "First argument type is expected to be a representation class"); + //BOOST_STATIC_ASSERT_MSG((boost::astronomy::detail::is_base_template_of + // < + // boost::astronomy::coordinate::base_representation, + // Representation2 + // >::value), + // "Second argument type is expected to be a representation class"); + + /*converting both coordinates/vector into cartesian system*/ + + typedef spherical_equatorial_differential differential1_type; + typedef Differential2 differential2_type; + + bg::model::point + < + typename std::conditional + < + sizeof(typename differential2_type::type) >= + sizeof(typename differential1_type::type), + typename differential2_type::type, + typename differential1_type::type + >::type, + 3, + bg::cs::cartesian + > tempPoint1, tempPoint2, result; + + auto cartesian1 = make_cartesian_differential(differential1); + auto cartesian2 = make_cartesian_differential(differential2); + + typedef decltype(cartesian1) cartesian1_type; + typedef decltype(cartesian2) cartesian2_type; + + + bg::transform(differential1.get_differential(), tempPoint1); + bg::transform(differential2.get_differential(), tempPoint2); + + + bg::set<0>( + tempPoint2, + bg::get<0>(tempPoint2)* + bu::conversion_factor(typename cartesian2_type::quantity1::unit_type(), + typename cartesian2_type::quantity1::unit_type()) + ); + bg::set<1>( + tempPoint2, + bg::get<1>(tempPoint2)* + bu::conversion_factor(typename cartesian2_type::quantity2::unit_type(), + typename cartesian2_type::quantity1::unit_type()) + ); + bg::set<2>( + tempPoint2, + bg::get<2>(tempPoint2)* + bu::conversion_factor(typename cartesian2_type::quantity3::unit_type(), + typename cartesian2_type::quantity1::unit_type()) + ); + + result = bg::cross_product(tempPoint1,tempPoint2); + + return + spherical_equatorial_differential + < + typename differential1_type::type, + typename differential1_type::quantity1, + typename differential1_type::quantity2, + bu::quantity::type + > + >(result); +} + +//!Returns the cross product of differential1(spherical coslat differential) and differential2 +template +< + template class Differential2, + typename ...Args1, + typename ...Args2 +> +auto cross +( + spherical_coslat_differential const& differential1, + Differential2 const& differential2 +) +{ + /*!both the coordinates/vector are first converted into + cartesian coordinate system then cross product of both cartesian + vectors is converted into spherical coslat differential system type and returned*/ + + /*checking types if it is not subclass of + base_representaion then compile time erorr is generated*/ + //BOOST_STATIC_ASSERT_MSG((boost::astronomy::detail::is_base_template_of + // < + // boost::astronomy::coordinate::base_representation, + // Representation1 + // >::value), + // "First argument type is expected to be a representation class"); + //BOOST_STATIC_ASSERT_MSG((boost::astronomy::detail::is_base_template_of + // < + // boost::astronomy::coordinate::base_representation, + // Representation2 + // >::value), + // "Second argument type is expected to be a representation class"); + + /*converting both coordinates/vector into cartesian system*/ + + typedef spherical_coslat_differential differential1_type; + typedef Differential2 differential2_type; + + bg::model::point + < + typename std::conditional + < + sizeof(typename differential2_type::type) >= + sizeof(typename differential1_type::type), + typename differential2_type::type, + typename differential1_type::type + >::type, + 3, + bg::cs::cartesian + > tempPoint1, tempPoint2, result; + + auto cartesian1 = make_cartesian_differential(differential1); + auto cartesian2 = make_cartesian_differential(differential2); + + typedef decltype(cartesian1) cartesian1_type; + typedef decltype(cartesian2) cartesian2_type; + + + bg::transform(differential1.get_differential(), tempPoint1); + bg::transform(differential2.get_differential(), tempPoint2); + + + bg::set<0>( + tempPoint2, + bg::get<0>(tempPoint2)* + bu::conversion_factor(typename cartesian2_type::quantity1::unit_type(), + typename cartesian2_type::quantity1::unit_type()) + ); + bg::set<1>( + tempPoint2, + bg::get<1>(tempPoint2)* + bu::conversion_factor(typename cartesian2_type::quantity2::unit_type(), + typename cartesian2_type::quantity1::unit_type()) + ); + bg::set<2>( + tempPoint2, + bg::get<2>(tempPoint2)* + bu::conversion_factor(typename cartesian2_type::quantity3::unit_type(), + typename cartesian2_type::quantity1::unit_type()) + ); + + result = bg::cross_product(tempPoint1,tempPoint2); + + return + spherical_coslat_differential + < + typename differential1_type::type, + typename differential1_type::quantity1, + typename differential1_type::quantity2, + bu::quantity::type + > + >(result); +} //! Returns dot product of representation1 and representation2 template @@ -142,7 +539,7 @@ auto dot(Representation1 const& representation1, Representation2 const& represen 3, bg::cs::cartesian > tempPoint1, tempPoint2; - + auto cartesian1 = make_cartesian_representation(representation1); auto cartesian2 = make_cartesian_representation(representation2); @@ -155,19 +552,243 @@ auto dot(Representation1 const& representation1, Representation2 const& represen bg::set<2>(tempPoint1, static_cast(cartesian1.get_z()).value()); - bg::set<0>(tempPoint2, cartesian2.get_x().value()); - bg::set<1>(tempPoint2, - static_cast(cartesian2.get_y()).value()); - bg::set<2>(tempPoint2, - static_cast(cartesian2.get_z()).value()); + bg::set<0>(tempPoint2, cartesian2.get_x().value()); + bg::set<1>(tempPoint2, + static_cast(cartesian2.get_y()).value()); + bg::set<2>(tempPoint2, + static_cast(cartesian2.get_z()).value()); + + return bg::dot_product(tempPoint1, tempPoint2) * + typename cartesian1_type::quantity1::unit_type() * + typename cartesian2_type::quantity1::unit_type(); +} + +//! Returns dot product of differential1(spherical_coslat_differential) and differential2 +template +auto dot(spherical_coslat_differential const& differential1, Differential2 const& differential2) +{ + /*!both the coordinates/vector are first converted into + cartesian differential system then dot product of both cartesian + product is converted into requested type and returned*/ + + /*converting both coordinates/vector into cartesian system*/ + typedef spherical_coslat_differential Differential1; + bg::model::point + < + typename std::conditional + < + sizeof(typename Differential2::type) >= + sizeof(typename Differential1::type), + typename Differential2::type, + typename Differential1::type + >::type, + 3, + bg::cs::cartesian + > tempPoint1, tempPoint2; + + auto cartesian1 = make_cartesian_differential(differential1); + auto cartesian2 = make_cartesian_differential(differential2); + + typedef decltype(cartesian1) cartesian1_type; + typedef decltype(cartesian2) cartesian2_type; + + bg::set<0>(tempPoint1, cartesian1.get_dx().value()); + bg::set<1>(tempPoint1, + static_cast(cartesian1.get_dy()).value()); + bg::set<2>(tempPoint1, + static_cast(cartesian1.get_dz()).value()); + + bg::set<0>(tempPoint2, cartesian2.get_dx().value()); + bg::set<1>(tempPoint2, + static_cast(cartesian2.get_dy()).value()); + bg::set<2>(tempPoint2, + static_cast(cartesian2.get_dz()).value()); + + return bg::dot_product(tempPoint1, tempPoint2) * + typename cartesian1_type::quantity1::unit_type() * + typename cartesian2_type::quantity1::unit_type(); +} + + +//! Returns dot product of differential1(spherical_equatorial_differential) and differential2 +template +auto dot(spherical_equatorial_differential const& differential1, Differential2 const& differential2) +{ + /*!both the coordinates/vector are first converted into + cartesian differential system then dot product of both cartesian + product is converted into requested type and returned*/ + + /*converting both coordinates/vector into cartesian system*/ + typedef spherical_equatorial_differential Differential1; + bg::model::point + < + typename std::conditional + < + sizeof(typename Differential2::type) >= + sizeof(typename Differential1::type), + typename Differential2::type, + typename Differential1::type + >::type, + 3, + bg::cs::cartesian + > tempPoint1, tempPoint2; + + auto cartesian1 = make_cartesian_differential(differential1); + auto cartesian2 = make_cartesian_differential(differential2); + + typedef decltype(cartesian1) cartesian1_type; + typedef decltype(cartesian2) cartesian2_type; + + bg::set<0>(tempPoint1, cartesian1.get_dx().value()); + bg::set<1>(tempPoint1, + static_cast(cartesian1.get_dy()).value()); + bg::set<2>(tempPoint1, + static_cast(cartesian1.get_dz()).value()); + + bg::set<0>(tempPoint2, cartesian2.get_dx().value()); + bg::set<1>(tempPoint2, + static_cast(cartesian2.get_dy()).value()); + bg::set<2>(tempPoint2, + static_cast(cartesian2.get_dz()).value()); + + return bg::dot_product(tempPoint1, tempPoint2) * + typename cartesian1_type::quantity1::unit_type() * + typename cartesian2_type::quantity1::unit_type(); +} + + +//! Returns dot product of differential1(cartesian_differential) and differential2 +template +auto dot(cartesian_differential const& differential1, Differential2 const& differential2) +{ + + /*!both the coordinates/vector are first converted into + cartesian differential system then dot product of both cartesian + product is converted into requested type and returned*/ + + /*converting both coordinates/vector into cartesian system*/ + typedef cartesian_differential Differential1; + bg::model::point + < + typename std::conditional + < + sizeof(typename Differential2::type) >= + sizeof(typename Differential1::type), + typename Differential2::type, + typename Differential1::type + >::type, + 3, + bg::cs::cartesian + > tempPoint1, tempPoint2; + + auto cartesian1 = make_cartesian_differential(differential1); + auto cartesian2 = make_cartesian_differential(differential2); + + typedef decltype(cartesian1) cartesian1_type; + typedef decltype(cartesian2) cartesian2_type; + + bg::set<0>(tempPoint1, cartesian1.get_dx().value()); + bg::set<1>(tempPoint1, + static_cast(cartesian1.get_dy()).value()); + bg::set<2>(tempPoint1, + static_cast(cartesian1.get_dz()).value()); + + bg::set<0>(tempPoint2, cartesian2.get_dx().value()); + bg::set<1>(tempPoint2, + static_cast(cartesian2.get_dy()).value()); + bg::set<2>(tempPoint2, + static_cast(cartesian2.get_dz()).value()); + + return bg::dot_product(tempPoint1, tempPoint2) * + typename cartesian1_type::quantity1::unit_type() * + typename cartesian2_type::quantity1::unit_type(); +} + +//! Returns dot product of differential1(spherical_differential) and differential2 +template +auto dot(spherical_differential const& differential1, Differential2 const& differential2) +{ + /*!both the coordinates/vector are first converted into + cartesian differential system then dot product of both cartesian + product is converted into requested type and returned*/ + + /*converting both coordinates/vector into cartesian system*/ + typedef spherical_differential Differential1; + bg::model::point + < + typename std::conditional + < + sizeof(typename Differential2::type) >= + sizeof(typename Differential1::type), + typename Differential2::type, + typename Differential1::type + >::type, + 3, + bg::cs::cartesian + > tempPoint1, tempPoint2; + + auto cartesian1 = make_cartesian_differential(differential1); + auto cartesian2 = make_cartesian_differential(differential2); + + typedef decltype(cartesian1) cartesian1_type; + typedef decltype(cartesian2) cartesian2_type; + + bg::set<0>(tempPoint1, cartesian1.get_dx().value()); + bg::set<1>(tempPoint1, + static_cast(cartesian1.get_dy()).value()); + bg::set<2>(tempPoint1, + static_cast(cartesian1.get_dz()).value()); + + bg::set<0>(tempPoint2, cartesian2.get_dx().value()); + bg::set<1>(tempPoint2, + static_cast(cartesian2.get_dy()).value()); + bg::set<2>(tempPoint2, + static_cast(cartesian2.get_dz()).value()); + + return bg::dot_product(tempPoint1, tempPoint2) * + typename cartesian1_type::quantity1::unit_type() * + typename cartesian2_type::quantity1::unit_type(); +} + +//! Returns magnitude of the cartesian vector +template +< + typename CoordinateType, + typename XQuantity, + typename YQuantity, + typename ZQuantity +> +auto magnitude +( + cartesian_representation + < + CoordinateType, + XQuantity, + YQuantity, + ZQuantity + > const& vector +) +{ + CoordinateType result = 0; + bg::model::point + < + CoordinateType, + 3, + bg::cs::cartesian + > tempPoint; + + bg::set<0>(tempPoint, vector.get_x().value()); + bg::set<1>(tempPoint, static_cast(vector.get_y()).value()); + bg::set<2>(tempPoint, static_cast(vector.get_z()).value()); - return bg::dot_product(tempPoint1, tempPoint2) * - typename cartesian1_type::quantity1::unit_type() * - typename cartesian2_type::quantity1::unit_type(); -} + result += std::pow(bg::get<0>(tempPoint), 2) + + std::pow(bg::get<1>(tempPoint), 2) + + std::pow(bg::get<2>(tempPoint), 2); + return std::sqrt(result) * typename XQuantity::unit_type(); +} -//! Returns magnitude of the cartesian vector +//! Returns magnitude of the cartesian differential vector template < typename CoordinateType, @@ -177,7 +798,7 @@ template > auto magnitude ( - cartesian_representation + cartesian_differential < CoordinateType, XQuantity, @@ -194,9 +815,9 @@ auto magnitude bg::cs::cartesian > tempPoint; - bg::set<0>(tempPoint, vector.get_x().value()); - bg::set<1>(tempPoint, static_cast(vector.get_y()).value()); - bg::set<2>(tempPoint, static_cast(vector.get_z()).value()); + bg::set<0>(tempPoint, vector.get_dx().value()); + bg::set<1>(tempPoint, static_cast(vector.get_dy()).value()); + bg::set<2>(tempPoint, static_cast(vector.get_dz()).value()); result += std::pow(bg::get<0>(tempPoint), 2) + std::pow(bg::get<1>(tempPoint), 2) + @@ -205,14 +826,38 @@ auto magnitude return std::sqrt(result) * typename XQuantity::unit_type(); } - -//! Returns magnitude of the vector other than cartesian +//! Returns magnitude of the vector other than cartesian representation template auto magnitude(Coordinate const& vector) { - return bg::get<2>(vector.get_point()) * typename Coordinate::quantity3::unit_type(); + return bg::get<2>(vector.get_point()) * + typename Coordinate::quantity3::unit_type(); +} + +//! Returns magnitude of the vector spherical differential +template +auto magnitude(spherical_differential const& vector) +{ + return bg::get<2>(vector.get_differential()) * + typename spherical_differential::quantity3::unit_type(); +} + + +//! Returns magnitude of the vector spherical coslat differential +template +auto magnitude(spherical_coslat_differential const& vector) +{ + return bg::get<2>(vector.get_differential()) * + typename spherical_coslat_differential::quantity3::unit_type(); } +//! Returns magnitude of the vector spherical equatorial differential +template +auto magnitude(spherical_equatorial_differential const& vector) +{ + return bg::get<2>(vector.get_differential()) * + typename spherical_equatorial_differential::quantity3::unit_type(); +} //! Returns the unit vector of vector given template @@ -239,19 +884,66 @@ unit_vector(cartesian_representation const& vector) return cartesian_representation(tempPoint); } +//! Returns the unit vector of vector given +template +cartesian_differential +unit_vector(cartesian_differential const& vector) +{ + bg::model::point + < + typename cartesian_differential::type, + 3, + bg::cs::cartesian + > tempPoint; + auto mag = magnitude(vector); //magnitude of vector + + //performing calculations to find unit vector + bg::set<0>(tempPoint, vector.get_dx().value() / mag.value()); + bg::set<1>(tempPoint, + vector.get_dy().value() / + static_cast::quantity2>(mag).value()); + bg::set<2>(tempPoint, + vector.get_dz().value() / + static_cast::quantity3>(mag).value()); + + return cartesian_differential(tempPoint); +} + //! Returns unit vector of given vector other than Cartesian template auto unit_vector(Coordinate const& vector) { - Coordinate tempVector; + auto tempPoint = vector.get_point(); + bg::set<2>(tempPoint,1.0); + return Coordinate(tempPoint); +} - tempVector.set_lat(vector.get_lat()); - tempVector.set_lon(vector.get_lon()); - tempVector.set_dist(1.0 * typename Coordinate::quantity3::unit_type()); +//! Returns unit vector of spherical differential vector +template +auto unit_vector(spherical_differential const& vector) +{ + auto tempPoint = vector.get_differential(); + bg::set<2>(tempPoint,1.0); + return spherical_differential(tempPoint); +} - return tempVector; +//! Returns unit vector of spherical differential vector +template +auto unit_vector(spherical_coslat_differential const& vector) +{ + auto tempPoint = vector.get_differential(); + bg::set<2>(tempPoint,1.0); + return spherical_coslat_differential(tempPoint); } +//! Returns unit vector of spherical differential vector +template +auto unit_vector(spherical_equatorial_differential const& vector) +{ + auto tempPoint = vector.get_differential(); + bg::set<2>(tempPoint,1.0); + return spherical_equatorial_differential(tempPoint); +} //! Returns sum of representation1 and representation2 template @@ -310,6 +1002,180 @@ Representation1 sum return Representation1(result); } +//! Returns sum of cartesian_differetnial and differential2 +template +auto sum +( + cartesian_differential const& differential1, + Differential2 const& differential2 +) +{ + /*!both the coordinates/vector are first converted into + cartesian differential system then sum of both cartesian + vectors is converted into the type of first argument and returned*/ + + typedef cartesian_differential Differential1; + + /*converting both coordinates/vector into cartesian system*/ + bg::model::point + < + typename std::conditional + < + sizeof(typename Differential2::type) >= + sizeof(typename Differential1::type), + typename Differential2::type, + typename Differential1::type + >::type, + 3, + bg::cs::cartesian + > result; + + auto cartesian1 = make_cartesian_differential(differential1); + auto cartesian2 = make_cartesian_differential(differential2); + + typedef decltype(cartesian1) cartesian1_type; + + //performing calculation to find the sum + bg::set<0>(result, (cartesian1.get_dx().value() + + static_cast(cartesian2.get_dx()).value())); + bg::set<1>(result, (cartesian1.get_dy().value() + + static_cast(cartesian2.get_dy()).value())); + bg::set<2>(result, (cartesian1.get_dz().value() + + static_cast(cartesian2.get_dz()).value())); + + return cartesian_differential(result); +} + +//! Returns sum of spherical_differetnial and differential2 +template +auto sum +( + spherical_differential const& differential1, + Differential2 const& differential2 +) +{ + /*!both the coordinates/vector are first converted into + cartesian differential system then sum of both cartesian + vectors is converted into the type of first argument and returned*/ + + typedef spherical_differential Differential1; + + /*converting both coordinates/vector into cartesian system*/ + bg::model::point + < + typename std::conditional + < + sizeof(typename Differential2::type) >= + sizeof(typename Differential1::type), + typename Differential2::type, + typename Differential1::type + >::type, + 3, + bg::cs::cartesian + > result; + + auto cartesian1 = make_cartesian_differential(differential1); + auto cartesian2 = make_cartesian_differential(differential2); + + typedef decltype(cartesian1) cartesian1_type; + + //performing calculation to find the sum + bg::set<0>(result, (cartesian1.get_dx().value() + + static_cast(cartesian2.get_dx()).value())); + bg::set<1>(result, (cartesian1.get_dy().value() + + static_cast(cartesian2.get_dy()).value())); + bg::set<2>(result, (cartesian1.get_dz().value() + + static_cast(cartesian2.get_dz()).value())); + + return spherical_differential(result); +} + +//! Returns sum of spherical_coslat_differetnial and differential2 +template +auto sum +( + spherical_coslat_differential const& differential1, + Differential2 const& differential2 +) +{ + /*!both the coordinates/vector are first converted into + cartesian differential system then sum of both cartesian + vectors is converted into the type of first argument and returned*/ + + typedef spherical_coslat_differential Differential1; + + /*converting both coordinates/vector into cartesian system*/ + bg::model::point + < + typename std::conditional + < + sizeof(typename Differential2::type) >= + sizeof(typename Differential1::type), + typename Differential2::type, + typename Differential1::type + >::type, + 3, + bg::cs::cartesian + > result; + + auto cartesian1 = make_cartesian_differential(differential1); + auto cartesian2 = make_cartesian_differential(differential2); + + typedef decltype(cartesian1) cartesian1_type; + + //performing calculation to find the sum + bg::set<0>(result, (cartesian1.get_dx().value() + + static_cast(cartesian2.get_dx()).value())); + bg::set<1>(result, (cartesian1.get_dy().value() + + static_cast(cartesian2.get_dy()).value())); + bg::set<2>(result, (cartesian1.get_dz().value() + + static_cast(cartesian2.get_dz()).value())); + + return spherical_coslat_differential(result); +} +//! Returns sum of spherfica_equatorial_differetnial and differential2 +template +auto sum +( + spherical_equatorial_differential const& differential1, + Differential2 const& differential2 +) +{ + /*!both the coordinates/vector are first converted into + cartesian differential system then sum of both cartesian + vectors is converted into the type of first argument and returned*/ + + typedef spherical_equatorial_differential Differential1; + + /*converting both coordinates/vector into cartesian system*/ + bg::model::point + < + typename std::conditional + < + sizeof(typename Differential2::type) >= + sizeof(typename Differential1::type), + typename Differential2::type, + typename Differential1::type + >::type, + 3, + bg::cs::cartesian + > result; + + auto cartesian1 = make_cartesian_differential(differential1); + auto cartesian2 = make_cartesian_differential(differential2); + + typedef decltype(cartesian1) cartesian1_type; + + //performing calculation to find the sum + bg::set<0>(result, (cartesian1.get_dx().value() + + static_cast(cartesian2.get_dx()).value())); + bg::set<1>(result, (cartesian1.get_dy().value() + + static_cast(cartesian2.get_dy()).value())); + bg::set<2>(result, (cartesian1.get_dz().value() + + static_cast(cartesian2.get_dz()).value())); + + return spherical_equatorial_differential(result); +} //! Returns mean of representation1 and representation2 template @@ -360,5 +1226,188 @@ Representation1 mean return Representation1(result); } +//! Returns mean of differential1(spherical coslat differential) and differential2 +template +auto mean +( + cartesian_differential const& differential1, + Differential2 const& differential2 +) +{ + + /*!both the coordinates/vector are first converted into + cartesian differential system then mean of both cartesian + vectors is converted into the type of first argument and returned*/ + + typedef cartesian_differential Differential1; + + /*converting both coordinates/vector into cartesian system*/ + bg::model::point + < + typename std::conditional + < + sizeof(typename Differential2::type) >= + sizeof(typename Differential1::type), + typename Differential2::type, + typename Differential1::type + >::type, + 3, + bg::cs::cartesian + > result; + + auto cartesian1 = make_cartesian_differential(differential1); + auto cartesian2 = make_cartesian_differential(differential2); + + typedef decltype(cartesian1) cartesian1_type; + + //performing calculation to find the mean + bg::set<0>(result, (cartesian1.get_dx().value() + + static_cast(cartesian2.get_dx()).value())/2); + bg::set<1>(result, (cartesian1.get_dy().value() + + static_cast(cartesian2.get_dy()).value())/2); + bg::set<2>(result, (cartesian1.get_dz().value() + + static_cast(cartesian2.get_dz()).value())/2); + + return cartesian_differential(result); +} + + +//! Returns mean of differential1(spherical coslat differential) and differential2 +template +auto mean +( + spherical_differential const& differential1, + Differential2 const& differential2 +) +{ + + /*!both the coordinates/vector are first converted into + cartesian differential system then mean of both cartesian + vectors is converted into the type of first argument and returned*/ + + typedef spherical_differential Differential1; + + /*converting both coordinates/vector into cartesian system*/ + bg::model::point + < + typename std::conditional + < + sizeof(typename Differential2::type) >= + sizeof(typename Differential1::type), + typename Differential2::type, + typename Differential1::type + >::type, + 3, + bg::cs::cartesian + > result; + + auto cartesian1 = make_cartesian_differential(differential1); + auto cartesian2 = make_cartesian_differential(differential2); + + typedef decltype(cartesian1) cartesian1_type; + + //performing calculation to find the mean + bg::set<0>(result, (cartesian1.get_dx().value() + + static_cast(cartesian2.get_dx()).value())/2); + bg::set<1>(result, (cartesian1.get_dy().value() + + static_cast(cartesian2.get_dy()).value())/2); + bg::set<2>(result, (cartesian1.get_dz().value() + + static_cast(cartesian2.get_dz()).value())/2); + + return spherical_differential(result); +} + + +//! Returns mean of differential1(spherical coslat differential) and differential2 +template +auto mean +( + spherical_equatorial_differential const& differential1, + Differential2 const& differential2 +) +{ + + /*!both the coordinates/vector are first converted into + cartesian differential system then mean of both cartesian + vectors is converted into the type of first argument and returned*/ + + typedef spherical_equatorial_differential Differential1; + + /*converting both coordinates/vector into cartesian system*/ + bg::model::point + < + typename std::conditional + < + sizeof(typename Differential2::type) >= + sizeof(typename Differential1::type), + typename Differential2::type, + typename Differential1::type + >::type, + 3, + bg::cs::cartesian + > result; + + auto cartesian1 = make_cartesian_differential(differential1); + auto cartesian2 = make_cartesian_differential(differential2); + + typedef decltype(cartesian1) cartesian1_type; + + //performing calculation to find the mean + bg::set<0>(result, (cartesian1.get_dx().value() + + static_cast(cartesian2.get_dx()).value())/2); + bg::set<1>(result, (cartesian1.get_dy().value() + + static_cast(cartesian2.get_dy()).value())/2); + bg::set<2>(result, (cartesian1.get_dz().value() + + static_cast(cartesian2.get_dz()).value())/2); + + return spherical_equatorial_differential(result); +} + + +//! Returns mean of differential1(spherical coslat differential) and differential2 +template +auto mean +( + spherical_coslat_differential const& differential1, + Differential2 const& differential2 +) +{ + + /*!both the coordinates/vector are first converted into + cartesian differential system then mean of both cartesian + vectors is converted into the type of first argument and returned*/ + + typedef spherical_coslat_differential Differential1; + + /*converting both coordinates/vector into cartesian system*/ + bg::model::point + < + typename std::conditional + < + sizeof(typename Differential2::type) >= + sizeof(typename Differential1::type), + typename Differential2::type, + typename Differential1::type + >::type, + 3, + bg::cs::cartesian + > result; + + auto cartesian1 = make_cartesian_differential(differential1); + auto cartesian2 = make_cartesian_differential(differential2); + + typedef decltype(cartesian1) cartesian1_type; + + //performing calculation to find the mean + bg::set<0>(result, (cartesian1.get_dx().value() + + static_cast(cartesian2.get_dx()).value())/2); + bg::set<1>(result, (cartesian1.get_dy().value() + + static_cast(cartesian2.get_dy()).value())/2); + bg::set<2>(result, (cartesian1.get_dz().value() + + static_cast(cartesian2.get_dz()).value())/2); + + return spherical_coslat_differential(result); +} + }}} // namespace boost::astronomy::coordinate #endif // !BOOST_ASTRONOMY_COORDINATE_ARITHMETIC_HPP diff --git a/include/boost/astronomy/coordinate/base_differential.hpp b/include/boost/astronomy/coordinate/base_differential.hpp index 0e8a35fc..976736fb 100644 --- a/include/boost/astronomy/coordinate/base_differential.hpp +++ b/include/boost/astronomy/coordinate/base_differential.hpp @@ -39,58 +39,6 @@ struct base_differential typedef CoordinateSystem system; typedef CoordinateType type; - //! returns the unit vector of current differential - template - ReturnType unit_vector() const - { - /*!given coordinates/vectors are converted into cartesian and - unit vector of it is returned by converting it into requested type*/ - - /*checking return type if they both are not subclass of - base_representaion then compile time erorr is generated*/ - BOOST_STATIC_ASSERT_MSG((boost::astronomy::detail::is_base_template_of - ::value), - "return type is expected to be a differential class"); - - bg::model::point tempPoint; - double mag = this->magnitude(); //magnitude of vector stored in current object - - //converting coordinate/vector into cartesian - bg::transform(this->diff, tempPoint); - - //performing calculations to find unit vector - bg::set<0>(tempPoint, (bg::get<0>(tempPoint) / mag)); - bg::set<1>(tempPoint, (bg::get<1>(tempPoint) / mag)); - bg::set<2>(tempPoint, (bg::get<2>(tempPoint) / mag)); - - return ReturnType(tempPoint); - } - - //! magnitude of the current class is returned - double magnitude() const - { - double result = 0.0; - bg::model::point tempPoint; - bg::transform(this->diff, tempPoint); - - switch (DimensionCount) - { - case 2: - result += std::pow(bg::get<0>(tempPoint), 2); - result += std::pow(bg::get<1>(tempPoint), 2); - break; - case 3: - result += std::pow(bg::get<0>(tempPoint), 2); - result += std::pow(bg::get<1>(tempPoint), 2); - result += std::pow(bg::get<2>(tempPoint), 2); - break; - default: - return -1; - } - - return std::sqrt(result); - } - //! converts current representation into specified representation template ReturnType to_differential() const diff --git a/test/coordinate/cartesian_differential.cpp b/test/coordinate/cartesian_differential.cpp index 22581e54..aaaaf19f 100644 --- a/test/coordinate/cartesian_differential.cpp +++ b/test/coordinate/cartesian_differential.cpp @@ -250,3 +250,116 @@ BOOST_AUTO_TEST_CASE(cartesian_differential_multiplication_operator) BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE(cartesian_differential_arithmetic_function) + +BOOST_AUTO_TEST_CASE(cartesian_differential_cross_product) +{ + auto motion1 = make_cartesian_differential + (3.0*meters/second,9.0*si::kilo*meters/second,18.0*si::centi*meters/second); + auto motion2 = make_cartesian_differential + (2.0*si::kilo*meters/second,29.0*meters/second,38.0*si::kilo*meters/second); + + auto result = boost::astronomy::coordinate::cross(motion1,motion2); + + BOOST_CHECK_CLOSE(result.get_dx().value(), 342, 0.001); + BOOST_CHECK_CLOSE(result.get_dy().value(), -11364, 0.001); + BOOST_CHECK_CLOSE(result.get_dz().value(), -1.79999e+07, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same::type>>::value)); + BOOST_TEST((std::is_same::type>>::value)); + BOOST_TEST((std::is_same::type>>::value)); + +} + +BOOST_AUTO_TEST_CASE(cartesian_differential_dot_product) +{ + auto motion1 = make_cartesian_differential + (3.0 * meters/second, 5.0 * si::kilo *meters/second, 4.0 * si::mega * meters/second); + auto motion2 = make_cartesian_differential + (3.0 * si::milli * meters/second, 5.0 * si::centi * meters/second, 4.0 * meters/second); + + auto result = dot(motion1, motion2); + + BOOST_CHECK_CLOSE(result.value(), 16000250009.0, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same::type>>::value)); +} + +BOOST_AUTO_TEST_CASE(cartesian_differential_unit_vector) +{ + auto motion1 = make_cartesian_differential + (25.0*meter/second, 36.0*meter/second, 90.0*meter/second); + + auto result = boost::astronomy::coordinate::unit_vector(motion1); + + BOOST_CHECK_CLOSE(result.get_dx().value(), 0.2497379127153113, 0.001); + BOOST_CHECK_CLOSE(result.get_dy().value(), 0.3596225943100483, 0.001); + BOOST_CHECK_CLOSE(result.get_dz().value(), 0.8990564857751207, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); +} + +BOOST_AUTO_TEST_CASE(cartesian_differential_magnitude) +{ + auto motion1 = make_cartesian_differential + (25.0 * meter/second, 3600.0 * si::centi*meter/second, 90.0 * meter/second); + + auto result = boost::astronomy::coordinate::magnitude(motion1); + + BOOST_CHECK_CLOSE(result.value(), 100.1049449328054, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same>::value)); +} + +BOOST_AUTO_TEST_CASE(cartesian_differential_sum) +{ + auto motion1 = make_cartesian_differential + (10.0 * meter/second, 20.0 * si::kilo * meters/second, 30.0 * meter/second); + auto motion2 = make_cartesian_differential + (50.0 * si::centi * meter/second, 60.0 * meter/second, 30.0 * meter/second); + + auto result = boost::astronomy::coordinate::sum(motion1, motion2); + + BOOST_CHECK_CLOSE(result.get_dx().value(), 10.5, 0.001); + BOOST_CHECK_CLOSE(result.get_dy().value(), 20.06, 0.001); + BOOST_CHECK_CLOSE(result.get_dz().value(), 60, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); +} + +BOOST_AUTO_TEST_CASE(cartesian_differential_mean) +{ + auto motion1 = make_cartesian_differential + (10.0 * meter/second, 20.0 * si::kilo * meters/second, 30.0 * meter/second); + auto motion2 = make_cartesian_differential + (50.0 * si::centi * meter/second, 60.0 * meter/second, 30.0 * meter/second); + + auto result = boost::astronomy::coordinate::mean(motion1, motion2); + + BOOST_CHECK_CLOSE(result.get_dx().value(), 5.25, 0.001); + BOOST_CHECK_CLOSE(result.get_dy().value(), 10.03, 0.001); + BOOST_CHECK_CLOSE(result.get_dz().value(), 30.0, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); +} +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/coordinate/spherical_differential.cpp b/test/coordinate/spherical_differential.cpp index 71c84283..7d6a0c31 100644 --- a/test/coordinate/spherical_differential.cpp +++ b/test/coordinate/spherical_differential.cpp @@ -234,3 +234,113 @@ BOOST_AUTO_TEST_CASE(spherical_differential_multiplication_operator) BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE(spherical_differential_arithmetic_functions) + +BOOST_AUTO_TEST_CASE(spherical_differential_cross_product) +{ + auto motion1 = make_spherical_differential + (3.0 * bud::degrees, 50.0 * bud::degrees, 40.0 * meters/second); + auto motion2 = make_spherical_differential + (30.0 * bud::degrees, 45.0 * bud::degrees, 14.0 * meters/second); + + auto result = cross(motion1, motion2); + + BOOST_CHECK_CLOSE(result.get_dlat().value(), -143.4774246228, 0.001); + BOOST_CHECK_CLOSE(result.get_dlon().value(), 45.186034054587, 0.001); + BOOST_CHECK_CLOSE(result.get_ddist().value(), 195.39050840581, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same::type>>::value)); +} + +BOOST_AUTO_TEST_CASE(spherical_differential_dot_product) +{ + auto motion1 = make_spherical_differential + (3.0 * bud::degrees, 50.0 * bud::degrees, 40.0 * meters/second); + auto motion2 = make_spherical_differential + (30.0 * bud::degrees, 45.0 * bud::degrees, 14.0 * meters/second); + + auto result = dot(motion1, motion2); + + BOOST_CHECK_CLOSE(result.value(), 524.807154, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same::type>>::value)); +} + +BOOST_AUTO_TEST_CASE(spherical_differential_unit_vector) +{ + auto motion1 = make_spherical_differential + (25.0 * bud::degrees, 30.0 * bud::degrees, 90.0*meter/second); + + auto result = boost::astronomy::coordinate::unit_vector(motion1); + + BOOST_CHECK_CLOSE(result.get_dlat().value(), 25.0, 0.001); + BOOST_CHECK_CLOSE(result.get_dlon().value(), 30.0, 0.001); + BOOST_CHECK_CLOSE(result.get_ddist().value(), 1, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); +} + +BOOST_AUTO_TEST_CASE(spherical_differential_magnitude) +{ + auto motion1 = make_spherical_differential + (25.0 * bud::degrees, 36.0 * bud::degrees, 9.0 * meters/second); + + auto result = boost::astronomy::coordinate::magnitude(motion1); + + BOOST_CHECK_CLOSE(result.value(), 9, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same>::value)); + +} + +BOOST_AUTO_TEST_CASE(spherical_differential_sum) +{ + auto motion1 = make_spherical_differential + (15.0 * bud::degrees, 30.0 * bud::degrees, 10.0 * meters/second); + auto motion2 = make_spherical_differential + (30.0 * bud::degrees, 45.0 * bud::degrees, 20.0 * meters/second); + + auto result = boost::astronomy::coordinate::sum(motion1, motion2); + + BOOST_CHECK_CLOSE(result.get_dlat().value(), 26.097805456, 0.001); + BOOST_CHECK_CLOSE(result.get_dlon().value(), 39.826115507, 0.001); + BOOST_CHECK_CLOSE(result.get_ddist().value(), 29.6909332103, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); +} + +BOOST_AUTO_TEST_CASE(spherical_differential_mean) +{ + auto motion1 = make_spherical_differential + (15.0 * bud::degrees, 30.0 * bud::degrees, 10.0 * meter/second); + auto motion2 = make_spherical_differential + (30.0 * bud::degrees, 45.0 * bud::degrees, 20.0 * meter/second); + + auto result = boost::astronomy::coordinate::mean(motion1, motion2); + + BOOST_CHECK_CLOSE(result.get_dlat().value(), 26.097805456543, 0.001); + BOOST_CHECK_CLOSE(result.get_dlon().value(), 39.826115384099, 0.001); + BOOST_CHECK_CLOSE(result.get_ddist().value(), 14.845466643593, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/coordinate/spherical_equatorial_differential.cpp b/test/coordinate/spherical_equatorial_differential.cpp index 0dba0e3b..35f4a55a 100644 --- a/test/coordinate/spherical_equatorial_differential.cpp +++ b/test/coordinate/spherical_equatorial_differential.cpp @@ -234,3 +234,113 @@ BOOST_AUTO_TEST_CASE(spherical_equatorial_differential_multiplication_operator) BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE(spherical_equatorial_differential_arithmetic_functions) + +BOOST_AUTO_TEST_CASE(spherical_equatorial_differential_cross_product) +{ + auto motion1 = make_spherical_equatorial_differential + (3.0 * bud::degrees, 50.0 * bud::degrees, 40.0 * meters/second); + auto motion2 = make_spherical_equatorial_differential + (30.0 * bud::degrees, 45.0 * bud::degrees, 14.0 * meters/second); + + auto result = cross(motion1, motion2); + + BOOST_CHECK_CLOSE(result.get_dlat().value(), 176.47742460814121, 0.001); + BOOST_CHECK_CLOSE(result.get_dlon().value(), 39.816895281423861, 0.001); + BOOST_CHECK_CLOSE(result.get_ddist().value(), 180.459280550626, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same::type>>::value)); +} + +BOOST_AUTO_TEST_CASE(spherical_equatorial_differential_dot_product) +{ + auto motion1 = make_spherical_equatorial_differential + (3.0 * bud::degrees, 50.0 * bud::degrees, 40.0 * meters/second); + auto motion2 = make_spherical_equatorial_differential + (30.0 * bud::degrees, 45.0 * bud::degrees, 14.0 * meters/second); + + auto result = dot(motion1, motion2); + + BOOST_CHECK_CLOSE(result.value(), 530.12682262186127, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same::type>>::value)); +} + +BOOST_AUTO_TEST_CASE(spherical_equatorial_differential_unit_vector) +{ + auto motion1 = make_spherical_equatorial_differential + (25.0 * bud::degrees, 30.0 * bud::degrees, 90.0*meter/second); + + auto result = boost::astronomy::coordinate::unit_vector(motion1); + + BOOST_CHECK_CLOSE(result.get_dlat().value(), 25.0, 0.001); + BOOST_CHECK_CLOSE(result.get_dlon().value(), 30.0, 0.001); + BOOST_CHECK_CLOSE(result.get_ddist().value(), 1, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); +} + +BOOST_AUTO_TEST_CASE(spherical_equatorial_differential_magnitude) +{ + auto motion1 = make_spherical_equatorial_differential + (25.0 * bud::degrees, 36.0 * bud::degrees, 9.0 * meters/second); + + auto result = boost::astronomy::coordinate::magnitude(motion1); + + BOOST_CHECK_CLOSE(result.value(), 9, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same>::value)); + +} + +BOOST_AUTO_TEST_CASE(spherical_equatorial_differential_sum) +{ + auto motion1 = make_spherical_equatorial_differential + (15.0 * bud::degrees, 30.0 * bud::degrees, 10.0 * meters/second); + auto motion2 = make_spherical_equatorial_differential + (30.0 * bud::degrees, 45.0 * bud::degrees, 20.0 * meters/second); + + auto result = boost::astronomy::coordinate::sum(motion1, motion2); + + BOOST_CHECK_CLOSE(result.get_dlat().value(), 24.312825776474799, 0.001); + BOOST_CHECK_CLOSE(result.get_dlon().value(), 40.241218583331623, 0.001); + BOOST_CHECK_CLOSE(result.get_ddist().value(), 29.631468013173954, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); +} + +BOOST_AUTO_TEST_CASE(spherical_equatorial_differential_mean) +{ + auto motion1 = make_spherical_equatorial_differential + (15.0 * bud::degrees, 30.0 * bud::degrees, 10.0 * meter/second); + auto motion2 = make_spherical_equatorial_differential + (30.0 * bud::degrees, 45.0 * bud::degrees, 20.0 * meter/second); + + auto result = boost::astronomy::coordinate::mean(motion1, motion2); + + BOOST_CHECK_CLOSE(result.get_dlat().value(), 24.312825776474799, 0.001); + BOOST_CHECK_CLOSE(result.get_dlon().value(), 40.241218583331623, 0.001); + BOOST_CHECK_CLOSE(result.get_ddist().value(), 14.815734006586977, 0.001); + + //checking whether quantity stored is as expected or not + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); + BOOST_TEST((std::is_same>::value)); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file