-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsuffstat.py
More file actions
91 lines (75 loc) · 2.99 KB
/
suffstat.py
File metadata and controls
91 lines (75 loc) · 2.99 KB
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
83
84
85
86
87
88
89
from collections import Counter
import numpy as np
class Cache:
def __init__(self, plain_seq, cipher_seq):
counters = dict()
for p, c in zip(plain_seq, cipher_seq):
if p not in counters:
counters[p] = Counter()
counters[p][c] += 1
self.counters = counters
def get_counter(self, plain_char):
if plain_char not in self.counters:
self.counters[plain_char] = Counter()
return self.counters[plain_char]
def increment_char(self, plain_char, cipher_char):
cipher_counts = self.get_counter(plain_char)
cipher_counts[cipher_char] += 1
return cipher_counts[cipher_char]
def increment(self, plain, cipher):
try:
for p, c in zip(plain, cipher):
self._increment_char(p, c)
except TypeError:
self._increment_char(plain, cipher)
def decrement_char(self, plain_char, cipher_char):
cipher_counts = self.get_counter(plain_char)
if cipher_char not in cipher_counts:
return 0
else:
cipher_counts[cipher_char] -= 1
return cipher_counts[cipher_char]
def decrement(self, plain, cipher):
try:
for p, c in zip(plain, cipher):
self._decrement_char(p, c)
except TypeError:
self._decrement_char(plain, cipher)
def get_counts(self, plain_char, cipher_char):
"""
return count of plain character and count of cipher character given the plain character
"""
if plain_char not in self.counters:
return 0, 0
else:
return sum(self.counters[plain_char].values()), self.counters[plain_char][cipher_char]
class EmissionKernel:
def __init__(self, n_hidden, n_obs, plain_seq=None, cipher_seq=None):
self.emission = np.zeros([n_hidden, n_obs], dtype=int)
if plain_seq is not None and cipher_seq is not None:
for p, c in zip(plain_seq, cipher_seq):
self.emission[p, c] += 1
def _increment_char(self, plain_char, cipher_char):
self.emission[plain_char, cipher_char] += 1
return self.emission[plain_char, cipher_char]
def increment(self, plain, cipher):
try:
for p, c in zip(plain, cipher):
self._increment_char(p, c)
except TypeError:
self._increment_char(plain, cipher)
def decrement_char(self, plain_char, cipher_char):
assert(self.emission[plain_char, cipher_char] >= 0)
if self.emission[plain_char, cipher_char] == 0:
return 0
else:
self.emission[plain_char, cipher_char] -= 1
return self.emission[plain_char, cipher_char]
def decrement(self, plain, cipher):
try:
for p, c in zip(plain, cipher):
self._decrement_char(p, c)
except TypeError:
self._decrement_char(plain, cipher)
def get(self, plain_char):
return self.emission[plain_char, :]