# Path: mitty/benchmarking/complexity.py
# class ShannonEntropy:
#   """Computes Shannon Entropy of k-mers in given sequence. Initialize with value of k.
#   Shannon entropy of a sequence ranges from >0 to 4**k)
#   """
#   def __init__(self, k=1):
#     self.k = k
#     self.alphabet = list(dna_alphabet(k=k))
# 
#   def header_info(self):
#     """Return a list of elements that should be added to the VCF header so:
# 
#     vcf_in.header.info.add(*se.header_info())
#     """
#     return 'SE{}'.format(self.k), 1, 'Float', '{}-mer Shannon entropy for the local region around the variant'.format(self.k)
# 
#   def complexity(self, s, **kwargs):
#     l = len(s) - self.k + 1
#     p = [s.count(a) / l for a in self.alphabet]
#     return sum(- px * np.log2(max(px, 1e-6)) for px in p)
# 
# class LinguisticComplexity:
#   """Computes linguistic complexity"""
#   @staticmethod
#   def header_info():
#     """Return a list of elements that should be added to the VCF header so:
# 
#     vcf_in.header.info.add(*lc.header_info())
#     """
#     return 'LC', 1, 'Float', 'Linguistic complexity of local sequence'
# 
#   @staticmethod
#   def complexity(s, **kwargs):
#     """Compute the linguistic complexity of sequence s
# 
#     :param s:
#     :return:
#     """
#     num, den = 1, 1
#     for k in range(1, len(s)):
#       k4 = 4**k # For DNA
#       num += min(len(set(s[i:i+k] for i in range(len(s) - k + 1))), k4)
#       den += min(len(s) - k + 1, k4)
#     return num / den
# 
# def de_bruijn(k, n):
#   """
#   de Bruijn sequence for alphabet k
#   and subsequences of length n.
#   """
#   alphabet = k
#   k = len(k)
# 
#   a = [0] * k * n
#   sequence = []
# 
#   def db(t, p):
#     if t > n:
#       if n % p == 0:
#         sequence.extend(a[1:p + 1])
#     else:
#       a[t] = a[t - p]
#       db(t + 1, p)
#       for j in range(a[t - p] + 1, k):
#         a[t] = j
#         db(t + 1, t)
# 
#   db(1, 1)
#   sequence.extend(sequence[:n - 1])
# 
#   return "".join(alphabet[i] for i in sequence)


from mitty.benchmarking.complexity import ShannonEntropy, LinguisticComplexity, de_bruijn


def test_shannon():
  """complexity : Test shannon entropy for different k-mers"""
  for k in range(1, 6):
    se = ShannonEntropy(k=k)
    assert se.complexity(de_bruijn('ACTG', k)) == 2 * k


def test_lc():
  """complexity : Lingusitic complexity for de Bruijn sequences"""
  lc = LinguisticComplexity()
  for k in range(1, 5):

# Path: mitty/benchmarking/complexity.py
# class ShannonEntropy:
#   """Computes Shannon Entropy of k-mers in given sequence. Initialize with value of k.
#   Shannon entropy of a sequence ranges from >0 to 4**k)
#   """
#   def __init__(self, k=1):
#     self.k = k
#     self.alphabet = list(dna_alphabet(k=k))
# 
#   def header_info(self):
#     """Return a list of elements that should be added to the VCF header so:
# 
#     vcf_in.header.info.add(*se.header_info())
#     """
#     return 'SE{}'.format(self.k), 1, 'Float', '{}-mer Shannon entropy for the local region around the variant'.format(self.k)
# 
#   def complexity(self, s, **kwargs):
#     l = len(s) - self.k + 1
#     p = [s.count(a) / l for a in self.alphabet]
#     return sum(- px * np.log2(max(px, 1e-6)) for px in p)
# 
# class LinguisticComplexity:
#   """Computes linguistic complexity"""
#   @staticmethod
#   def header_info():
#     """Return a list of elements that should be added to the VCF header so:
# 
#     vcf_in.header.info.add(*lc.header_info())
#     """
#     return 'LC', 1, 'Float', 'Linguistic complexity of local sequence'
# 
#   @staticmethod
#   def complexity(s, **kwargs):
#     """Compute the linguistic complexity of sequence s
# 
#     :param s:
#     :return:
#     """
#     num, den = 1, 1
#     for k in range(1, len(s)):
#       k4 = 4**k # For DNA
#       num += min(len(set(s[i:i+k] for i in range(len(s) - k + 1))), k4)
#       den += min(len(s) - k + 1, k4)
#     return num / den
# 
# def de_bruijn(k, n):
#   """
#   de Bruijn sequence for alphabet k
#   and subsequences of length n.
#   """
#   alphabet = k
#   k = len(k)
# 
#   a = [0] * k * n
#   sequence = []
# 
#   def db(t, p):
#     if t > n:
#       if n % p == 0:
#         sequence.extend(a[1:p + 1])
#     else:
#       a[t] = a[t - p]
#       db(t + 1, p)
#       for j in range(a[t - p] + 1, k):
#         a[t] = j
#         db(t + 1, t)
# 
#   db(1, 1)
#   sequence.extend(sequence[:n - 1])
# 
#   return "".join(alphabet[i] for i in sequence)


# Path: mitty/test/benchmarking/test_complexity.py
from mitty.benchmarking.complexity import ShannonEntropy, LinguisticComplexity, de_bruijn



def test_shannon():
  """complexity : Test shannon entropy for different k-mers"""
  for k in range(1, 6):
    se = ShannonEntropy(k=k)
    assert se.complexity(de_bruijn('ACTG', k)) == 2 * k


def test_lc():
  """complexity : Lingusitic complexity for de Bruijn sequences"""
  lc = LinguisticComplexity()
  for k in range(1, 5):

    assert lc.complexity(de_bruijn('ACTG', k)) == 1