-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathsmoothing.el
37 lines (31 loc) · 1.46 KB
/
smoothing.el
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
;; Interpolate two frequency tables (or "bags").
;; We're representing a frequency table as an a-list of (key count)
;; sorted in descending order of counts.
;; An interpolated table has an entry for every key that's in *either*
;; original table. The count for each key in the new table is a
;; weighted sum of the counts in the originals (taking a missing key
;; in the other to have a 0 count).
(defun bag-interpolate (weight-1 bag-1 weight-2 bag-2)
"Return a linear combination of two frequency tables."
(let ((total-1 (float (bag--total bag-1)))
(total-2 (float (bag--total bag-2))))
(cond ((= total-1 0) bag-2)
((= total-2 0) bag-1)
(t (let ((scale-1 (/ weight-1 (+ weight-1 weight-2) total-1))
(scale-2 (/ weight-2 (+ weight-1 weight-2) total-2))
(keys (union (bag--keys bag-1) (bag--keys bag-2))))
(let ((pairs (loop for key in keys
collect `(,key ,(+ (* scale-1 (bag--get bag-1 key))
(* scale-2 (bag--get bag-2 key)))))))
(sort pairs (lambda (p q)
(< (cadr p) (cadr q))))))))))
(defun bag--keys (bag)
"Set of keys of a bag."
(mapcar #'car bag))
(defun bag--total (bag)
"Sum of all counts of a bag."
(reduce #'+ (mapcar #'cadr bag)))
(defun bag--get (bag key)
"The count for a given key of a bag (0 if missing)."
(or (cadr (assoc key bag))
0))