swh:1:snp:a422b851e16cc4f1262b8bf03a4a48e024193f52
Raw File
Tip revision: 11c2eb9b7b9ce2eb46162b8274c0c5ae71223057 authored by Dirk Roorda on 28 November 2016, 21:17:27 UTC
New minor release 0.0.2
Tip revision: 11c2eb9
prepare.py
import array,collections,functools

def getOtypeInfo(info, otype):
    result = (otype[-2], otype[-1], len(otype) - 2 + otype[-1])
    info('slot type = {}; max slot = {}; max node = {}'.format(*result))
    return result

def levels(info, error, otype, oslots):
    (slotType, maxSlot, maxNode) = getOtypeInfo(info, otype)
    info('max node = {}'.format(maxNode))
    otypeCount = collections.Counter()
    slotSetLengths = collections.Counter()
    info('get ranking of otypes')
    for n in range(len(oslots) - 1):
        ntp = otype[n]
        otypeCount[ntp] += 1
        slotSetLengths[ntp] += len(oslots[n])
    result = tuple(sorted(
        ((otp, slotSetLengths[otp]/otypeCount[otp]) for otp in otypeCount),
        key=lambda x: -x[1],
    )+[(slotType, 1)])
    info('results:')
    for (otp, av) in result:
        info('{:<15}: {:>4}'.format(otp, round(av, 2)), tm=False)
    return result

def order(info, error, otype, oslots, levels):
    (slotType, maxSlot, maxNode) = getOtypeInfo(info, otype)
    info('assigning otype levels to nodes')
    otypeLevels = dict(((x[0], i) for (i, x) in enumerate(levels)))
    otypeRank = lambda n: otypeLevels[slotType if n < maxSlot+1 else otype[n-maxSlot-1]]
    def before(na,nb):
        if na > maxSlot:
            a = na - maxSlot - 1
            sa = set(oslots[a])
        else:
            a = na
            sa = {a}
        if nb > maxSlot:
            b = nb - maxSlot - 1
            sb = set(oslots[b])
        else:
            b = nb
            sb = {b}
        oa = otypeRank(a)
        ob = otypeRank(b)
        if sa == sb: return 0 if oa == ob else -1 if oa < ob else 1
        if sa < sb: return 1
        if sa > sb: return -1
        am = min(sa - sb)
        bm = min(sb - sa)
        return -1 if am < bm else 1 if bm < am else None

    canonKey = functools.cmp_to_key(before)
    info('sorting nodes')
    nodes = sorted(range(maxNode+1), key=canonKey)
    return array.array('I', nodes)

def rank(info, error, otype, order):
    (slotType, maxSlot, maxNode) = getOtypeInfo(info, otype)
    info('ranking nodes')
    nodesRank = dict(((n,i) for (i,n) in enumerate(order)))
    return array.array('I', (nodesRank[n] for n in range(maxNode+1)))

def levUp(info, error, otype, oslots, rank):
    (slotType, maxSlot, maxNode) = getOtypeInfo(info, otype)
    info('making inverse of edge feature oslots')
    oslotsInv = {}
    for (n, mapList) in enumerate(oslots[0:-1]):
        for m in mapList:
            oslotsInv.setdefault(m, set()).add(n+maxSlot+1)
    info('listing embedders of all nodes')
    embedders = []
    for n in range(maxSlot+1):
        contentEmbedders = oslotsInv[n]
        embedders.append(tuple(sorted(
            [m for m in contentEmbedders if rank[m] < rank[n]],
            key=lambda m: -rank[m],
        )))
    for n in range(maxSlot+1, maxNode+1):
        mList = oslots[n-maxSlot-1]
        if len(mList) == 0:
            embedders.append(tuple())
        else:
            contentEmbedders = functools.reduce(
                lambda x,y: x & oslotsInv[y],
                mList[1:], oslotsInv[mList[0]],
            )
            embedders.append(tuple(sorted(
                [m for m in contentEmbedders if rank[m] < rank[n]],
                key=lambda m: -rank[m],
            )))
    return tuple(embedders)

def levDown(info, error, otype, embedders, rank):
    (slotType, maxSlot, maxNode) = getOtypeInfo(info, otype)
    info('inverting embedders')
    inverse = {}
    for n in range(maxSlot+1, maxNode+1):
        for m in embedders[n]:
            inverse.setdefault(m, set()).add(n)
    info('turning embeddees into list')
    embeddees = []
    for n in range(maxSlot+1, maxNode+1):
        embeddees.append(tuple(sorted(
            inverse.get(n, []),
            key=lambda m: rank[m],
        )))
    return tuple(embeddees)

back to top