24
24
from . import umath
25
25
from .umath import (multiply , invert , sin , UFUNC_BUFSIZE_DEFAULT ,
26
26
ERR_IGNORE , ERR_WARN , ERR_RAISE , ERR_CALL , ERR_PRINT ,
27
- ERR_LOG , ERR_DEFAULT , PINF , NAN )
27
+ ERR_LOG , ERR_DEFAULT , PINF , NAN , ceil )
28
28
from . import numerictypes
29
29
from .numerictypes import longlong , intc , int_ , float_ , complex_ , bool_
30
30
from ._internal import TooHardError , AxisError
@@ -907,7 +907,35 @@ def _mode_from_name(mode):
907
907
return mode
908
908
909
909
910
- def correlate (a , v , mode = 'valid' ):
910
+ def _lags_from_mode (alen , vlen , mode ):
911
+ if type (mode ) is int : # maxlag
912
+ lags = (- mode + 1 , mode , 1 )
913
+ mode = 3
914
+ elif type (mode ) is tuple : # minlag and maxlag
915
+ if len (mode ) > 2 :
916
+ lags = (int (mode [0 ]), int (mode [1 ]), int (mode [2 ]))
917
+ else :
918
+ lags = (int (mode [0 ]), int (mode [1 ]), 1 )
919
+ mode = 3
920
+ elif isinstance (mode , basestring ):
921
+ mode = _mode_from_name_dict [mode .lower ()[0 ]]
922
+ if alen < vlen :
923
+ alen , vlen = vlen , alen
924
+ inverted = 1
925
+ else :
926
+ inverted = 0
927
+ if mode is 0 :
928
+ lags = (0 , alen - vlen + 1 , 1 )
929
+ elif mode is 1 :
930
+ lags = (- int (vlen / 2 ), alen - int (vlen / 2 ), 1 )
931
+ elif mode is 2 :
932
+ lags = (- vlen + 1 , alen , 1 )
933
+ if inverted :
934
+ lags = (- int (ceil ((lags [1 ]- lags [0 ])/ float (lags [2 ])))* lags [2 ]- lags [0 ]+ lags [2 ], - lags [0 ]+ lags [2 ], lags [2 ])
935
+ return mode , lags
936
+
937
+
938
+ def correlate (a , v , mode = 'valid' , returns_lags = False ):
911
939
"""
912
940
Cross-correlation of two 1-dimensional sequences.
913
941
@@ -923,9 +951,15 @@ def correlate(a, v, mode='valid'):
923
951
----------
924
952
a, v : array_like
925
953
Input sequences.
926
- mode : {'valid', 'same', 'full'}, optional
954
+ mode : int, int tuple, or {'valid', 'same', 'full'}, optional
927
955
Refer to the `convolve` docstring. Note that the default
928
- is 'valid', unlike `convolve`, which uses 'full'.
956
+ is `valid`, unlike `convolve`, which uses `full`.
957
+ returns_lags : bool, optional
958
+ If True, the function returns a lagvector array in addition to the
959
+ cross-correlation result. The lagvector contains the indices of
960
+ the lags for which the cross-correlation was calculated. It is
961
+ the same length as the return array, and corresponds one-to-one.
962
+ False is default.
929
963
old_behavior : bool
930
964
`old_behavior` was removed in NumPy 1.10. If you need the old
931
965
behavior, use `multiarray.correlate`.
@@ -934,6 +968,9 @@ def correlate(a, v, mode='valid'):
934
968
-------
935
969
out : ndarray
936
970
Discrete cross-correlation of `a` and `v`.
971
+ lagvector : ndarray, optional
972
+ The indices of the lags for which the cross-correlation was calculated.
973
+ It is the same length as out, and corresponds one-to-one.
937
974
938
975
See Also
939
976
--------
@@ -953,10 +990,14 @@ def correlate(a, v, mode='valid'):
953
990
--------
954
991
>>> np.correlate([1, 2, 3], [0, 1, 0.5])
955
992
array([ 3.5])
956
- >>> np.correlate([1, 2, 3], [0, 1, 0.5], "same")
993
+ >>> np.correlate([1, 2, 3], [0, 1, 0.5], mode="same")
994
+ array([ 2. , 3.5, 3. ])
995
+ >>> np.correlate([1, 2, 3], [0, 1, 0.5], mode="full", returns_lags=True)
996
+ (array([ 0.5, 2. , 3.5, 3. , 0. ]), array([-2, -1, 0, 1, 2]))
997
+ >>> np.correlate([1, 2, 3], [0, 1, 0.5], mode=2)
957
998
array([ 2. , 3.5, 3. ])
958
- >>> np.correlate([1, 2, 3], [0, 1, 0.5], "full" )
959
- array([ 0.5, 2. , 3.5, 3. , 0. ] )
999
+ >>> np.correlate([1, 2, 3], [0, 1, 0.5], mode=(-1,2,2), returns_lags=True )
1000
+ ( array([ 2. , 3.]), array([-1 , 1]) )
960
1001
961
1002
Using complex sequences:
962
1003
@@ -971,11 +1012,15 @@ def correlate(a, v, mode='valid'):
971
1012
array([ 0.0+0.j , 3.0+1.j , 1.5+1.5j, 1.0+0.j , 0.5+0.5j])
972
1013
973
1014
"""
974
- mode = _mode_from_name (mode )
975
- return multiarray .correlate2 (a , v , mode )
1015
+ mode , lags = _lags_from_mode (len (a ), len (v ), mode )
1016
+ if returns_lags :
1017
+ return multiarray .correlate2 (a , v , 3 , lags [0 ], lags [1 ], lags [2 ]), \
1018
+ arange (lags [0 ], lags [1 ], lags [2 ])
1019
+ else :
1020
+ return multiarray .correlate2 (a , v , 3 , lags [0 ], lags [1 ], lags [2 ])
976
1021
977
1022
978
- def convolve (a , v , mode = 'full' ):
1023
+ def convolve (a , v , mode = 'full' , returns_lags = False ):
979
1024
"""
980
1025
Returns the discrete, linear convolution of two one-dimensional sequences.
981
1026
@@ -993,27 +1038,53 @@ def convolve(a, v, mode='full'):
993
1038
First one-dimensional input array.
994
1039
v : (M,) array_like
995
1040
Second one-dimensional input array.
996
- mode : {'full', 'valid', 'same'}, optional
1041
+ mode : int, int tuple, or {'full', 'valid', 'same'}, optional
1042
+ int (maxlag):
1043
+ This calculates the convolution for all lags starting at
1044
+ (-maxlag + 1) and ending at (maxlag - 1), with steps of size 1.
1045
+ See the optional lagvec argument to get an array containing
1046
+ lags corresponding to the convolution values in the return array.
1047
+
1048
+ tuple (minlag, maxlag) or (minlag, maxlag, lagstep):
1049
+ This calculates the convolution for all lags starting at
1050
+ minlag and ending at (maxlag - 1), with steps of size lagstep.
1051
+ The lags for which the convolution will be calculated correspond
1052
+ with the values in the vector formed by numpy.arange() with the
1053
+ same tuple argument.
1054
+
997
1055
'full':
998
1056
By default, mode is 'full'. This returns the convolution
999
1057
at each point of overlap, with an output shape of (N+M-1,). At
1000
1058
the end-points of the convolution, the signals do not overlap
1001
- completely, and boundary effects may be seen.
1059
+ completely, and boundary effects may be seen. This corresponds
1060
+ with a lag tuple of (-M+1, N, 1) for N>M or (-N+1, M, 1)
1061
+ for M>N.
1002
1062
1003
1063
'same':
1004
- Mode 'same' returns output of length ``max(M, N)``. Boundary
1005
- effects are still visible.
1064
+ Mode `same` returns output of length ``max(M, N)``. Boundary
1065
+ effects are still visible. This corresponds with a lag tuple of
1066
+ (-M/2, N-M/2, 1) for N>M or (-M+N/2+1, N/2+1, 1) for M>N.
1006
1067
1007
1068
'valid':
1008
1069
Mode 'valid' returns output of length
1009
1070
``max(M, N) - min(M, N) + 1``. The convolution product is only given
1010
1071
for points where the signals overlap completely. Values outside
1011
- the signal boundary have no effect.
1072
+ the signal boundary have no effect. This corresponds with a lag tuple
1073
+ of (0, N-M+1, 1) for N>M or (-M+N, 1, 1) for M>N.
1074
+ returns_lags : bool, optional
1075
+ If True, the function returns a lagvector array in addition to the
1076
+ convolution result. The lagvector contains the indices of
1077
+ the lags for which the convolution was calculated. It is
1078
+ the same length as the return array, and corresponds one-to-one.
1079
+ False is default.
1012
1080
1013
1081
Returns
1014
1082
-------
1015
1083
out : ndarray
1016
1084
Discrete, linear convolution of `a` and `v`.
1085
+ lagvector : ndarray, optional
1086
+ The indices of the lags for which the convolution was calculated.
1087
+ It is the same length as out, and corresponds one-to-one.
1017
1088
1018
1089
See Also
1019
1090
--------
@@ -1052,14 +1123,34 @@ def convolve(a, v, mode='full'):
1052
1123
Contains boundary effects, where zeros are taken
1053
1124
into account:
1054
1125
1055
- >>> np.convolve([1,2,3],[0,1,0.5], 'same')
1126
+ >>> np.convolve([1,2,3],[0,1,0.5], mode= 'same')
1056
1127
array([ 1. , 2.5, 4. ])
1057
1128
1058
1129
The two arrays are of the same length, so there
1059
- is only one position where they completely overlap:
1130
+ is only one position where they completely overlap,
1131
+ corresponding to a lag of 0. lagvector=True causes
1132
+ the function to return the lagvector corresponding
1133
+ to the convolution in addition to the convolution
1134
+ itself:
1135
+
1136
+ >>> np.convolve([1,2,3],[0,1,0.5], mode='valid', returns_lags=True)
1137
+ (array([ 2.5]), array([0]))
1138
+
1139
+ Find the convolution for lags ranging from -1 to 1
1140
+ (0 is the lag for which the left sides of the arrays
1141
+ are aligned, -1 has the second vector to the left of
1142
+ the first, and +1 has the second vector to the right
1143
+ of the first):
1060
1144
1061
- >>> np.convolve([1,2,3],[0,1,0.5], 'valid')
1062
- array([ 2.5])
1145
+ >>> np.convolve([1,2,3],[0,1,0.5], mode=2, returns_lags=True)
1146
+ (array([ 1. , 2.5, 4. ]), array([-1, 0, 1]))
1147
+
1148
+ Find the convolution for lags ranging from -2 to 4
1149
+ with steps of length 2 (the maxlag member of the
1150
+ lag range tuple is non-inclusive, similar to np.arange()):
1151
+
1152
+ >>> np.convolve([1,2,3,4,5],[0,1,0.5], mode=(-2,6,2), returns_lags=True)
1153
+ (array([ 0. , 2.5, 5.5, 2.5]), array([-2, 0, 2, 4]))
1063
1154
1064
1155
"""
1065
1156
a , v = array (a , copy = False , ndmin = 1 ), array (v , copy = False , ndmin = 1 )
@@ -1069,8 +1160,12 @@ def convolve(a, v, mode='full'):
1069
1160
raise ValueError ('a cannot be empty' )
1070
1161
if len (v ) == 0 :
1071
1162
raise ValueError ('v cannot be empty' )
1072
- mode = _mode_from_name (mode )
1073
- return multiarray .correlate (a , v [::- 1 ], mode )
1163
+ mode , lags = _lags_from_mode (len (a ), len (v ), mode )
1164
+ if returns_lags :
1165
+ return multiarray .correlate2 (a , v [::- 1 ], 3 , lags [0 ], lags [1 ], lags [2 ]), \
1166
+ arange (lags [0 ], lags [1 ], lags [2 ])
1167
+ else :
1168
+ return multiarray .correlate2 (a , v [::- 1 ], 3 , lags [0 ], lags [1 ], lags [2 ])
1074
1169
1075
1170
1076
1171
def outer (a , b , out = None ):
0 commit comments