-
Notifications
You must be signed in to change notification settings - Fork 0
/
optimisation_one.py
82 lines (73 loc) · 2.77 KB
/
optimisation_one.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import scipy.spatial.distance as distance
from PeakType import PeakType
import numpy as np
def findpeak(data,idx,r):
threshold = 0.01
# value of first point
focus_val = data[idx]
# initialisaton
window_measure = 10
# runs till the difference between current point and data >= threshold
while window_measure >= threshold:
# compute eucledian distance of focus point to each point in the data.
dist_arr = distance.cdist(focus_val.reshape((1,-1)), data, 'euclidean')
# get points which lie in the range of radius, r
inclusion_pts_idx = np.argwhere(dist_arr < r)[:,1]
# data values corresponding to the points
data_inclusion = data[inclusion_pts_idx]
# if only one value, no mean compute required
if len(data_inclusion) <= 1:
mean_val = focus_val
# compute the new mean value to shift the window towards more dense point.
else:
mean_val = np.mean(data_inclusion, axis=0)
# update the conditional argument
window_measure = np.linalg.norm(mean_val - focus_val)
# update new peak value with the computed mean value
focus_val = mean_val
return mean_val, inclusion_pts_idx
def meanshift_opt_one(data, r):
peak_count = -1
# init empty peaks
peaks = np.array([])
labels = np.zeros(len(data), dtype=int)
# init labels with -100
labels -= 100
for d_ind in (enumerate((data))):
# init the status as new peak
peak_status = PeakType.NEW_PEAK
# if label has already been set for this point, skip the iteration
if labels[d_ind[0]] != -100:
continue
# compute the peak for this point
curr_peak, inside_pts = findpeak(data, int(d_ind[0]), r)
for peak_ind in range(len(peaks)):
# check the constraints if the peak is new or not
if (np.linalg.norm(curr_peak - peaks[peak_ind]) < float(r/2)):
# update peaks array
peaks[peak_ind] = curr_peak
# update peak status
peak_status = PeakType.OLD_PEAK
for inside_idx in inside_pts:
# update labels
labels[inside_idx] = peak_ind
break
# if peak is indeed new peak
if peak_status is PeakType.NEW_PEAK:
# if this is the first peak discovered yet
if peak_count == -1:
peaks = np.append(peaks, curr_peak, axis=0)[np.newaxis]
for inside_idx in inside_pts:
# update labels
labels[inside_idx] = peak_count
# increase peak count by 1
peak_count = 0
# previous peaks existed
else:
# perform updates
peaks = np.append(peaks, curr_peak[np.newaxis], axis=0)
peak_count += 1
peaks[peak_count] = curr_peak
for inside_idx in inside_pts:
labels[inside_idx] = peak_count
return labels, peaks