Libbarrett  1.2.4
include/barrett/math/detail/utils-inl.h
00001 /*
00002  * utils-inl.h
00003  *
00004  *  Created on: Nov 11, 2009
00005  *      Author: dc
00006  */
00007 
00008 /* Copyright 2009 Barrett Technology <support@barrett.com> */
00009 
00010 /* This file is part of libbarrett.
00011  *
00012  * This version of libbarrett is free software: you can redistribute it
00013  * and/or modify it under the terms of the GNU General Public License as
00014  * published by the Free Software Foundation, either version 3 of the
00015  * License, or (at your option) any later version.
00016  *
00017  * This version of libbarrett is distributed in the hope that it will be
00018  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  * GNU General Public License for more details.
00021  *
00022  * You should have received a copy of the GNU General Public License along
00023  * with this version of libbarrett.  If not, see
00024  * <http://www.gnu.org/licenses/>.
00025  *
00026  * Further, non-binding information about licensing is available at:
00027  * <http://wiki.barrett.com/libbarrett/wiki/LicenseNotes>
00028  */
00029 
00030 
00031 #include <algorithm>
00032 #include <cmath>
00033 #include <cassert>
00034 
00035 namespace barrett {
00036 namespace math {
00037 
00038 
00039 namespace detail {
00040 template<typename Scalar> struct CwiseSignOp {
00041         inline const Scalar operator() (const Scalar& x) const {
00042                 return sign(x);
00043         }
00044 };
00045 }
00046 
00047 template<typename Derived>
00048 inline const Eigen::CwiseUnaryOp<
00049         detail::CwiseSignOp<typename Eigen::ei_traits<Derived>::Scalar>,
00050         Derived
00051 > sign(const Eigen::MatrixBase<Derived>& x)
00052 {
00053         return x.unaryExpr(detail::CwiseSignOp<typename Eigen::ei_traits<Derived>::Scalar>());
00054 }
00055 
00056 inline double sign(double x)
00057 {
00058         if (x > 0.0) {
00059                 return 1.0;
00060         } else if (x == 0.0) {
00061                 return 0.0;
00062         } else {
00063                 return -1.0;
00064         }
00065 }
00066 
00067 
00068 using std::abs;
00069 
00070 template<typename Derived>
00071 inline const Eigen::CwiseUnaryOp<
00072         Eigen::ei_scalar_abs_op<typename Eigen::ei_traits<Derived>::Scalar>,
00073         Derived
00074 > abs(const Eigen::MatrixBase<Derived>& x)
00075 {
00076         return x.cwise().abs();
00077 }
00078 
00079 
00080 template<typename Derived1, typename Derived2>
00081 inline const Eigen::CwiseBinaryOp<
00082         Eigen::ei_scalar_min_op<typename Eigen::ei_traits<Derived1>::Scalar>,
00083         Derived1,
00084         Derived2
00085 > min(const Eigen::MatrixBase<Derived1>& a, const Eigen::MatrixBase<Derived2>& b)
00086 {
00087         return a.cwise().min(b);
00088 }
00089 
00090 inline double min(double a, double b)
00091 {
00092         return std::min(a, b);
00093 }
00094 
00095 
00096 template<typename Derived1, typename Derived2>
00097 inline const Eigen::CwiseBinaryOp<
00098         Eigen::ei_scalar_max_op<typename Eigen::ei_traits<Derived1>::Scalar>,
00099         Derived1,
00100         Derived2
00101 > max(const Eigen::MatrixBase<Derived1>& a, const Eigen::MatrixBase<Derived2>& b)
00102 {
00103         return a.cwise().max(b);
00104 }
00105 
00106 inline double max(double a, double b)
00107 {
00108         return std::max(a, b);
00109 }
00110 
00111 
00112 namespace detail {
00113 template<typename Scalar> struct CwiseUnarySaturateOp {
00114         CwiseUnarySaturateOp(Scalar lowerLimit, Scalar upperLimit) : lowerLimit(lowerLimit), upperLimit(upperLimit) {}
00115 
00116         inline const Scalar operator() (const Scalar& x) const {
00117                 return saturate(x, lowerLimit, upperLimit);
00118         }
00119 
00120         Scalar lowerLimit, upperLimit;
00121 };
00122 
00123 template<typename Scalar> struct CwiseBinarySaturateOp {
00124         inline const Scalar operator() (const Scalar& x, const Scalar& limit) const {
00125                 return saturate(x, limit);
00126         }
00127 };
00128 }
00129 
00130 template<typename Derived>
00131 inline const Eigen::CwiseUnaryOp<
00132         detail::CwiseUnarySaturateOp<typename Eigen::ei_traits<Derived>::Scalar>,
00133         Derived
00134 > saturate(const Eigen::MatrixBase<Derived>& x, double limit)
00135 {
00136         return x.unaryExpr(detail::CwiseUnarySaturateOp<typename Eigen::ei_traits<Derived>::Scalar>(-limit, limit));
00137 }
00138 
00139 template<typename Derived1, typename Derived2>
00140 inline const Eigen::CwiseBinaryOp<
00141         detail::CwiseBinarySaturateOp<typename Eigen::ei_traits<Derived1>::Scalar>,
00142         Derived1,
00143         Derived2
00144 > saturate(const Eigen::MatrixBase<Derived1>& x, const Eigen::MatrixBase<Derived2>& limit)
00145 {
00146         return x.binaryExpr(limit, detail::CwiseBinarySaturateOp<typename Eigen::ei_traits<Derived1>::Scalar>());
00147 }
00148 
00149 inline double saturate(double x, double limit)
00150 {
00151         return saturate(x, -limit, limit);
00152 }
00153 
00154 
00155 template<typename Derived>
00156 inline const Eigen::CwiseUnaryOp<
00157         detail::CwiseUnarySaturateOp<typename Eigen::ei_traits<Derived>::Scalar>,
00158         Derived
00159 > saturate(const Eigen::MatrixBase<Derived>& x, double lowerLimit, double upperLimit)
00160 {
00161         return x.unaryExpr(detail::CwiseUnarySaturateOp<typename Eigen::ei_traits<Derived>::Scalar>(lowerLimit, upperLimit));
00162 }
00163 
00164 inline double saturate(double x, double lowerLimit, double upperLimit)
00165 {
00166         assert(lowerLimit < upperLimit);
00167 
00168         if (x > upperLimit) {
00169                 return upperLimit;
00170         } else if (x < lowerLimit) {
00171                 return lowerLimit;
00172         } else {
00173                 return x;
00174         }
00175 }
00176 
00177 
00178 namespace detail {
00179 template<typename Scalar> struct CwiseUnaryDeadbandOp {
00180         CwiseUnaryDeadbandOp(Scalar cutoff) : cutoff(cutoff) {}
00181 
00182         inline const Scalar operator() (const Scalar& x) const {
00183                 return deadband(x, cutoff);
00184         }
00185 
00186         Scalar cutoff;
00187 };
00188 
00189 template<typename Scalar> struct CwiseBinaryDeadbandOp {
00190         inline const Scalar operator() (const Scalar& x, const Scalar& cutoff) const {
00191                 return deadband(x, cutoff);
00192         }
00193 };
00194 }
00195 
00196 template<typename Derived>
00197 inline const Eigen::CwiseUnaryOp<
00198         detail::CwiseUnaryDeadbandOp<typename Eigen::ei_traits<Derived>::Scalar>,
00199         Derived
00200 > deadband(const Eigen::MatrixBase<Derived>& x, double cutoff)
00201 {
00202         return x.unaryExpr(detail::CwiseUnaryDeadbandOp<typename Eigen::ei_traits<Derived>::Scalar>(cutoff));
00203 }
00204 
00205 template<typename Derived1, typename Derived2>
00206 inline const Eigen::CwiseBinaryOp<
00207         detail::CwiseBinaryDeadbandOp<typename Eigen::ei_traits<Derived1>::Scalar>,
00208         Derived1,
00209         Derived2
00210 > deadband(const Eigen::MatrixBase<Derived1>& x, const Eigen::MatrixBase<Derived2>& cutoff)
00211 {
00212         return x.binaryExpr(cutoff, detail::CwiseBinaryDeadbandOp<typename Eigen::ei_traits<Derived1>::Scalar>());
00213 }
00214 
00215 inline double deadband(double x, double cutoff)
00216 {
00217         if (x > cutoff) {
00218                 return x - cutoff;
00219         } else if (x < -cutoff) {
00220                 return x + cutoff;
00221         } else {
00222                 return 0.0;
00223         }
00224 }
00225 
00226 
00227 }
00228 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Defines