Exemplo n.º 1
0
 def test_TREE5(self):
     """Alpha Equal One. Sixteen Equal Weights."""
     W = PartiallySortedArray([10] * 16)
     T = gdmCodeTree(W)
     self.assertEqual(T.weight(), W.rangeSum(0, len(W)))
     L = T.depths()
     self.assertEqual(L, [4] * 16)
Exemplo n.º 2
0
 def test_TREE5(self):
     """Alpha Equal One. Sixteen Equal Weights."""
     W = PartiallySortedArray([10]*16)
     T = dvlCodeTree(W)
     self.assertEqual(T.weight(),W.rangeSum(0,len(W)))        
     L = T.depths()
     self.assertEqual(L,[4]*16)
Exemplo n.º 3
0
 def initialize(self, weights, D):
     self.weights = PartiallySortedArray(weights)
     self.D = D
     self.N = len(weights)
     n0 = (self.N - 2) % (self.D - 1) + 2  # 2 <= n0 <= D
     self.externals = [
         ExternalNode(self.weights, i)
         for i in range(n0, len(self.weights))
     ]  # N - n0 external nodes
     self.internals = [
         InternalNode(self.weights,
                      [ExternalNode(self.weights, i) for i in range(0, n0)])
     ]  #internal with n0 external nodes
Exemplo n.º 4
0
 def test_TREE10(self):
     """Exponential Sequence."""
     W = PartiallySortedArray([1, 2, 4])
     T = dvlCodeTree(W)
     self.assertEqual(str(T), '(7,(3,[select(0)],[select(1)]),[4])')
     L = T.depths()
     self.assertEqual(sorted(L), [1, 2, 2])
Exemplo n.º 5
0
 def test_TREE7(self):
     """Alpha Equal One. Three Equal Weights."""
     W = PartiallySortedArray([10] * 3)
     T = gdmCodeTree(W)
     self.assertEqual(str(T), "(30,[10],(20,[select(0)],[select(1)]))")
     L = T.depths()
     self.assertEqual(L, [1, 2, 2])
Exemplo n.º 6
0
 def test_TREE3(self):
     """Alpha Equal One. Two Weights."""
     W = PartiallySortedArray([10, 10])
     T = gdmCodeTree(W)
     self.assertEqual(str(T), "(20,[select(0)],[select(1)])")
     L = T.depths()
     self.assertEqual(L, [1] * 2)
Exemplo n.º 7
0
 def test_TREE8(self):
     """Alpha Equal One. Three Similar Weights."""
     W = PartiallySortedArray([12, 11, 10])
     T = gdmCodeTree(W)
     self.assertEqual(str(T), "(33,[12],(21,[select(0)],[select(1)]))")
     L = T.depths()
     self.assertEqual(L, [1, 2, 2])
Exemplo n.º 8
0
 def test_Mix3(self):
     """Three Levels."""
     frequencies = PartiallySortedArray([8] * 8 + [255, 1024])
     frequencies, externals, internals = INITIALIZE(frequencies)
     self.assertEqual(nodeListToWeightList(internals), [16])
     self.assertEqual(nodeListToWeightList(externals),
                      [8] * 6 + [255, 1024])
     frequencies, externals, internals = GroupExternals(
         frequencies, externals, internals)
     self.assertEqual(nodeListToWeightList(internals), [16] * 4)
     self.assertEqual(nodeListToWeightList(externals), [255, 1024])
     frequencies, externals, internals = DockInternals(
         frequencies, externals, internals)
     self.assertEqual(nodeListToWeightList(internals), [64])
     self.assertEqual(nodeListToWeightList(externals), [255, 1024])
     frequencies, externals, internals = MixInternalWithExternal(
         frequencies, externals, internals)
     self.assertEqual(nodeListToWeightList(internals), [319])
     self.assertEqual(nodeListToWeightList(externals), [1024])
     frequencies, externals, internals = GroupExternals(
         frequencies, externals, internals)
     self.assertEqual(nodeListToWeightList(internals), [319])
     self.assertEqual(nodeListToWeightList(externals), [1024])
     frequencies, externals, internals = DockInternals(
         frequencies, externals, internals)
     self.assertEqual(nodeListToWeightList(internals), [319])
     self.assertEqual(nodeListToWeightList(externals), [1024])
     frequencies, externals, internals = MixInternalWithExternal(
         frequencies, externals, internals)
     self.assertEqual(nodeListToWeightList(internals), [1343])
     self.assertEqual(nodeListToWeightList(externals), [])
