@@ -23,22 +23,22 @@ type KMP struct {
2323 tStd [][]float64 // sliding standard deviation of each timeseries with a window of m each
2424 tF [][]complex128 // holds an existing calculation of the FFT for each timeseries
2525 n int // length of the timeseries
26- M int // length of a subsequence
26+ W int // length of a subsequence
2727 MP [][]float64 // matrix profile
2828 Idx [][]int // matrix profile index
2929}
3030
3131// NewKMP creates a matrix profile struct specifically to be used with the k dimensional
3232// matrix profile computation. The number of rows represents the number of dimensions,
3333// and each row holds a series of points of equal length as each other.
34- func NewKMP (t [][]float64 , m int ) (* KMP , error ) {
34+ func NewKMP (t [][]float64 , w int ) (* KMP , error ) {
3535 if t == nil || len (t ) == 0 {
3636 return nil , fmt .Errorf ("slice is nil or has a length of 0 dimensions" )
3737 }
3838
3939 k := KMP {
4040 T : t ,
41- M : m ,
41+ W : w ,
4242 n : len (t [0 ]),
4343 }
4444
@@ -49,11 +49,11 @@ func NewKMP(t [][]float64, m int) (*KMP, error) {
4949 }
5050 }
5151
52- if k .M * 2 >= k .n {
52+ if k .W * 2 >= k .n {
5353 return nil , fmt .Errorf ("subsequence length must be less than half the timeseries" )
5454 }
5555
56- if k .M < 2 {
56+ if k .W < 2 {
5757 return nil , fmt .Errorf ("subsequence length must be at least 2" )
5858 }
5959
@@ -63,15 +63,15 @@ func NewKMP(t [][]float64, m int) (*KMP, error) {
6363 k .MP = make ([][]float64 , len (t ))
6464 k .Idx = make ([][]int , len (t ))
6565 for d := 0 ; d < len (t ); d ++ {
66- k .tMean [d ] = make ([]float64 , k .n - k .M + 1 )
67- k .tStd [d ] = make ([]float64 , k .n - k .M + 1 )
68- k .tF [d ] = make ([]complex128 , k .n - k .M + 1 )
69- k .MP [d ] = make ([]float64 , k .n - k .M + 1 )
70- k .Idx [d ] = make ([]int , k .n - k .M + 1 )
66+ k .tMean [d ] = make ([]float64 , k .n - k .W + 1 )
67+ k .tStd [d ] = make ([]float64 , k .n - k .W + 1 )
68+ k .tF [d ] = make ([]complex128 , k .n - k .W + 1 )
69+ k .MP [d ] = make ([]float64 , k .n - k .W + 1 )
70+ k .Idx [d ] = make ([]int , k .n - k .W + 1 )
7171 }
7272
7373 for d := 0 ; d < len (t ); d ++ {
74- for i := 0 ; i < k .n - k .M + 1 ; i ++ {
74+ for i := 0 ; i < k .n - k .W + 1 ; i ++ {
7575 k.MP [d ][i ] = math .Inf (1 )
7676 k.Idx [d ][i ] = math .MaxInt64
7777 }
@@ -136,7 +136,7 @@ func (k *KMP) initCaches() error {
136136 // precompute the mean and standard deviation for each window of size m for all
137137 // sliding windows across the b timeseries
138138 for d := 0 ; d < len (k .T ); d ++ {
139- k .tMean [d ], k .tStd [d ], err = util .MovMeanStd (k .T [d ], k .M )
139+ k .tMean [d ], k .tStd [d ], err = util .MovMeanStd (k .T [d ], k .W )
140140 if err != nil {
141141 return err
142142 }
@@ -170,36 +170,36 @@ func (k *KMP) mStomp() error {
170170 var D [][]float64
171171 D = make ([][]float64 , len (k .T ))
172172 for d := 0 ; d < len (D ); d ++ {
173- D [d ] = make ([]float64 , k .n - k .M + 1 )
173+ D [d ] = make ([]float64 , k .n - k .W + 1 )
174174 }
175175
176176 dots := make ([][]float64 , len (k .T ))
177177 for d := 0 ; d < len (dots ); d ++ {
178- dots [d ] = make ([]float64 , k .n - k .M + 1 )
178+ dots [d ] = make ([]float64 , k .n - k .W + 1 )
179179 copy (dots [d ], cachedDots [d ])
180180 }
181181
182- for idx := 0 ; idx < k .n - k .M + 1 ; idx ++ {
182+ for idx := 0 ; idx < k .n - k .W + 1 ; idx ++ {
183183 for d := 0 ; d < len (dots ); d ++ {
184184 if idx > 0 {
185- for j := k .n - k .M ; j > 0 ; j -- {
186- dots [d ][j ] = dots [d ][j - 1 ] - k .T [d ][j - 1 ]* k .T [d ][idx - 1 ] + k .T [d ][j + k .M - 1 ]* k .T [d ][idx + k .M - 1 ]
185+ for j := k .n - k .W ; j > 0 ; j -- {
186+ dots [d ][j ] = dots [d ][j - 1 ] - k .T [d ][j - 1 ]* k .T [d ][idx - 1 ] + k .T [d ][j + k .W - 1 ]* k .T [d ][idx + k .W - 1 ]
187187 }
188188 dots [d ][0 ] = cachedDots [d ][idx ]
189189 }
190190
191- for i := 0 ; i < k .n - k .M + 1 ; i ++ {
192- D [d ][i ] = math .Sqrt (2 * float64 (k .M ) * math .Abs (1 - (dots [d ][i ]- float64 (k .M )* k.tMean [d ][i ]* k.tMean [d ][idx ])/ (float64 (k .M )* k.tStd [d ][i ]* k.tStd [d ][idx ])))
191+ for i := 0 ; i < k .n - k .W + 1 ; i ++ {
192+ D [d ][i ] = math .Sqrt (2 * float64 (k .W ) * math .Abs (1 - (dots [d ][i ]- float64 (k .W )* k.tMean [d ][i ]* k.tMean [d ][idx ])/ (float64 (k .W )* k.tStd [d ][i ]* k.tStd [d ][idx ])))
193193 }
194194 // sets the distance in the exclusion zone to +Inf
195- util .ApplyExclusionZone (D [d ], idx , k .M / 2 )
195+ util .ApplyExclusionZone (D [d ], idx , k .W / 2 )
196196 }
197197
198198 k .columnWiseSort (D )
199199 k .columnWiseCumSum (D )
200200
201201 for d := 0 ; d < len (D ); d ++ {
202- for i := 0 ; i < k .n - k .M + 1 ; i ++ {
202+ for i := 0 ; i < k .n - k .W + 1 ; i ++ {
203203 if D [d ][i ]/ (float64 (d )+ 1 ) < k.MP [d ][i ] {
204204 k.MP [d ][i ] = D [d ][i ] / (float64 (d ) + 1 )
205205 k.Idx [d ][i ] = idx
@@ -222,8 +222,8 @@ func (k KMP) crossCorrelate(idx int, fft *fourier.FFT, D [][]float64) {
222222 var dot []float64
223223
224224 for d := 0 ; d < len (D ); d ++ {
225- for i := 0 ; i < k .M ; i ++ {
226- qpad [i ] = k .T [d ][idx + k .M - i - 1 ]
225+ for i := 0 ; i < k .W ; i ++ {
226+ qpad [i ] = k .T [d ][idx + k .W - i - 1 ]
227227 }
228228 qf = fft .Coefficients (nil , qpad )
229229
@@ -235,16 +235,16 @@ func (k KMP) crossCorrelate(idx int, fft *fourier.FFT, D [][]float64) {
235235
236236 dot = fft .Sequence (nil , qf )
237237
238- for i := 0 ; i < k .n - k .M + 1 ; i ++ {
239- dot [k .M - 1 + i ] = dot [k .M - 1 + i ] / float64 (k .n )
238+ for i := 0 ; i < k .n - k .W + 1 ; i ++ {
239+ dot [k .W - 1 + i ] = dot [k .W - 1 + i ] / float64 (k .n )
240240 }
241- D [d ] = dot [k .M - 1 :]
241+ D [d ] = dot [k .W - 1 :]
242242 }
243243}
244244
245245func (k KMP ) columnWiseSort (D [][]float64 ) {
246246 dist := make ([]float64 , len (D ))
247- for i := 0 ; i < k .n - k .M + 1 ; i ++ {
247+ for i := 0 ; i < k .n - k .W + 1 ; i ++ {
248248 for d := 0 ; d < len (D ); d ++ {
249249 dist [d ] = D [d ][i ]
250250 }
@@ -259,7 +259,7 @@ func (k KMP) columnWiseCumSum(D [][]float64) {
259259 for d := 0 ; d < len (D ); d ++ {
260260 // change D to be a cumulative sum of distances across dimensions
261261 if d > 0 {
262- for i := 0 ; i < k .n - k .M + 1 ; i ++ {
262+ for i := 0 ; i < k .n - k .W + 1 ; i ++ {
263263 D [d ][i ] += D [d - 1 ][i ]
264264 }
265265 }
0 commit comments