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