This file is indexed.

/usr/share/pyshared/pebl/posterior.py is in python-pebl 1.0.2-2build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
"""Class for representing posterior distribution."""

import math
from copy import deepcopy
from itertools import izip

import pydot
import numpy as N

from pebl import network
from pebl.util import *


class Posterior(object):
    """Class for representing posterior distribution.
    
    Except for trivial cases, we can only have an estimated posterior
    distribution. It is usually constructed as a list of the top N networks
    found during a search of the space of networks. 

    The pebl posterior object supports a list-like interface. So, given a
    posterior object post, one can do the following:
   
        * Access the top-scoring network: post[0]
        * Access the top 10 networks as a new posterior object: post[0:10]
        * Calculate entropy of distribution: post.entropy
        * Iterate through networks: for net in post: print net.score
     

    Note: a posterior object is immutable. That is, you cannot add and remove
    networks once it is created. See result.Result for a mutable container for
    networks.  
    
    """

    def __init__(self, nodes, adjacency_matrices, scores, sortedscores=False):
        """Creates a posterior object.

        adjacency_matrices and scores can be lists or numpy arrays.
        If sorted is True, adjacency_matrices and scores should be sorted in
        descending order of score.

        """

        if not sortedscores:
            mycmp = lambda x,y: cmp(x[1],y[1])
            adjmat_and_scores = sorted(zip(adjacency_matrices, scores), 
                                       cmp=mycmp, reverse=True)
            adjacency_matrices, scores = unzip(adjmat_and_scores)

        self.adjacency_matrices = N.array(adjacency_matrices)
        self.scores = N.array(scores)
        self.nodes = nodes


    #
    # Public interface
    #
    def consensus_network(self, threshold=.3):
        """Return a consensus network with the given threshold."""

        features = self.consensus_matrix
        features[features >= threshold] = 1
        features[features < threshold] = 0
        features = features.astype(bool)
        
        return network.Network(self.nodes, features)

    @property
    def entropy(self):
        """The information entropy of the posterior distribution."""

        # entropy = -scores*log(scores)
        # but since scores are in log, 
        # entropy = -exp(scores)*scores
        lscores = rescale_logvalues(self.scores)
        return -N.sum(N.exp(lscores)*lscores)

    @property
    def consensus_matrix(self):
        norm_scores = normalize(N.exp(rescale_logvalues(self.scores)))
        return sum(n*s for n,s in zip(self.adjacency_matrices, norm_scores))

    #
    # Special interfaces
    #
    def __iter__(self):
        """Iterate over the networks in the posterior in sorted order."""
        for adjmat,score in zip(self.adjacency_matrices, self.scores):
            net = network.Network(self.nodes, adjmat)
            net.score = score
            yield net

    def __getitem__(self, key):
        """Retrieve a specific network (and score) from the posterior."""
        if isinstance(key, slice):
            return self.__getslice__(self, key.start, key.stop)
        
        net = network.Network(self.nodes, self.adjacency_matrices[key])
        net.score = self.scores[key]
        return net

    def __getslice__(self, i, j):
        """Retrieve a subset (as a new posterior object) of the networks."""
        return Posterior(
                    self.nodes, 
                    self.adjacency_matrices[i:j], self.scores[i:j]
                )

    def __len__(self):
        """Return the number of networks in this posterior distribution."""
        return len(self.scores)


#
# Factory functions
#
def from_sorted_scored_networks(nodes, networks):
    """Create a posterior object from a list of sorted, scored networks.
    
    networks should be sorted in descending order.
    """

    return Posterior(
        nodes,
        [n.edges.adjacency_matrix for n in networks],
        [n.score for n in networks]
    )