changeset 147:e16e42c55a20

Add autocorrelation
author Chris Cannam
date Sat, 27 Apr 2013 23:56:15 +0100
parents cb5ab186f146
children b973e8a31bd6
files yetilab/feature/features.yeti yetilab/signal/autocorrelation.yeti yetilab/signal/test/test_signal.yeti yetilab/test/all.yeti
diffstat 4 files changed, 65 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/yetilab/feature/features.yeti	Sat Apr 27 17:09:48 2013 +0100
+++ b/yetilab/feature/features.yeti	Sat Apr 27 23:56:15 2013 +0100
@@ -1,15 +1,18 @@
 
 module yetilab.feature.features;
 
+block = load yetilab.block.block;
 cplx = load yetilab.block.complex;
 fr = load yetilab.stream.framer;
 
-specdiff frame1 frame2 = 
-    sum (map2 do a b: abs(cplx.magnitude b - cplx.magnitude a) done
-         frame1 frame2);
+magdiff frame1 frame2 =
+    sum (map2 do a b: abs(a - b) done (block.data frame1) (block.data frame2));
 
 emptyFrameFor frames =
-    if empty? frames then array [] else cplx.zeros (length (head frames)) fi;
+    block.zeros
+        if empty? frames then 0
+        else block.length (head frames)
+        fi;
 
 features featureFunc frames =
    (featuresOf prev frames =
@@ -19,13 +22,14 @@
         esac;
     featuresOf (emptyFrameFor frames) frames);
 
-featuresOfFile featureFunc file =
-    features featureFunc 
-       (fr.frequencyDomainFramesOfFile { framesize = 1024, hop = 512 } file);
+specdiff frames = 
+    features magdiff (map cplx.magnitudes frames);
+
+specdiffOfFile parameters filename =
+    specdiff (fr.frequencyDomainFramesOfFile parameters filename);
 
 {
     specdiff,
-    features,
-    featuresOfFile
+    specdiffOfFile,
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/yetilab/signal/autocorrelation.yeti	Sat Apr 27 23:56:15 2013 +0100
@@ -0,0 +1,26 @@
+
+module yetilab.signal.autocorrelation;
+
+acf len series =
+   (a = array series;
+    map do i:
+        sum (map do j:
+                 a[j] * a[j-i]
+                 done [i..length a - 1])
+        done [0..len-1]);
+
+acfNormalised len series =
+   (n = length series;
+    map2 do v i: v / (n - i) done (acf len series) [0..len-1]);
+
+acfUnityNormalised len series =
+   (a = acfNormalised len series;
+    max = head (sortBy (>) a);
+    map (/ max) a);
+
+{
+    acf,
+    acfNormalised,
+    acfUnityNormalised,
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/yetilab/signal/test/test_signal.yeti	Sat Apr 27 23:56:15 2013 +0100
@@ -0,0 +1,24 @@
+module yetilab.signal.test.test_signal;
+
+{ acf, acfNormalised, acfUnityNormalised } = load yetilab.signal.autocorrelation;
+
+{ compare } = load yetilab.test.test;
+
+[
+
+"unnormalised": \(
+    compare (acf 12 (array [1,0,0, 1,0,0, 1,0,0, 1,0,0]))
+        [4,0,0, 3,0,0, 2,0,0, 1,0,0 ];
+),
+
+"normalised": \(
+    compare (acfNormalised 9 (array [1,0,0, 1,0,0, 1,0,0, 1,0,0]))
+        [4/12,0,0, 3/9,0,0, 2/6,0,0 ];
+),
+
+"normalisedUnity": \(
+    compare (acfUnityNormalised 9 (array [1,0,0, 1,0,0, 1,0,0, 1,0,0]))
+        [1,0,0, 1,0,0, 1,0,0 ];
+),
+
+] is hash<string, () -> boolean>;
--- a/yetilab/test/all.yeti	Sat Apr 27 17:09:48 2013 +0100
+++ b/yetilab/test/all.yeti	Sat Apr 27 23:56:15 2013 +0100
@@ -11,7 +11,8 @@
 "fft"        : load yetilab.transform.test.test_fft,
 "vamppost"   : load yetilab.vamp.test.test_vamppost,
 "matrix"     : load yetilab.matrix.test.test_matrix,
-"plot"       : load yetilab.plot.test.test_plot
+"plot"       : load yetilab.plot.test.test_plot,
+"signal"     : load yetilab.signal.test.test_signal,
 ];
 
 bad = sum (mapHash do name testHash: runTests name testHash done tests);