ivl 679
ivl/details/core/math/trigonometric.hpp
00001 /* This file is part of the ivl C++ library <http://image.ntua.gr/ivl>.
00002    A C++ template library extending syntax towards mathematical notation.
00003 
00004    Copyright (C) 2012 Yannis Avrithis <iavr@image.ntua.gr>
00005    Copyright (C) 2012 Kimon Kontosis <kimonas@image.ntua.gr>
00006 
00007    ivl is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU Lesser General Public License 
00009    version 3 as published by the Free Software Foundation.
00010 
00011    Alternatively, you can redistribute it and/or modify it under the terms 
00012    of the GNU General Public License version 2 as published by the Free 
00013    Software Foundation.
00014 
00015    ivl is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00018    See the GNU General Public License for more details.
00019 
00020    You should have received a copy of the GNU General Public License 
00021    and a copy of the GNU Lesser General Public License along 
00022    with ivl. If not, see <http://www.gnu.org/licenses/>. */
00023 
00024 #ifndef IVL_CORE_DETAILS_MATH_TRIGONOMETRIC_HPP
00025 #define IVL_CORE_DETAILS_MATH_TRIGONOMETRIC_HPP
00026 
00027 namespace ivl {
00028 namespace math {
00029 /* Note:
00030 Functions is the math namespace need not be used directly.
00031 They are brought to the ivl namespace by element functions.
00032 The element functions are the same but they are defined
00033 for both single elements and arrays.
00034 */
00035 
00036 // - Chapter 1------ Unary trigonometric functions first ---------------------
00037 
00038 /* First section: trigonometric functions (circular functions) took
00039 directly from std */
00040 
00041 using std::cos;
00042 using std::sin;
00043 using std::tan;
00044 using std::cosh;
00045 using std::sinh;
00046 using std::tanh;
00047 
00048 /* Second section: trigonometric functions (circular functions) that are
00049 defined in std but maybe not for all types (not for complex). */
00050 
00051 using std::atan;
00052 
00053 template <class T>
00054 std::complex<T> atan(const std::complex<T> & c)
00055 {
00056         T real = c.real();
00057         T imag = c.imag();
00058 
00059         std::complex<T> log_v = log(std::complex<T>(T(1) - imag, real)
00060                                         / std::complex<T>(T(1) + imag, -real));
00061 
00062         return std::complex<T>(log_v.imag() * T(1.0/2),
00063                                 -log_v.real() * T(1.0/2));
00064 }
00065 
00066 using std::asin;
00067 
00068 template <class T>
00069 std::complex<T> asin(const std::complex<T> & c)
00070 {
00071         typedef typename std::complex<T> tp;
00072         T real = c.real();
00073         T imag = c.imag();
00074         std::complex<T> ic(-imag, real);
00075         std::complex<T> expr = log(ic + sqrt(tp(1) - c * c));
00076 
00077         return std::complex<T>(expr.imag(), -expr.real());
00078 }
00079 
00080 using std::acos;
00081 
00082 template <class T>
00083 std::complex<T> acos(const std::complex<T> & c)
00084 {
00085         typedef typename std::complex<T> tp;
00086         std::complex<T> expr = sqrt(tp(1) - c * c);
00087         std::complex<T> iexpr(-expr.imag(), expr.real());
00088         expr = log(c + iexpr);
00089 
00090         return std::complex<T>(expr.imag(), -expr.real());
00091 }
00092 
00093 /* Third section: trigonometric functions which are not existant in std,
00094 and implemented here */
00095 
00096 template <class T>
00097 T acosh(const T& c)
00098 {
00099         return log (c + sqrt (c * c - T(1)));
00100 }
00101 
00102 template <class T>
00103 std::complex<T> acosh(const std::complex<T> & c)
00104 {
00105         typedef typename std::complex<T> tp;
00106         return log(c + (c + tp(1)) * sqrt((c - tp(1)) / (c + tp(1))));
00107 }
00108 
00109 template <class T>
00110 T asinh(const T& c)
00111 {
00112         return log (c + sqrt (c * c + T(1)));
00113 }
00114 
00115 template <class T>
00116 std::complex<T> asinh(const std::complex<T> & c)
00117 {
00118         typedef typename std::complex<T> tp;
00119         return log(c + sqrt(tp(1) + c * c));
00120 }
00121 
00122 template <class T>
00123 T atanh(const T& c)
00124 {
00125         return 0.5 * log((T(1) + c) / (T(1) - c));
00126 }
00127 
00128 template <class T>
00129 std::complex<T> atanh(const std::complex<T> & c)
00130 {
00131         typedef typename std::complex<T> tp;
00132         return log((tp(1) + c) * sqrt(tp(1) / (tp(1) - c * c)));
00133 }
00134 
00135 // small note: cast<T> is used, because we are sure that T is not an array type.
00136 template <class T>
00137 inline
00138 T cot(const T elem)
00139 {
00140         return cast<T>(1) / tan(elem);
00141 }
00142 
00143 template <class T>
00144 inline
00145 T coth(const T elem)
00146 {
00147         const T tmp = exp(elem);
00148         return (tmp +
00149                 cast<T>(1) / tmp) / (tmp - cast<T>(1) / tmp);
00150 }
00151 
00152 template <class T>
00153 inline
00154 T csc(const T elem)
00155 {
00156         return (cast<T>(1) / sin(elem));
00157 }
00158 
00159 template <class T>
00160 inline
00161 T csch(const T elem)
00162 {
00163         T tmp = exp(elem);
00164         return cast<T>(2) / (tmp - cast<T>(1) / tmp);
00165 }
00166 
00167 template <class T>
00168 inline
00169 T sec(const T elem)
00170 {
00171         return (cast<T>(1) / cos(elem));
00172 }
00173 
00174 template <class T>
00175 inline
00176 T sech(const T elem)
00177 {
00178         T tmp = exp(elem);
00179         return (cast<T>(2) / (tmp + cast<T>(1) / tmp));
00180 }
00181 
00182 template <class T>
00183 inline
00184 T acot(const T elem)
00185 {
00186         return atan(cast<T>(1) / elem);
00187 }
00188 
00189 template <class T>
00190 inline
00191 T acoth(const T elem)
00192 {
00193         return log((elem + cast<T>(1)) /
00194                 (elem - cast<T>(1))) / cast<T>(2);
00195 }
00196 
00197 template <class T>
00198 inline
00199 T acsc(const T elem)
00200 {
00201         return asin(cast<T>(1) / elem);
00202 }
00203 
00204 template <class T>
00205 inline
00206 T acsch(const T elem)
00207 {
00208         return log((sign(elem) * cast<T>(sqrt(cast<T>(1) +
00209                 elem * elem)) + cast<T>(1)) / elem);
00210 }
00211 
00212 template <class T>
00213 inline
00214 T asec(const T elem)
00215 {
00216         return acos(cast<T>(1) / elem);
00217 }
00218 
00219 template <class T>
00220 inline
00221 T asech(const T elem)
00222 {
00223         return log((sqrt(cast<T>(1) - elem * elem) +
00224                 cast<T>(1)) / elem);
00225 }
00226 
00227 // - Chapter 2------ Binary trigonometric functions (second) ----------------
00228 // (basically atan2)
00229 
00230 using std::atan2;
00231 
00232 } /* namespace math */
00233 } /* namespace ivl */
00234 
00235 #endif // IVL_CORE_DETAILS_MATH_TRIGONOMETRIC_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations