mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
Loading...
Searching...
No Matches
crossCorrelation.hpp
Go to the documentation of this file.
1/** \file crossCorrelation.hpp
2 * \brief Declares direct discrete cross-correlation utilities.
3 * \author Jared R. Males (jaredmales@gmail.com)
4 */
5
6#ifndef __crossCorrelation_hpp__
7#define __crossCorrelation_hpp__
8
10
11namespace mx
12{
13
14// make these _worker
15// change to pre-allocate native arrays
16// add x and y lag differences
17
18// template<class eigenT, class eigenTin1, class eigenTin2>
19template <typename floatT, typename sizeT = size_t>
20void calcDiscreteCrossCorrelation( floatT *cc,
21 floatT *m1,
22 floatT *m2,
23 sizeT dim1,
24 sizeT dim2,
25 sizeT min_x_lag,
26 sizeT max_x_lag,
27 sizeT min_y_lag,
28 sizeT max_y_lag )
29{
30
31 sizeT cc_dim1, cc_dim2;
32 // size_t dim1 = m1.rows();
33 // size_t dim2 = m2.cols();
34
35 // if( dim1 != m2.rows() || dim2 != m2.cols())
36 // {
37 // error
38 // return;
39 // }
40
41 // if( min_x_lag <= 0 )
42 // {
43 // max_x_lag = dim1; //std::min(dim1,dim2);
44 // min_x_lag = -max_x_lag;
45 // }
46 //
47 // if( min_y_lag <= 0 )
48 // {
49 // max_y_lag = dim2; //std::min(dim1,dim2);
50 // min_y_lag = -max_y_lag;
51 // }
52
53 // cc.resize(maxlag-minlag+1, maxlag-minlag+1);
54
55 cc_dim1 = max_x_lag - min_x_lag + 1;
56 cc_dim2 = max_y_lag - min_y_lag + 1;
57
58 // pout("cc_dims ", cc_dim1, cc_dim2);
59 for( sizeT i = min_x_lag; i < max_x_lag + 1; ++i )
60 {
61 for( sizeT j = min_y_lag; j < max_y_lag + 1; ++j )
62 {
63 // cc(i-minlag, j-minlag) = 0;
64 cc[( j - min_y_lag ) * cc_dim1 + ( i - min_x_lag )] = 0;
65
66 // pout((j-min_y_lag)*cc_dim1 + (i-min_x_lag));
67
68 for( sizeT k = 0; k < dim1; ++k )
69 {
70 if( k + i < 0 )
71 continue;
72 if( k + i >= dim1 )
73 continue;
74
75 for( sizeT l = 0; l < dim2; ++l )
76 {
77 if( l + j < 0 )
78 continue;
79 if( l + j >= dim2 )
80 continue;
81 cc[( j - min_y_lag ) * cc_dim1 + ( i - min_x_lag )] +=
82 m1[l * dim1 + k] * m2[( l + j ) * dim1 + ( k + i )];
83 }
84 }
85 }
86 }
87}
88
89template <class eigenT, class eigenTin1, class eigenTin2, class eigenTmask>
90void xdiscreteCrossCorrelation(
91 eigenT &cc, const eigenTin1 &m1, const eigenTin2 &m2, eigenTmask &mask, int minlag = 0, int maxlag = 0 )
92{
93
94 size_t dim1 = m1.rows();
95 size_t dim2 = m2.cols();
96
97 if( dim1 != m2.rows() || dim2 != m2.cols() || dim1 != mask.rows() || dim2 != mask.cols() )
98 {
99 // error
100 return;
101 }
102
103 if( minlag <= 0 )
104 {
105 maxlag = std::min( dim1, dim2 );
106 minlag = -maxlag;
107 }
108
109 cc.resize( maxlag - minlag + 1, maxlag - minlag + 1 );
110
111 for( int i = minlag; i < maxlag + 1; i++ )
112 {
113 for( int j = minlag; j < maxlag + 1; j++ )
114 {
115 cc( i - minlag, j - minlag ) = 0;
116
117 for( int k = 0; k < dim1; k++ )
118 {
119 if( k + i < 0 )
120 continue;
121 if( k + i >= dim1 )
122 continue;
123
124 for( int l = 0; l < dim2; l++ )
125 {
126 if( l + j < 0 )
127 continue;
128 if( l + j >= dim2 )
129 continue;
130 cc( i - minlag, j - minlag ) +=
131 m1( k, l ) * mask( k, l ) * m2( k + i, l + j ) * mask( k + i, l + j );
132 }
133 }
134 }
135 }
136}
137
138template <class eigenT, class eigenTin1, class eigenTin2>
139void discreteCrossCorrelation( typename eigenT::Scalar &xlag,
140 typename eigenT::Scalar &ylag,
141 eigenT &cc,
142 const eigenTin1 &m1,
143 const eigenTin2 &m2,
144 int min_x_lag = 0,
145 int max_x_lag = 0,
146 int min_y_lag = 0,
147 int max_y_lag = 0 )
148{
150
151 size_t dim1 = m1.rows();
152 size_t dim2 = m1.cols();
153
154 if( dim1 != m2.rows() || dim2 != m2.cols() )
155 {
156 // error
157 return;
158 }
159
160 // if( min_x_lag == 0 )
161 // {
162 // max_x_lag = dim1;//std::min(dim1,dim2);
163 // min_x_lag = -max_x_lag;
164 // }
165 //
166 // if( min_y_lag <= 0 )
167 // {
168 // max_y_lag = dim2;//std::min(dim1,dim2);
169 // min_y_lag = -max_y_lag;
170 // }
171
172 cc.resize( max_x_lag - min_x_lag + 1, max_y_lag - min_y_lag + 1 );
173
174 calcDiscreteCrossCorrelation<float, int>( (float *)cc.data(),
175 (float *)m1.data(),
176 (float *)m2.data(),
177 dim1,
178 dim2,
179 min_x_lag,
180 max_x_lag,
181 min_y_lag,
182 max_y_lag );
183
184 fitG.setArray( cc.data(), cc.rows(), cc.cols() );
185
186 typename eigenT::Index row, col;
187 typename eigenT::Scalar maxval;
188 maxval = cc.maxCoeff( &row, &col );
189 cc /= maxval; // Normalize to avoid crazy nans in fit, etc.
190 // pout(maxval, row, col);
191
192 fitG.setGuess( 0., 1., row, col, 4., 4., 0. );
193 fitG.fit();
194
195 // fitG.dump_report();
196
197 xlag = min_x_lag + fitG.get_params()[2];
198 ylag = min_y_lag + fitG.get_params()[3];
199}
200
201} // namespace mx
202
203#endif //__crossCorrelation_hpp__
Class to manage fitting a 2D Gaussian to data via the levmarInterface.
Tools for fitting Gaussians to data.
constexpr units::realT k()
Boltzmann Constant.
Definition constants.hpp:69
The mxlib c++ namespace.
Definition mxlib.hpp:37