Exemplo n.º 9
0
 def test_INIT1(self):
     """Alpha Equal One. Two Weights."""
     frequencies = PartiallySortedArray([10, 10])
     frequencies, externals, internals = INITIALIZE(frequencies)
     self.assertEqual(nodeListToString(internals),
                      '[(rangeSum(0,2),[select(0)],[select(1)])]')
     self.assertEqual(nodeListToWeightList(internals), [20])
     self.assertEqual(nodeListToWeightList(externals), [])
Exemplo n.º 10
0
 def test_TREE4(self):
     """Alpha Equal One. Four Equal Weights."""
     W = PartiallySortedArray([10] * 4)
     T = gdmCodeTree(W)
     self.assertEqual(T.toStringWithAllWeightsCalculated(),
                      '(40,(20,[10],[10]),(20,[10],[10]))')
     L = T.depths()
     self.assertEqual(L, [2] * 4)
Exemplo n.º 11
0
 def test_TREE10(self):
     """Exponential Sequence."""
     W = PartiallySortedArray([1, 2, 4])
     T = gdmCodeTree(W)
     self.assertEqual(T.toStringWithAllWeightsCalculated(),
                      '(7,(3,[1],[2]),[4])')
     L = T.depths()
     self.assertEqual(sorted(L), [1, 2, 2])
Exemplo n.º 12
0
 def test_TREE12(self):
     """Exponential Sequence."""
     W = PartiallySortedArray([1, 2, 4, 8, 16, 32, 64, 128, 256])
     T = gdmCodeTree(W)
     self.assertEqual(
         T.toStringWithAllWeightsCalculated(),
         '(511,(255,(127,(63,(31,(15,(7,(3,[1],[2]),[4]),[8]),[16]),[32]),[64]),[128]),[256])'
     )
     L = T.depths()
     self.assertEqual(sorted(L), [1, 2, 3, 4, 5, 6, 7, 8, 8])
Exemplo n.º 13
0
 def test_TREE4(self):
     """Alpha Equal One. Four Equal Weights."""
     W = PartiallySortedArray([10] * 4)
     T = dvlCodeTree(W)
     self.assertEqual(
         str(T),
         '(40,(20,[select(0)],[select(1)]),(rangeSum(2,4),[select(2)],[select(3)]))'
     )
     L = T.depths()
     self.assertEqual(L, [2] * 4)
Exemplo n.º 14
0
 def test_DockInternals1(self):
     """Number of nodes to dock equal to a power of three."""
     frequencies = PartiallySortedArray([8] * 4 + [32])
     frequencies, externals, internals = INITIALIZE(frequencies)
     frequencies, externals, internals = GroupExternals(
         frequencies, externals, internals)
     frequencies, externals, internals = DockInternals(
         frequencies, externals, internals)
     self.assertEqual(nodeListToWeightList(internals), [32])
     self.assertEqual(nodeListToWeightList(externals), [32])
Exemplo n.º 15
0
 def test_DockInternals2(self):
     """Number of nodes to dock is a power of two minus one."""
     frequencies = PartiallySortedArray([14, 13, 12, 11, 10, 9, 8, 256])
     frequencies, externals, internals = INITIALIZE(frequencies)
     frequencies, externals, internals = GroupExternals(
         frequencies, externals, internals)
     frequencies, externals, internals = DockInternals(
         frequencies, externals, internals)
     self.assertEqual(nodeListToWeightList(internals), [77])
     self.assertEqual(nodeListToWeightList(externals), [256])
