1import cmsisdsp as dsp
2import numpy as np
3import scipy.spatial.distance as d
4from numpy.testing import assert_allclose
5
6a=[1,2,3]
7b=[1,5,2]
8
9def kulsinski(va,vb):
10    n = len(va)
11    ctt=1.0*np.count_nonzero((va==1) & (vb==1))
12    ctf=1.0*np.count_nonzero((va==1) & (vb==0))
13    cft=1.0*np.count_nonzero((va==0) & (vb==1))
14    return(1.0*(ctf + cft - ctt+n)/(cft + ctf + n))
15
16
17print("\nBray-Curtis")
18ref=d.braycurtis(a,b)
19res=dsp.arm_braycurtis_distance_f32(a,b)
20print(ref)
21print(res)
22assert_allclose(ref,res,1e-6)
23
24
25print("\nCanberra")
26ref=d.canberra(a,b)
27res=dsp.arm_canberra_distance_f32(a,b)
28print(ref)
29print(res)
30assert_allclose(ref,res,1e-6)
31
32print("\nChebyshev")
33ref=d.chebyshev(a,b)
34res=dsp.arm_chebyshev_distance_f32(a,b)
35print(ref)
36print(res)
37assert_allclose(ref,res,1e-6)
38
39res=dsp.arm_chebyshev_distance_f64(a,b)
40print(res)
41assert_allclose(ref,res,1e-10)
42
43print("\nCity Block")
44ref=d.cityblock(a,b)
45res=dsp.arm_cityblock_distance_f32(a,b)
46print(ref)
47print(res)
48assert_allclose(ref,res,1e-6)
49
50res=dsp.arm_cityblock_distance_f64(a,b)
51print(res)
52assert_allclose(ref,res,1e-10)
53
54print("\nCorrelation")
55ref=d.correlation(a,b)
56res=dsp.arm_correlation_distance_f32(a,b)
57print(ref)
58print(res)
59assert_allclose(ref,res,1e-6)
60
61print("\nCosine")
62ref=d.cosine(a,b)
63res=dsp.arm_cosine_distance_f32(a,b)
64print(ref)
65print(res)
66assert_allclose(ref,res,1e-6)
67
68res=dsp.arm_cosine_distance_f64(a,b)
69print(res)
70assert_allclose(ref,res,1e-10)
71
72print("\nEuclidean")
73ref=d.euclidean(a,b)
74res=dsp.arm_euclidean_distance_f32(a,b)
75print(ref)
76print(res)
77assert_allclose(ref,res,1e-6)
78
79res=dsp.arm_euclidean_distance_f64(a,b)
80print(res)
81assert_allclose(ref,res,1e-10)
82
83print("\nJensen-Shannon")
84pa=a/np.sum(a)
85pb=b/np.sum(b)
86ref=d.jensenshannon(pa,pb)
87res=dsp.arm_jensenshannon_distance_f32(pa,pb)
88print(ref)
89print(res)
90assert_allclose(ref,res,1e-6)
91
92print("\nMinkowski")
93w=3
94ref=d.minkowski(a,b,w)
95res=dsp.arm_minkowski_distance_f32(a,b,w)
96print(ref)
97print(res)
98assert_allclose(ref,res,1e-6)
99
100# Int distance
101# For CMSIS-DSP the bool must be packed as bit arrays
102
103# Pack an array of boolean into uint32
104def packset(a):
105    b = np.packbits(a)
106    newSize = int(np.ceil(b.shape[0] / 4.0)) * 4
107    c = np.copy(b).astype(np.uint32)
108    c.resize(newSize)
109    #print(c)
110    vecSize = round(newSize/4)
111    c=c.reshape(vecSize,4)
112    #print(c)
113    r = np.zeros(vecSize)
114    result = []
115    for i in range(0,vecSize):
116        print(c[i,:])
117        #print("%X %X %X %X" % (c[i,0],c[i,1],c[i,2],c[i,3]))
118        d = (c[i,0] << 24) | (c[i,1] << 16) | (c[i,2] << 8) | c[i,3]
119        result.append(np.uint32(d))
120    return(result)
121
122nb = 34
123va = np.random.choice([0,1],nb)
124# Array of word32 containing all of our bits
125pva = packset(va)
126
127
128vb = np.random.choice([0,1],nb)
129# Array of word32 containing all of our bits
130pvb = packset(vb)
131
132print("\nDice")
133ref=d.dice(va,vb)
134res=dsp.arm_dice_distance(pva,pvb,nb)
135print(ref)
136print(res)
137assert_allclose(ref,res,1e-6)
138
139print("\nHamming")
140ref=d.hamming(va,vb)
141res=dsp.arm_hamming_distance(pva,pvb,nb)
142print(ref)
143print(res)
144assert_allclose(ref,res,1e-6)
145
146print("\nJaccard-Needham")
147ref=d.jaccard(va,vb)
148res=dsp.arm_jaccard_distance(pva,pvb,nb)
149print(ref)
150print(res)
151assert_allclose(ref,res,1e-6)
152
153print("\nKulsinski")
154ref=kulsinski(va,vb)
155res=dsp.arm_kulsinski_distance(pva,pvb,nb)
156print(ref)
157print(res)
158assert_allclose(ref,res,1e-6)
159
160print("\nRogers-Tanimoto")
161ref=d.rogerstanimoto(va,vb)
162res=dsp.arm_rogerstanimoto_distance(pva,pvb,nb)
163print(ref)
164print(res)
165assert_allclose(ref,res,1e-6)
166
167print("\nRussell-Rao")
168ref=d.russellrao(va,vb)
169res=dsp.arm_russellrao_distance(pva,pvb,nb)
170print(ref)
171print(res)
172assert_allclose(ref,res,1e-6)
173
174print("\nSokal-Michener")
175ref=d.sokalmichener(va,vb)
176res=dsp.arm_sokalmichener_distance(pva,pvb,nb)
177print(ref)
178print(res)
179assert_allclose(ref,res,1e-6)
180
181print("\nSokal-Sneath")
182ref=d.sokalsneath(va,vb)
183res=dsp.arm_sokalsneath_distance(pva,pvb,nb)
184print(ref)
185print(res)
186assert_allclose(ref,res,1e-6)
187
188print("\nYule")
189ref=d.yule(va,vb)
190res=dsp.arm_yule_distance(pva,pvb,nb)
191print(ref)
192print(res)
193assert_allclose(ref,res,1e-6)
194