36 #ifndef VIGRA_MULTI_MATH_HXX 
   37 #define VIGRA_MULTI_MATH_HXX 
   39 #include "multi_array.hxx" 
   40 #include "tinyvector.hxx" 
   41 #include "rgbvalue.hxx" 
   42 #include "mathutil.hxx" 
   48 namespace multi_math {
 
   51 struct MultiMathOperand
 
   53     typedef typename ARG::result_type result_type;
 
   55     static const int ndim = ARG::ndim;
 
   57     MultiMathOperand(ARG 
const & a)
 
   66     template <
class SHAPE>
 
   67     bool checkShape(SHAPE & s)
 const 
   69         return arg_.checkShape(s);
 
   73     void inc(
unsigned int axis)
 const 
   79     void reset(
unsigned int axis)
 const 
   85     result_type operator*()
 const 
   91     template <
class SHAPE>
 
   92     result_type operator[](SHAPE 
const & s)
 const 
  100 template <
unsigned int N, 
class T, 
class C>
 
  101 struct MultiMathOperand<MultiArrayView<N, T, C> >
 
  103     typedef MultiMathOperand AllowOverload;
 
  104     typedef typename MultiArrayShape<N>::type Shape;
 
  106     typedef T result_type;
 
  108     static const int ndim = (int)N;
 
  110     MultiMathOperand(MultiArrayView<N, T, C> 
const & a)
 
  116         for(
unsigned int k=0; k<N; ++k)
 
  121     bool checkShape(Shape & s)
 const 
  126         for(
unsigned int k=0; k<N; ++k)
 
  136             else if(shape_[k] > 1 && shape_[k] != s[k])
 
  144     T 
const & operator[](Shape 
const & s)
 const 
  146         return p_[
dot(s, strides_)];
 
  149     void inc(
unsigned int axis)
 const 
  151         p_ += strides_[axis];
 
  154     void reset(
unsigned int axis)
 const 
  156         p_ -= shape_[axis]*strides_[axis];
 
  159     result_type operator*()
 const 
  164     mutable T 
const * p_;
 
  165     Shape shape_, strides_;
 
  168 template <
unsigned int N, 
class T, 
class A>
 
  169 struct MultiMathOperand<MultiArray<N, T, A> >
 
  170 : 
public MultiMathOperand<MultiArrayView<N, T, UnstridedArrayTag> >
 
  172     typedef MultiMathOperand AllowOverload;
 
  174     MultiMathOperand(MultiArray<N, T, A> 
const & a)
 
  175     : MultiMathOperand<MultiArrayView<N, T, UnstridedArrayTag> >(a)
 
  180 struct MultiMathScalarOperand
 
  182     typedef MultiMathOperand<T> AllowOverload;
 
  183     typedef T result_type;
 
  185     static const int ndim = 0;
 
  187     MultiMathScalarOperand(T 
const & v)
 
  191     template <
class SHAPE>
 
  192     bool checkShape(SHAPE 
const &)
 const 
  197     template <
class SHAPE>
 
  198     T 
const & operator[](SHAPE 
const &)
 const 
  203     void inc(
unsigned int )
 const 
  206     void reset(
unsigned int )
 const 
  209     T 
const & operator*()
 const 
  217 #define VIGRA_CONSTANT_OPERAND(template_dcl, type) \ 
  218 template template_dcl \ 
  219 struct MultiMathOperand<type > \ 
  220 : MultiMathScalarOperand<type > \ 
  222     MultiMathOperand(type const & v) \ 
  223     : MultiMathScalarOperand<type >(v) \ 
  227 VIGRA_CONSTANT_OPERAND(<>, 
signed char)
 
  228 VIGRA_CONSTANT_OPERAND(<>, 
signed short)
 
  229 VIGRA_CONSTANT_OPERAND(<>, 
signed int)
 
  230 VIGRA_CONSTANT_OPERAND(<>, 
signed long)
 
  231 VIGRA_CONSTANT_OPERAND(<>, 
signed long long)
 
  232 VIGRA_CONSTANT_OPERAND(<>, 
unsigned char)
 
  233 VIGRA_CONSTANT_OPERAND(<>, 
unsigned short)
 
  234 VIGRA_CONSTANT_OPERAND(<>, 
unsigned int)
 
  235 VIGRA_CONSTANT_OPERAND(<>, 
unsigned long)
 
  236 VIGRA_CONSTANT_OPERAND(<>, 
unsigned long long)
 
  237 VIGRA_CONSTANT_OPERAND(<>, 
float)
 
  238 VIGRA_CONSTANT_OPERAND(<>, 
double)
 
  239 VIGRA_CONSTANT_OPERAND(<>, 
long double)
 
  240 VIGRA_CONSTANT_OPERAND(<class T>, std::complex<T>)
 
  242 #define VIGRA_TINYVECTOR_ARGS <class T, int N> 
  243 #define VIGRA_TINYVECTOR_DECL TinyVector<T, N> 
  244 VIGRA_CONSTANT_OPERAND(VIGRA_TINYVECTOR_ARGS, VIGRA_TINYVECTOR_DECL)
 
  245 #undef VIGRA_TINYVECTOR_ARGS 
  246 #undef VIGRA_TINYVECTOR_DECL 
  248 #define VIGRA_RGBVALUE_ARGS <class V, unsigned int R, unsigned int G, unsigned int B> 
  249 #define VIGRA_RGBVALUE_DECL RGBValue<V, R, G, B> 
  250 VIGRA_CONSTANT_OPERAND(VIGRA_RGBVALUE_ARGS, VIGRA_RGBVALUE_DECL)
 
  251 #undef VIGRA_RGBVALUE_ARGS 
  252 #undef VIGRA_RGBVALUE_DECL 
  254 #undef VIGRA_CONSTANT_OPERAND 
  256 template <
class O, 
class F>
 
  257 struct MultiMathUnaryOperator
 
  259     typedef typename F::template Result<typename O::result_type>::type result_type;
 
  261     static const int ndim = O::ndim;
 
  263     MultiMathUnaryOperator(O 
const & o)
 
  267     template <
class SHAPE>
 
  268     bool checkShape(SHAPE & s)
 const 
  270         return o_.checkShape(s);
 
  274     void inc(
unsigned int axis)
 const 
  279     void reset(
unsigned int axis)
 const 
  284     template <
class POINT>
 
  285     result_type operator[](POINT 
const & p)
 const 
  290     result_type operator*()
 const 
  299 #define VIGRA_MULTIMATH_UNARY_OPERATOR(NAME, FCT, OPNAME, RESTYPE) \ 
  300 namespace math_detail { \ 
  306         typedef RESTYPE type; \ 
  310     typename Result<T>::type \ 
  311     operator()(T const & t) const \ 
  318 template <unsigned int N, class T, class C> \ 
  319 MultiMathOperand<MultiMathUnaryOperator<MultiMathOperand<MultiArrayView<N, T, C> >, \ 
  320                                         math_detail::NAME> > \ 
  321 OPNAME(MultiArrayView<N, T, C> const & v) \ 
  323     typedef MultiMathOperand<MultiArrayView<N, T, C> > O; \ 
  324     typedef MultiMathUnaryOperator<O, math_detail::NAME> OP; \ 
  325     return MultiMathOperand<OP>(OP(v)); \ 
  328 template <unsigned int N, class T, class A> \ 
  329 MultiMathOperand<MultiMathUnaryOperator<MultiMathOperand<MultiArray<N, T, A> >, \ 
  330                                         math_detail::NAME> > \ 
  331 OPNAME(MultiArray<N, T, A> const & v) \ 
  333     typedef MultiMathOperand<MultiArray<N, T, A> > O; \ 
  334     typedef MultiMathUnaryOperator<O, math_detail::NAME> OP; \ 
  335     return MultiMathOperand<OP>(OP(v)); \ 
  339 MultiMathOperand<MultiMathUnaryOperator<MultiMathOperand<T>, \ 
  340                                         math_detail::NAME> > \ 
  341 OPNAME(MultiMathOperand<T> const & v) \ 
  343     typedef MultiMathOperand<T> O; \ 
  344     typedef MultiMathUnaryOperator<O, math_detail::NAME> OP; \ 
  345     return MultiMathOperand<OP>(OP(v)); \ 
  348 #define VIGRA_REALPROMOTE typename NumericTraits<T>::RealPromote 
  350 #ifndef DOXYGEN  // doxygen gets confused by these macros 
  352 VIGRA_MULTIMATH_UNARY_OPERATOR(Negate, -, 
operator-, T)
 
  353 VIGRA_MULTIMATH_UNARY_OPERATOR(Not, !, operator!, T)
 
  354 VIGRA_MULTIMATH_UNARY_OPERATOR(BitwiseNot, ~, operator~, T)
 
  357 VIGRA_MULTIMATH_UNARY_OPERATOR(Abs, vigra::abs, abs, typename NormTraits<T>::NormType)
 
  360 VIGRA_MULTIMATH_UNARY_OPERATOR(Erf, vigra::erf, erf, VIGRA_REALPROMOTE)
 
  361 VIGRA_MULTIMATH_UNARY_OPERATOR(Even, vigra::
even, even, 
bool)
 
  362 VIGRA_MULTIMATH_UNARY_OPERATOR(Odd, vigra::
odd, odd, 
bool)
 
  363 VIGRA_MULTIMATH_UNARY_OPERATOR(Sign, vigra::
sign, sign, T)
 
  364 VIGRA_MULTIMATH_UNARY_OPERATOR(Signi, vigra::
signi, signi, 
int)
 
  367 VIGRA_MULTIMATH_UNARY_OPERATOR(Round, vigra::round, round, T)
 
  369 VIGRA_MULTIMATH_UNARY_OPERATOR(Roundi, vigra::
roundi, roundi, 
int)
 
  370 VIGRA_MULTIMATH_UNARY_OPERATOR(Sqrti, vigra::
sqrti, sqrti, T)
 
  371 VIGRA_MULTIMATH_UNARY_OPERATOR(Sq, vigra::
sq, sq, typename NumericTraits<T>::Promote)
 
  372 VIGRA_MULTIMATH_UNARY_OPERATOR(Norm, vigra::
norm, norm, typename NormTraits<T>::NormType)
 
  373 VIGRA_MULTIMATH_UNARY_OPERATOR(SquaredNorm, vigra::
squaredNorm, squaredNorm,
 
  374                                typename NormTraits<T>::SquaredNormType)
 
  375 VIGRA_MULTIMATH_UNARY_OPERATOR(Sin_pi, vigra::
sin_pi, sin_pi, VIGRA_REALPROMOTE)
 
  376 VIGRA_MULTIMATH_UNARY_OPERATOR(Cos_pi, vigra::
cos_pi, cos_pi, VIGRA_REALPROMOTE)
 
  379 VIGRA_MULTIMATH_UNARY_OPERATOR(Gamma, vigra::gamma, gamma, VIGRA_REALPROMOTE)
 
  382 VIGRA_MULTIMATH_UNARY_OPERATOR(Loggamma, vigra::loggamma, loggamma, VIGRA_REALPROMOTE)
 
  384 VIGRA_MULTIMATH_UNARY_OPERATOR(Sqrt, std::
sqrt, sqrt, VIGRA_REALPROMOTE)
 
  386 VIGRA_MULTIMATH_UNARY_OPERATOR(Exp, vigra::exp, exp, VIGRA_REALPROMOTE)
 
  387 VIGRA_MULTIMATH_UNARY_OPERATOR(Log, std::
log, log, VIGRA_REALPROMOTE)
 
  388 VIGRA_MULTIMATH_UNARY_OPERATOR(Log10, std::
log10, log10, VIGRA_REALPROMOTE)
 
  389 VIGRA_MULTIMATH_UNARY_OPERATOR(Sin, std::
sin, sin, VIGRA_REALPROMOTE)
 
  390 VIGRA_MULTIMATH_UNARY_OPERATOR(Asin, std::
asin, asin, VIGRA_REALPROMOTE)
 
  391 VIGRA_MULTIMATH_UNARY_OPERATOR(Cos, std::
cos, cos, VIGRA_REALPROMOTE)
 
  392 VIGRA_MULTIMATH_UNARY_OPERATOR(Acos, std::
acos, acos, VIGRA_REALPROMOTE)
 
  393 VIGRA_MULTIMATH_UNARY_OPERATOR(Tan, std::
tan, tan, VIGRA_REALPROMOTE)
 
  394 VIGRA_MULTIMATH_UNARY_OPERATOR(Atan, std::
atan, atan, VIGRA_REALPROMOTE)
 
  395 VIGRA_MULTIMATH_UNARY_OPERATOR(Floor, std::
floor, floor, VIGRA_REALPROMOTE)
 
  396 VIGRA_MULTIMATH_UNARY_OPERATOR(Ceil, std::
ceil, ceil, VIGRA_REALPROMOTE)
 
  398 VIGRA_MULTIMATH_UNARY_OPERATOR(Conj, 
conj, conj, T)
 
  399 VIGRA_MULTIMATH_UNARY_OPERATOR(Real, 
real, real, typename T::value_type)
 
  400 VIGRA_MULTIMATH_UNARY_OPERATOR(Imag, 
imag, imag, typename T::value_type)
 
  401 VIGRA_MULTIMATH_UNARY_OPERATOR(Arg, 
arg, arg, typename T::value_type)
 
  405 #undef VIGRA_REALPROMOTE 
  406 #undef VIGRA_MULTIMATH_UNARY_OPERATOR 
  408 template <
class O1, 
class O2, 
class F>
 
  409 struct MultiMathBinaryOperator
 
  411     typedef typename F::template Result<
typename O1::result_type,
 
  412                                          typename O2::result_type>::type result_type;
 
  414     static const int ndim = O1::ndim > O2::ndim ? O1::ndim : O2::ndim;
 
  416     MultiMathBinaryOperator(O1 
const & o1, O2 
const & o2)
 
  421     template <
class SHAPE>
 
  422     bool checkShape(SHAPE & s)
 const 
  424         return o1_.checkShape(s) && o2_.checkShape(s);
 
  427     template <
class POINT>
 
  428     result_type operator[](POINT 
const & p)
 const 
  430         return f_(o1_[p], o2_[p]);
 
  433     void inc(
unsigned int axis)
 const 
  439     void reset(
unsigned int axis)
 const 
  445     result_type operator*()
 const 
  447         return f_(*o1_, *o2_);
 
  461 #define VIGRA_MULTIMATH_BINARY_OPERATOR(NAME, FCT, OPNAME, SEP, RESTYPE) \ 
  463 namespace math_detail { \ 
  466     template <class T1, class T2> \ 
  469         typedef RESTYPE type; \ 
  472     template <class T1, class T2> \ 
  473     typename Result<T1, T2>::type \ 
  474     operator()(T1 const & t1, T2 const & t2) const \ 
  476         return FCT(t1 SEP t2); \ 
  481 template <unsigned int N, class T1, class A1, class T2, class A2> \ 
  482 MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<MultiArrayView<N, T1> >, \ 
  483                                          MultiMathOperand<MultiArrayView<N, T2> >, \ 
  484                                          math_detail::NAME> > \ 
  485 OPNAME(MultiArray<N, T1, A1> const & v1, MultiArray<N, T2, A2> const & v2) \ 
  487     typedef MultiMathOperand<MultiArrayView<N, T1> > O1; \ 
  488     typedef MultiMathOperand<MultiArrayView<N, T2> > O2; \ 
  489     typedef MultiMathBinaryOperator<O1, O2, math_detail::NAME> OP; \ 
  490     return MultiMathOperand<OP>(OP((MultiArrayView<N, T1> const &)v1, (MultiArrayView<N, T2> const &)v2)); \ 
  493 template <unsigned int N, class T1, class C1, class T2, class C2> \ 
  494 MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<MultiArrayView<N, T1, C1> >, \ 
  495                                          MultiMathOperand<MultiArrayView<N, T2, C2> >, \ 
  496                                          math_detail::NAME> > \ 
  497 OPNAME(MultiArrayView<N, T1, C1> const & v1, MultiArrayView<N, T2, C2> const & v2) \ 
  499     typedef MultiMathOperand<MultiArrayView<N, T1, C1> > O1; \ 
  500     typedef MultiMathOperand<MultiArrayView<N, T2, C2> > O2; \ 
  501     typedef MultiMathBinaryOperator<O1, O2, math_detail::NAME> OP; \ 
  502     return MultiMathOperand<OP>(OP(v1, v2)); \ 
  505 template <unsigned int N, class T1, class T2, class C2> \ 
  506 MultiMathOperand<MultiMathBinaryOperator<typename MultiMathOperand<T1>::AllowOverload, \ 
  507                                          MultiMathOperand<MultiArrayView<N, T2, C2> >, \ 
  508                                          math_detail::NAME> > \ 
  509 OPNAME(T1 const & v1, MultiArrayView<N, T2, C2> const & v2) \ 
  511     typedef MultiMathOperand<T1> O1; \ 
  512     typedef MultiMathOperand<MultiArrayView<N, T2, C2> > O2; \ 
  513     typedef MultiMathBinaryOperator<O1, O2, math_detail::NAME> OP; \ 
  514     return MultiMathOperand<OP>(OP(v1, v2)); \ 
  517 template <unsigned int N, class T1, class C1, class T2> \ 
  518 MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<MultiArrayView<N, T1, C1> >, \ 
  519                                          typename MultiMathOperand<T2>::AllowOverload, \ 
  520                                          math_detail::NAME> > \ 
  521 OPNAME(MultiArrayView<N, T1, C1> const & v1, T2 const & v2) \ 
  523     typedef MultiMathOperand<MultiArrayView<N, T1, C1> > O1; \ 
  524     typedef MultiMathOperand<T2> O2; \ 
  525     typedef MultiMathBinaryOperator<O1, O2, math_detail::NAME> OP; \ 
  526     return MultiMathOperand<OP>(OP(v1, v2)); \ 
  529 template <unsigned int N, class T1, class T2, class C2> \ 
  530 MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<T1>, \ 
  531                                          MultiMathOperand<MultiArrayView<N, T2, C2> >, \ 
  532                                          math_detail::NAME> > \ 
  533 OPNAME(MultiMathOperand<T1> const & v1, MultiArrayView<N, T2, C2> const & v2) \ 
  535     typedef MultiMathOperand<T1> O1; \ 
  536     typedef MultiMathOperand<MultiArrayView<N, T2, C2> > O2; \ 
  537     typedef MultiMathBinaryOperator<O1, O2, math_detail::NAME> OP; \ 
  538     return MultiMathOperand<OP>(OP(v1, v2)); \ 
  541 template <unsigned int N, class T1, class C1, class T2> \ 
  542 MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<MultiArrayView<N, T1, C1> >, \ 
  543                                          MultiMathOperand<T2>, \ 
  544                                          math_detail::NAME> > \ 
  545 OPNAME(MultiArrayView<N, T1, C1> const & v1, MultiMathOperand<T2> const & v2) \ 
  547     typedef MultiMathOperand<MultiArrayView<N, T1, C1> > O1; \ 
  548     typedef MultiMathOperand<T2> O2; \ 
  549     typedef MultiMathBinaryOperator<O1, O2, math_detail::NAME> OP; \ 
  550     return MultiMathOperand<OP>(OP(v1, v2)); \ 
  553 template <class T1, class T2> \ 
  554 MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<T1>, \ 
  555                                          MultiMathOperand<T2>, \ 
  556                                          math_detail::NAME> > \ 
  557 OPNAME(MultiMathOperand<T1> const & v1, MultiMathOperand<T2> const & v2) \ 
  559     typedef MultiMathOperand<T1> O1; \ 
  560     typedef MultiMathOperand<T2> O2; \ 
  561     typedef MultiMathBinaryOperator<O1, O2, math_detail::NAME> OP; \ 
  562     return MultiMathOperand<OP>(OP(v1, v2)); \ 
  565 template <class T1, class T2> \ 
  566 MultiMathOperand<MultiMathBinaryOperator<typename MultiMathOperand<T1>::AllowOverload, \ 
  567                                          MultiMathOperand<T2>, \ 
  568                                          math_detail::NAME> > \ 
  569 OPNAME(T1 const & v1, MultiMathOperand<T2> const & v2) \ 
  571     typedef MultiMathOperand<T1> O1; \ 
  572     typedef MultiMathOperand<T2> O2; \ 
  573     typedef MultiMathBinaryOperator<O1, O2, math_detail::NAME> OP; \ 
  574     return MultiMathOperand<OP>(OP(v1, v2)); \ 
  577 template <class T1, class T2> \ 
  578 MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<T1>, \ 
  579                                          typename MultiMathOperand<T2>::AllowOverload, \ 
  580                                          math_detail::NAME> > \ 
  581 OPNAME(MultiMathOperand<T1> const & v1, T2 const & v2) \ 
  583     typedef MultiMathOperand<T1> O1; \ 
  584     typedef MultiMathOperand<T2> O2; \ 
  585     typedef MultiMathBinaryOperator<O1, O2, math_detail::NAME> OP; \ 
  586     return MultiMathOperand<OP>(OP(v1, v2)); \ 
  589 #define VIGRA_NOTHING 
  590 #define VIGRA_COMMA , 
  591 #define VIGRA_PROMOTE typename PromoteTraits<T1, T2>::Promote 
  592 #define VIGRA_REALPROMOTE typename PromoteTraits<typename NumericTraits<T1>::RealPromote, \ 
  593                                                  typename NumericTraits<T2>::RealPromote>::Promote 
  595 VIGRA_MULTIMATH_BINARY_OPERATOR(Plus, VIGRA_NOTHING, 
operator+, +, VIGRA_PROMOTE)
 
  596 VIGRA_MULTIMATH_BINARY_OPERATOR(Minus, VIGRA_NOTHING, operator-, -, VIGRA_PROMOTE)
 
  597 VIGRA_MULTIMATH_BINARY_OPERATOR(Multiplies, VIGRA_NOTHING, operator*, *, VIGRA_PROMOTE)
 
  598 VIGRA_MULTIMATH_BINARY_OPERATOR(Divides, VIGRA_NOTHING, operator/, /, VIGRA_PROMOTE)
 
  599 VIGRA_MULTIMATH_BINARY_OPERATOR(Modulo, VIGRA_NOTHING, operator%, %, VIGRA_PROMOTE)
 
  600 VIGRA_MULTIMATH_BINARY_OPERATOR(And, VIGRA_NOTHING, operator&&, &&, VIGRA_PROMOTE)
 
  601 VIGRA_MULTIMATH_BINARY_OPERATOR(Or, VIGRA_NOTHING, operator||, ||, VIGRA_PROMOTE)
 
  602 VIGRA_MULTIMATH_BINARY_OPERATOR(Equal, VIGRA_NOTHING, operator==, ==, 
bool)
 
  603 VIGRA_MULTIMATH_BINARY_OPERATOR(NotEqual, VIGRA_NOTHING, operator!=, !=, 
bool)
 
  604 VIGRA_MULTIMATH_BINARY_OPERATOR(Less, VIGRA_NOTHING, operator<, <, 
bool)
 
  605 VIGRA_MULTIMATH_BINARY_OPERATOR(LessEqual, VIGRA_NOTHING, operator<=, <=, 
bool)
 
  606 VIGRA_MULTIMATH_BINARY_OPERATOR(Greater, VIGRA_NOTHING, operator>, >, 
bool)
 
  607 VIGRA_MULTIMATH_BINARY_OPERATOR(GreaterEqual, VIGRA_NOTHING, operator>=, >=, 
bool)
 
  608 VIGRA_MULTIMATH_BINARY_OPERATOR(Leftshift, VIGRA_NOTHING, operator<<, <<, VIGRA_PROMOTE)
 
  609 VIGRA_MULTIMATH_BINARY_OPERATOR(Rightshift, VIGRA_NOTHING, operator>>, >>, VIGRA_PROMOTE)
 
  610 VIGRA_MULTIMATH_BINARY_OPERATOR(BitwiseAnd, VIGRA_NOTHING, operator&, &, VIGRA_PROMOTE)
 
  611 VIGRA_MULTIMATH_BINARY_OPERATOR(BitwiseOr, VIGRA_NOTHING, operator|, |, VIGRA_PROMOTE)
 
  612 VIGRA_MULTIMATH_BINARY_OPERATOR(BitwiseXor, VIGRA_NOTHING, operator^, ^, VIGRA_PROMOTE)
 
  614 VIGRA_MULTIMATH_BINARY_OPERATOR(Atan2, std::
atan2, atan2, VIGRA_COMMA, VIGRA_REALPROMOTE)
 
  615 VIGRA_MULTIMATH_BINARY_OPERATOR(Pow, vigra::pow, pow, VIGRA_COMMA, VIGRA_REALPROMOTE)
 
  616 VIGRA_MULTIMATH_BINARY_OPERATOR(Fmod, std::fmod, fmod, VIGRA_COMMA, VIGRA_REALPROMOTE)
 
  617 VIGRA_MULTIMATH_BINARY_OPERATOR(Min, std::min, min, VIGRA_COMMA, VIGRA_PROMOTE)
 
  618 VIGRA_MULTIMATH_BINARY_OPERATOR(Max, std::max, max, VIGRA_COMMA, VIGRA_PROMOTE)
 
  619 VIGRA_MULTIMATH_BINARY_OPERATOR(Minimum, std::min, minimum, VIGRA_COMMA, VIGRA_PROMOTE)
 
  620 VIGRA_MULTIMATH_BINARY_OPERATOR(Maximum, std::max, maximum, VIGRA_COMMA, VIGRA_PROMOTE)
 
  625 #undef VIGRA_REALPROMOTE 
  626 #undef VIGRA_MULTIMATH_BINARY_OPERATOR 
  628 namespace math_detail {
 
  636 template <
unsigned int N, 
class Assign>
 
  639     enum { LEVEL = N-1 };
 
  641     template <
class T, 
class Shape, 
class Expression>
 
  642     static void exec(T * data, Shape 
const & shape, Shape 
const & strides,
 
  643                      Shape 
const & strideOrder, Expression 
const & e)
 
  646         for(
MultiArrayIndex k=0; k<shape[axis]; ++k, data += strides[axis], e.inc(axis))
 
  648             MultiMathExec<N-1, Assign>::exec(data, shape, strides, strideOrder, e);
 
  651         data -= shape[axis]*strides[axis];
 
  655 template <
class Assign>
 
  656 struct MultiMathExec<1, Assign>
 
  660     template <
class T, 
class Shape, 
class Expression>
 
  661     static void exec(T * data, Shape 
const & shape, Shape 
const & strides,
 
  662                      Shape 
const & strideOrder, Expression 
const & e)
 
  665         for(
MultiArrayIndex k=0; k<shape[axis]; ++k, data += strides[axis], e.inc(axis))
 
  667             Assign::assign(data, e);
 
  670         data -= shape[axis]*strides[axis];
 
  674 #define VIGRA_MULTIMATH_ASSIGN(NAME, OP) \ 
  675 struct MultiMath##NAME \ 
  677     template <class T, class Expression> \ 
  678     static void assign(T * data, Expression const & e) \ 
  680         *data OP vigra::detail::RequiresExplicitCast<T>::cast(*e); \ 
  684 template <unsigned int N, class T, class C, class Expression> \ 
  685 void NAME(MultiArrayView<N, T, C> a, MultiMathOperand<Expression> const & e) \ 
  687     typename MultiArrayShape<N>::type shape(a.shape()); \ 
  689     vigra_precondition(e.checkShape(shape), \ 
  690        "multi_math: shape mismatch in expression."); \ 
  692     MultiMathExec<N, MultiMath##NAME>::exec(a.data(), a.shape(), a.stride(), \ 
  693                                             a.strideOrdering(), e); \ 
  696 template <unsigned int N, class T, class A, class Expression> \ 
  697 void NAME##OrResize(MultiArray<N, T, A> & a, MultiMathOperand<Expression> const & e) \ 
  699     typename MultiArrayShape<N>::type shape(a.shape()); \ 
  701     vigra_precondition(e.checkShape(shape), \ 
  702        "multi_math: shape mismatch in expression."); \ 
  707     MultiMathExec<N, MultiMath##NAME>::exec(a.data(), a.shape(), a.stride(), \ 
  708                                             a.strideOrdering(), e); \ 
  711 VIGRA_MULTIMATH_ASSIGN(assign, =)
 
  712 VIGRA_MULTIMATH_ASSIGN(plusAssign, +=)
 
  713 VIGRA_MULTIMATH_ASSIGN(minusAssign, -=)
 
  714 VIGRA_MULTIMATH_ASSIGN(multiplyAssign, *=)
 
  715 VIGRA_MULTIMATH_ASSIGN(divideAssign, /=)
 
  717 #undef VIGRA_MULTIMATH_ASSIGN 
  719 template <
unsigned int N, 
class Assign>
 
  720 struct MultiMathReduce
 
  722     enum { LEVEL = N-1 };
 
  724     template <
class T, 
class Shape, 
class Expression>
 
  725     static void exec(T & t, Shape 
const & shape, Expression 
const & e)
 
  729             MultiMathReduce<N-1, Assign>::exec(t, shape, e);
 
  735 template <
class Assign>
 
  736 struct MultiMathReduce<1, Assign>
 
  740     template <
class T, 
class Shape, 
class Expression>
 
  741     static void exec(T & t, Shape 
const & shape, Expression 
const & e)
 
  745             Assign::assign(&t, e);
 
  751 struct MultiMathReduceAll
 
  753     template <
class T, 
class Expression>
 
  754     static void assign(T * data, Expression 
const & e)
 
  756         *data = *data && (*e != NumericTraits<typename Expression::result_type>::zero());
 
  760 struct MultiMathReduceAny
 
  762     template <
class T, 
class Expression>
 
  763     static void assign(T * data, Expression 
const & e)
 
  765         *data = *data || (*e != NumericTraits<typename Expression::result_type>::zero());
 
  772 template <
class U, 
class T>
 
  774 sum(MultiMathOperand<T> 
const & v, U res = NumericTraits<U>::zero())
 
  776     static const int ndim = MultiMathOperand<T>::ndim;
 
  777     typename MultiArrayShape<ndim>::type shape;
 
  779     math_detail::MultiMathReduce<ndim, math_detail::MultiMathplusAssign>::exec(res, shape, v);
 
  783 template <
class U, 
unsigned int N, 
class T, 
class S>
 
  785 sum(MultiArrayView<N, T, S> 
const & v, U res = NumericTraits<U>::zero())
 
  787     return v.template sum<U>() + res;
 
  790 template <
class U, 
class T>
 
  792 product(MultiMathOperand<T> 
const & v, U res = NumericTraits<U>::one())
 
  794     static const int ndim = MultiMathOperand<T>::ndim;
 
  795     typename MultiArrayShape<ndim>::type shape;
 
  797     math_detail::MultiMathReduce<ndim, math_detail::MultiMathmultiplyAssign>::exec(res, shape, v);
 
  801 template <
class U, 
unsigned int N, 
class T, 
class S>
 
  803 product(MultiArrayView<N, T, S> 
const & v, U res = NumericTraits<U>::one())
 
  805     return v.template product<U>() * res;
 
  810 all(MultiMathOperand<T> 
const & v)
 
  812     static const int ndim = MultiMathOperand<T>::ndim;
 
  813     typename MultiArrayShape<ndim>::type shape;
 
  816     math_detail::MultiMathReduce<ndim, math_detail::MultiMathReduceAll>::exec(res, shape, v);
 
  822 any(MultiMathOperand<T> 
const & v)
 
  824     static const int ndim = MultiMathOperand<T>::ndim;
 
  825     typename MultiArrayShape<ndim>::type shape;
 
  828     math_detail::MultiMathReduce<ndim, math_detail::MultiMathReduceAny>::exec(res, shape, v);
 
  835 #endif // VIGRA_MULTI_MATH_HXX 
REAL sin_pi(REAL x)
sin(pi*x). 
Definition: mathutil.hxx:1204
linalg::TemporaryMatrix< T > acos(MultiArrayView< 2, T, C > const &v)
FixedPoint16< 2, OverflowHandling > atan2(FixedPoint16< IntBits, OverflowHandling > y, FixedPoint16< IntBits, OverflowHandling > x)
Arctangent. Accuracy better than 1/3 degree (9 significant bits). 
Definition: fixedpoint.hxx:1654
PromoteTraits< V1, V2 >::Promote dot(RGBValue< V1, RIDX1, GIDX1, BIDX1 > const &r1, RGBValue< V2, RIDX2, GIDX2, BIDX2 > const &r2)
dot product 
Definition: rgbvalue.hxx:906
FFTWComplex< R > conj(const FFTWComplex< R > &a)
complex conjugate 
Definition: fftw3.hxx:1030
R imag(const FFTWComplex< R > &a)
imaginary part 
Definition: fftw3.hxx:1023
R arg(const FFTWComplex< R > &a)
phase 
Definition: fftw3.hxx:1009
Int32 roundi(FixedPoint16< IntBits, OverflowHandling > v)
rounding to the nearest integer. 
Definition: fixedpoint.hxx:1775
linalg::TemporaryMatrix< T > sin(MultiArrayView< 2, T, C > const &v)
linalg::TemporaryMatrix< T > exp(MultiArrayView< 2, T, C > const &v)
FFTWComplex< R >::SquaredNormType squaredNorm(const FFTWComplex< R > &a)
squared norm (= squared magnitude) 
Definition: fftw3.hxx:1044
R real(const FFTWComplex< R > &a)
real part 
Definition: fftw3.hxx:1016
int round(FixedPoint< IntBits, FracBits > v)
rounding to the nearest integer. 
Definition: fixedpoint.hxx:683
linalg::TemporaryMatrix< T > asin(MultiArrayView< 2, T, C > const &v)
int signi(T t)
The integer sign function. 
Definition: mathutil.hxx:608
std::ptrdiff_t MultiArrayIndex
Definition: multi_fwd.hxx:60
bool odd(int t)
Check if an integer is odd. 
REAL cos_pi(REAL x)
cos(pi*x). 
Definition: mathutil.hxx:1242
FFTWComplex< R >::NormType norm(const FFTWComplex< R > &a)
norm (= magnitude) 
Definition: fftw3.hxx:1037
NumericTraits< T >::Promote sq(T t)
The square function. 
Definition: mathutil.hxx:382
linalg::TemporaryMatrix< T > log10(MultiArrayView< 2, T, C > const &v)
bool even(int t)
Check if an integer is even. 
double gamma(double x)
The gamma function. 
Definition: mathutil.hxx:1587
linalg::TemporaryMatrix< T > log(MultiArrayView< 2, T, C > const &v)
double loggamma(double x)
The natural logarithm of the gamma function. 
Definition: mathutil.hxx:1603
FFTWComplex< R >::NormType abs(const FFTWComplex< R > &a)
absolute value (= magnitude) 
Definition: fftw3.hxx:1002
linalg::TemporaryMatrix< T > atan(MultiArrayView< 2, T, C > const &v)
linalg::TemporaryMatrix< T > tan(MultiArrayView< 2, T, C > const &v)
Int32 sqrti(Int32 v)
Signed integer square root. 
Definition: mathutil.hxx:538
int ceil(FixedPoint< IntBits, FracBits > v)
rounding up. 
Definition: fixedpoint.hxx:675
linalg::TemporaryMatrix< T > cos(MultiArrayView< 2, T, C > const &v)
T sign(T t)
The sign function. 
Definition: mathutil.hxx:591
int floor(FixedPoint< IntBits, FracBits > v)
rounding down. 
Definition: fixedpoint.hxx:667
SquareRootTraits< FixedPoint< IntBits, FracBits > >::SquareRootResult sqrt(FixedPoint< IntBits, FracBits > v)
square root. 
Definition: fixedpoint.hxx:616