Exemplo n.º 16
0
 def test_INIT3(self):
     """Exponential Sequence."""
     frequencies = PartiallySortedArray(
         [10, 20, 40, 80, 160, 320, 640, 1280, 2560])
     frequencies, externals, internals = INITIALIZE(frequencies)
     self.assertEqual(nodeListToString(internals),
                      '[(rangeSum(0,2),[select(0)],[select(1)])]')
     self.assertEqual(nodeListToWeightList(internals), [30])
     self.assertEqual(nodeListToWeightList(externals),
                      [40, 80, 160, 320, 640, 1280, 2560])
Exemplo n.º 17
0
    def test_GroupExternals1(self):
        """Basic Example.
"""
        frequencies = PartiallySortedArray([10, 10, 11, 13, 14, 15, 20, 30])
        frequencies, externals, internals = INITIALIZE(frequencies)
        self.assertEqual(nodeListToWeightList(internals), [20])
        self.assertEqual(nodeListToWeightList(externals),
                         [11, 13, 14, 15, 20, 30])
        frequencies, externals, internals = GroupExternals(
            frequencies, externals, internals)
        self.assertEqual(nodeListToWeightList(internals), [24, 29, 40])
        self.assertEqual(nodeListToWeightList(externals), [30])
Exemplo n.º 18
0
def gdm(frequencies):
    """Given a sorted list of weights, return an array with the code lengths of an optimal prefix free code according to the GDM algorithm.

>>> print(gdm([1]*4+[8]*3))
[4, 4, 4, 4, 2, 2, 2]
"""
    # Degenerated cases
    if len(frequencies) == 0 :
        return []
    elif len(frequencies)==1:
        return [0]
    elif len(frequencies)==2:
        return [1,1]
    codeTree = gdmCodeTree(PartiallySortedArray(frequencies))
    codeLengths = codeTree.depths()
    return codeLengths
Exemplo n.º 19
0
def dvl(frequencies):
    """Given a sorted list of weights, return an array with the code lengths of an optimal prefix free code according to the Deferred van Leeuwen's algorithm.

>>> print(dvl([1,1,1,1]))
[2, 2, 2, 2]

"""
    # Degenerated cases
    if len(frequencies) == 0:
        return []
    elif len(frequencies) == 1:
        return [0]
    elif len(frequencies) == 2:
        return [1, 1]
    codeTree = dvlCodeTree(PartiallySortedArray(frequencies))
    codeLengths = codeTree.depths()
    return codeLengths
Exemplo n.º 20
0
 def test_Mix1(self):
     """All weights equal."""
     frequencies = PartiallySortedArray([8] * 8)
     frequencies, externals, internals = INITIALIZE(frequencies)
     self.assertEqual(nodeListToWeightList(internals), [16])
     self.assertEqual(nodeListToWeightList(externals), [8] * 6)
     frequencies, externals, internals = GroupExternals(
         frequencies, externals, internals)
     self.assertEqual(nodeListToWeightList(internals), [16] * 4)
     self.assertEqual(nodeListToWeightList(externals), [])
     frequencies, externals, internals = DockInternals(
         frequencies, externals, internals)
     self.assertEqual(nodeListToWeightList(internals), [16] * 4)
     self.assertEqual(nodeListToWeightList(externals), [])
     frequencies, externals, internals = MixInternalWithExternal(
         frequencies, externals, internals)
     self.assertEqual(nodeListToWeightList(internals), [16] * 4)
     self.assertEqual(nodeListToWeightList(externals), [])
