36 #ifndef VIGRA_MULTI_TENSORUTILITIES_HXX
37 #define VIGRA_MULTI_TENSORUTILITIES_HXX
41 #include "mathutil.hxx"
42 #include "metaprogramming.hxx"
43 #include "multi_shape.hxx"
44 #include "multi_pointoperators.hxx"
50 template <
int N,
class ArgumentVector,
class ResultVector>
51 class OuterProductFunctor
54 typedef ArgumentVector argument_type;
55 typedef ResultVector result_type;
56 typedef typename ArgumentVector::value_type ValueType;
58 result_type operator()(argument_type
const & in)
const
61 for(
int b=0, i=0; i<N; ++i)
63 for(
int j=i; j<N; ++j, ++b)
65 res[b] = detail::RequiresExplicitCast<ValueType>::cast(in[i]*in[j]);
72 template <
int N,
class ArgumentVector>
73 class TensorTraceFunctor
77 typedef ArgumentVector argument_type;
78 typedef typename ArgumentVector::value_type result_type;
80 result_type exec(argument_type
const & v, MetaInt<1>)
const
85 result_type exec(argument_type
const & v, MetaInt<2>)
const
90 result_type exec(argument_type
const & v, MetaInt<3>)
const
92 return v[0] + v[3] + v[5];
96 void exec(argument_type
const &, result_type &, MetaInt<N2>)
const
98 vigra_fail(
"tensorTraceMultiArray(): Sorry, can only handle dimensions up to 3.");
101 result_type operator()(
const argument_type & a )
const
103 return exec(a, MetaInt<N>());
107 template <
int N,
class ArgumentVector,
class ResultVector>
108 class EigenvaluesFunctor
112 typedef ArgumentVector argument_type;
113 typedef ResultVector result_type;
115 void exec(argument_type
const & v, result_type & r, MetaInt<1>)
const
120 void exec(argument_type
const & v, result_type & r, MetaInt<2>)
const
125 void exec(argument_type
const & v, result_type & r, MetaInt<3>)
const
131 void exec(argument_type
const &, result_type &, MetaInt<N2>)
const
133 vigra_fail(
"tensorEigenvaluesMultiArray(): Sorry, can only handle dimensions up to 3.");
136 result_type operator()(
const argument_type & a )
const
139 exec(a, res, MetaInt<N>());
145 template <
int N,
class ArgumentVector>
146 class DeterminantFunctor
150 typedef ArgumentVector argument_type;
151 typedef typename ArgumentVector::value_type result_type;
153 result_type exec(argument_type
const & v, MetaInt<1>)
const
158 result_type exec(argument_type
const & v, MetaInt<2>)
const
160 return v[0]*v[2] -
sq(v[1]);
163 result_type exec(argument_type
const & v, MetaInt<3>)
const
165 result_type r0, r1, r2;
171 void exec(argument_type
const &, result_type &, MetaInt<N2>)
const
173 vigra_fail(
"tensorDeterminantMultiArray(): Sorry, can only handle dimensions up to 3.");
176 result_type operator()(
const argument_type & a )
const
178 return exec(a, MetaInt<N>());
260 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
261 class DestIterator,
class DestAccessor>
264 DestIterator di, DestAccessor dest)
266 static const int N = SrcShape::static_size;
267 static const int M = N*(N+1)/2;
269 typedef typename SrcAccessor::value_type SrcType;
270 typedef typename DestAccessor::value_type DestType;
272 for(
int k=0; k<N; ++k)
276 vigra_precondition(N == (
int)src.size(si),
277 "vectorToTensorMultiArray(): Wrong number of channels in input array.");
278 vigra_precondition(M == (
int)dest.size(di),
279 "vectorToTensorMultiArray(): Wrong number of channels in output array.");
282 detail::OuterProductFunctor<N, SrcType, DestType>());
285 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
286 class DestIterator,
class DestAccessor>
289 pair<DestIterator, DestAccessor> d)
294 template <
unsigned int N,
class T1,
class S1,
298 MultiArrayView<N, T2, S2> dest)
300 vigra_precondition(source.shape() == dest.shape(),
301 "vectorToTensorMultiArray(): shape mismatch between input and output.");
375 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
376 class DestIterator,
class DestAccessor>
379 DestIterator di, DestAccessor dest)
381 static const int N = SrcShape::static_size;
382 typedef typename SrcAccessor::value_type SrcType;
385 detail::TensorTraceFunctor<N, SrcType>());
388 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
389 class DestIterator,
class DestAccessor>
392 pair<DestIterator, DestAccessor> d)
397 template <
unsigned int N,
class T1,
class S1,
401 MultiArrayView<N, T2, S2> dest)
403 vigra_precondition(source.shape() == dest.shape(),
404 "tensorTraceMultiArray(): shape mismatch between input and output.");
480 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
481 class DestIterator,
class DestAccessor>
484 DestIterator di, DestAccessor dest)
486 static const int N = SrcShape::static_size;
487 static const int M = N*(N+1)/2;
489 typedef typename SrcAccessor::value_type SrcType;
490 typedef typename DestAccessor::value_type DestType;
492 for(
int k=0; k<N; ++k)
496 vigra_precondition(M == (
int)src.size(si),
497 "tensorEigenvaluesMultiArray(): Wrong number of channels in input array.");
498 vigra_precondition(N == (
int)dest.size(di),
499 "tensorEigenvaluesMultiArray(): Wrong number of channels in output array.");
502 detail::EigenvaluesFunctor<N, SrcType, DestType>());
505 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
506 class DestIterator,
class DestAccessor>
509 pair<DestIterator, DestAccessor> d)
514 template <
unsigned int N,
class T1,
class S1,
518 MultiArrayView<N, T2, S2> dest)
520 vigra_precondition(source.shape() == dest.shape(),
521 "tensorEigenvaluesMultiArray(): shape mismatch between input and output.");
595 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
596 class DestIterator,
class DestAccessor>
599 DestIterator di, DestAccessor dest)
601 typedef typename SrcAccessor::value_type SrcType;
603 static const int N = SrcShape::static_size;
604 static const int M = N*(N+1)/2;
606 for(
int k=0; k<N; ++k)
610 vigra_precondition(M == (
int)src.size(si),
611 "tensorDeterminantMultiArray(): Wrong number of channels in output array.");
614 detail::DeterminantFunctor<N, SrcType>());
617 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
618 class DestIterator,
class DestAccessor>
621 pair<DestIterator, DestAccessor> d)
626 template <
unsigned int N,
class T1,
class S1,
630 MultiArrayView<N, T2, S2> dest)
632 vigra_precondition(source.shape() == dest.shape(),
633 "tensorDeterminantMultiArray(): shape mismatch between input and output.");
void symmetric3x3Eigenvalues(T a00, T a01, T a02, T a11, T a12, T a22, T *r0, T *r1, T *r2)
Compute the eigenvalues of a 3x3 real symmetric matrix.
Definition: mathutil.hxx:754
void tensorDeterminantMultiArray(...)
Calculate the tensor determinant for every element of a ND tensor array.
void tensorTraceMultiArray(...)
Calculate the tensor trace for every element of a N-D tensor array.
void vectorToTensorMultiArray(...)
Calculate the tensor (outer) product of a N-D vector with itself.
NumericTraits< T >::Promote sq(T t)
The square function.
Definition: mathutil.hxx:382
void symmetric2x2Eigenvalues(T a00, T a01, T a11, T *r0, T *r1)
Compute the eigenvalues of a 2x2 real symmetric matrix.
Definition: mathutil.hxx:734
vigra::GridGraph< N, DirectedTag >::vertex_descriptor source(typename vigra::GridGraph< N, DirectedTag >::edge_descriptor const &e, vigra::GridGraph< N, DirectedTag > const &g)
Get a vertex descriptor for the start vertex of edge e in graph g (API: boost).
Definition: multi_gridgraph.hxx:2943
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.
void transformMultiArray(...)
Transform a multi-dimensional array with a unary function or functor.
void tensorEigenvaluesMultiArray(...)
Calculate the tensor eigenvalues for every element of a N-D tensor array.