diff --git a/CImg.h b/CImg.h index 6f514d52..e5ec705b 100644 --- a/CImg.h +++ b/CImg.h @@ -22411,8 +22411,8 @@ namespace cimg_library { _cimg_mp_const_scalar(is_scalar(arg1)?0:size(arg1)); } - if (!std::strncmp(ss,"softmax(",8)) { // Softmax - _cimg_mp_op("Function 'softmax()'"); + if (!std::strncmp(ss,"softmax(",8) || !std::strncmp(ss,"softmin(",8)) { // Softmax & softmin + _cimg_mp_op(ss[5]=='a'?"Function 'softmax()'":"Function 'softmin()'"); s1 = ss8; while (s10) pos = is_comp_vector(arg1)?arg1:((return_comp = true), vector(p1)); else _cimg_mp_return(1); - CImg::vector((ulongT)mp_softmax,pos,arg1,p1,arg2).move_to(code); + CImg::vector((ulongT)(ss[5]=='a'?mp_softmax:mp_softmin),pos,arg1,p1,arg2).move_to(code); _cimg_mp_return(pos); } @@ -28602,6 +28602,19 @@ namespace cimg_library { return 1; } + static double mp_softmin(_cimg_math_parser& mp) { + const unsigned int siz = (unsigned int)mp.opcode[3]; + const double temperature = _mp_arg(4); + if (siz>0) { // Vector-valued argument + double *const ptrd = &_mp_arg(1) + 1; + const double *const ptrs = &_mp_arg(2) + 1; + CImg(ptrd,siz,1,1,1,true) = CImg(ptrs,siz,1,1,1,true).get_softmin(temperature); + return cimg::type::nan(); + } + // Scalar-valued argument. + return 1; + } + static double mp_solve(_cimg_math_parser& mp) { double *ptrd = &_mp_arg(1) + 1; const double @@ -30315,6 +30328,28 @@ namespace cimg_library { return res/=sum; } + //! Softmin operator. + CImg& softmin(const float temperature=1) { + return get_softmin(temperature).move_to(*this); + } + + //! Softmin operator \newinstance. + CImg get_softmin(const float temperature=1) const { + if (is_empty()) return CImg(); + CImg res(_width,_height,_depth,_spectrum); + const T val_min = min(); + Tfloat sum = 0; + cimg_pragma_openmp(parallel reduction(+:sum) cimg_openmp_if_size(size(),4096)) { + cimg_pragma_openmp(for) + cimg_rofoff(*this,off) { + const Tfloat val = std::exp((-(Tfloat)_data[off] + val_min)/temperature); + res[off] = val; + sum+=val; + } + } + return res/=sum; + } + //! Pointwise min operator between instance image and a value. /** \param val Value used as the reference argument of the min operator. diff --git a/html/header.html b/html/header.html index 49193f42..384c4f43 100644 --- a/html/header.html +++ b/html/header.html @@ -23,7 +23,7 @@
Logo

- Latest stable version: 3.4.3        Current pre-release: 3.5.0 (2024/12/04) + Latest stable version: 3.4.3        Current pre-release: 3.5.0 (2024/12/12)


diff --git a/html/header_doxygen.html b/html/header_doxygen.html index ca1e14e1..54d0c8e2 100644 --- a/html/header_doxygen.html +++ b/html/header_doxygen.html @@ -26,7 +26,7 @@
Logo

- Latest stable version: 3.4.3        Current pre-release: 3.5.0 (2024/12/04) + Latest stable version: 3.4.3        Current pre-release: 3.5.0 (2024/12/12)