khiva 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +305 -10
- data/lib/khiva/dimensionality.rb +36 -0
- data/lib/khiva/features.rb +182 -0
- data/lib/khiva/matrix.rb +13 -0
- data/lib/khiva/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5bf2169ce0f0464a8c9d6e07e962a3d00cc8cf1403178f562b2dc6b694915460
|
4
|
+
data.tar.gz: eb67390404557a984c16a7bcdf72cf3b943cf9b85e4f57b9ed2ae22fd55a1eab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 60d803c2a01cfcc47fb05e5663fc5c884b77ba20b73aaed88bc8042912546c846d57265800409eb41fccfc2d5a5720e81c4a5f3f13c987ca73ac429d801d6ce7
|
7
|
+
data.tar.gz: c5e223048d0736927ec5b1440f7b3d993bc71a411f0e08f6a0ee26d1407a275e3a7da2e6e22b5515deb5f45e701ce899334fd72b6ea8e7e8963a983a9db0b545
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[Khiva](https://github.com/shapelets/khiva) - high-performance time series algorithms - for Ruby
|
4
4
|
|
5
|
-
:fire: Runs on GPUs and CPUs
|
5
|
+
:fire: Runs on GPUs (even on Mac) and CPUs
|
6
6
|
|
7
7
|
[](https://github.com/ankane/khiva-ruby/actions)
|
8
8
|
|
@@ -22,24 +22,85 @@ gem 'khiva'
|
|
22
22
|
|
23
23
|
## Getting Started
|
24
24
|
|
25
|
-
Calculate
|
25
|
+
Calculate the [matrix profile](https://stumpy.readthedocs.io/en/latest/Tutorial_The_Matrix_Profile.html) between two time series
|
26
26
|
|
27
27
|
```ruby
|
28
|
-
a = Khiva::Array.new([11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11])
|
29
|
-
b = Khiva::Array.new([9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9])
|
30
|
-
|
28
|
+
a = Khiva::Array.new([11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11], type: :f32)
|
29
|
+
b = Khiva::Array.new([9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9], type: :f32)
|
30
|
+
m = 3 # subsequence length
|
31
|
+
profile, index = Khiva::Matrix.stomp(a, b, m)
|
31
32
|
```
|
32
33
|
|
33
|
-
Find
|
34
|
+
Find motifs (repeated patterns)
|
34
35
|
|
35
36
|
```ruby
|
36
|
-
|
37
|
+
n = 2 # number of motifs to extract
|
38
|
+
distances, indices, subsequences = Khiva::Matrix.find_best_n_motifs(profile, index, m, n)
|
37
39
|
```
|
38
40
|
|
39
|
-
Find
|
41
|
+
Find discords (anomalies)
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
n = 2 # number of discords to extract
|
45
|
+
distances, indices, subsequences = Khiva::Matrix.find_best_n_discords(profile, index, m, n)
|
46
|
+
```
|
47
|
+
|
48
|
+
## Examples
|
49
|
+
|
50
|
+
- [Anomaly Detection](#anomaly-detection)
|
51
|
+
- [Similarity Search](#similarity-search)
|
52
|
+
|
53
|
+
### Anomaly Detection
|
54
|
+
|
55
|
+
Detect anomalies in a time series
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
# generate a random time series with anomalies from position 100-109
|
59
|
+
series = 1000.times.map { |i| i >= 100 && i <= 109 ? 0.5 : rand }
|
60
|
+
|
61
|
+
# calculate the matrix profile with subsequence length 10
|
62
|
+
a = Khiva::Array.new(series, type: :f32)
|
63
|
+
m = 10
|
64
|
+
profile, index = Khiva::Matrix.stomp_self_join(a, m)
|
65
|
+
|
66
|
+
# find and print the position of the most anomalous subsequence
|
67
|
+
_, _, subsequences = Khiva::Matrix.find_best_n_discords(profile, index, m, 1)
|
68
|
+
pos = subsequences.to_a.first
|
69
|
+
p pos
|
70
|
+
```
|
71
|
+
|
72
|
+
Use [matplotlib.rb](https://github.com/mrkn/matplotlib.rb) for visualization
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
require "matplotlib/pyplot"
|
76
|
+
plt = Matplotlib::Pyplot
|
77
|
+
|
78
|
+
# series
|
79
|
+
plt.figure(0)
|
80
|
+
plt.title("Series")
|
81
|
+
plt.plot(series)
|
82
|
+
|
83
|
+
# matrix profile
|
84
|
+
plt.figure(1)
|
85
|
+
plt.title("Matrix Profile")
|
86
|
+
plt.plot(profile.to_a)
|
87
|
+
|
88
|
+
# most anomalous subsequence and its closest subsequence
|
89
|
+
plt.figure(2)
|
90
|
+
plt.title("Subsequences")
|
91
|
+
plt.plot(series[pos, m], label: "Anomalous")
|
92
|
+
plt.plot(series[index.to_a[pos], m], label: "Closest")
|
93
|
+
plt.legend
|
94
|
+
```
|
95
|
+
|
96
|
+
### Similarity Search
|
97
|
+
|
98
|
+
Find a similar pattern in time series
|
40
99
|
|
41
100
|
```ruby
|
42
|
-
|
101
|
+
series = Khiva::Array.new([1, 2, 3, 4, 3, 4, 5, 6], type: :f32)
|
102
|
+
query = Khiva::Array.new([1, 2, 1], type: :f32)
|
103
|
+
distances, indices = Khiva::Matrix.find_best_n_occurrences(query, series, 1)
|
43
104
|
```
|
44
105
|
|
45
106
|
## Modules
|
@@ -117,12 +178,48 @@ centroids, labels = Khiva::Clustering.k_shape(tss, k)
|
|
117
178
|
|
118
179
|
## Dimensionality
|
119
180
|
|
120
|
-
Piecewise
|
181
|
+
Piecewise Aggregate Approximation (PAA)
|
121
182
|
|
122
183
|
```ruby
|
123
184
|
Khiva::Dimensionality.paa(a, bins)
|
124
185
|
```
|
125
186
|
|
187
|
+
Perceptually Important Points (PIP)
|
188
|
+
|
189
|
+
```ruby
|
190
|
+
Khiva::Dimensionality.pip(a, number_ips)
|
191
|
+
```
|
192
|
+
|
193
|
+
Piecewise Linear Approximation (PLA Bottom Up)
|
194
|
+
|
195
|
+
```ruby
|
196
|
+
Khiva::Dimensionality.pla_bottom_up(a, max_error)
|
197
|
+
```
|
198
|
+
|
199
|
+
Piecewise Linear Approximation (PLA Sliding Window)
|
200
|
+
|
201
|
+
```ruby
|
202
|
+
Khiva::Dimensionality.pla_sliding_window(a, max_error)
|
203
|
+
```
|
204
|
+
|
205
|
+
Ramer-Douglas-Peucker (RDP)
|
206
|
+
|
207
|
+
```ruby
|
208
|
+
Khiva::Dimensionality.ramer_douglas_peucker(a, epsilon)
|
209
|
+
```
|
210
|
+
|
211
|
+
Symbolic Aggregate ApproXimation (SAX)
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
Khiva::Dimensionality.sax(a, alphabet_size)
|
215
|
+
```
|
216
|
+
|
217
|
+
Visvalingam
|
218
|
+
|
219
|
+
```ruby
|
220
|
+
Khiva::Dimensionality.visvalingam(a, num_points)
|
221
|
+
```
|
222
|
+
|
126
223
|
## Distances
|
127
224
|
|
128
225
|
Dynamic time warping (DTW) distance
|
@@ -175,6 +272,48 @@ Absolute sum of changes
|
|
175
272
|
Khiva::Features.absolute_sum_of_changes(tss)
|
176
273
|
```
|
177
274
|
|
275
|
+
Aggregated autocorrelation
|
276
|
+
|
277
|
+
```ruby
|
278
|
+
Khiva::Features.aggregated_autocorrelation(tss, aggregation_function)
|
279
|
+
```
|
280
|
+
|
281
|
+
Approximate entropy
|
282
|
+
|
283
|
+
```ruby
|
284
|
+
Khiva::Features.approximate_entropy(tss, m, r)
|
285
|
+
```
|
286
|
+
|
287
|
+
Autocorrelation
|
288
|
+
|
289
|
+
```ruby
|
290
|
+
Khiva::Features.auto_correlation(tss, max_lag, unbiased)
|
291
|
+
```
|
292
|
+
|
293
|
+
Auto-covariance
|
294
|
+
|
295
|
+
```ruby
|
296
|
+
Khiva::Features.auto_covariance(tss, unbiased: false)
|
297
|
+
```
|
298
|
+
|
299
|
+
Binned entropy
|
300
|
+
|
301
|
+
```ruby
|
302
|
+
Khiva::Features.binned_entropy(tss, max_bins)
|
303
|
+
```
|
304
|
+
|
305
|
+
Schreiber, T. and Schmitz, A. (1997) measure of non-linearity
|
306
|
+
|
307
|
+
```ruby
|
308
|
+
Khiva::Features.c3(tss, lag)
|
309
|
+
```
|
310
|
+
|
311
|
+
Estimate of complexity defined by Batista, Gustavo EAPA, et al (2014)
|
312
|
+
|
313
|
+
```ruby
|
314
|
+
Khiva::Features.cid_ce(tss, z_normalize)
|
315
|
+
```
|
316
|
+
|
178
317
|
Number of values above the mean
|
179
318
|
|
180
319
|
```ruby
|
@@ -187,6 +326,24 @@ Number of values below the mean
|
|
187
326
|
Khiva::Features.count_below_mean(tss)
|
188
327
|
```
|
189
328
|
|
329
|
+
Cross-correlation
|
330
|
+
|
331
|
+
```ruby
|
332
|
+
Khiva::Features.cross_correlation(xss, yss, unbiased)
|
333
|
+
```
|
334
|
+
|
335
|
+
Cross-covariance
|
336
|
+
|
337
|
+
```ruby
|
338
|
+
Khiva::Features.cross_covariance(xss, yss, unbiased)
|
339
|
+
```
|
340
|
+
|
341
|
+
Energy ratio by chunks
|
342
|
+
|
343
|
+
```ruby
|
344
|
+
Khiva::Features.energy_ratio_by_chunks(arr, num_segments, segment_focus)
|
345
|
+
```
|
346
|
+
|
190
347
|
The spectral centroid (mean), variance, skew, and kurtosis of the absolute fourier transform spectrum
|
191
348
|
|
192
349
|
```ruby
|
@@ -205,6 +362,42 @@ First location of the minimum value
|
|
205
362
|
Khiva::Features.first_location_of_minimum(tss)
|
206
363
|
```
|
207
364
|
|
365
|
+
Maximum is duplicated
|
366
|
+
|
367
|
+
```ruby
|
368
|
+
Khiva::Features.has_duplicate_max(tss)
|
369
|
+
```
|
370
|
+
|
371
|
+
Minimum is duplicated
|
372
|
+
|
373
|
+
```ruby
|
374
|
+
Khiva::Features.has_duplicate_min(tss)
|
375
|
+
```
|
376
|
+
|
377
|
+
Any elements are duplicated
|
378
|
+
|
379
|
+
```ruby
|
380
|
+
Khiva::Features.has_duplicates(tss)
|
381
|
+
```
|
382
|
+
|
383
|
+
Index of the mass quantile
|
384
|
+
|
385
|
+
```ruby
|
386
|
+
Khiva::Features.index_mass_quantile(tss, q)
|
387
|
+
```
|
388
|
+
|
389
|
+
Kurtosis
|
390
|
+
|
391
|
+
```ruby
|
392
|
+
Khiva::Features.kurtosis(tss)
|
393
|
+
```
|
394
|
+
|
395
|
+
Standard deviation above threshold
|
396
|
+
|
397
|
+
```ruby
|
398
|
+
Khiva::Features.large_standard_deviation(tss, r)
|
399
|
+
```
|
400
|
+
|
208
401
|
Last location of the maximum value
|
209
402
|
|
210
403
|
```ruby
|
@@ -283,6 +476,54 @@ Minimum
|
|
283
476
|
Khiva::Features.minimum(tss)
|
284
477
|
```
|
285
478
|
|
479
|
+
Number of m-crossings
|
480
|
+
|
481
|
+
```ruby
|
482
|
+
Khiva::Features.number_crossing_m(tss, m)
|
483
|
+
```
|
484
|
+
|
485
|
+
Number of peaks of at least support `n`
|
486
|
+
|
487
|
+
```ruby
|
488
|
+
Khiva::Features.number_peaks(tss, n)
|
489
|
+
```
|
490
|
+
|
491
|
+
Partial autocorrelation
|
492
|
+
|
493
|
+
```ruby
|
494
|
+
Khiva::Features.partial_autocorrelation(tss, lags)
|
495
|
+
```
|
496
|
+
|
497
|
+
Percentage of unique values present more than once
|
498
|
+
|
499
|
+
```ruby
|
500
|
+
Khiva::Features.percentage_of_reoccurring_datapoints_to_all_datapoints(tss, sorted)
|
501
|
+
```
|
502
|
+
|
503
|
+
Percentage of values present more than once
|
504
|
+
|
505
|
+
```ruby
|
506
|
+
Khiva::Features.percentage_of_reoccurring_values_to_all_values(tss, sorted)
|
507
|
+
```
|
508
|
+
|
509
|
+
Quantile
|
510
|
+
|
511
|
+
```ruby
|
512
|
+
Khiva::Features.quantile(tss, q, precision: 100000000)
|
513
|
+
```
|
514
|
+
|
515
|
+
Count of values within the interval [min, max]
|
516
|
+
|
517
|
+
```ruby
|
518
|
+
Khiva::Features.range_count(tss, min, max)
|
519
|
+
```
|
520
|
+
|
521
|
+
Ratio of values more than `r` sigma away from the mean
|
522
|
+
|
523
|
+
```ruby
|
524
|
+
Khiva::Features.ratio_beyond_r_sigma(tss, coeff)
|
525
|
+
```
|
526
|
+
|
286
527
|
Ratio of unique values
|
287
528
|
|
288
529
|
```ruby
|
@@ -301,18 +542,48 @@ Skewness
|
|
301
542
|
Khiva::Features.skewness(tss)
|
302
543
|
```
|
303
544
|
|
545
|
+
Cross power spectral density at different frequencies
|
546
|
+
|
547
|
+
```ruby
|
548
|
+
Khiva::Features.spkt_welch_density(tss, coeff)
|
549
|
+
```
|
550
|
+
|
304
551
|
Standard deviation
|
305
552
|
|
306
553
|
```ruby
|
307
554
|
Khiva::Features.standard_deviation(tss)
|
308
555
|
```
|
309
556
|
|
557
|
+
Sum of all data points present more than once
|
558
|
+
|
559
|
+
```ruby
|
560
|
+
Khiva::Features.sum_of_reoccurring_datapoints(tss, sorted: false)
|
561
|
+
```
|
562
|
+
|
563
|
+
Sum of all values present more than once
|
564
|
+
|
565
|
+
```ruby
|
566
|
+
Khiva::Features.sum_of_reoccurring_values(tss, sorted: false)
|
567
|
+
```
|
568
|
+
|
310
569
|
Sum of values
|
311
570
|
|
312
571
|
```ruby
|
313
572
|
Khiva::Features.sum_values(tss)
|
314
573
|
```
|
315
574
|
|
575
|
+
If looks symmetric
|
576
|
+
|
577
|
+
```ruby
|
578
|
+
Khiva::Features.symmetry_looking(tss, r)
|
579
|
+
```
|
580
|
+
|
581
|
+
Time reversal asymmetry
|
582
|
+
|
583
|
+
```ruby
|
584
|
+
Khiva::Features.time_reversal_asymmetry_statistic(tss, lag)
|
585
|
+
```
|
586
|
+
|
316
587
|
Number of occurrences of a value
|
317
588
|
|
318
589
|
```ruby
|
@@ -395,6 +666,30 @@ Khiva::Linalg.lls(a, b)
|
|
395
666
|
|
396
667
|
## Matrix
|
397
668
|
|
669
|
+
Find discords
|
670
|
+
|
671
|
+
```ruby
|
672
|
+
distances, indices, subsequences = Khiva::Matrix.find_best_n_discords(profile, index, m, n)
|
673
|
+
```
|
674
|
+
|
675
|
+
Find motifs
|
676
|
+
|
677
|
+
```ruby
|
678
|
+
distances, indices, subsequences = Khiva::Matrix.find_best_n_motifs(profile, index, m, n)
|
679
|
+
```
|
680
|
+
|
681
|
+
Find best occurences
|
682
|
+
|
683
|
+
```ruby
|
684
|
+
distances, indices = Khiva::Matrix.find_best_n_occurrences(q, t, n)
|
685
|
+
```
|
686
|
+
|
687
|
+
Mueen’s Algorithm for Similarity Search (MASS)
|
688
|
+
|
689
|
+
```ruby
|
690
|
+
distances = Khiva::Matrix.mass(q, t)
|
691
|
+
```
|
692
|
+
|
398
693
|
Calculate the matrix profile between `ta` and `tb` using a subsequence length of `m` with the STOMP algorithm
|
399
694
|
|
400
695
|
```ruby
|
data/lib/khiva/dimensionality.rb
CHANGED
@@ -6,6 +6,42 @@ module Khiva
|
|
6
6
|
FFI.call(:paa, a, Utils.int_ptr(bins), result)
|
7
7
|
Array.new(result)
|
8
8
|
end
|
9
|
+
|
10
|
+
def pip(a, number_ips)
|
11
|
+
result = Utils.create_ptr
|
12
|
+
FFI.call(:pip, a, Utils.int_ptr(number_ips), result)
|
13
|
+
Array.new(result)
|
14
|
+
end
|
15
|
+
|
16
|
+
def pla_bottom_up(a, max_error)
|
17
|
+
result = Utils.create_ptr
|
18
|
+
FFI.call(:pla_bottom_up, a, Utils.float_ptr(max_error), result)
|
19
|
+
Array.new(result)
|
20
|
+
end
|
21
|
+
|
22
|
+
def pla_sliding_window(a, max_error)
|
23
|
+
result = Utils.create_ptr
|
24
|
+
FFI.call(:pla_sliding_window, a, Utils.float_ptr(max_error), result)
|
25
|
+
Array.new(result)
|
26
|
+
end
|
27
|
+
|
28
|
+
def ramer_douglas_peucker(a, epsilon)
|
29
|
+
result = Utils.create_ptr
|
30
|
+
FFI.call(:ramer_douglas_peucker, a, Utils.double_ptr(epsilon), result)
|
31
|
+
Array.new(result)
|
32
|
+
end
|
33
|
+
|
34
|
+
def sax(a, alphabet_size)
|
35
|
+
result = Utils.create_ptr
|
36
|
+
FFI.call(:sax, a, Utils.int_ptr(alphabet_size), result)
|
37
|
+
Array.new(result)
|
38
|
+
end
|
39
|
+
|
40
|
+
def visvalingam(a, num_points)
|
41
|
+
result = Utils.create_ptr
|
42
|
+
FFI.call(:visvalingam, a, Utils.int_ptr(num_points), result)
|
43
|
+
Array.new(result)
|
44
|
+
end
|
9
45
|
end
|
10
46
|
end
|
11
47
|
end
|
data/lib/khiva/features.rb
CHANGED
@@ -13,6 +13,50 @@ module Khiva
|
|
13
13
|
Array.new(result)
|
14
14
|
end
|
15
15
|
|
16
|
+
def aggregated_autocorrelation(arr, aggregation_function)
|
17
|
+
result = Utils.create_ptr
|
18
|
+
FFI.call(:aggregated_autocorrelation, arr, Utils.int_ptr(aggregation_function), result)
|
19
|
+
Array.new(result)
|
20
|
+
end
|
21
|
+
|
22
|
+
# TODO aggregated_linear_trend
|
23
|
+
|
24
|
+
def approximate_entropy(arr, m, r)
|
25
|
+
result = Utils.create_ptr
|
26
|
+
FFI.call(:approximate_entropy, arr, Utils.int_ptr(m), Utils.float_ptr(r), result)
|
27
|
+
Array.new(result)
|
28
|
+
end
|
29
|
+
|
30
|
+
def auto_correlation(arr, max_lag, unbiased)
|
31
|
+
result = Utils.create_ptr
|
32
|
+
FFI.call(:auto_correlation, arr, Utils.long_ptr(max_lag), Utils.bool_ptr(unbiased), result)
|
33
|
+
Array.new(result)
|
34
|
+
end
|
35
|
+
|
36
|
+
def auto_covariance(arr, unbiased: false)
|
37
|
+
result = Utils.create_ptr
|
38
|
+
FFI.call(:auto_covariance, arr, Utils.bool_ptr(unbiased), result)
|
39
|
+
Array.new(result)
|
40
|
+
end
|
41
|
+
|
42
|
+
def binned_entropy(arr, max_bins)
|
43
|
+
result = Utils.create_ptr
|
44
|
+
FFI.call(:binned_entropy, arr, Utils.int_ptr(max_bins), result)
|
45
|
+
Array.new(result)
|
46
|
+
end
|
47
|
+
|
48
|
+
def c3(arr, lag)
|
49
|
+
result = Utils.create_ptr
|
50
|
+
FFI.call(:c3, arr, Utils.long_ptr(lag), result)
|
51
|
+
Array.new(result)
|
52
|
+
end
|
53
|
+
|
54
|
+
def cid_ce(arr, z_normalize)
|
55
|
+
result = Utils.create_ptr
|
56
|
+
FFI.call(:cid_ce, arr, Utils.bool_ptr(z_normalize), result)
|
57
|
+
Array.new(result)
|
58
|
+
end
|
59
|
+
|
16
60
|
def count_above_mean(arr)
|
17
61
|
result = Utils.create_ptr
|
18
62
|
FFI.call(:count_above_mean, arr, result)
|
@@ -25,12 +69,34 @@ module Khiva
|
|
25
69
|
Array.new(result)
|
26
70
|
end
|
27
71
|
|
72
|
+
def cross_correlation(xss, yss, unbiased)
|
73
|
+
result = Utils.create_ptr
|
74
|
+
FFI.call(:cross_correlation, xss, yss, Utils.bool_ptr(unbiased), result)
|
75
|
+
Array.new(result)
|
76
|
+
end
|
77
|
+
|
78
|
+
def cross_covariance(xss, yss, unbiased)
|
79
|
+
result = Utils.create_ptr
|
80
|
+
FFI.call(:cross_covariance, xss, yss, Utils.bool_ptr(unbiased), result)
|
81
|
+
Array.new(result)
|
82
|
+
end
|
83
|
+
|
84
|
+
# TODO cwt_coefficients
|
85
|
+
|
86
|
+
def energy_ratio_by_chunks(arr, num_segments, segment_focus)
|
87
|
+
result = Utils.create_ptr
|
88
|
+
FFI.call(:energy_ratio_by_chunks, arr, Utils.long_ptr(num_segments), Utils.long_ptr(segment_focus), result)
|
89
|
+
Array.new(result)
|
90
|
+
end
|
91
|
+
|
28
92
|
def fft_aggregated(arr)
|
29
93
|
result = Utils.create_ptr
|
30
94
|
FFI.call(:fft_aggregated, arr, result)
|
31
95
|
Array.new(result)
|
32
96
|
end
|
33
97
|
|
98
|
+
# TODO fft_coefficient
|
99
|
+
|
34
100
|
def first_location_of_maximum(arr)
|
35
101
|
result = Utils.create_ptr
|
36
102
|
FFI.call(:first_location_of_maximum, arr, result)
|
@@ -43,6 +109,42 @@ module Khiva
|
|
43
109
|
Array.new(result)
|
44
110
|
end
|
45
111
|
|
112
|
+
def has_duplicate_max(arr)
|
113
|
+
result = Utils.create_ptr
|
114
|
+
FFI.call(:has_duplicate_max, arr, result)
|
115
|
+
Array.new(result)
|
116
|
+
end
|
117
|
+
|
118
|
+
def has_duplicate_min(arr)
|
119
|
+
result = Utils.create_ptr
|
120
|
+
FFI.call(:has_duplicate_min, arr, result)
|
121
|
+
Array.new(result)
|
122
|
+
end
|
123
|
+
|
124
|
+
def has_duplicates(arr)
|
125
|
+
result = Utils.create_ptr
|
126
|
+
FFI.call(:has_duplicates, arr, result)
|
127
|
+
Array.new(result)
|
128
|
+
end
|
129
|
+
|
130
|
+
def index_mass_quantile(arr, q)
|
131
|
+
result = Utils.create_ptr
|
132
|
+
FFI.call(:index_mass_quantile, arr, Utils.float_ptr(q), result)
|
133
|
+
Array.new(result)
|
134
|
+
end
|
135
|
+
|
136
|
+
def kurtosis(arr)
|
137
|
+
result = Utils.create_ptr
|
138
|
+
FFI.call(:kurtosis, arr, result)
|
139
|
+
Array.new(result)
|
140
|
+
end
|
141
|
+
|
142
|
+
def large_standard_deviation(arr, r)
|
143
|
+
result = Utils.create_ptr
|
144
|
+
FFI.call(:large_standard_deviation, arr, Utils.float_ptr(r), result)
|
145
|
+
Array.new(result)
|
146
|
+
end
|
147
|
+
|
46
148
|
def last_location_of_maximum(arr)
|
47
149
|
result = Utils.create_ptr
|
48
150
|
FFI.call(:last_location_of_maximum, arr, result)
|
@@ -121,6 +223,56 @@ module Khiva
|
|
121
223
|
Array.new(result)
|
122
224
|
end
|
123
225
|
|
226
|
+
def number_crossing_m(arr, m)
|
227
|
+
result = Utils.create_ptr
|
228
|
+
FFI.call(:number_crossing_m, arr, Utils.int_ptr(m), result)
|
229
|
+
Array.new(result)
|
230
|
+
end
|
231
|
+
|
232
|
+
# TODO number_cwt_peaks
|
233
|
+
|
234
|
+
def number_peaks(arr, n)
|
235
|
+
result = Utils.create_ptr
|
236
|
+
FFI.call(:number_peaks, arr, Utils.int_ptr(n), result)
|
237
|
+
Array.new(result)
|
238
|
+
end
|
239
|
+
|
240
|
+
def partial_autocorrelation(arr, lags)
|
241
|
+
result = Utils.create_ptr
|
242
|
+
FFI.call(:partial_autocorrelation, arr, lags, result)
|
243
|
+
Array.new(result)
|
244
|
+
end
|
245
|
+
|
246
|
+
def percentage_of_reoccurring_datapoints_to_all_datapoints(arr, sorted)
|
247
|
+
result = Utils.create_ptr
|
248
|
+
FFI.call(:percentage_of_reoccurring_datapoints_to_all_datapoints, arr, Utils.bool_ptr(sorted), result)
|
249
|
+
Array.new(result)
|
250
|
+
end
|
251
|
+
|
252
|
+
def percentage_of_reoccurring_values_to_all_values(arr, sorted)
|
253
|
+
result = Utils.create_ptr
|
254
|
+
FFI.call(:percentage_of_reoccurring_values_to_all_values, arr, Utils.bool_ptr(sorted), result)
|
255
|
+
Array.new(result)
|
256
|
+
end
|
257
|
+
|
258
|
+
def quantile(arr, q, precision: 100000000)
|
259
|
+
result = Utils.create_ptr
|
260
|
+
FFI.call(:quantile, arr, q, Utils.float_ptr(precision), result)
|
261
|
+
Array.new(result)
|
262
|
+
end
|
263
|
+
|
264
|
+
def range_count(arr, min, max)
|
265
|
+
result = Utils.create_ptr
|
266
|
+
FFI.call(:range_count, arr, Utils.float_ptr(min), Utils.float_ptr(max), result)
|
267
|
+
Array.new(result)
|
268
|
+
end
|
269
|
+
|
270
|
+
def ratio_beyond_r_sigma(arr, r)
|
271
|
+
result = Utils.create_ptr
|
272
|
+
FFI.call(:ratio_beyond_r_sigma, arr, Utils.float_ptr(r), result)
|
273
|
+
Array.new(result)
|
274
|
+
end
|
275
|
+
|
124
276
|
def ratio_value_number_to_time_series_length(arr)
|
125
277
|
result = Utils.create_ptr
|
126
278
|
FFI.call(:ratio_value_number_to_time_series_length, arr, result)
|
@@ -139,18 +291,48 @@ module Khiva
|
|
139
291
|
Array.new(result)
|
140
292
|
end
|
141
293
|
|
294
|
+
def spkt_welch_density(arr, coeff)
|
295
|
+
result = Utils.create_ptr
|
296
|
+
FFI.call(:spkt_welch_density, arr, Utils.int_ptr(coeff), result)
|
297
|
+
Array.new(result)
|
298
|
+
end
|
299
|
+
|
142
300
|
def standard_deviation(arr)
|
143
301
|
result = Utils.create_ptr
|
144
302
|
FFI.call(:standard_deviation, arr, result)
|
145
303
|
Array.new(result)
|
146
304
|
end
|
147
305
|
|
306
|
+
def sum_of_reoccurring_datapoints(arr, sorted: false)
|
307
|
+
result = Utils.create_ptr
|
308
|
+
FFI.call(:sum_of_reoccurring_datapoints, arr, Utils.bool_ptr(sorted), result)
|
309
|
+
Array.new(result)
|
310
|
+
end
|
311
|
+
|
312
|
+
def sum_of_reoccurring_values(arr, sorted: false)
|
313
|
+
result = Utils.create_ptr
|
314
|
+
FFI.call(:sum_of_reoccurring_values, arr, Utils.bool_ptr(sorted), result)
|
315
|
+
Array.new(result)
|
316
|
+
end
|
317
|
+
|
148
318
|
def sum_values(arr)
|
149
319
|
result = Utils.create_ptr
|
150
320
|
FFI.call(:sum_values, arr, result)
|
151
321
|
Array.new(result)
|
152
322
|
end
|
153
323
|
|
324
|
+
def symmetry_looking(arr, r)
|
325
|
+
result = Utils.create_ptr
|
326
|
+
FFI.call(:symmetry_looking, arr, Utils.float_ptr(r), result)
|
327
|
+
Array.new(result)
|
328
|
+
end
|
329
|
+
|
330
|
+
def time_reversal_asymmetry_statistic(arr, lag)
|
331
|
+
result = Utils.create_ptr
|
332
|
+
FFI.call(:time_reversal_asymmetry_statistic, arr, Utils.int_ptr(lag), result)
|
333
|
+
Array.new(result)
|
334
|
+
end
|
335
|
+
|
154
336
|
def value_count(arr, v)
|
155
337
|
result = Utils.create_ptr
|
156
338
|
FFI.call(:value_count, arr, Utils.float_ptr(v), result)
|
data/lib/khiva/matrix.rb
CHANGED
@@ -17,6 +17,19 @@ module Khiva
|
|
17
17
|
[Array.new(motif_distances), Array.new(motif_indices), Array.new(subsequence_indices)]
|
18
18
|
end
|
19
19
|
|
20
|
+
def find_best_n_occurrences(q, t, n)
|
21
|
+
distances = Fiddle::Pointer.malloc(Fiddle::SIZEOF_VOIDP)
|
22
|
+
indices = Fiddle::Pointer.malloc(Fiddle::SIZEOF_VOIDP)
|
23
|
+
FFI.call(:find_best_n_occurrences, q, t, n, distances, indices)
|
24
|
+
[Array.new(distances), Array.new(indices)]
|
25
|
+
end
|
26
|
+
|
27
|
+
def mass(q, t)
|
28
|
+
distances = Fiddle::Pointer.malloc(Fiddle::SIZEOF_VOIDP)
|
29
|
+
FFI.call(:mass, q, t, distances)
|
30
|
+
Array.new(distances)
|
31
|
+
end
|
32
|
+
|
20
33
|
def stomp(tssa, tssb, m)
|
21
34
|
profile = Fiddle::Pointer.malloc(Fiddle::SIZEOF_VOIDP)
|
22
35
|
index = Fiddle::Pointer.malloc(Fiddle::SIZEOF_VOIDP)
|
data/lib/khiva/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: khiva
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-12-
|
11
|
+
date: 2020-12-20 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email: andrew@chartkick.com
|