24 #ifndef MT_BASIC_SCALAR_H
25 #define MT_BASIC_SCALAR_H
34 #include <mt/basic_scalar_traits.h>
35 #include <mt/exception.h>
188 bool operator< (const BasicScalar<T>& s)
const;
191 bool operator<=(const BasicScalar<T>& s)
const;
236 friend std::ostream& operator<<(std::ostream& os,
240 friend std::istream& operator>>(std::istream& is,
272 template<
class T1,
class T2>
303 template<
class T1,
class T2>
322 template<
class T1,
class T2>
337 template<
class T1,
class T2>
352 template<
class T1,
class T2>
367 template<
class T1,
class T2>
386 std::ostream& operator<<(std::ostream& os,
391 std::istream& operator>>(std::istream& is,
435 template<
class T1,
class T2>
475 template<
class T1,
class T2>
539 template<
class T>
inline
543 template<
class T1>
template<
class T2>
inline
549 template<
class T1>
template<
class T2>
inline
557 template<
class T>
inline
565 template<
class T>
inline
573 template<
class T>
inline
574 BasicScalar<T>& BasicScalar<T>::operator-=(
const BasicScalar<T>& s)
581 template<
class T>
inline
582 BasicScalar<T>& BasicScalar<T>::operator*=(
const BasicScalar<T>& s)
589 template<
class T>
inline
590 BasicScalar<T>& BasicScalar<T>::operator/=(
const BasicScalar<T>& s)
592 util::Assert(std::abs(s.m_val) >= std::numeric_limits<T>::epsilon(),
599 template<
class T>
inline
600 bool BasicScalar<T>::operator==(
const BasicScalar<T>& s)
const
604 return test ? absEquality(s) : relEquality(s);
608 template<
class T>
inline
609 bool BasicScalar<T>::operator<(
const BasicScalar<T>& s)
const
613 return test ? absLessThan(s) : relLessThan(s);
617 template<
class T>
inline
618 bool BasicScalar<T>::operator!=(
const BasicScalar<T>& s)
const
620 return !(*
this == s);
624 template<
class T>
inline
625 bool BasicScalar<T>::operator>(
const BasicScalar<T>& s)
const
631 template<
class T>
inline
632 bool BasicScalar<T>::operator<=(
const BasicScalar<T>& s)
const
634 return (*
this < s) || (*
this == s);
638 template<
class T>
inline
639 bool BasicScalar<T>::operator>=(
const BasicScalar<T>& s)
const
641 return (*
this > s) || (*
this == s);
647 template<
class T>
inline
654 template<
class T>
inline
661 template<
class T>
inline
668 template<
class T>
inline
677 template<
class T>
inline
680 const T diff = std::abs(m_val - s.m_val);
681 return diff <= BasicScalarTraits<T>::getTestTol();
685 template<
class T>
inline
686 bool BasicScalar<T>::absLessThan(
const BasicScalar<T>& s)
const
688 const T diff = s.m_val - m_val;
693 template<
class T>
inline
694 bool BasicScalar<T>::relEquality(
const BasicScalar<T>& s)
const
696 T ref = std::min(std::abs(s.m_val), std::abs(m_val));
698 if (!(ref > std::numeric_limits<T>::epsilon()))
703 const T diff = std::abs(s.m_val - m_val);
708 template<
class T>
inline
709 bool BasicScalar<T>::relLessThan(
const BasicScalar<T>& s)
const
711 T ref = std::min(std::abs(s.m_val), std::abs(m_val));
712 if (!(ref > std::numeric_limits<T>::epsilon()))
717 const T diff = s.m_val - m_val;
726 template<
class T>
inline
727 BasicScalar<T> operator+(
const BasicScalar<T>& s)
733 template<
class T>
inline
734 BasicScalar<T> operator-(
const BasicScalar<T>& s)
736 const BasicScalar<T> s1(-s.getValue());
741 template<
class T1,
class T2>
inline
742 BasicScalar<T1> operator+(
const BasicScalar<T1>& s1,
743 const BasicScalar<T2>& s2)
745 BasicScalar<T1> s(s2);
768 template<
class T1,
class T2>
inline
769 BasicScalar<T1> operator-(
const BasicScalar<T1>& s1,
770 const BasicScalar<T2>& s2)
772 BasicScalar<T1> s3(s1);
773 const BasicScalar<T1> s4(s2);
796 template<
class T1,
class T2>
inline
797 BasicScalar<T1> operator*(
const BasicScalar<T1>& s1,
798 const BasicScalar<T2>& s2)
800 BasicScalar<T1> s(s2);
823 template<
class T1,
class T2>
inline
824 BasicScalar<T1> operator/(
const BasicScalar<T1>& s1,
825 const BasicScalar<T2>& s2)
827 BasicScalar<T1> s3(s1);
828 const BasicScalar<T1> s4(s2);
851 template<
class T>
inline
852 std::ostream& operator<<(std::ostream& os,
853 const BasicScalar<T>& s)
857 return os << std::setw(width) << round(s, tol).m_val;
861 template<
class T>
inline
862 std::istream& operator>>(std::istream& is,
863 const BasicScalar<T>& s)
865 return is >> s.m_val;
871 template<
class T>
inline
872 BasicScalar<T> min(
const BasicScalar<T>& s1,
873 const BasicScalar<T>& s2)
875 const T x = std::min(s1.m_val, s2.m_val);
876 return BasicScalar<T>(x);
880 template<
class T>
inline
881 BasicScalar<T> max(
const BasicScalar<T>& s1,
882 const BasicScalar<T>& s2)
884 const T x = std::max(s1.m_val, s2.m_val);
885 return BasicScalar<T>(x);
889 template<
class T>
inline
890 BasicScalar<T> abs(
const BasicScalar<T>& s)
892 const T x = std::abs(s.m_val);
893 return BasicScalar<T>(x);
897 template<
class T>
inline
898 BasicScalar<T> ceil(
const BasicScalar<T>& s)
900 const T x = std::ceil(s.m_val);
901 return BasicScalar<T>(x);
905 template<
class T>
inline
906 BasicScalar<T> floor(
const BasicScalar<T>& s)
908 const T x = std::floor(s.m_val);
909 return BasicScalar<T>(x);
913 template<
class T>
inline
914 BasicScalar<T> sqrt(
const BasicScalar<T>& s)
916 util::Assert((s >= 0.0), Exception(
"Negative sqrt parameter"));
917 const T x = std::sqrt(std::abs(s.m_val));
918 return BasicScalar<T>(x);
922 template<
class T>
inline
923 BasicScalar<T> exp(
const BasicScalar<T>& s)
925 const T x = std::exp(s.m_val);
926 return BasicScalar<T>(x);
930 template<
class T>
inline
931 BasicScalar<T> log(
const BasicScalar<T>& s)
933 util::Assert((s >= 0.0), Exception(
"Negative log parameter"));
934 const T x = std::log(std::abs(s.m_val));
935 return BasicScalar<T>(x);
939 template<
class T>
inline
940 BasicScalar<T> log10(
const BasicScalar<T>& s)
942 util::Assert((s >= 0.0), Exception(
"Negative log10 parameter"));
943 const T x = std::log10(std::abs(s.m_val));
944 return BasicScalar<T>(x);
948 template<
class T1,
class T2>
inline
949 BasicScalar<T1> pow(
const BasicScalar<T1>& s1,
950 const BasicScalar<T2>& s2)
952 const T1 x = std::pow(s1.m_val, static_cast<T1>(s2.m_val));
953 return BasicScalar<T1>(x);
957 template<
class T>
inline
958 BasicScalar<T> sin(
const BasicScalar<T>& s)
960 const T x = std::sin(s.m_val);
961 return BasicScalar<T>(x);
965 template<
class T>
inline
966 BasicScalar<T> cos(
const BasicScalar<T>& s)
968 const T x = std::cos(s.m_val);
969 return BasicScalar<T>(x);
973 template<
class T>
inline
974 BasicScalar<T> tan(
const BasicScalar<T>& s)
976 const T x = std::tan(s.m_val);
977 return BasicScalar<T>(x);
981 template<
class T>
inline
982 BasicScalar<T> sinh(
const BasicScalar<T>& s)
984 const T x = std::sinh(s.m_val);
985 return BasicScalar<T>(x);
989 template<
class T>
inline
990 BasicScalar<T> cosh(
const BasicScalar<T>& s)
992 const T x = std::cosh(s.m_val);
993 return BasicScalar<T>(x);
997 template<
class T>
inline
998 BasicScalar<T> tanh(
const BasicScalar<T>& s)
1000 const T x = std::tanh(s.m_val);
1001 return BasicScalar<T>(x);
1005 template<
class T>
inline
1006 BasicScalar<T> asin(
const BasicScalar<T>& s)
1008 const BasicScalar<T> s1(saturate(s,
1009 BasicScalar<T>(-1.0),
1010 BasicScalar<T>( 1.0)));
1011 const T x = std::asin(s1.m_val);
1012 return BasicScalar<T>(x);
1016 template<
class T>
inline
1017 BasicScalar<T> acos(
const BasicScalar<T>& s)
1019 const BasicScalar<T> s1(saturate(s,
1020 BasicScalar<T>(-1.0),
1021 BasicScalar<T>( 1.0)));
1022 const T x = std::acos(s1.m_val);
1023 return BasicScalar<T>(x);
1027 template<
class T>
inline
1028 BasicScalar<T> atan(
const BasicScalar<T>& s)
1030 const T x = std::atan(s.m_val);
1031 return BasicScalar<T>(x);
1035 template<
class T1,
class T2>
inline
1036 BasicScalar<T1> atan2(
const BasicScalar<T1>& s1,
1037 const BasicScalar<T2>& s2)
1040 T1 t2 =
static_cast<T1
>(s2.m_val);
1043 if (s1 == BasicScalar<T1>(0.0))
1045 t1 =
static_cast<T1
>(0.0);
1048 if (s2 == BasicScalar<T2>(0.0))
1050 t2 =
static_cast<T1
>(0.0);
1053 const T1 x = std::atan2(t1, t2);
1054 return BasicScalar<T1>(x);
1058 template<
class T>
inline
1059 BasicScalar<T> normalize(
const BasicScalar<T>& s,
1060 const BasicScalar<T>& lower,
1061 const BasicScalar<T>& upper,
1062 BasicScalar<T>& cycles)
1064 util::Assert(lower < upper,
1065 Exception(
"Normalizing interval is ill defined"));
1067 BasicScalar<T> s_norm(s);
1068 if (s >= lower && s < upper)
1070 cycles = BasicScalar<T>(0.0);
1074 const BasicScalar<T> diff(upper - lower);
1075 cycles = (s.getValue() < lower.getValue()) ?
1076 ceil((s - upper) / diff) : floor((s - lower) / diff);
1077 s_norm -= (diff * cycles);
1083 template<
class T>
inline
1084 BasicScalar<T> normalize(
const BasicScalar<T>& s,
1085 const BasicScalar<T>& lower,
1086 const BasicScalar<T>& upper)
1088 BasicScalar<T> cycles;
1089 return normalize(s, lower, upper, cycles);
1093 template<
class T>
inline
1094 BasicScalar<T> saturate(
const BasicScalar<T>& s,
1095 const BasicScalar<T>& lower,
1096 const BasicScalar<T>& upper)
1098 util::Assert(lower < upper,
1099 Exception(
"Saturation interval is ill defined"));
1101 BasicScalar<T> s_sat(s);
1102 if (s.getValue() < lower.getValue())
1106 else if (s.getValue() > upper.getValue())
1114 template<
class T>
inline
1115 BasicScalar<T> round(
const BasicScalar<T>& s,
1116 const BasicScalar<T>& tol)
1118 if (tol > std::numeric_limits<T>::epsilon())
1121 const T abs_tol = std::abs(tol.getValue());
1122 const T x = (s.getValue() + std::numeric_limits<T>::epsilon()) / abs_tol;
1123 return BasicScalar<T>(std::floor(x + 0.5) * abs_tol);
1132 template<
class T>
inline
1133 T getValue(
const BasicScalar<T> s)
1135 return s.getValue();
1140 #endif // MT_BASIC_SCALAR_H