Rev Author Line No. Line
178 kaklik 1 #ifndef ARRAY_CONVOLUTION_H
2 #define ARRAY_CONVOLUTION_H
3  
4 // For compatibility with boost <1.31 when apply_if replaced with eval_if
5 #include <boost/version.hpp>
6 #if BOOST_VERSION<=103100
7 #include <boost/mpl/apply_if.hpp>
8 #ifndef eval_if
9 #define eval_if apply_if
10 #endif
11 #else
12 #include <boost/mpl/eval_if.hpp>
13 #endif
14  
15 #include <boost/array.hpp>
16 #include <boost/multi_array.hpp>
17 #include <map>
18 #include <vector>
19 #include "linalg.h"
20  
21 namespace mimas {
22  
23 /** @addtogroup arrayOp
24 @{ */
25 /** Correlation of two multi-arrays.
26 This method provides correlation of two n-dimensional arrays. The
27 resulting array will have the same size as the input-array \c x.
28 Elements outside of the array-boundaries are assumed to be zero.
29  
30 The algorithm is intented to be used for convoluting an array with
31 a small filter. If the filter is very big, it may be more efficient, to
32 perform the correlation in fourier-space.
33  
34 For a small array \c y this algorithm is <b>very fast</b>, because before
35 doing the correlation the <b>loops are reordered for maximum
36 performance</b>.
37  
38 @param x First array (the big one).
39 @param y Second array (the small one).
40 @return Result of correlation.
41 @see fourierTransforms
42 @author Jan Wedekind (jan@wedesoft.de)
43 @date Fri Jul 15 21:37:32 UTC 2005 */
44 template< class _Array1, class _Array2 >
45 boost::multi_array< typename _Array1::element, _Array1::dimensionality >
46 correlate( const _Array1 &x, const _Array2 &y );
47  
48 /** Perform a two-dimensional separable correlation.
49 If you have compiled Mimas with LAPACK-wrappers, you can also
50 let Mimas separate the filter for you (if it is separable).
51  
52 @param x 2D array to be filtered.
53 @param f Two 2D arrays (one with a single column and one with a single
54 row)
55 @see correlate_separable */
56 template< typename T >
57 boost::multi_array< T, 2 > correlate_separable
58 ( const boost::const_multi_array_ref< T, 2 > &x,
59 const std::vector< boost::multi_array< T, 2 > > &f )
60 {
61 assert( f.size() == 2 );
62 return correlate( correlate( x, f[0] ), f[1] );
63 }
64  
65 /** Separate a 2D filter.
66 Separate the 2D filter using singular value decomposition. If the filter
67 is not separable, you will only get an approximate solution.
68  
69 The 2D filter is copied to a matrix. In an ideal case only the first
70 singular value \f$\sigma_1\f$ is unequal to zero and the
71 corresponding vectors \f$\vec{u_1}\f$ and \f$\vec{v_1}\f$ are holding
72 the elements of the separable filter:
73 \f[A=\vec{u_1}\sigma_1\vec{v_1}^\top\f] */
74 template< typename T >
75 std::vector< boost::multi_array< T, 2 > > separate
76 ( const boost::const_multi_array_ref< T, 2 > &array );
77  
78 /** Fast 2D correlation with a separable 2D filter.
79 @see separate */
80 template< typename T >
81 boost::multi_array< T, 2 > correlate_separable
82 ( const boost::const_multi_array_ref< T, 2 > &x,
83 const boost::const_multi_array_ref< T, 2 > &f )
84 {
85 boost::multi_array< T, 2 > result( boost::extents[ x.shape()[0] ]
86 [ x.shape()[1] ] );
87 std::vector< boost::multi_array< T, 2 > > components( separate( f ) );
88 return correlate_separable< T >( x, components );
89 }
90  
91 ///@}
92  
93 };
94  
95 #include "multi_array_conv.tcc"
96  
97 #endif