Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/ALGLIB/corr.cs @ 2571

Last change on this file since 2571 was 2563, checked in by gkronber, 15 years ago

Updated ALGLIB to latest version. #751 (Plugin for for data-modeling with ANN (integrated into CEDMA))

File size: 12.8 KB
Line 
1/*************************************************************************
2Copyright (c) 2009, Sergey Bochkanov (ALGLIB project).
3
4>>> SOURCE LICENSE >>>
5This program is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation (www.fsf.org); either version 2 of the
8License, or (at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13GNU General Public License for more details.
14
15A copy of the GNU General Public License is available at
16http://www.fsf.org/licensing/licenses
17
18>>> END OF LICENSE >>>
19*************************************************************************/
20
21using System;
22
23namespace alglib
24{
25    public class corr
26    {
27        /*************************************************************************
28        1-dimensional complex cross-correlation.
29
30        For given Pattern/Signal returns corr(Pattern,Signal) (non-circular).
31
32        Correlation is calculated using reduction to  convolution.  Algorithm with
33        max(N,N)*log(max(N,N)) complexity is used (see  ConvC1D()  for  more  info
34        about performance).
35
36        IMPORTANT:
37            for  historical reasons subroutine accepts its parameters in  reversed
38            order: CorrC1D(Signal, Pattern) = Pattern x Signal (using  traditional
39            definition of cross-correlation, denoting cross-correlation as "x").
40
41        INPUT PARAMETERS
42            Signal  -   array[0..N-1] - complex function to be transformed,
43                        signal containing pattern
44            N       -   problem size
45            Pattern -   array[0..M-1] - complex function to be transformed,
46                        pattern to search withing signal
47            M       -   problem size
48
49        OUTPUT PARAMETERS
50            R       -   cross-correlation, array[0..N+M-2]:
51                        * positive lags are stored in R[0..N-1],
52                          R[i] = sum(conj(pattern[j])*signal[i+j]
53                        * negative lags are stored in R[N..N+M-2],
54                          R[N+M-1-i] = sum(conj(pattern[j])*signal[-i+j]
55
56        NOTE:
57            It is assumed that pattern domain is [0..M-1].  If Pattern is non-zero
58        on [-K..M-1],  you can still use this subroutine, just shift result by K.
59
60          -- ALGLIB --
61             Copyright 21.07.2009 by Bochkanov Sergey
62        *************************************************************************/
63        public static void corrc1d(ref AP.Complex[] signal,
64            int n,
65            ref AP.Complex[] pattern,
66            int m,
67            ref AP.Complex[] r)
68        {
69            AP.Complex[] p = new AP.Complex[0];
70            AP.Complex[] b = new AP.Complex[0];
71            int i = 0;
72            int i_ = 0;
73            int i1_ = 0;
74
75            System.Diagnostics.Debug.Assert(n>0 & m>0, "CorrC1D: incorrect N or M!");
76            p = new AP.Complex[m];
77            for(i=0; i<=m-1; i++)
78            {
79                p[m-1-i] = AP.Math.Conj(pattern[i]);
80            }
81            conv.convc1d(ref p, m, ref signal, n, ref b);
82            r = new AP.Complex[m+n-1];
83            i1_ = (m-1) - (0);
84            for(i_=0; i_<=n-1;i_++)
85            {
86                r[i_] = b[i_+i1_];
87            }
88            if( m+n-2>=n )
89            {
90                i1_ = (0) - (n);
91                for(i_=n; i_<=m+n-2;i_++)
92                {
93                    r[i_] = b[i_+i1_];
94                }
95            }
96        }
97
98
99        /*************************************************************************
100        1-dimensional circular complex cross-correlation.
101
102        For given Pattern/Signal returns corr(Pattern,Signal) (circular).
103        Algorithm has linearithmic complexity for any M/N.
104
105        IMPORTANT:
106            for  historical reasons subroutine accepts its parameters in  reversed
107            order:   CorrC1DCircular(Signal, Pattern) = Pattern x Signal    (using
108            traditional definition of cross-correlation, denoting cross-correlation
109            as "x").
110
111        INPUT PARAMETERS
112            Signal  -   array[0..N-1] - complex function to be transformed,
113                        periodic signal containing pattern
114            N       -   problem size
115            Pattern -   array[0..M-1] - complex function to be transformed,
116                        non-periodic pattern to search withing signal
117            M       -   problem size
118
119        OUTPUT PARAMETERS
120            R   -   convolution: A*B. array[0..M-1].
121
122
123          -- ALGLIB --
124             Copyright 21.07.2009 by Bochkanov Sergey
125        *************************************************************************/
126        public static void corrc1dcircular(ref AP.Complex[] signal,
127            int m,
128            ref AP.Complex[] pattern,
129            int n,
130            ref AP.Complex[] c)
131        {
132            AP.Complex[] p = new AP.Complex[0];
133            AP.Complex[] b = new AP.Complex[0];
134            int i1 = 0;
135            int i2 = 0;
136            int i = 0;
137            int j2 = 0;
138            int i_ = 0;
139            int i1_ = 0;
140
141            System.Diagnostics.Debug.Assert(n>0 & m>0, "ConvC1DCircular: incorrect N or M!");
142           
143            //
144            // normalize task: make M>=N,
145            // so A will be longer (at least - not shorter) that B.
146            //
147            if( m<n )
148            {
149                b = new AP.Complex[m];
150                for(i1=0; i1<=m-1; i1++)
151                {
152                    b[i1] = 0;
153                }
154                i1 = 0;
155                while( i1<n )
156                {
157                    i2 = Math.Min(i1+m-1, n-1);
158                    j2 = i2-i1;
159                    i1_ = (i1) - (0);
160                    for(i_=0; i_<=j2;i_++)
161                    {
162                        b[i_] = b[i_] + pattern[i_+i1_];
163                    }
164                    i1 = i1+m;
165                }
166                corrc1dcircular(ref signal, m, ref b, m, ref c);
167                return;
168            }
169           
170            //
171            // Task is normalized
172            //
173            p = new AP.Complex[n];
174            for(i=0; i<=n-1; i++)
175            {
176                p[n-1-i] = AP.Math.Conj(pattern[i]);
177            }
178            conv.convc1dcircular(ref signal, m, ref p, n, ref b);
179            c = new AP.Complex[m];
180            i1_ = (n-1) - (0);
181            for(i_=0; i_<=m-n;i_++)
182            {
183                c[i_] = b[i_+i1_];
184            }
185            if( m-n+1<=m-1 )
186            {
187                i1_ = (0) - (m-n+1);
188                for(i_=m-n+1; i_<=m-1;i_++)
189                {
190                    c[i_] = b[i_+i1_];
191                }
192            }
193        }
194
195
196        /*************************************************************************
197        1-dimensional real cross-correlation.
198
199        For given Pattern/Signal returns corr(Pattern,Signal) (non-circular).
200
201        Correlation is calculated using reduction to  convolution.  Algorithm with
202        max(N,N)*log(max(N,N)) complexity is used (see  ConvC1D()  for  more  info
203        about performance).
204
205        IMPORTANT:
206            for  historical reasons subroutine accepts its parameters in  reversed
207            order: CorrR1D(Signal, Pattern) = Pattern x Signal (using  traditional
208            definition of cross-correlation, denoting cross-correlation as "x").
209
210        INPUT PARAMETERS
211            Signal  -   array[0..N-1] - real function to be transformed,
212                        signal containing pattern
213            N       -   problem size
214            Pattern -   array[0..M-1] - real function to be transformed,
215                        pattern to search withing signal
216            M       -   problem size
217
218        OUTPUT PARAMETERS
219            R       -   cross-correlation, array[0..N+M-2]:
220                        * positive lags are stored in R[0..N-1],
221                          R[i] = sum(pattern[j]*signal[i+j]
222                        * negative lags are stored in R[N..N+M-2],
223                          R[N+M-1-i] = sum(pattern[j]*signal[-i+j]
224
225        NOTE:
226            It is assumed that pattern domain is [0..M-1].  If Pattern is non-zero
227        on [-K..M-1],  you can still use this subroutine, just shift result by K.
228
229          -- ALGLIB --
230             Copyright 21.07.2009 by Bochkanov Sergey
231        *************************************************************************/
232        public static void corrr1d(ref double[] signal,
233            int n,
234            ref double[] pattern,
235            int m,
236            ref double[] r)
237        {
238            double[] p = new double[0];
239            double[] b = new double[0];
240            int i = 0;
241            int i_ = 0;
242            int i1_ = 0;
243
244            System.Diagnostics.Debug.Assert(n>0 & m>0, "CorrR1D: incorrect N or M!");
245            p = new double[m];
246            for(i=0; i<=m-1; i++)
247            {
248                p[m-1-i] = pattern[i];
249            }
250            conv.convr1d(ref p, m, ref signal, n, ref b);
251            r = new double[m+n-1];
252            i1_ = (m-1) - (0);
253            for(i_=0; i_<=n-1;i_++)
254            {
255                r[i_] = b[i_+i1_];
256            }
257            if( m+n-2>=n )
258            {
259                i1_ = (0) - (n);
260                for(i_=n; i_<=m+n-2;i_++)
261                {
262                    r[i_] = b[i_+i1_];
263                }
264            }
265        }
266
267
268        /*************************************************************************
269        1-dimensional circular real cross-correlation.
270
271        For given Pattern/Signal returns corr(Pattern,Signal) (circular).
272        Algorithm has linearithmic complexity for any M/N.
273
274        IMPORTANT:
275            for  historical reasons subroutine accepts its parameters in  reversed
276            order:   CorrR1DCircular(Signal, Pattern) = Pattern x Signal    (using
277            traditional definition of cross-correlation, denoting cross-correlation
278            as "x").
279
280        INPUT PARAMETERS
281            Signal  -   array[0..N-1] - real function to be transformed,
282                        periodic signal containing pattern
283            N       -   problem size
284            Pattern -   array[0..M-1] - real function to be transformed,
285                        non-periodic pattern to search withing signal
286            M       -   problem size
287
288        OUTPUT PARAMETERS
289            R   -   convolution: A*B. array[0..M-1].
290
291
292          -- ALGLIB --
293             Copyright 21.07.2009 by Bochkanov Sergey
294        *************************************************************************/
295        public static void corrr1dcircular(ref double[] signal,
296            int m,
297            ref double[] pattern,
298            int n,
299            ref double[] c)
300        {
301            double[] p = new double[0];
302            double[] b = new double[0];
303            int i1 = 0;
304            int i2 = 0;
305            int i = 0;
306            int j2 = 0;
307            int i_ = 0;
308            int i1_ = 0;
309
310            System.Diagnostics.Debug.Assert(n>0 & m>0, "ConvC1DCircular: incorrect N or M!");
311           
312            //
313            // normalize task: make M>=N,
314            // so A will be longer (at least - not shorter) that B.
315            //
316            if( m<n )
317            {
318                b = new double[m];
319                for(i1=0; i1<=m-1; i1++)
320                {
321                    b[i1] = 0;
322                }
323                i1 = 0;
324                while( i1<n )
325                {
326                    i2 = Math.Min(i1+m-1, n-1);
327                    j2 = i2-i1;
328                    i1_ = (i1) - (0);
329                    for(i_=0; i_<=j2;i_++)
330                    {
331                        b[i_] = b[i_] + pattern[i_+i1_];
332                    }
333                    i1 = i1+m;
334                }
335                corrr1dcircular(ref signal, m, ref b, m, ref c);
336                return;
337            }
338           
339            //
340            // Task is normalized
341            //
342            p = new double[n];
343            for(i=0; i<=n-1; i++)
344            {
345                p[n-1-i] = pattern[i];
346            }
347            conv.convr1dcircular(ref signal, m, ref p, n, ref b);
348            c = new double[m];
349            i1_ = (n-1) - (0);
350            for(i_=0; i_<=m-n;i_++)
351            {
352                c[i_] = b[i_+i1_];
353            }
354            if( m-n+1<=m-1 )
355            {
356                i1_ = (0) - (m-n+1);
357                for(i_=m-n+1; i_<=m-1;i_++)
358                {
359                    c[i_] = b[i_+i1_];
360                }
361            }
362        }
363    }
364}
Note: See TracBrowser for help on using the repository browser.