#ifndef FUNCTIONS_H#define FUNCTIONS_H#include <boost/array.hpp>#include <cmath>#include <complex>#include <functional>#include "mimasexception.h"namespace mimas {#ifndef sgn#define sgn(x) ((x<0)?-1:((x>0)?1:0))#endif/// Absolute value.template< typename T >struct _abs: public std::unary_function< T, T >{/** Compute absolute value.@param x A number.@return Absolute value of \c x. */T operator()( const T &x ) const { return std::abs( x ); }};/** Fast square.Compute square of values between -511 and +511 using a precomputedtable. */template< typename T >struct _fastsqr: public std::unary_function< T, int >{/// Constructor._fastsqr(void) {for ( int i=0; i<(signed)table.size(); i++ )table[i] = i * i;}/// Function.int operator()( const T &x ) const {assert( x > -(signed)table.size() && x < (signed)table.size() );return table[ x < 0 ? -x : x ];}/// Table with precomputed values.boost::array< int, 512 > table;};/// Square.template< typename T >struct _sqr: public std::unary_function< T, T >{T operator()( const T &x ) const { return x * x; }};/// Square root.template<typename T>struct _sqrt: public std::unary_function< T, T >{/** Compute square root.@param x A number.@return Square root of \c x. */T operator()( const T &x ) const { return (T)std::sqrt( (float)x ); }};/// Thresholding function.template< typename T >struct _threshold: public std::binary_function< T, T, T >{/** Compare value with threshold.@param x The value to be considered.@param y The threshold to compare with.@return Default-value, if \c x is lower than \c y. Value of \c xotherwise. */T operator()( const T &x, const T &y ) const { return x < y ? T() : x; }};/// Thresholding function.template< typename T >struct _tobinary: public std::binary_function< T, T, bool >{/** Compare value with threshold.@param x The value to be considered.@param y The threshold to compare with.@return A boolean, which is indicating, wether \c x is greater or equalto \c y. */bool operator()( const T &x, const T &y ) const { return x >= y; }};/// Convert boolean-pixel to bilevel-pixel.template< typename T >struct _bilevel: public std::binary_function< T, T, T > {_bilevel( T _val1, T _val2 ): val1(_val1), val2(_val2) {}/** Compare value with threshold and map to {val1,val2}.@param x The value to be considered.@param y The threshold to compare with.@return Bilevel-pixel, which is either \c val1 or \c val2. */T operator()( const T &x, const T &y ) const { return x >= y ? val2 : val1; }T val1;T val2;};/// Thresholding function with 2 levelstemplate< typename T >struct _bilevel_double: public std::unary_function< T, T> {T val1, val2, min, max;_bilevel_double( T _val1, T _val2, T _min, T _max ): val1(_val1), val2(_val2), min(_min), max(_max){}/** Compare value with threshold levels . If value is between minand max, the output is val2, else it's val1.@param x The value to be considered.@return Bilevel-pixel, which is either \c val1 or \c val2. */T operator()( const T &x ) const { return (x >= min && x <= max) ? val2 : val1;}};/// Linear companding function.template< typename T >struct _normalise: public std::unary_function< T, T >{///_normalise( T _minval, T _maxval, T _val1, T _val2 ) {if ( _maxval > _minval ) {factor = (double)( _val2 - _val1 ) / ( _maxval - _minval );offset = _val1 - _minval * factor;} else {factor = 0.0;offset = _val1;};}T operator()( const T &x ) const {// Scale each pixel-value: ( pixel - minval ) * factor + val1.// pixel * factor - minval * factor + val1return (T)( x * factor + offset );}double factor;double offset;};/// Take norm of a real or complex value.template< typename T1, typename T2 >struct _norm: public std::unary_function< T2, T1 >{T1 operator()( const T2 &x ) const { return std::norm( x ); }};/// The argument of a complex value.template< typename T1, typename T2 >struct _arg: public std::unary_function< T2, T1 >{T1 operator()( const T2 &x ) const { return std::arg( x ); }};/// Complex conjugate.template< typename T >struct _conj: public std::unary_function< T, T >{T operator()( const T &x ) const { return std::conj( x ); }};/// Compute logarithm.template< typename T >struct _log: public std::unary_function< T, T >{T operator()( const T &x ) const { return log( x ); }};/** Compute sum of squares.The sum of squares can be computed with the multiplication- andplus-operator as well, but it would require allocation of one temporaryarray. */template< typename T >struct _sumsquares: public std::binary_function< T, T, T > {/** Compute sum of squares.@param x First value.@param y Second value.@return x^2+y^2 */T operator()( const T &x, const T &y ) const { return x * x + y * y; }};/// Compute angle.template< typename T >struct _orientation: public std::binary_function< T, T, T > {/** Compute sum of squares.@param y y-component@param x x-component@return atan2( y, x ) */T operator()( const T &y, const T &x ) const { return atan2( y, x ); }};};#endif