Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1""" 

2Functions for acting on a axis of an array. 

3""" 

4import numpy as np 

5 

6 

7def axis_slice(a, start=None, stop=None, step=None, axis=-1): 

8 """Take a slice along axis 'axis' from 'a'. 

9 

10 Parameters 

11 ---------- 

12 a : numpy.ndarray 

13 The array to be sliced. 

14 start, stop, step : int or None 

15 The slice parameters. 

16 axis : int, optional 

17 The axis of `a` to be sliced. 

18 

19 Examples 

20 -------- 

21 >>> a = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) 

22 >>> axis_slice(a, start=0, stop=1, axis=1) 

23 array([[1], 

24 [4], 

25 [7]]) 

26 >>> axis_slice(a, start=1, axis=0) 

27 array([[4, 5, 6], 

28 [7, 8, 9]]) 

29 

30 Notes 

31 ----- 

32 The keyword arguments start, stop and step are used by calling 

33 slice(start, stop, step). This implies axis_slice() does not 

34 handle its arguments the exactly the same as indexing. To select 

35 a single index k, for example, use 

36 axis_slice(a, start=k, stop=k+1) 

37 In this case, the length of the axis 'axis' in the result will 

38 be 1; the trivial dimension is not removed. (Use numpy.squeeze() 

39 to remove trivial axes.) 

40 """ 

41 a_slice = [slice(None)] * a.ndim 

42 a_slice[axis] = slice(start, stop, step) 

43 b = a[tuple(a_slice)] 

44 return b 

45 

46 

47def axis_reverse(a, axis=-1): 

48 """Reverse the 1-D slices of `a` along axis `axis`. 

49 

50 Returns axis_slice(a, step=-1, axis=axis). 

51 """ 

52 return axis_slice(a, step=-1, axis=axis) 

53 

54 

55def odd_ext(x, n, axis=-1): 

56 """ 

57 Odd extension at the boundaries of an array 

58 

59 Generate a new ndarray by making an odd extension of `x` along an axis. 

60 

61 Parameters 

62 ---------- 

63 x : ndarray 

64 The array to be extended. 

65 n : int 

66 The number of elements by which to extend `x` at each end of the axis. 

67 axis : int, optional 

68 The axis along which to extend `x`. Default is -1. 

69 

70 Examples 

71 -------- 

72 >>> from scipy.signal._arraytools import odd_ext 

73 >>> a = np.array([[1, 2, 3, 4, 5], [0, 1, 4, 9, 16]]) 

74 >>> odd_ext(a, 2) 

75 array([[-1, 0, 1, 2, 3, 4, 5, 6, 7], 

76 [-4, -1, 0, 1, 4, 9, 16, 23, 28]]) 

77 

78 Odd extension is a "180 degree rotation" at the endpoints of the original 

79 array: 

80 

81 >>> t = np.linspace(0, 1.5, 100) 

82 >>> a = 0.9 * np.sin(2 * np.pi * t**2) 

83 >>> b = odd_ext(a, 40) 

84 >>> import matplotlib.pyplot as plt 

85 >>> plt.plot(arange(-40, 140), b, 'b', lw=1, label='odd extension') 

86 >>> plt.plot(arange(100), a, 'r', lw=2, label='original') 

87 >>> plt.legend(loc='best') 

88 >>> plt.show() 

89 """ 

90 if n < 1: 

91 return x 

92 if n > x.shape[axis] - 1: 

93 raise ValueError(("The extension length n (%d) is too big. " + 

94 "It must not exceed x.shape[axis]-1, which is %d.") 

95 % (n, x.shape[axis] - 1)) 

96 left_end = axis_slice(x, start=0, stop=1, axis=axis) 

97 left_ext = axis_slice(x, start=n, stop=0, step=-1, axis=axis) 

98 right_end = axis_slice(x, start=-1, axis=axis) 

99 right_ext = axis_slice(x, start=-2, stop=-(n + 2), step=-1, axis=axis) 

100 ext = np.concatenate((2 * left_end - left_ext, 

101 x, 

102 2 * right_end - right_ext), 

103 axis=axis) 

104 return ext 

105 

106 

107def even_ext(x, n, axis=-1): 