Exemplo n.º 21
0
class DaryGDMCodeTree:
    def __init__(self, weights, D):

        self.unfinished = None
        self.initialize(weights, D)
        while (len(self.externals) > 0):
            self.groupExternals()
            self.dockInternals()
            self.mixInternalWithExternal()
        self.wrapUp()
        self.root = self.internals[0]

    """
    Given an array, partially sort the array and initialize the list of
    external nodes and the list of internal nodes with the
    first n0 external nodes
    """

    def initialize(self, weights, D):
        self.weights = PartiallySortedArray(weights)
        self.D = D
        self.N = len(weights)
        n0 = (self.N - 2) % (self.D - 1) + 2  # 2 <= n0 <= D
        self.externals = [
            ExternalNode(self.weights, i)
            for i in range(n0, len(self.weights))
        ]  # N - n0 external nodes
        self.internals = [
            InternalNode(self.weights,
                         [ExternalNode(self.weights, i) for i in range(0, n0)])
        ]  #internal with n0 external nodes

    """
    Given a partially sorted array of frequencies, a list of external nodes and
    a list of internal nodes, selects the external nodes of weight smaller than
    the smallest internal node, and join them by list of size D in internal nodes
    """

    def groupExternals(self):
        # EE...E
        if not self.unfinished:
            r = self.weights.rankRight(self.internals[0].weight())
        else:
            r = self.weights.rankRight(self.unfinished.weight())
        nbNodes = r - len(self.weights) + len(self.externals)

        #Fill first the unfinished node with E's if there is any
        if self.unfinished:
            leftToFill = self.D - len(self.unfinished.children)  #
            if nbNodes >= leftToFill:  #complete the unfinished node
                self.unfinished.children += self.externals[:leftToFill]
                self.externals = self.externals[leftToFill:]
                self.internals.append(
                    InternalNode(self.weights, self.unfinished.children))
                self.unfinished = None
                nbNodes -= leftToFill
            else:  #we fill what we can
                self.unfinished.children += self.externals[:
                                                           nbNodes] + self.internals[:
                                                                                     1]
                self.externals = self.externals[nbNodes:]
                self.internals = self.internals[1:]
                if len(self.unfinished.children) == self.D:
                    self.internals.append(
                        InternalNode(self.weights, self.unfinished.children))
                    self.unfinished = None
                nbNodes = 0

        # Create internals of E..E's
        while nbNodes >= self.D:
            self.internals.append(
                InternalNode(self.weights, self.externals[:self.D]))
            self.externals = self.externals[self.D:]
            nbNodes -= self.D
        # If there are unpaired nodes, create an unfinished node with the remaining ones
        if nbNodes > 0:
            # The next node must be internal
            nodes = self.externals[:nbNodes] + self.internals[:1]
            self.externals = self.externals[nbNodes:]
            self.internals = self.internals[1:]
            #After adding the first internal the node could be complete
            if len(nodes) == self.D:
                self.internals.append(InternalNode(self.weights, nodes))
            else:
                self.unfinished = InternalNode(self.weights, nodes)

    """
    Given a partially sorted array of frequencies and the number of frequencies
    already processed, a set of internal nodes whose weight is all within a
    factor of D, and a weight maxWeight;
    group the internal nodes by D until at least one internal node has weight
    larger than maxWeight; and return the resulting set of nodes.
    """

    #I...I
    def dockInternals(self):
        nbNodes = len(self.internals)
        #Fill first the unfinished node with I's if there is any
        if self.unfinished:
            leftToFill = self.D - len(self.unfinished.children)
            nbNodes = len(self.internals)
            if nbNodes >= leftToFill:  #complete the unfinished node
                self.unfinished.children += self.internals[:leftToFill]
                self.internals = self.internals[leftToFill:]
                self.internals.append(
                    InternalNode(self.weights, self.unfinished.children))
                self.unfinished = None
                nbNodes -= leftToFill
            else:  #we fill what we can
                self.unfinished.children += self.internals[:nbNodes]
                self.internals = self.internals[nbNodes:]
                nbNodes = 0

        # Group remaining internals into other internals
        while self.externals and len(
                self.internals) >= self.D and self.internals[-1].weight(
                ) <= self.externals[0].weight():
            nbPairsToForm = len(self.internals) // self.D
            for i in range(nbPairsToForm):
                self.internals.append(
                    InternalNode(self.weights, self.internals[:self.D]))
                self.internals = self.internals[self.D:]

    """ """

    def mixInternalWithExternal(self):
        if not self.externals:
            return
        # I*E
        #find the first r smallest intenral weights equal or smaller than the first external
        #TODO do it with a doubling search
        nbNodes = 0
        while nbNodes < len(self.internals) and self.internals[nbNodes].weight(
        ) <= self.externals[0].weight():
            nbNodes += 1
        #finish first an unfinished node
        if self.unfinished:
            leftToFill = self.D - len(self.unfinished.children)
            if nbNodes >= leftToFill:  #complete the unfinished node
                self.unfinished.children += self.internals[:leftToFill]
                self.internals = self.internals[leftToFill:]
                self.internals.append(
                    InternalNode(self.weights, self.unfinished.children))
                self.unfinished = None
                nbNodes -= leftToFill
            else:  #we fill what we can
                self.unfinished.children += self.internals[:
                                                           nbNodes] + self.externals[:
                                                                                     1]
                self.internals = self.internals[nbNodes:]
                self.externals = self.externals[1:]
                if len(self.unfinished.children) == self.D:
                    self.internals.append(
                        InternalNode(self.weights, self.unfinished.children))
                    self.unfinished = None
                nbNodes = 0

        # Create internals of I..I's
        while nbNodes >= self.D:
            self.internals.append(
                InternalNode(self.weights, self.internals[:self.D]))
            self.internals = self.internals[self.D:]
            nbNodes -= self.D

        # If there are unpaired nodes, create an unfinished node with the remaining ones
        if nbNodes > 0:
            # The next node must be external
            nodes = self.internals[:nbNodes] + self.externals[:1]  #IE
            self.internals = self.internals[nbNodes:]
            self.externals = self.externals[1:]
            #After adding the first internal the node could be complete
            if len(nodes) == self.D:
                self.internals.append(InternalNode(self.weights, nodes))
            else:
                self.unfinished = InternalNode(self.weights, nodes)

    """
    Given a list of internal nodes (when there is no external nodes left),
    combine the nodes of the list until only one is left.
    """

    def wrapUp(self):
        #Ther should be N inner nodes left, were (N-1)/(D-1) is an integer
        while len(self.internals) > 1:
            self.internals.append(
                InternalNode(self.weights, self.internals[:self.D]))
            self.internals = self.internals[self.D:]
        self.internals[0].weight()
Exemplo n.º 22
0
 def test_TREE2(self):
     """Alpha Equal One. Singleton input."""
     frequencies = PartiallySortedArray([10])
     self.assertEqual(dvlCodeTree(frequencies),
                      ExternalNode(frequencies, 0))
Exemplo n.º 23
0
 def test_TREE6(self):
     """Alpha Equal One. Eight Similar Weights."""
     W = PartiallySortedArray([10, 11, 12, 13, 14, 15, 16, 17])
     T = gdmCodeTree(W)
     L = T.depths()
     self.assertEqual(L, [3] * 8)
Exemplo n.º 24
0
 def test_TREE1(self):
     """Empty input."""
     frequencies = PartiallySortedArray([])
     self.assertEqual(dvlCodeTree(frequencies), None)
Exemplo n.º 25
0
 def test_TREE9(self):
     """Alpha Equal Two. Single very small weight."""
     W = PartiallySortedArray([1] + [8] * 3)
     T = gdmCodeTree(W)
     L = T.depths()
     self.assertEqual(L, [2] * 4)