From 569564fead6e7f3367db1764ae26f83498e6ff41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Tschumperl=C3=A9?= <David.Tschumperle@gmail.com> Date: Sun, 1 Jul 2018 15:36:33 +0200 Subject: [PATCH] Add inverse hyperbolic functions --- CImg.h | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/CImg.h b/CImg.h index f964cd6..586eaca 100644 --- a/CImg.h +++ b/CImg.h @@ -7034,6 +7034,21 @@ namespace cimg_library_suffixed { return instance.get_tanh(); } + template<typename T> + inline CImg<_cimg_Tfloat> acosh(const CImg<T>& instance) { + return instance.get_acosh(); + } + + template<typename T> + inline CImg<_cimg_Tfloat> asinh(const CImg<T>& instance) { + return instance.get_asinh(); + } + + template<typename T> + inline CImg<_cimg_Tfloat> atanh(const CImg<T>& instance) { + return instance.get_atanh(); + } + template<typename T> inline CImg<T> transpose(const CImg<T>& instance) { return instance.get_transpose(); @@ -17407,6 +17422,30 @@ namespace cimg_library_suffixed { _cimg_mp_scalar1(mp_acos,arg1); } + if (!std::strncmp(ss,"acosh(",6)) { // Hyperbolic arccosine + _cimg_mp_op("Function 'acosh()'"); + arg1 = compile(ss6,se1,depth1,0,is_single); + if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_acosh,arg1); + if (_cimg_mp_is_constant(arg1)) _cimg_mp_constant(std::acosh(mem[arg1])); + _cimg_mp_scalar1(mp_acosh,arg1); + } + + if (!std::strncmp(ss,"asinh(",6)) { // Hyperbolic arcsine + _cimg_mp_op("Function 'asinh()'"); + arg1 = compile(ss6,se1,depth1,0,is_single); + if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_asinh,arg1); + if (_cimg_mp_is_constant(arg1)) _cimg_mp_constant(std::asinh(mem[arg1])); + _cimg_mp_scalar1(mp_asinh,arg1); + } + + if (!std::strncmp(ss,"atanh(",6)) { // Hyperbolic arctangent + _cimg_mp_op("Function 'atanh()'"); + arg1 = compile(ss6,se1,depth1,0,is_single); + if (_cimg_mp_is_vector(arg1)) _cimg_mp_vector1_v(mp_atanh,arg1); + if (_cimg_mp_is_constant(arg1)) _cimg_mp_constant(std::atanh(mem[arg1])); + _cimg_mp_scalar1(mp_atanh,arg1); + } + if (!std::strncmp(ss,"arg(",4)) { // Nth argument _cimg_mp_op("Function 'arg()'"); s1 = ss4; while (s1<se1 && (*s1!=',' || level[s1 - expr._data]!=clevel1)) ++s1; @@ -20252,6 +20291,18 @@ namespace cimg_library_suffixed { return std::acos(_mp_arg(2)); } + static double mp_acosh(_cimg_math_parser& mp) { + return std::acosh(_mp_arg(2)); + } + + static double mp_asinh(_cimg_math_parser& mp) { + return std::asinh(_mp_arg(2)); + } + + static double mp_atanh(_cimg_math_parser& mp) { + return std::atanh(_mp_arg(2)); + } + static double mp_arg(_cimg_math_parser& mp) { const int _ind = (int)_mp_arg(4); const unsigned int @@ -23947,6 +23998,66 @@ namespace cimg_library_suffixed { return CImg<Tfloat>(*this,false).atan2(img); } + //! Compute the hyperbolic arccosine of each pixel value. + /** + Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its arccosineh + \f$\mathrm{acosh}(I_{(x,y,z,c)})\f$. + \note + - The \inplace of this method statically casts the computed values to the pixel type \c T. + - The \newinstance returns a \c CImg<float> image, if the pixel type \c T is \e not float-valued. + **/ + CImg<T>& acosh() { + if (is_empty()) return *this; + cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=8192)) + cimg_rof(*this,ptrd,T) *ptrd = (T)std::acosh((double)*ptrd); + return *this; + } + + //! Compute the hyperbolic arccosine of each pixel value \newinstance. + CImg<Tfloat> get_acosh() const { + return CImg<Tfloat>(*this,false).acosh(); + } + + //! Compute the hyperbolic arcsine of each pixel value. + /** + Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its hyperbolic arcsine + \f$\mathrm{asinh}(I_{(x,y,z,c)})\f$. + \note + - The \inplace of this method statically casts the computed values to the pixel type \c T. + - The \newinstance returns a \c CImg<float> image, if the pixel type \c T is \e not float-valued. + **/ + CImg<T>& asinh() { + if (is_empty()) return *this; + cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=8192)) + cimg_rof(*this,ptrd,T) *ptrd = (T)std::asinh((double)*ptrd); + return *this; + } + + //! Compute the hyperbolic arcsine of each pixel value \newinstance. + CImg<Tfloat> get_asinh() const { + return CImg<Tfloat>(*this,false).asinh(); + } + + //! Compute the hyperbolic arctangent of each pixel value. + /** + Replace each pixel value \f$I_{(x,y,z,c)}\f$ of the image instance by its hyperbolic arctangent + \f$\mathrm{atanh}(I_{(x,y,z,c)})\f$. + \note + - The \inplace of this method statically casts the computed values to the pixel type \c T. + - The \newinstance returns a \c CImg<float> image, if the pixel type \c T is \e not float-valued. + **/ + CImg<T>& atanh() { + if (is_empty()) return *this; + cimg_pragma_openmp(parallel for cimg_openmp_if(size()>=8192)) + cimg_rof(*this,ptrd,T) *ptrd = (T)std::atanh((double)*ptrd); + return *this; + } + + //! Compute the hyperbolic arcsine of each pixel value \newinstance. + CImg<Tfloat> get_atanh() const { + return CImg<Tfloat>(*this,false).atanh(); + } + //! In-place pointwise multiplication. /** Compute the pointwise multiplication between the image instance and the specified input image \c img. -- GitLab