108 """ 

109 Even extension at the boundaries of an array 

110 

111 Generate a new ndarray by making an even extension of `x` along an axis. 

112 

113 Parameters 

114 ---------- 

115 x : ndarray 

116 The array to be extended. 

117 n : int 

118 The number of elements by which to extend `x` at each end of the axis. 

119 axis : int, optional 

120 The axis along which to extend `x`. Default is -1. 

121 

122 Examples 

123 -------- 

124 >>> from scipy.signal._arraytools import even_ext 

125 >>> a = np.array([[1, 2, 3, 4, 5], [0, 1, 4, 9, 16]]) 

126 >>> even_ext(a, 2) 

127 array([[ 3, 2, 1, 2, 3, 4, 5, 4, 3], 

128 [ 4, 1, 0, 1, 4, 9, 16, 9, 4]]) 

129 

130 Even extension is a "mirror image" at the boundaries of the original array: 

131 

132 >>> t = np.linspace(0, 1.5, 100) 

133 >>> a = 0.9 * np.sin(2 * np.pi * t**2) 

134 >>> b = even_ext(a, 40) 

135 >>> import matplotlib.pyplot as plt 

136 >>> plt.plot(arange(-40, 140), b, 'b', lw=1, label='even extension') 

137 >>> plt.plot(arange(100), a, 'r', lw=2, label='original') 

138 >>> plt.legend(loc='best') 

139 >>> plt.show() 

140 """ 

141 if n < 1: 

142 return x 

143 if n > x.shape[axis] - 1: 

144 raise ValueError(("The extension length n (%d) is too big. " + 

145 "It must not exceed x.shape[axis]-1, which is %d.") 

146 % (n, x.shape[axis] - 1)) 

147 left_ext = axis_slice(x, start=n, stop=0, step=-1, axis=axis) 

148 right_ext = axis_slice(x, start=-2, stop=-(n + 2), step=-1, axis=axis) 

149 ext = np.concatenate((left_ext, 

150 x, 

151 right_ext), 

152 axis=axis) 

153 return ext 

154 

155 

156def const_ext(x, n, axis=-1): 

157 """ 

158 Constant extension at the boundaries of an array 

159 

160 Generate a new ndarray that is a constant extension of `x` along an axis. 

161 

162 The extension repeats the values at the first and last element of 

163 the axis. 

164 

165 Parameters 

166 ---------- 

167 x : ndarray 

168 The array to be extended. 

169 n : int 

170 The number of elements by which to extend `x` at each end of the axis. 

171 axis : int, optional 

172 The axis along which to extend `x`. Default is -1. 

173 

174 Examples 

175 -------- 

176 >>> from scipy.signal._arraytools import const_ext 

177 >>> a = np.array([[1, 2, 3, 4, 5], [0, 1, 4, 9, 16]]) 

178 >>> const_ext(a, 2) 

179 array([[ 1, 1, 1, 2, 3, 4, 5, 5, 5], 

180 [ 0, 0, 0, 1, 4, 9, 16, 16, 16]]) 

181 

182 Constant extension continues with the same values as the endpoints of the 

183 array: 

184 

185 >>> t = np.linspace(0, 1.5, 100) 

186 >>> a = 0.9 * np.sin(2 * np.pi * t**2) 

187 >>> b = const_ext(a, 40) 

188 >>> import matplotlib.pyplot as plt 

189 >>> plt.plot(arange(-40, 140), b, 'b', lw=1, label='constant extension') 

190 >>> plt.plot(arange(100), a, 'r', lw=2, label='original') 

191 >>> plt.legend(loc='best') 

192 >>> plt.show() 

193 """ 

194 if n < 1: 

195 return x 

196 left_end = axis_slice(x, start=0, stop=1, axis=axis) 

197 ones_shape = [1] * x.ndim 

198 ones_shape[axis] = n 

199 ones = np.ones(ones_shape, dtype=x.dtype) 

200 left_ext = ones * left_end 

201 right_end = axis_slice(x, start=-1, axis=axis) 

202 right_ext = ones * right_end 

203 ext = np.concatenate((left_ext, 

204 x, 

205 right_ext), 

206 axis=axis) 

207 return ext 

208 

209 

210def zero_ext(x, n, axis=-1): 

211 """ 

212 Zero padding at the boundaries of an array 

213 

214 Generate a new ndarray that is a zero-padded extension of `x` along 

215 an axis. 

216 

217 Parameters 

218 ---------- 

219 x : ndarray 

220 The array to be extended. 

221 n : int 

222 The number of elements by which to extend `x` at each end of the 

223 axis. 

224 axis : int, optional 

225 The axis along which to extend `x`. Default is -1. 

226 

227 Examples 

228 -------- 

229 >>> from scipy.signal._arraytools import zero_ext 

230 >>> a = np.array([[1, 2, 3, 4, 5], [0, 1, 4, 9, 16]]) 

231 >>> zero_ext(a, 2) 

232 array([[ 0, 0, 1, 2, 3, 4, 5, 0, 0], 

233 [ 0, 0, 0, 1, 4, 9, 16, 0, 0]]) 

234 """ 

235 if n < 1: 

236 return x 

237 zeros_shape = list(x.shape) 

238 zeros_shape[axis] = n 

239 zeros = np.zeros(zeros_shape, dtype=x.dtype) 

240 ext = np.concatenate((zeros, x, zeros), axis=axis) 

241 return ext