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"
95 namespace multi_math {
98 struct MultiMathOperand
100 typedef typename ARG::result_type result_type;
102 static const int ndim = ARG::ndim;
104 MultiMathOperand(ARG
const & a)
113 template <
class SHAPE>
114 bool checkShape(SHAPE & s)
const
116 return arg_.checkShape(s);
120 void inc(
unsigned int axis)
const
126 void reset(
unsigned int axis)
const
132 result_type operator*()
const
138 template <
class SHAPE>
139 result_type operator[](SHAPE
const & s)
const
147 template <
unsigned int N,
class T,
class C>
148 struct MultiMathOperand<MultiArrayView<N, T, C> >
150 typedef MultiMathOperand AllowOverload;
151 typedef typename MultiArrayShape<N>::type Shape;
153 typedef T result_type;
155 static const int ndim = (int)N;
157 MultiMathOperand(MultiArrayView<N, T, C>
const & a)
163 for(
unsigned int k=0; k<N; ++k)
168 bool checkShape(Shape & s)
const
173 for(
unsigned int k=0; k<N; ++k)
183 else if(shape_[k] > 1 && shape_[k] != s[k])
191 T
const & operator[](Shape
const & s)
const
193 return p_[
dot(s, strides_)];
196 void inc(
unsigned int axis)
const
198 p_ += strides_[axis];
201 void reset(
unsigned int axis)
const
203 p_ -= shape_[axis]*strides_[axis];
206 result_type operator*()
const
211 mutable T
const * p_;
212 Shape shape_, strides_;
215 template <
unsigned int N,
class T,
class A>
216 struct MultiMathOperand<MultiArray<N, T, A> >
217 :
public MultiMathOperand<MultiArrayView<N, T, UnstridedArrayTag> >
219 typedef MultiMathOperand AllowOverload;
221 MultiMathOperand(MultiArray<N, T, A>
const & a)
222 : MultiMathOperand<MultiArrayView<N, T, UnstridedArrayTag> >(a)
227 struct MultiMathScalarOperand
229 typedef MultiMathOperand<T> AllowOverload;
230 typedef T result_type;
232 static const int ndim = 0;
234 MultiMathScalarOperand(T
const & v)
238 template <
class SHAPE>
239 bool checkShape(SHAPE
const &)
const
244 template <
class SHAPE>
245 T
const & operator[](SHAPE
const &)
const
250 void inc(
unsigned int )
const
253 void reset(
unsigned int )
const
256 T
const & operator*()
const
264 #define VIGRA_CONSTANT_OPERAND(template_dcl, type) \
265 template template_dcl \
266 struct MultiMathOperand<type > \
267 : MultiMathScalarOperand<type > \
269 MultiMathOperand(type const & v) \
270 : MultiMathScalarOperand<type >(v) \
274 VIGRA_CONSTANT_OPERAND(<>,
signed char)
275 VIGRA_CONSTANT_OPERAND(<>,
signed short)
276 VIGRA_CONSTANT_OPERAND(<>,
signed int)
277 VIGRA_CONSTANT_OPERAND(<>,
signed long)
278 VIGRA_CONSTANT_OPERAND(<>,
signed long long)
279 VIGRA_CONSTANT_OPERAND(<>,
unsigned char)
280 VIGRA_CONSTANT_OPERAND(<>,
unsigned short)
281 VIGRA_CONSTANT_OPERAND(<>,
unsigned int)
282 VIGRA_CONSTANT_OPERAND(<>,
unsigned long)
283 VIGRA_CONSTANT_OPERAND(<>,
unsigned long long)
284 VIGRA_CONSTANT_OPERAND(<>,
float)
285 VIGRA_CONSTANT_OPERAND(<>,
double)
286 VIGRA_CONSTANT_OPERAND(<>,
long double)
287 VIGRA_CONSTANT_OPERAND(<class T>, std::complex<T>)
289 #define VIGRA_TINYVECTOR_ARGS <class T, int N>
290 #define VIGRA_TINYVECTOR_DECL TinyVector<T, N>
291 VIGRA_CONSTANT_OPERAND(VIGRA_TINYVECTOR_ARGS, VIGRA_TINYVECTOR_DECL)
292 #undef VIGRA_TINYVECTOR_ARGS
293 #undef VIGRA_TINYVECTOR_DECL
295 #define VIGRA_RGBVALUE_ARGS <class V, unsigned int R, unsigned int G, unsigned int B>
296 #define VIGRA_RGBVALUE_DECL RGBValue<V, R, G, B>
297 VIGRA_CONSTANT_OPERAND(VIGRA_RGBVALUE_ARGS, VIGRA_RGBVALUE_DECL)
298 #undef VIGRA_RGBVALUE_ARGS
299 #undef VIGRA_RGBVALUE_DECL
301 #undef VIGRA_CONSTANT_OPERAND
303 template <
class O,
class F>
304 struct MultiMathUnaryOperator
306 typedef typename F::template Result<typename O::result_type>::type result_type;
308 static const int ndim = O::ndim;
310 MultiMathUnaryOperator(O
const & o)
314 template <
class SHAPE>
315 bool checkShape(SHAPE & s)
const
317 return o_.checkShape(s);
321 void inc(
unsigned int axis)
const
326 void reset(
unsigned int axis)
const
331 template <
class POINT>
332 result_type operator[](POINT
const & p)
const
337 result_type operator*()
const
346 #define VIGRA_MULTIMATH_UNARY_OPERATOR(NAME, FCT, OPNAME, RESTYPE) \
353 typedef RESTYPE type; \
357 typename Result<T>::type \
358 operator()(T const & t) const \
365 template <unsigned int N, class T, class C> \
366 MultiMathOperand<MultiMathUnaryOperator<MultiMathOperand<MultiArrayView<N, T, C> >, \
368 OPNAME(MultiArrayView<N, T, C> const & v) \
370 typedef MultiMathOperand<MultiArrayView<N, T, C> > O; \
371 typedef MultiMathUnaryOperator<O, detail::NAME> OP; \
372 return MultiMathOperand<OP>(OP(v)); \
375 template <unsigned int N, class T, class A> \
376 MultiMathOperand<MultiMathUnaryOperator<MultiMathOperand<MultiArray<N, T, A> >, \
378 OPNAME(MultiArray<N, T, A> const & v) \
380 typedef MultiMathOperand<MultiArray<N, T, A> > O; \
381 typedef MultiMathUnaryOperator<O, detail::NAME> OP; \
382 return MultiMathOperand<OP>(OP(v)); \
386 MultiMathOperand<MultiMathUnaryOperator<MultiMathOperand<T>, \
388 OPNAME(MultiMathOperand<T> const & v) \
390 typedef MultiMathOperand<T> O; \
391 typedef MultiMathUnaryOperator<O, detail::NAME> OP; \
392 return MultiMathOperand<OP>(OP(v)); \
395 #define VIGRA_REALPROMOTE typename NumericTraits<T>::RealPromote
397 #ifndef DOXYGEN // doxygen gets confused by these macros
399 VIGRA_MULTIMATH_UNARY_OPERATOR(Negate, -,
operator-, T)
400 VIGRA_MULTIMATH_UNARY_OPERATOR(Not, !, operator!, T)
401 VIGRA_MULTIMATH_UNARY_OPERATOR(BitwiseNot, ~, operator~, T)
404 VIGRA_MULTIMATH_UNARY_OPERATOR(Abs, vigra::abs, abs, typename NormTraits<T>::NormType)
407 VIGRA_MULTIMATH_UNARY_OPERATOR(Erf, vigra::erf, erf, VIGRA_REALPROMOTE)
408 VIGRA_MULTIMATH_UNARY_OPERATOR(Even, vigra::
even, even,
bool)
409 VIGRA_MULTIMATH_UNARY_OPERATOR(Odd, vigra::
odd, odd,
bool)
410 VIGRA_MULTIMATH_UNARY_OPERATOR(Sign, vigra::
sign, sign, T)
411 VIGRA_MULTIMATH_UNARY_OPERATOR(Signi, vigra::
signi, signi,
int)
414 VIGRA_MULTIMATH_UNARY_OPERATOR(Round, vigra::round, round, T)
416 VIGRA_MULTIMATH_UNARY_OPERATOR(Roundi, vigra::
roundi, roundi,
int)
417 VIGRA_MULTIMATH_UNARY_OPERATOR(Sqrti, vigra::
sqrti, sqrti, T)
418 VIGRA_MULTIMATH_UNARY_OPERATOR(Sq, vigra::
sq, sq, typename NumericTraits<T>::Promote)
419 VIGRA_MULTIMATH_UNARY_OPERATOR(Norm, vigra::
norm, norm, typename NormTraits<T>::NormType)
420 VIGRA_MULTIMATH_UNARY_OPERATOR(SquaredNorm, vigra::
squaredNorm, squaredNorm,
421 typename NormTraits<T>::SquaredNormType)
422 VIGRA_MULTIMATH_UNARY_OPERATOR(Sin_pi, vigra::
sin_pi, sin_pi, VIGRA_REALPROMOTE)
423 VIGRA_MULTIMATH_UNARY_OPERATOR(Cos_pi, vigra::
cos_pi, cos_pi, VIGRA_REALPROMOTE)
426 VIGRA_MULTIMATH_UNARY_OPERATOR(Gamma, vigra::gamma, gamma, VIGRA_REALPROMOTE)
429 VIGRA_MULTIMATH_UNARY_OPERATOR(Loggamma, vigra::loggamma, loggamma, VIGRA_REALPROMOTE)
431 VIGRA_MULTIMATH_UNARY_OPERATOR(Sqrt, std::
sqrt, sqrt, VIGRA_REALPROMOTE)
433 VIGRA_MULTIMATH_UNARY_OPERATOR(Exp, vigra::exp, exp, VIGRA_REALPROMOTE)
434 VIGRA_MULTIMATH_UNARY_OPERATOR(Log, std::
log, log, VIGRA_REALPROMOTE)
435 VIGRA_MULTIMATH_UNARY_OPERATOR(Log10, std::
log10, log10, VIGRA_REALPROMOTE)
436 VIGRA_MULTIMATH_UNARY_OPERATOR(Sin, std::
sin, sin, VIGRA_REALPROMOTE)
437 VIGRA_MULTIMATH_UNARY_OPERATOR(Asin, std::
asin, asin, VIGRA_REALPROMOTE)
438 VIGRA_MULTIMATH_UNARY_OPERATOR(Cos, std::
cos, cos, VIGRA_REALPROMOTE)
439 VIGRA_MULTIMATH_UNARY_OPERATOR(Acos, std::
acos, acos, VIGRA_REALPROMOTE)
440 VIGRA_MULTIMATH_UNARY_OPERATOR(Tan, std::
tan, tan, VIGRA_REALPROMOTE)
441 VIGRA_MULTIMATH_UNARY_OPERATOR(Atan, std::
atan, atan, VIGRA_REALPROMOTE)
442 VIGRA_MULTIMATH_UNARY_OPERATOR(Floor, std::
floor, floor, VIGRA_REALPROMOTE)
443 VIGRA_MULTIMATH_UNARY_OPERATOR(Ceil, std::
ceil, ceil, VIGRA_REALPROMOTE)
445 VIGRA_MULTIMATH_UNARY_OPERATOR(Conj,
conj, conj, T)
446 VIGRA_MULTIMATH_UNARY_OPERATOR(Real,
real, real, typename T::value_type)
447 VIGRA_MULTIMATH_UNARY_OPERATOR(Imag,
imag, imag, typename T::value_type)
448 VIGRA_MULTIMATH_UNARY_OPERATOR(Arg,
arg, arg, typename T::value_type)
452 #undef VIGRA_REALPROMOTE
453 #undef VIGRA_MULTIMATH_UNARY_OPERATOR
455 template <
class O1,
class O2,
class F>
456 struct MultiMathBinaryOperator
458 typedef typename F::template Result<
typename O1::result_type,
459 typename O2::result_type>::type result_type;
461 static const int ndim = O1::ndim > O2::ndim ? O1::ndim : O2::ndim;
463 MultiMathBinaryOperator(O1
const & o1, O2
const & o2)
468 template <
class SHAPE>
469 bool checkShape(SHAPE & s)
const
471 return o1_.checkShape(s) && o2_.checkShape(s);
474 template <
class POINT>
475 result_type operator[](POINT
const & p)
const
477 return f_(o1_[p], o2_[p]);
480 void inc(
unsigned int axis)
const
486 void reset(
unsigned int axis)
const
492 result_type operator*()
const
494 return f_(*o1_, *o2_);
508 #define VIGRA_MULTIMATH_BINARY_OPERATOR(NAME, FCT, OPNAME, SEP, RESTYPE) \
513 template <class T1, class T2> \
516 typedef RESTYPE type; \
519 template <class T1, class T2> \
520 typename Result<T1, T2>::type \
521 operator()(T1 const & t1, T2 const & t2) const \
523 return FCT(t1 SEP t2); \
528 template <unsigned int N, class T1, class A1, class T2, class A2> \
529 MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<MultiArrayView<N, T1> >, \
530 MultiMathOperand<MultiArrayView<N, T2> >, \
532 OPNAME(MultiArray<N, T1, A1> const & v1, MultiArray<N, T2, A2> const & v2) \
534 typedef MultiMathOperand<MultiArrayView<N, T1> > O1; \
535 typedef MultiMathOperand<MultiArrayView<N, T2> > O2; \
536 typedef MultiMathBinaryOperator<O1, O2, detail::NAME> OP; \
537 return MultiMathOperand<OP>(OP((MultiArrayView<N, T1> const &)v1, (MultiArrayView<N, T2> const &)v2)); \
540 template <unsigned int N, class T1, class C1, class T2, class C2> \
541 MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<MultiArrayView<N, T1, C1> >, \
542 MultiMathOperand<MultiArrayView<N, T2, C2> >, \
544 OPNAME(MultiArrayView<N, T1, C1> const & v1, MultiArrayView<N, T2, C2> const & v2) \
546 typedef MultiMathOperand<MultiArrayView<N, T1, C1> > O1; \
547 typedef MultiMathOperand<MultiArrayView<N, T2, C2> > O2; \
548 typedef MultiMathBinaryOperator<O1, O2, detail::NAME> OP; \
549 return MultiMathOperand<OP>(OP(v1, v2)); \
552 template <unsigned int N, class T1, class T2, class C2> \
553 MultiMathOperand<MultiMathBinaryOperator<typename MultiMathOperand<T1>::AllowOverload, \
554 MultiMathOperand<MultiArrayView<N, T2, C2> >, \
556 OPNAME(T1 const & v1, MultiArrayView<N, T2, C2> const & v2) \
558 typedef MultiMathOperand<T1> O1; \
559 typedef MultiMathOperand<MultiArrayView<N, T2, C2> > O2; \
560 typedef MultiMathBinaryOperator<O1, O2, detail::NAME> OP; \
561 return MultiMathOperand<OP>(OP(v1, v2)); \
564 template <unsigned int N, class T1, class C1, class T2> \
565 MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<MultiArrayView<N, T1, C1> >, \
566 typename MultiMathOperand<T2>::AllowOverload, \
568 OPNAME(MultiArrayView<N, T1, C1> const & v1, T2 const & v2) \
570 typedef MultiMathOperand<MultiArrayView<N, T1, C1> > O1; \
571 typedef MultiMathOperand<T2> O2; \
572 typedef MultiMathBinaryOperator<O1, O2, detail::NAME> OP; \
573 return MultiMathOperand<OP>(OP(v1, v2)); \
576 template <unsigned int N, class T1, class T2, class C2> \
577 MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<T1>, \
578 MultiMathOperand<MultiArrayView<N, T2, C2> >, \
580 OPNAME(MultiMathOperand<T1> const & v1, MultiArrayView<N, T2, C2> const & v2) \
582 typedef MultiMathOperand<T1> O1; \
583 typedef MultiMathOperand<MultiArrayView<N, T2, C2> > O2; \
584 typedef MultiMathBinaryOperator<O1, O2, detail::NAME> OP; \
585 return MultiMathOperand<OP>(OP(v1, v2)); \
588 template <unsigned int N, class T1, class C1, class T2> \
589 MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<MultiArrayView<N, T1, C1> >, \
590 MultiMathOperand<T2>, \
592 OPNAME(MultiArrayView<N, T1, C1> const & v1, MultiMathOperand<T2> const & v2) \
594 typedef MultiMathOperand<MultiArrayView<N, T1, C1> > O1; \
595 typedef MultiMathOperand<T2> O2; \
596 typedef MultiMathBinaryOperator<O1, O2, detail::NAME> OP; \
597 return MultiMathOperand<OP>(OP(v1, v2)); \
600 template <class T1, class T2> \
601 MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<T1>, \
602 MultiMathOperand<T2>, \
604 OPNAME(MultiMathOperand<T1> const & v1, MultiMathOperand<T2> const & v2) \
606 typedef MultiMathOperand<T1> O1; \
607 typedef MultiMathOperand<T2> O2; \
608 typedef MultiMathBinaryOperator<O1, O2, detail::NAME> OP; \
609 return MultiMathOperand<OP>(OP(v1, v2)); \
612 template <class T1, class T2> \
613 MultiMathOperand<MultiMathBinaryOperator<typename MultiMathOperand<T1>::AllowOverload, \
614 MultiMathOperand<T2>, \
616 OPNAME(T1 const & v1, MultiMathOperand<T2> const & v2) \
618 typedef MultiMathOperand<T1> O1; \
619 typedef MultiMathOperand<T2> O2; \
620 typedef MultiMathBinaryOperator<O1, O2, detail::NAME> OP; \
621 return MultiMathOperand<OP>(OP(v1, v2)); \
624 template <class T1, class T2> \
625 MultiMathOperand<MultiMathBinaryOperator<MultiMathOperand<T1>, \
626 typename MultiMathOperand<T2>::AllowOverload, \
628 OPNAME(MultiMathOperand<T1> const & v1, T2 const & v2) \
630 typedef MultiMathOperand<T1> O1; \
631 typedef MultiMathOperand<T2> O2; \
632 typedef MultiMathBinaryOperator<O1, O2, detail::NAME> OP; \
633 return MultiMathOperand<OP>(OP(v1, v2)); \
636 #define VIGRA_NOTHING
637 #define VIGRA_COMMA ,
638 #define VIGRA_PROMOTE typename PromoteTraits<T1, T2>::Promote
639 #define VIGRA_REALPROMOTE typename PromoteTraits<typename NumericTraits<T1>::RealPromote, \
640 typename NumericTraits<T2>::RealPromote>::Promote
642 VIGRA_MULTIMATH_BINARY_OPERATOR(Plus, VIGRA_NOTHING,
operator+, +, VIGRA_PROMOTE)
643 VIGRA_MULTIMATH_BINARY_OPERATOR(Minus, VIGRA_NOTHING, operator-, -, VIGRA_PROMOTE)
644 VIGRA_MULTIMATH_BINARY_OPERATOR(Multiplies, VIGRA_NOTHING, operator*, *, VIGRA_PROMOTE)
645 VIGRA_MULTIMATH_BINARY_OPERATOR(Divides, VIGRA_NOTHING, operator/, /, VIGRA_PROMOTE)
646 VIGRA_MULTIMATH_BINARY_OPERATOR(Modulo, VIGRA_NOTHING, operator%, %, VIGRA_PROMOTE)
647 VIGRA_MULTIMATH_BINARY_OPERATOR(And, VIGRA_NOTHING, operator&&, &&, VIGRA_PROMOTE)
648 VIGRA_MULTIMATH_BINARY_OPERATOR(Or, VIGRA_NOTHING, operator||, ||, VIGRA_PROMOTE)
649 VIGRA_MULTIMATH_BINARY_OPERATOR(Equal, VIGRA_NOTHING, operator==, ==,
bool)
650 VIGRA_MULTIMATH_BINARY_OPERATOR(NotEqual, VIGRA_NOTHING, operator!=, !=,
bool)
651 VIGRA_MULTIMATH_BINARY_OPERATOR(Less, VIGRA_NOTHING, operator<, <,
bool)
652 VIGRA_MULTIMATH_BINARY_OPERATOR(LessEqual, VIGRA_NOTHING, operator<=, <=,
bool)
653 VIGRA_MULTIMATH_BINARY_OPERATOR(Greater, VIGRA_NOTHING, operator>, >,
bool)
654 VIGRA_MULTIMATH_BINARY_OPERATOR(GreaterEqual, VIGRA_NOTHING, operator>=, >=,
bool)
655 VIGRA_MULTIMATH_BINARY_OPERATOR(Leftshift, VIGRA_NOTHING, operator<<, <<, VIGRA_PROMOTE)
656 VIGRA_MULTIMATH_BINARY_OPERATOR(Rightshift, VIGRA_NOTHING, operator>>, >>, VIGRA_PROMOTE)
657 VIGRA_MULTIMATH_BINARY_OPERATOR(BitwiseAnd, VIGRA_NOTHING, operator&, &, VIGRA_PROMOTE)
658 VIGRA_MULTIMATH_BINARY_OPERATOR(BitwiseOr, VIGRA_NOTHING, operator|, |, VIGRA_PROMOTE)
659 VIGRA_MULTIMATH_BINARY_OPERATOR(BitwiseXor, VIGRA_NOTHING, operator^, ^, VIGRA_PROMOTE)
661 VIGRA_MULTIMATH_BINARY_OPERATOR(Atan2, std::
atan2, atan2, VIGRA_COMMA, VIGRA_REALPROMOTE)
662 VIGRA_MULTIMATH_BINARY_OPERATOR(Pow, vigra::pow, pow, VIGRA_COMMA, VIGRA_REALPROMOTE)
663 VIGRA_MULTIMATH_BINARY_OPERATOR(Fmod, std::fmod, fmod, VIGRA_COMMA, VIGRA_REALPROMOTE)
664 VIGRA_MULTIMATH_BINARY_OPERATOR(Min, std::min, min, VIGRA_COMMA, VIGRA_PROMOTE)
665 VIGRA_MULTIMATH_BINARY_OPERATOR(Max, std::max, max, VIGRA_COMMA, VIGRA_PROMOTE)
666 VIGRA_MULTIMATH_BINARY_OPERATOR(Minimum, std::min, minimum, VIGRA_COMMA, VIGRA_PROMOTE)
667 VIGRA_MULTIMATH_BINARY_OPERATOR(Maximum, std::max, maximum, VIGRA_COMMA, VIGRA_PROMOTE)
672 #undef VIGRA_REALPROMOTE
673 #undef VIGRA_MULTIMATH_BINARY_OPERATOR
683 template <
unsigned int N,
class Assign>
686 enum { LEVEL = N-1 };
688 template <
class T,
class Shape,
class Expression>
689 static void exec(T * data, Shape
const & shape, Shape
const & strides,
690 Shape
const & strideOrder, Expression
const & e)
693 for(
MultiArrayIndex k=0; k<shape[axis]; ++k, data += strides[axis], e.inc(axis))
695 MultiMathExec<N-1, Assign>::exec(data, shape, strides, strideOrder, e);
698 data -= shape[axis]*strides[axis];
702 template <
class Assign>
703 struct MultiMathExec<1, Assign>
707 template <
class T,
class Shape,
class Expression>
708 static void exec(T * data, Shape
const & shape, Shape
const & strides,
709 Shape
const & strideOrder, Expression
const & e)
712 for(
MultiArrayIndex k=0; k<shape[axis]; ++k, data += strides[axis], e.inc(axis))
714 Assign::assign(data, e);
717 data -= shape[axis]*strides[axis];
721 #define VIGRA_MULTIMATH_ASSIGN(NAME, OP) \
722 struct MultiMath##NAME \
724 template <class T, class Expression> \
725 static void assign(T * data, Expression const & e) \
727 *data OP vigra::detail::RequiresExplicitCast<T>::cast(*e); \
731 template <unsigned int N, class T, class C, class Expression> \
732 void NAME(MultiArrayView<N, T, C> a, MultiMathOperand<Expression> const & e) \
734 typename MultiArrayShape<N>::type shape(a.shape()); \
736 vigra_precondition(e.checkShape(shape), \
737 "multi_math: shape mismatch in expression."); \
739 MultiMathExec<N, MultiMath##NAME>::exec(a.data(), a.shape(), a.stride(), \
740 a.strideOrdering(), e); \
743 template <unsigned int N, class T, class A, class Expression> \
744 void NAME##OrResize(MultiArray<N, T, A> & a, MultiMathOperand<Expression> const & e) \
746 typename MultiArrayShape<N>::type shape(a.shape()); \
748 vigra_precondition(e.checkShape(shape), \
749 "multi_math: shape mismatch in expression."); \
754 MultiMathExec<N, MultiMath##NAME>::exec(a.data(), a.shape(), a.stride(), \
755 a.strideOrdering(), e); \
758 VIGRA_MULTIMATH_ASSIGN(assign, =)
759 VIGRA_MULTIMATH_ASSIGN(plusAssign, +=)
760 VIGRA_MULTIMATH_ASSIGN(minusAssign, -=)
761 VIGRA_MULTIMATH_ASSIGN(multiplyAssign, *=)
762 VIGRA_MULTIMATH_ASSIGN(divideAssign, /=)
764 #undef VIGRA_MULTIMATH_ASSIGN
766 template <
unsigned int N,
class Assign>
767 struct MultiMathReduce
769 enum { LEVEL = N-1 };
771 template <
class T,
class Shape,
class Expression>
772 static void exec(T & t, Shape
const & shape, Expression
const & e)
776 MultiMathReduce<N-1, Assign>::exec(t, shape, e);
782 template <
class Assign>
783 struct MultiMathReduce<1, Assign>
787 template <
class T,
class Shape,
class Expression>
788 static void exec(T & t, Shape
const & shape, Expression
const & e)
792 Assign::assign(&t, e);
798 struct MultiMathReduceAll
800 template <
class T,
class Expression>
801 static void assign(T * data, Expression
const & e)
803 *data = *data && (*e != NumericTraits<typename Expression::result_type>::zero());
807 struct MultiMathReduceAny
809 template <
class T,
class Expression>
810 static void assign(T * data, Expression
const & e)
812 *data = *data || (*e != NumericTraits<typename Expression::result_type>::zero());
819 template <
class U,
class T>
821 sum(MultiMathOperand<T>
const & v, U res = NumericTraits<U>::zero())
823 static const int ndim = MultiMathOperand<T>::ndim;
824 typename MultiArrayShape<ndim>::type shape;
826 detail::MultiMathReduce<ndim, detail::MultiMathplusAssign>::exec(res, shape, v);
830 template <
class U,
unsigned int N,
class T,
class S>
832 sum(MultiArrayView<N, T, S>
const & v, U res = NumericTraits<U>::zero())
834 return v.template sum<U>() + res;
837 template <
class U,
class T>
839 product(MultiMathOperand<T>
const & v, U res = NumericTraits<U>::one())
841 static const int ndim = MultiMathOperand<T>::ndim;
842 typename MultiArrayShape<ndim>::type shape;
844 detail::MultiMathReduce<ndim, detail::MultiMathmultiplyAssign>::exec(res, shape, v);
848 template <
class U,
unsigned int N,
class T,
class S>
850 product(MultiArrayView<N, T, S>
const & v, U res = NumericTraits<U>::one())
852 return v.template product<U>() * res;
857 all(MultiMathOperand<T>
const & v)
859 static const int ndim = MultiMathOperand<T>::ndim;
860 typename MultiArrayShape<ndim>::type shape;
863 detail::MultiMathReduce<ndim, detail::MultiMathReduceAll>::exec(res, shape, v);
869 any(MultiMathOperand<T>
const & v)
871 static const int ndim = MultiMathOperand<T>::ndim;
872 typename MultiArrayShape<ndim>::type shape;
875 detail::MultiMathReduce<ndim, detail::MultiMathReduceAny>::exec(res, shape, v);
882 #endif // VIGRA_MULTI_MATH_HXX
REAL sin_pi(REAL x)
Definition: mathutil.hxx:1163
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:1640
PromoteTraits< V1, V2 >::Promote dot(RGBValue< V1, RIDX1, GIDX1, BIDX1 > const &r1, RGBValue< V2, RIDX2, GIDX2, BIDX2 > const &r2)
dot product
Definition: rgbvalue.hxx:894
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)
pahse
Definition: fftw3.hxx:1009
Int32 roundi(FixedPoint16< IntBits, OverflowHandling > v)
rounding to the nearest integer.
Definition: fixedpoint.hxx:1761
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)
Definition: mathutil.hxx:568
std::ptrdiff_t MultiArrayIndex
Definition: multi_iterator.hxx:348
REAL cos_pi(REAL x)
Definition: mathutil.hxx:1201
FFTWComplex< R >::NormType norm(const FFTWComplex< R > &a)
norm (= magnitude)
Definition: fftw3.hxx:1037
NumericTraits< T >::Promote sq(T t)
Definition: mathutil.hxx:341
linalg::TemporaryMatrix< T > log10(MultiArrayView< 2, T, C > const &v)
double gamma(double x)
Definition: mathutil.hxx:1500
linalg::TemporaryMatrix< T > log(MultiArrayView< 2, T, C > const &v)
double loggamma(double x)
Definition: mathutil.hxx:1516
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)
Definition: mathutil.hxx:498
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)
Definition: mathutil.hxx:551
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