mt
 All Classes Files Functions Enumerations Groups Pages
basic_scalar.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2006 by Adolfo Rodriguez *
3  * adolfo.rodriguez@upc.edu *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
20 
22 
23 // HEADER GUARD
24 #ifndef MT_BASIC_SCALAR_H
25 #define MT_BASIC_SCALAR_H
26 
27 // C++ STANDARD HEADERS
28 #include <algorithm>
29 #include <cmath>
30 #include <iomanip>
31 #include <iostream>
32 
33 // MT LIBRARY HEADERS
34 #include <mt/basic_scalar_traits.h>
35 #include <mt/exception.h>
36 
37 
39 
40 namespace mt
41 {
42 
43 
45 
48 
143 
144 template<class T>
146 {
147 public:
148 
149 // LIFECYCLE
150 
151  // Compiler generated default constructor for a BasicScalar<T> is being used
152 
154  BasicScalar(const T& x = 0.0);
155 
156  // Compiler generated copy constructor for a BasicScalar<T> is being used
157 
159  template<class T2>
160  BasicScalar(const BasicScalar<T2>& s);
161 
162 
163  // Compiler generated destructor is being used
164 
165 
166 // OPERATORS
167 
168  // Compiler generated assignment operator for a BasicScalar<T> is being used
169 
173  template<class T2>
175 
176 
180  BasicScalar<T>& operator=(const T& x);
181 
182  BasicScalar<T>& operator+=(const BasicScalar<T>& s);
183  BasicScalar<T>& operator-=(const BasicScalar<T>& s);
184  BasicScalar<T>& operator*=(const BasicScalar<T>& s);
185  BasicScalar<T>& operator/=(const BasicScalar<T>& s);
186 
187  bool operator==(const BasicScalar<T>& s) const;
188  bool operator< (const BasicScalar<T>& s) const;
189  bool operator!=(const BasicScalar<T>& s) const;
190  bool operator> (const BasicScalar<T>& s) const;
191  bool operator<=(const BasicScalar<T>& s) const;
192  bool operator>=(const BasicScalar<T>& s) const;
193 
194 
195 // ACCESS
196 
198  T getValue() const;
199 
201  T& getRef();
202 
204  const T& getRef() const;
205 
207  void setValue(const T& x);
208 
209 
210 private:
211 
212 // MEMBERS
213 
215  T m_val;
216 
217 
218 // METHODS
219 
221  bool absEquality(const BasicScalar<T>& s) const;
222 
224  bool absLessThan(const BasicScalar<T>& s) const;
225 
227  bool relEquality(const BasicScalar<T>& s) const;
228 
230  bool relLessThan(const BasicScalar<T>& s) const;
231 
232 
233 // FRIENDS
234 
235  template<class T1>
236  friend std::ostream& operator<<(std::ostream& os,
237  const BasicScalar<T1>& s);
238 
239  template<class T1>
240  friend std::istream& operator>>(std::istream& is,
241  const BasicScalar<T1>& s);
242 
243  template<class T1>
244  friend BasicScalar<T1> min(const BasicScalar<T1>& s1,
245  const BasicScalar<T1>& s2);
246 
247  template<class T1>
248  friend BasicScalar<T1> max(const BasicScalar<T1>& s1,
249  const BasicScalar<T1>& s2);
250 
251  template<class T1>
252  friend BasicScalar<T1> abs(const BasicScalar<T1>& s);
253 
254  template<class T1>
255  friend BasicScalar<T1> ceil(const BasicScalar<T1>& s);
256 
257  template<class T1>
258  friend BasicScalar<T1> floor(const BasicScalar<T1>& s);
259 
260  template<class T1>
261  friend BasicScalar<T1> sqrt(const BasicScalar<T1>& s);
262 
263  template<class T1>
264  friend BasicScalar<T1> exp(const BasicScalar<T1>& s);
265 
266  template<class T1>
267  friend BasicScalar<T1> log(const BasicScalar<T1>& s);
268 
269  template<class T1>
270  friend BasicScalar<T1> log10(const BasicScalar<T1>& s);
271 
272  template<class T1, class T2>
273  friend BasicScalar<T1> pow(const BasicScalar<T1>& s1,
274  const BasicScalar<T2>& s2);
275 
276  template<class T1>
277  friend BasicScalar<T1> sin(const BasicScalar<T1>& s);
278 
279  template<class T1>
280  friend BasicScalar<T1> cos(const BasicScalar<T1>& s);
281 
282  template<class T2>
283  friend BasicScalar<T2> tan(const BasicScalar<T2>& s);
284 
285  template<class T2>
286  friend BasicScalar<T2> sinh(const BasicScalar<T2>& s);
287 
288  template<class T2>
289  friend BasicScalar<T2> cosh(const BasicScalar<T2>& s);
290 
291  template<class T2>
292  friend BasicScalar<T2> tanh(const BasicScalar<T2>& s);
293 
294  template<class T2>
295  friend BasicScalar<T2> asin(const BasicScalar<T2>& s);
296 
297  template<class T2>
298  friend BasicScalar<T2> acos(const BasicScalar<T2>& s);
299 
300  template<class T2>
301  friend BasicScalar<T2> atan(const BasicScalar<T2>& s);
302 
303  template<class T1, class T2>
304  friend BasicScalar<T1> atan2(const BasicScalar<T1>& s1,
305  const BasicScalar<T2>& s2);
306 
307 };
308 
309 
311 
312 // OPERATORS
313 
314 template<class T>
315 BasicScalar<T> operator+(const BasicScalar<T>& s);
316 
317 
318 template<class T>
319 BasicScalar<T> operator-(const BasicScalar<T>& s);
320 
321 
322 template<class T1, class T2>
323 BasicScalar<T1> operator+(const BasicScalar<T1>& s1,
324  const BasicScalar<T2>& s2);
325 
326 
327 // template<class T>
328 // BasicScalar<T> operator+(const BasicScalar<T>& s,
329 // const T& x);
330 //
331 //
332 // template<class T>
333 // BasicScalar<T> operator+(const T& x,
334 // const BasicScalar<T>& s);
335 
336 
337 template<class T1, class T2>
338 BasicScalar<T1> operator-(const BasicScalar<T1>& s1,
339  const BasicScalar<T2>& s2);
340 
341 
342 // template<class T>
343 // BasicScalar<T> operator-(const BasicScalar<T>& s,
344 // const T& x);
345 //
346 //
347 // template<class T>
348 // BasicScalar<T> operator-(const T& x,
349 // const BasicScalar<T>& s);
350 
351 
352 template<class T1, class T2>
353 BasicScalar<T1> operator*(const BasicScalar<T1>& s1,
354  const BasicScalar<T2>& s2);
355 
356 
357 // template<class T>
358 // BasicScalar<T> operator*(const BasicScalar<T>& s,
359 // const T& x);
360 //
361 //
362 // template<class T>
363 // BasicScalar<T> operator*(const T& x,
364 // const BasicScalar<T>& s);
365 
366 
367 template<class T1, class T2>
368 BasicScalar<T1> operator/(const BasicScalar<T1>& s1,
369  const BasicScalar<T2>& s2);
370 
371 
372 // template<class T>
373 // BasicScalar<T> operator/(const BasicScalar<T>& s,
374 // const T& x);
375 //
376 //
377 // template<class T>
378 // BasicScalar<T> operator/(const T& x,
379 // const BasicScalar<T>& s);
380 
385 template<class T>
386 std::ostream& operator<<(std::ostream& os,
387  const BasicScalar<T>& s);
388 
389 
390 template<class T>
391 std::istream& operator>>(std::istream& is,
392  const BasicScalar<T>& s);
393 
394 
395 // FUNCTIONS
396 
397 template<class T>
398 BasicScalar<T> min(const BasicScalar<T>& s1,
399  const BasicScalar<T>& s2);
400 
401 
402 template<class T>
403 BasicScalar<T> max(const BasicScalar<T>& s1,
404  const BasicScalar<T>& s2);
405 
406 
407 template<class T>
408 BasicScalar<T> abs(const BasicScalar<T>& s);
409 
410 
411 template<class T>
412 BasicScalar<T> ceil(const BasicScalar<T>& s);
413 
414 
415 template<class T>
416 BasicScalar<T> floor(const BasicScalar<T>& s);
417 
418 
419 template<class T>
420 BasicScalar<T> sqrt(const BasicScalar<T>& s);
421 
422 
423 template<class T>
424 BasicScalar<T> exp(const BasicScalar<T>& s);
425 
426 
427 template<class T>
428 BasicScalar<T> log(const BasicScalar<T>& s);
429 
430 
431 template<class T>
432 BasicScalar<T> log10(const BasicScalar<T>& s);
433 
434 
435 template<class T1, class T2>
436 BasicScalar<T1> pow(const BasicScalar<T1>& s1,
437  const BasicScalar<T2>& s2);
438 
439 
440 template<class T>
441 BasicScalar<T> sin(const BasicScalar<T>& s);
442 
443 
444 template<class T>
445 BasicScalar<T> cos(const BasicScalar<T>& s);
446 
447 
448 template<class T>
449 BasicScalar<T> tan(const BasicScalar<T>& s);
450 
451 
452 template<class T>
453 BasicScalar<T> sinh(const BasicScalar<T>& s);
454 
455 
456 template<class T>
457 BasicScalar<T> cosh(const BasicScalar<T>& s);
458 
459 
460 template<class T>
461 BasicScalar<T> tanh(const BasicScalar<T>& s);
462 
463 template<class T>
464 BasicScalar<T> asin(const BasicScalar<T>& s);
465 
466 
467 template<class T>
468 BasicScalar<T> acos(const BasicScalar<T>& s);
469 
470 
471 template<class T>
472 BasicScalar<T> atan(const BasicScalar<T>& s);
473 
474 
475 template<class T1, class T2>
476 BasicScalar<T1> atan2(const BasicScalar<T1>& s1,
477  const BasicScalar<T2>& s2);
478 
479 
500 template<class T>
501 BasicScalar<T> normalize(const BasicScalar<T>& s,
502  const BasicScalar<T>& lower,
503  const BasicScalar<T>& upper,
504  BasicScalar<T>& cycles);
505 
507 template<class T>
508 BasicScalar<T> normalize(const BasicScalar<T>& s,
509  const BasicScalar<T>& lower,
510  const BasicScalar<T>& upper);
511 
512 
515 template<class T>
516 BasicScalar<T> saturate(const BasicScalar<T>& s,
517  const BasicScalar<T>& lower,
518  const BasicScalar<T>& upper);
519 
520 
526 template<class T>
527 BasicScalar<T> round(const BasicScalar<T>& s,
528  const BasicScalar<T>& tol = BasicScalar<T>(1.0));
529 
531 template<class T>
532 T getValue(const BasicScalar<T> s);
533 
534 
536 
537 // LIFECYCLE
538 
539 template<class T> inline
540 BasicScalar<T>::BasicScalar(const T& x) : m_val(x) {}
541 
542 
543 template<class T1> template<class T2> inline
544 BasicScalar<T1>::BasicScalar(const BasicScalar<T2>& s) : m_val(s.getValue()){}
545 
546 
547 // OPERATORS
548 
549 template<class T1> template<class T2> inline
551 {
552  m_val = s.getValue();
553  return *this;
554 }
555 
556 
557 template<class T> inline
559 {
560  m_val = x;
561  return *this;
562 }
563 
564 
565 template<class T> inline
567 {
568  m_val += s.m_val;
569  return *this;
570 }
571 
572 
573 template<class T> inline
574 BasicScalar<T>& BasicScalar<T>::operator-=(const BasicScalar<T>& s)
575 {
576  m_val -= s.m_val;
577  return *this;
578 }
579 
580 
581 template<class T> inline
582 BasicScalar<T>& BasicScalar<T>::operator*=(const BasicScalar<T>& s)
583 {
584  m_val *= s.m_val;
585  return *this;
586 }
587 
588 
589 template<class T> inline
590 BasicScalar<T>& BasicScalar<T>::operator/=(const BasicScalar<T>& s)
591 {
592  util::Assert(std::abs(s.m_val) >= std::numeric_limits<T>::epsilon(),
593  ZeroDivide());
594  m_val /= s.m_val;
595  return *this;
596 }
597 
598 
599 template<class T> inline
600 bool BasicScalar<T>::operator==(const BasicScalar<T>& s) const
601 {
602  const bool test =
603  BasicScalarTraits<T>::getTolType() == BasicScalarTraits<T>::ABSOLUTE;
604  return test ? absEquality(s) : relEquality(s);
605 }
606 
607 
608 template<class T> inline
609 bool BasicScalar<T>::operator<(const BasicScalar<T>& s) const
610 {
611  const bool test =
612  BasicScalarTraits<T>::getTolType() == BasicScalarTraits<T>::ABSOLUTE;
613  return test ? absLessThan(s) : relLessThan(s);
614 }
615 
616 
617 template<class T> inline
618 bool BasicScalar<T>::operator!=(const BasicScalar<T>& s) const
619 {
620  return !(*this == s);
621 }
622 
623 
624 template<class T> inline
625 bool BasicScalar<T>::operator>(const BasicScalar<T>& s) const
626 {
627  return s < *this;
628 }
629 
630 
631 template<class T> inline
632 bool BasicScalar<T>::operator<=(const BasicScalar<T>& s) const
633 {
634  return (*this < s) || (*this == s);
635 }
636 
637 
638 template<class T> inline
639 bool BasicScalar<T>::operator>=(const BasicScalar<T>& s) const
640 {
641  return (*this > s) || (*this == s);
642 }
643 
644 
645 // ACCESS
646 
647 template<class T> inline
649 {
650  return m_val;
651 }
652 
653 
654 template<class T> inline
656 {
657  return m_val;
658 }
659 
660 
661 template<class T> inline
662 const T& BasicScalar<T>::getRef() const
663 {
664  return m_val;
665 }
666 
667 
668 template<class T> inline
669 void BasicScalar<T>::setValue(const T& x)
670 {
671  m_val = x;
672 }
673 
674 
675 // PRIVATE METHODS
676 
677 template<class T> inline
678 bool BasicScalar<T>::absEquality(const BasicScalar<T>& s) const
679 {
680  const T diff = std::abs(m_val - s.m_val);
681  return diff <= BasicScalarTraits<T>::getTestTol();
682 }
683 
684 
685 template<class T> inline
686 bool BasicScalar<T>::absLessThan(const BasicScalar<T>& s) const
687 {
688  const T diff = s.m_val - m_val;
689  return diff > BasicScalarTraits<T>::getTestTol();
690 }
691 
692 
693 template<class T> inline
694 bool BasicScalar<T>::relEquality(const BasicScalar<T>& s) const
695 {
696  T ref = std::min(std::abs(s.m_val), std::abs(m_val));
697 
698  if (!(ref > std::numeric_limits<T>::epsilon()))
699  {
700  // Absolute tolerance is used for comparing values smaller than unity
701  ref = 1.0;
702  }
703  const T diff = std::abs(s.m_val - m_val);
704  return (diff / ref) <= BasicScalarTraits<T>::getTestTol();
705 }
706 
707 
708 template<class T> inline
709 bool BasicScalar<T>::relLessThan(const BasicScalar<T>& s) const
710 {
711  T ref = std::min(std::abs(s.m_val), std::abs(m_val));
712  if (!(ref > std::numeric_limits<T>::epsilon()))
713  {
714  // Absolute tolerance is used for comparing values smaller than unity
715  ref = 1.0;
716  }
717  const T diff = s.m_val - m_val;
718  return (diff / ref) > BasicScalarTraits<T>::getTestTol();
719 }
720 
721 
723 
724 // OPERATORS
725 
726 template<class T> inline
727 BasicScalar<T> operator+(const BasicScalar<T>& s)
728 {
729  return s;
730 }
731 
732 
733 template<class T> inline
734 BasicScalar<T> operator-(const BasicScalar<T>& s)
735 {
736  const BasicScalar<T> s1(-s.getValue());
737  return s1;
738 }
739 
740 
741 template<class T1, class T2> inline
742 BasicScalar<T1> operator+(const BasicScalar<T1>& s1,
743  const BasicScalar<T2>& s2)
744 {
745  BasicScalar<T1> s(s2);
746  return s += s1;
747 }
748 
749 
750 // template<class T> inline
751 // BasicScalar<T> operator+(const BasicScalar<T>& s,
752 // const T& x)
753 // {
754 // BasicScalar<T> s1(x);
755 // return s1 += s;
756 // }
757 //
758 //
759 // template<class T> inline
760 // BasicScalar<T> operator+(const T& x,
761 // const BasicScalar<T>& s)
762 // {
763 // BasicScalar<T> s1(x);
764 // return s1 += s;
765 // }
766 
767 
768 template<class T1, class T2> inline
769 BasicScalar<T1> operator-(const BasicScalar<T1>& s1,
770  const BasicScalar<T2>& s2)
771 {
772  BasicScalar<T1> s3(s1);
773  const BasicScalar<T1> s4(s2);
774  return s3 -= s4;
775 }
776 
777 
778 // template<class T> inline
779 // BasicScalar<T> operator-(const BasicScalar<T>& s,
780 // const T& x)
781 // {
782 // BasicScalar<T> s1(s);
783 // return s1 -= x;
784 // }
785 //
786 //
787 // template<class T> inline
788 // BasicScalar<T> operator-(const T& x,
789 // const BasicScalar<T>& s)
790 // {
791 // BasicScalar<T> s1(x);
792 // return s1 -= s;
793 // }
794 
795 
796 template<class T1, class T2> inline
797 BasicScalar<T1> operator*(const BasicScalar<T1>& s1,
798  const BasicScalar<T2>& s2)
799 {
800  BasicScalar<T1> s(s2);
801  return s *= s1;
802 }
803 
804 
805 // template<class T> inline
806 // BasicScalar<T> operator*(const BasicScalar<T>& s,
807 // const T& x)
808 // {
809 // BasicScalar<T> s1(x);
810 // return s1 *= s;
811 // }
812 //
813 //
814 // template<class T> inline
815 // BasicScalar<T> operator*(const T& x,
816 // const BasicScalar<T>& s)
817 // {
818 // BasicScalar<T> s1(x);
819 // return s1 *= s;
820 // }
821 
822 
823 template<class T1, class T2> inline
824 BasicScalar<T1> operator/(const BasicScalar<T1>& s1,
825  const BasicScalar<T2>& s2)
826 {
827  BasicScalar<T1> s3(s1);
828  const BasicScalar<T1> s4(s2);
829  return s3 /= s4;
830 }
831 
832 
833 // template<class T> inline
834 // BasicScalar<T> operator/(const BasicScalar<T>& s,
835 // const T& x)
836 // {
837 // BasicScalar<T> s1(s);
838 // return s1 /= x;
839 // }
840 //
841 //
842 // template<class T> inline
843 // BasicScalar<T> operator/(const T& x,
844 // const BasicScalar<T>& s)
845 // {
846 // BasicScalar<T> s1(x);
847 // return s1 /= s;
848 // }
849 
850 
851 template<class T> inline
852 std::ostream& operator<<(std::ostream& os,
853  const BasicScalar<T>& s)
854 {
855  const size_t width = BasicScalarTraits<T>::getWidth();
856  const BasicScalar<T> tol = BasicScalarTraits<T>::getTol();
857  return os << std::setw(width) << round(s, tol).m_val;
858 }
859 
860 
861 template<class T> inline
862 std::istream& operator>>(std::istream& is,
863  const BasicScalar<T>& s)
864 {
865  return is >> s.m_val;
866 }
867 
868 
869 // FUNCTIONS
870 
871 template<class T> inline
872 BasicScalar<T> min(const BasicScalar<T>& s1,
873  const BasicScalar<T>& s2)
874 {
875  const T x = std::min(s1.m_val, s2.m_val);
876  return BasicScalar<T>(x);
877 }
878 
879 
880 template<class T> inline
881 BasicScalar<T> max(const BasicScalar<T>& s1,
882  const BasicScalar<T>& s2)
883 {
884  const T x = std::max(s1.m_val, s2.m_val);
885  return BasicScalar<T>(x);
886 }
887 
888 
889 template<class T> inline
890 BasicScalar<T> abs(const BasicScalar<T>& s)
891 {
892  const T x = std::abs(s.m_val);
893  return BasicScalar<T>(x);
894 }
895 
896 
897 template<class T> inline
898 BasicScalar<T> ceil(const BasicScalar<T>& s)
899 {
900  const T x = std::ceil(s.m_val);
901  return BasicScalar<T>(x);
902 }
903 
904 
905 template<class T> inline
906 BasicScalar<T> floor(const BasicScalar<T>& s)
907 {
908  const T x = std::floor(s.m_val);
909  return BasicScalar<T>(x);
910 }
911 
912 
913 template<class T> inline
914 BasicScalar<T> sqrt(const BasicScalar<T>& s)
915 {
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);
919 }
920 
921 
922 template<class T> inline
923 BasicScalar<T> exp(const BasicScalar<T>& s)
924 {
925  const T x = std::exp(s.m_val);
926  return BasicScalar<T>(x);
927 }
928 
929 
930 template<class T> inline
931 BasicScalar<T> log(const BasicScalar<T>& s)
932 {
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);
936 }
937 
938 
939 template<class T> inline
940 BasicScalar<T> log10(const BasicScalar<T>& s)
941 {
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);
945 }
946 
947 
948 template<class T1, class T2> inline
949 BasicScalar<T1> pow(const BasicScalar<T1>& s1,
950  const BasicScalar<T2>& s2)
951 {
952  const T1 x = std::pow(s1.m_val, static_cast<T1>(s2.m_val));
953  return BasicScalar<T1>(x);
954 }
955 
956 
957 template<class T> inline
958 BasicScalar<T> sin(const BasicScalar<T>& s)
959 {
960  const T x = std::sin(s.m_val);
961  return BasicScalar<T>(x);
962 }
963 
964 
965 template<class T> inline
966 BasicScalar<T> cos(const BasicScalar<T>& s)
967 {
968  const T x = std::cos(s.m_val);
969  return BasicScalar<T>(x);
970 }
971 
972 
973 template<class T> inline
974 BasicScalar<T> tan(const BasicScalar<T>& s)
975 {
976  const T x = std::tan(s.m_val);
977  return BasicScalar<T>(x);
978 }
979 
980 
981 template<class T> inline
982 BasicScalar<T> sinh(const BasicScalar<T>& s)
983 {
984  const T x = std::sinh(s.m_val);
985  return BasicScalar<T>(x);
986 }
987 
988 
989 template<class T> inline
990 BasicScalar<T> cosh(const BasicScalar<T>& s)
991 {
992  const T x = std::cosh(s.m_val);
993  return BasicScalar<T>(x);
994 }
995 
996 
997 template<class T> inline
998 BasicScalar<T> tanh(const BasicScalar<T>& s)
999 {
1000  const T x = std::tanh(s.m_val);
1001  return BasicScalar<T>(x);
1002 }
1003 
1004 
1005 template<class T> inline
1006 BasicScalar<T> asin(const BasicScalar<T>& s)
1007 {
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);
1013 }
1014 
1015 
1016 template<class T> inline
1017 BasicScalar<T> acos(const BasicScalar<T>& s)
1018 {
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);
1024 }
1025 
1026 
1027 template<class T> inline
1028 BasicScalar<T> atan(const BasicScalar<T>& s)
1029 {
1030  const T x = std::atan(s.m_val);
1031  return BasicScalar<T>(x);
1032 }
1033 
1034 
1035 template<class T1, class T2> inline
1036 BasicScalar<T1> atan2(const BasicScalar<T1>& s1,
1037  const BasicScalar<T2>& s2)
1038 {
1039  T1 t1 = s1.m_val;
1040  T1 t2 = static_cast<T1>(s2.m_val);
1041 
1042  // Prevents sign problems for near-zero values
1043  if (s1 == BasicScalar<T1>(0.0))
1044  {
1045  t1 = static_cast<T1>(0.0);
1046  }
1047 
1048  if (s2 == BasicScalar<T2>(0.0))
1049  {
1050  t2 = static_cast<T1>(0.0);
1051  }
1052 
1053  const T1 x = std::atan2(t1, t2);
1054  return BasicScalar<T1>(x);
1055 }
1056 
1057 
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)
1063 {
1064  util::Assert(lower < upper,
1065  Exception("Normalizing interval is ill defined"));
1066 
1067  BasicScalar<T> s_norm(s);
1068  if (s >= lower && s < upper)
1069  {
1070  cycles = BasicScalar<T>(0.0);
1071  }
1072  else
1073  {
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);
1078  }
1079  return s_norm;
1080 }
1081 
1082 
1083 template<class T> inline
1084 BasicScalar<T> normalize(const BasicScalar<T>& s,
1085  const BasicScalar<T>& lower,
1086  const BasicScalar<T>& upper)
1087 {
1088  BasicScalar<T> cycles;
1089  return normalize(s, lower, upper, cycles);
1090 }
1091 
1092 
1093 template<class T> inline
1094 BasicScalar<T> saturate(const BasicScalar<T>& s,
1095  const BasicScalar<T>& lower,
1096  const BasicScalar<T>& upper)
1097 {
1098  util::Assert(lower < upper,
1099  Exception("Saturation interval is ill defined"));
1100 
1101  BasicScalar<T> s_sat(s);
1102  if (s.getValue() < lower.getValue())
1103  {
1104  s_sat = lower;
1105  }
1106  else if (s.getValue() > upper.getValue())
1107  {
1108  s_sat = upper;
1109  }
1110  return s_sat;
1111 }
1112 
1113 
1114 template<class T> inline
1115 BasicScalar<T> round(const BasicScalar<T>& s,
1116  const BasicScalar<T>& tol)
1117 {
1118  if (tol > std::numeric_limits<T>::epsilon())
1119  {
1120  // Tolerance is greater than 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);
1124  }
1125  else
1126  {
1127  // Tolerance is less or equal than epsilon
1128  return s;
1129  }
1130 }
1131 
1132 template<class T> inline
1133 T getValue(const BasicScalar<T> s)
1134 {
1135  return s.getValue();
1136 }
1137 
1138 } // mt
1139 
1140 #endif // MT_BASIC_SCALAR_H