示例#1
0
    def testMatrixSimilarity(self):
        numExamples = 5 
        numFeatures = 3 
        V1 = numpy.random.rand(numExamples, numFeatures)
          
        matcher = GraphMatch(alpha=0.0)
        C = matcher.matrixSimilarity(V1, V1)
        Cdiag = numpy.diag(C)
        nptst.assert_array_almost_equal(Cdiag, numpy.ones(Cdiag.shape[0]))
        
        V1[:, 2] *= 10 
        C2 = matcher.matrixSimilarity(V1, V1)
        Cdiag = numpy.diag(C2)
        nptst.assert_array_almost_equal(Cdiag, numpy.ones(Cdiag.shape[0]))      
        nptst.assert_array_almost_equal(C, C2)
        
        #print("Running match")
        J = numpy.ones((numExamples, numFeatures))
        Z = numpy.zeros((numExamples, numFeatures))

        C2 = matcher.matrixSimilarity(J, Z)
        #This should be 1 ideally 
        
        
        nptst.assert_array_almost_equal(C2, numpy.ones(C2.shape))  
        
        C2 = matcher.matrixSimilarity(J, J)
        nptst.assert_array_almost_equal(C2, numpy.ones(C2.shape))  
 def profileSimulateGraphMatch(self): 
     N, matchAlpha, breakDist, purtScale = HIVModelUtils.toyABCParams()
     startDate, endDate, recordStep, M, targetGraph = HIVModelUtils.toySimulationParams()
     theta, stdTheta = HIVModelUtils.toyTheta()
 
     featureInds= numpy.ones(targetGraph.vlist.getNumFeatures(), numpy.bool)
     featureInds[HIVVertices.dobIndex] = False 
     featureInds[HIVVertices.infectionTimeIndex] = False 
     featureInds[HIVVertices.hiddenDegreeIndex] = False 
     featureInds[HIVVertices.stateIndex] = False 
     featureInds = numpy.arange(featureInds.shape[0])[featureInds]        
     
     #QCV is fastest and most accurate 
     #PATH is slowests but quite accurate 
     #RANK is very fast by less accurate than PATH 
     #U is fastest but least accurate         
     
     matcher = GraphMatch("QCV", alpha=matchAlpha, featureInds=featureInds, useWeightM=False)
     matcher.lambdaM = 50 
     matcher.init = "rand"
     graphMetrics = HIVGraphMetrics2(targetGraph, breakDist, matcher, float(endDate))        
     
     def run(): 
         times, infectedIndices, removedIndices, graph = HIVModelUtils.simulate(theta, startDate, endDate, recordStep, M, graphMetrics)
         print("Mean distance " + str(graphMetrics.meanDistance()))
     
     ProfileUtils.profile('run()', globals(), locals())
示例#3
0
    def testVertexSimilarities(self):
        matcher = GraphMatch(alpha=0.0)
        C = matcher.vertexSimilarities(self.graph1, self.graph1)

        Cdiag = numpy.diag(C)
        nptst.assert_array_almost_equal(Cdiag, numpy.ones(Cdiag.shape[0]))

        #Now compute trace(C)/||C||
        #print(numpy.trace(C)/numpy.linalg.norm(C))

        #Test use of feature inds
        matcher = GraphMatch(alpha=0.0, featureInds=numpy.array([0]))

        C = matcher.vertexSimilarities(self.graph1, self.graph2)

        #Now, let's vary the non-used feature
        self.graph1.vlist[:, 1] = 0
        C2 = matcher.vertexSimilarities(self.graph1, self.graph2)
        nptst.assert_array_equal(C, C2)

        self.graph2.vlist[:, 1] = 0
        C2 = matcher.vertexSimilarities(self.graph1, self.graph2)
        nptst.assert_array_equal(C, C2)

        #Vary used feature
        self.graph1.vlist[:, 0] = 0
        C2 = matcher.vertexSimilarities(self.graph1, self.graph2)
        self.assertTrue((C != C2).any())
示例#4
0
 def __init__(self, realGraph, maxSize=100, matcher=None, startTime=None, alpha=0.5):
     """
     A class to model metrics about and between HIVGraphs such as summary 
     statistics and distances. In this case we perform graph matching 
     using the QCV algorithm and other graph matching methods. 
     
     :param realGraph: The target epidemic graph 
     
     :param epsilon: The max mean objective before we break the simulation
     
     :param matcher: The graph matcher object to compute graph objective. 
     
     :param startTime: A start time of the simulation 
     
     :param alpha: This is the weight factor for the average. Weights decay faster with a larger alpha. 
     """
     
     self.objectives = [] 
     self.graphObjs = []
     self.graphSizes = []
     self.labelObjs = []
     self.times = []
     
     self.realGraph = realGraph
     self.maxSize = maxSize
     self.startTime = startTime 
     self.computationalTimes = []
     self.alpha = alpha         
     
     if matcher == None: 
         self.matcher = GraphMatch("QCV")
     else: 
         self.matcher = matcher 
示例#5
0
 def testVertexSimilarities(self): 
     matcher = GraphMatch(alpha=0.0)
     C = matcher.vertexSimilarities(self.graph1, self.graph1) 
     
     Cdiag = numpy.diag(C)
     nptst.assert_array_almost_equal(Cdiag, numpy.ones(Cdiag.shape[0]))
     
     #Now compute trace(C)/||C||
     #print(numpy.trace(C)/numpy.linalg.norm(C))
     
     #Test use of feature inds 
     matcher = GraphMatch(alpha=0.0, featureInds=numpy.array([0]))
     
     C = matcher.vertexSimilarities(self.graph1, self.graph2) 
     
     #Now, let's vary the non-used feature 
     self.graph1.vlist[:, 1] = 0
     C2 = matcher.vertexSimilarities(self.graph1, self.graph2) 
     nptst.assert_array_equal(C, C2)
     
     self.graph2.vlist[:, 1] = 0
     C2 = matcher.vertexSimilarities(self.graph1, self.graph2) 
     nptst.assert_array_equal(C, C2)
     
     #Vary used feature 
     self.graph1.vlist[:, 0] = 0
     C2 = matcher.vertexSimilarities(self.graph1, self.graph2) 
     self.assertTrue((C != C2).any())
示例#6
0
    def testMatrixSimilarity(self):
        numExamples = 5
        numFeatures = 3
        V1 = numpy.random.rand(numExamples, numFeatures)

        matcher = GraphMatch(alpha=0.0)
        C = matcher.matrixSimilarity(V1, V1)
        Cdiag = numpy.diag(C)
        nptst.assert_array_almost_equal(Cdiag, numpy.ones(Cdiag.shape[0]))

        V1[:, 2] *= 10
        C2 = matcher.matrixSimilarity(V1, V1)
        Cdiag = numpy.diag(C2)
        nptst.assert_array_almost_equal(Cdiag, numpy.ones(Cdiag.shape[0]))
        nptst.assert_array_almost_equal(C, C2)

        #print("Running match")
        J = numpy.ones((numExamples, numFeatures))
        Z = numpy.zeros((numExamples, numFeatures))

        C2 = matcher.matrixSimilarity(J, Z)
        #This should be 1 ideally

        nptst.assert_array_almost_equal(C2, numpy.ones(C2.shape))

        C2 = matcher.matrixSimilarity(J, J)
        nptst.assert_array_almost_equal(C2, numpy.ones(C2.shape))
示例#7
0
    def testMatch(self): 
        matcher = GraphMatch(algorithm="U", alpha=0.3)
        permutation, distance, time = matcher.match(self.graph1, self.graph2)

        #Checked output file - seems correct 
        
        distance2 = GraphMatch(alpha=0.0).distance(self.graph1, self.graph2, permutation)
        self.assertAlmostEquals(distance[0], distance2)
        
        #Now test case in which alpha is different 
        matcher = GraphMatch(algorithm="U", alpha=0.5)
        permutation, distance, time = matcher.match(self.graph1, self.graph2)
        distance2 = GraphMatch(alpha=0.0).distance(self.graph1, self.graph2, permutation)
        self.assertAlmostEquals(distance[0], distance2)
        
        #Test normalised distance 
        alpha = 0.0
        permutation, distance, time = GraphMatch(algorithm="U", alpha=alpha).match(self.graph1, self.graph2)
        distance2 = GraphMatch(alpha=alpha).distance(self.graph1, self.graph2, permutation, True)
        self.assertAlmostEquals(distance[1], distance2)
        
        alpha = 1.0
        permutation, distance, time = GraphMatch(algorithm="U", alpha=alpha).match(self.graph1, self.graph2)
        distance2 = GraphMatch(alpha=alpha).distance(self.graph1, self.graph2, permutation, True)
        self.assertAlmostEquals(distance[1], distance2, 5)
        
        #Test empty graph
        alpha = 0.0
        graph1 = SparseGraph(VertexList(0, 0))
        graph2 = SparseGraph(VertexList(0, 0))
        
        permutation, distance, time = GraphMatch(algorithm="U", alpha=alpha).match(graph1, graph2)
        
        nptst.assert_array_equal(permutation, numpy.array([], numpy.int))
        self.assertEquals(distance, [0, 0, 0])
        
        #Test where 1 graph is empty 
        permutation, distance, time = GraphMatch(algorithm="U", alpha=alpha).match(graph1, self.graph1)
        self.assertEquals(numpy.linalg.norm(self.graph1.getWeightMatrix())**2, distance[0])
        self.assertEquals(distance[1], 1)
        self.assertEquals(distance[2], 1)
        
        permutation, distance, time = GraphMatch(algorithm="U", alpha=alpha).match(self.graph1, graph1)
        self.assertEquals(numpy.linalg.norm(self.graph1.getWeightMatrix())**2, distance[0])
        self.assertEquals(distance[1], 1)
        self.assertEquals(distance[2], 1)
        
        alpha = 1.0
        permutation, distance, time = GraphMatch(algorithm="U", alpha=alpha).match(graph1, self.graph1)
        self.assertEquals(numpy.linalg.norm(self.graph1.getWeightMatrix())**2, distance[0])
        
        V2 = self.graph1.vlist.getVertices()
        V1 = numpy.zeros(V2.shape)
        C = GraphMatch(algorithm="U", alpha=alpha).matrixSimilarity(V1, V2)
        dist = numpy.trace(C)/numpy.linalg.norm(C)
        
        self.assertAlmostEquals(distance[1], -dist, 4)
        self.assertAlmostEquals(distance[2], -dist, 4)
        
        permutation, distance, time = GraphMatch(algorithm="U", alpha=alpha).match(self.graph1, graph1)
        self.assertEquals(numpy.linalg.norm(self.graph1.getWeightMatrix())**2, distance[0])
        self.assertAlmostEquals(distance[1], -dist, 4)
        self.assertAlmostEquals(distance[2], -dist, 4)
        
        #Test one graph which is a subgraph of another 
        p = 0.2 
        k = 10 
        numVertices = 20
        generator = SmallWorldGenerator(p, k)
        graph = SparseGraph(VertexList(numVertices, 2))
        graph = generator.generate(graph)
        
        subgraphInds = numpy.random.permutation(numVertices)[0:10]
        subgraph = graph.subgraph(subgraphInds)
        
        matcher = GraphMatch(algorithm="U", alpha=0.0)
        permutation, distance, time = matcher.match(graph, subgraph)
        distance = matcher.distance(graph, subgraph, permutation, True, True)
        
        self.assertTrue(distance < 1)
示例#8
0
    def testDistance(self): 
        permutation = numpy.arange(self.numVertices)
        dist =  GraphMatch(alpha=0.0).distance(self.graph1, self.graph1, permutation)
        self.assertEquals(dist, 0.0)
        
        dist =  GraphMatch(alpha=0.0).distance(self.graph1, self.graph2, permutation)
        self.assertAlmostEquals(dist, 50.0)
        
        permutation = numpy.arange(self.numVertices)
        permutation[8] = 9
        permutation[9] = 8
        dist =  GraphMatch(alpha=0.0).distance(self.graph1, self.graph2, permutation)
        self.assertAlmostEquals(dist, 54.0)
        
        #Try graphs of unequal size 
        graph3 = self.graph1.subgraph(range(8))
        permutation = numpy.arange(self.numVertices)
        dist1 =  GraphMatch(alpha=0.0).distance(self.graph1, graph3, permutation)
        dist1a =  GraphMatch(alpha=0.0).distance(graph3, self.graph1, permutation)
        self.assertEquals(dist1, dist1a)

        graph3 = self.graph1.subgraph(range(5))
        dist2 =  GraphMatch(alpha=0.0).distance(self.graph1, graph3, permutation)
        dist2a =  GraphMatch(alpha=0.0).distance(graph3, self.graph1, permutation)
        self.assertEquals(dist2, dist2a)
        self.assertTrue(dist1 < dist2)
        
        #Test case where alpha!=0 
        alpha = 1.0
        permutation = numpy.arange(self.numVertices)
        distance = GraphMatch(alpha=alpha).distance(self.graph1, self.graph2, permutation, False)
        C = GraphMatch(alpha=alpha).vertexSimilarities(self.graph1, self.graph2)
        distance2 = -numpy.trace(C)
        self.assertEquals(distance, distance2)
        
        #Check case where we want non negativve distance even when alpha!=0 
        distance = GraphMatch(alpha=alpha).distance(self.graph1, self.graph2, permutation, True, True)
        self.assertTrue(distance >= 0)
        
        permutation = numpy.arange(self.numVertices)
        distance = GraphMatch(alpha=alpha).distance(self.graph1, self.graph1, permutation, True, True)
        self.assertEquals(distance, 0)
        
        #Check case where both graphs are empty 
        graph1 = SparseGraph(VertexList(0, 0))
        graph2 = SparseGraph(VertexList(0, 0))
        
        permutation = numpy.array([], numpy.int)
        distance = GraphMatch(alpha=alpha).distance(graph1, graph1, permutation, True, True)
        self.assertEquals(distance, 0)
        
        #Now, just one graph is empty 
        #Distance is always 1 due to normalisations 
        alpha = 0.0
        permutation = numpy.arange(10, dtype=numpy.int)
        distance = GraphMatch(alpha=alpha).distance(self.graph1, graph1, permutation, True, True)
        self.assertEquals(distance, 1.0)
        
        permutation = numpy.arange(10, dtype=numpy.int)
        distance = GraphMatch(alpha=alpha).distance(self.graph2, graph1, permutation, True, True)
        self.assertEquals(distance, 1.0)
        
        #distance = GraphMatch(alpha=alpha).distance(self.graph1, graph1, permutation, False, False)
        #self.assertEquals(distance, numpy.linalg.norm(self.graph1.getWeightMatrix())**2)
        
        alpha = 0.9 
        matcher = GraphMatch("U", alpha=alpha)
        permutation, distanceVector, time = matcher.match(self.graph2, graph1)
        distance = matcher.distance(self.graph2, graph1, permutation, True, True)
        self.assertEquals(distance, 1.0)        
        
        alpha = 1.0
        permutation = numpy.arange(10, dtype=numpy.int)
        distance = GraphMatch(alpha=alpha).distance(self.graph1, graph1, permutation, True, True)
        self.assertEquals(distance, 1.0)
        
        permutation = numpy.arange(10, dtype=numpy.int)
        distance = GraphMatch(alpha=alpha).distance(self.graph2, graph1, permutation, True, True)
        self.assertEquals(distance, 1.0)
        
        alpha = 0.5
        permutation = numpy.arange(10, dtype=numpy.int)
        distance = GraphMatch(alpha=alpha).distance(self.graph2, graph1, permutation, True, True)
        self.assertEquals(distance, 1.0)
           
        #Test on unequal graphs and compare against distance from graphm 
        alpha = 0.5 
        matcher = GraphMatch(alpha=alpha)
        permutation, distanceVector, time = matcher.match(self.graph1, self.graph2)
        distance = matcher.distance(self.graph1, self.graph2, permutation, True, False)
        
        self.assertAlmostEquals(distanceVector[1], distance, 3)
    def testAddGraph(self): 
        maxSize = 100
        metrics = HIVGraphMetrics2(self.graph, maxSize)
        
        metrics.addGraph(self.graph)

        self.assertAlmostEquals(metrics.objectives[0], -0.834, 3)
        self.assertAlmostEquals(metrics.meanObjective(), -0.834, 3)
        
        #Start a new graph 
        #Compute distances directly 
        matcher = GraphMatch("QCV")
        graph =  HIVGraph(self.graph.size)
        dists = [] 
        metrics = HIVGraphMetrics2(self.graph, maxSize)
        
        graph.vlist.setInfected(1, 0.0)
        graph.vlist.setDetected(1, 0.1, 0)
        graph.endEventTime = 1
        metrics.addGraph(graph)
        
        
        t = graph.endTime()
        subgraph1 = graph.subgraph(graph.removedIndsAt(t))
        subgraph2 = self.graph.subgraph(graph.removedIndsAt(t)) 
        permutation, distance, time = matcher.match(subgraph1, subgraph2)
        lastObj, lastGraphObj, lastLabelObj = matcher.distance(subgraph1, subgraph2, permutation, True, False, True)
        self.assertEquals(metrics.objectives[-1], lastObj)

        self.assertFalse(metrics.shouldBreak())
        
        graph.vlist.setInfected(2, 2.0)
        graph.vlist.setDetected(2, 2.0, 0)
        metrics.addGraph(graph)
        
        t = graph.endTime()
        subgraph1 = graph.subgraph(graph.removedIndsAt(t))
        subgraph2 = self.graph.subgraph(graph.removedIndsAt(t)) 
        permutation, distance, time = matcher.match(subgraph1, subgraph2)
        lastObj, lastGraphObj, lastLabelObj = matcher.distance(subgraph1, subgraph2, permutation, True, False, True)
        self.assertEquals(metrics.objectives[-1], lastObj)   
        self.assertFalse(metrics.shouldBreak())
        
        graph.vlist.setInfected(7, 3.0)
        graph.vlist.setDetected(7, 3.0, 0)
        metrics.addGraph(graph)
        
        t = graph.endTime()
        subgraph1 = graph.subgraph(graph.removedIndsAt(t))
        subgraph2 = self.graph.subgraph(graph.removedIndsAt(t)) 
        permutation, distance, time = matcher.match(subgraph1, subgraph2)
        lastObj, lastGraphObj, lastLabelObj = matcher.distance(subgraph1, subgraph2, permutation, True, False, True)
        self.assertEquals(metrics.objectives[-1], lastObj) 
        self.assertFalse(metrics.shouldBreak())
        
        #Test case where one graph has zero size 
        graph1 = HIVGraph(10)
        graph2 = HIVGraph(10)
        
        graph1.vlist[:, HIVVertices.stateIndex] = HIVVertices.removed
        metrics = HIVGraphMetrics2(graph2, maxSize)
        metrics.addGraph(graph1)
        
        #Problem is that distance is 1 when one graph is zero
        self.assertEquals(len(metrics.objectives), 0) 
示例#10
0
class HIVGraphMetrics2(object): 
    def __init__(self, realGraph, maxSize=100, matcher=None, startTime=None, alpha=0.5):
        """
        A class to model metrics about and between HIVGraphs such as summary 
        statistics and distances. In this case we perform graph matching 
        using the QCV algorithm and other graph matching methods. 
        
        :param realGraph: The target epidemic graph 
        
        :param epsilon: The max mean objective before we break the simulation
        
        :param matcher: The graph matcher object to compute graph objective. 
        
        :param startTime: A start time of the simulation 
        
        :param alpha: This is the weight factor for the average. Weights decay faster with a larger alpha. 
        """
        
        self.objectives = [] 
        self.graphObjs = []
        self.graphSizes = []
        self.labelObjs = []
        self.times = []
        
        self.realGraph = realGraph
        self.maxSize = maxSize
        self.startTime = startTime 
        self.computationalTimes = []
        self.alpha = alpha         
        
        if matcher == None: 
            self.matcher = GraphMatch("QCV")
        else: 
            self.matcher = matcher 
        
    def addGraph(self, simulatedGraph): 
        """
        Compute the objective between this graph and the realGraph at the time 
        of the last event of this one. 
        """
        t = simulatedGraph.endTime()
        #Only select vertices added after startTime and before t 
        inds = numpy.setdiff1d(simulatedGraph.removedIndsAt(t), simulatedGraph.removedIndsAt(self.startTime))
        subgraph = simulatedGraph.subgraph(inds)  
        
        inds = numpy.setdiff1d(self.realGraph.removedIndsAt(t), self.realGraph.removedIndsAt(self.startTime))
        subTargetGraph = self.realGraph.subgraph(inds)  
        
        #logging.debug("Simulated size " + str(subgraph.size) + " and real size " + str(subTargetGraph.size))
        self.graphSizes.append(subgraph.size)
            
        #Only add objective if the real graph has nonzero size
        if subTargetGraph.size != 0 and subgraph.size <= self.maxSize: 
            permutation, distance, time = self.matcher.match(subgraph, subTargetGraph)
            lastObj, lastGraphObj, lastLabelObj = self.matcher.distance(subgraph, subTargetGraph, permutation, True, False, True)
     
            self.computationalTimes.append(time)
            self.objectives.append(lastObj)
            self.graphObjs.append(lastGraphObj)
            self.labelObjs.append(lastLabelObj)
            self.times.append(t) 
        else: 
            logging.debug("Not adding objective at time " + str(t) + " with simulated size " + str(subgraph.size) + " and real size " + str(subTargetGraph.size))
            
    def meanObjective(self, objectives=None):
        """
        This is the moving average objective of the graph matches so far. 
        """
        if objectives == None: 
            objectives = numpy.array(self.objectives)       
        
        if objectives.shape[0]!=0: 
            weights = self.alpha * (1 - self.alpha)**(numpy.arange(objectives.shape[0], 0, -1)-1)
            logging.debug("weights="+str(weights))
            return numpy.average(objectives, weights=weights)
        else: 
            return float("inf")
            
    def meanGraphObjective(self):
        """
        This is the mean graph objective of the graph matches so far. 
        """
        graphObjs = numpy.array(self.graphObjs)
        if graphObjs.shape[0]!=0: 
            return graphObjs.mean()
        else: 
            return float("inf")
            
    def meanLabelObjective(self):
        """
        This is the mean label objective of the graph matches so far. 
        """
        labelObjs = numpy.array(self.labelObjs)
        if labelObjs.shape[0]!=0: 
            return labelObjs.mean()
        else: 
            return float("inf")
        
    def shouldBreak(self): 
        """
        We break when the graph size exceeds a threshold 
        """
        if self.graphSizes[-1] > self.maxSize:
            logging.debug("Breaking as size has become too large: " + str(self.graphSizes[-1]) + " > " + str(self.maxSize))
            
        return self.graphSizes[-1] > self.maxSize 
        
示例#11
0
    def testMatch(self):
        matcher = GraphMatch(algorithm="U", alpha=0.3)
        permutation, distance, time = matcher.match(self.graph1, self.graph2)

        #Checked output file - seems correct

        distance2 = GraphMatch(alpha=0.0).distance(self.graph1, self.graph2,
                                                   permutation)
        self.assertAlmostEquals(distance[0], distance2)

        #Now test case in which alpha is different
        matcher = GraphMatch(algorithm="U", alpha=0.5)
        permutation, distance, time = matcher.match(self.graph1, self.graph2)
        distance2 = GraphMatch(alpha=0.0).distance(self.graph1, self.graph2,
                                                   permutation)
        self.assertAlmostEquals(distance[0], distance2)

        #Test normalised distance
        alpha = 0.0
        permutation, distance, time = GraphMatch(algorithm="U",
                                                 alpha=alpha).match(
                                                     self.graph1, self.graph2)
        distance2 = GraphMatch(alpha=alpha).distance(self.graph1, self.graph2,
                                                     permutation, True)
        self.assertAlmostEquals(distance[1], distance2)

        alpha = 1.0
        permutation, distance, time = GraphMatch(algorithm="U",
                                                 alpha=alpha).match(
                                                     self.graph1, self.graph2)
        distance2 = GraphMatch(alpha=alpha).distance(self.graph1, self.graph2,
                                                     permutation, True)
        self.assertAlmostEquals(distance[1], distance2, 5)

        #Test empty graph
        alpha = 0.0
        graph1 = SparseGraph(VertexList(0, 0))
        graph2 = SparseGraph(VertexList(0, 0))

        permutation, distance, time = GraphMatch(algorithm="U",
                                                 alpha=alpha).match(
                                                     graph1, graph2)

        nptst.assert_array_equal(permutation, numpy.array([], numpy.int))
        self.assertEquals(distance, [0, 0, 0])

        #Test where 1 graph is empty
        permutation, distance, time = GraphMatch(algorithm="U",
                                                 alpha=alpha).match(
                                                     graph1, self.graph1)
        self.assertEquals(
            numpy.linalg.norm(self.graph1.getWeightMatrix())**2, distance[0])
        self.assertEquals(distance[1], 1)
        self.assertEquals(distance[2], 1)

        permutation, distance, time = GraphMatch(algorithm="U",
                                                 alpha=alpha).match(
                                                     self.graph1, graph1)
        self.assertEquals(
            numpy.linalg.norm(self.graph1.getWeightMatrix())**2, distance[0])
        self.assertEquals(distance[1], 1)
        self.assertEquals(distance[2], 1)

        alpha = 1.0
        permutation, distance, time = GraphMatch(algorithm="U",
                                                 alpha=alpha).match(
                                                     graph1, self.graph1)
        self.assertEquals(
            numpy.linalg.norm(self.graph1.getWeightMatrix())**2, distance[0])

        V2 = self.graph1.vlist.getVertices()
        V1 = numpy.zeros(V2.shape)
        C = GraphMatch(algorithm="U", alpha=alpha).matrixSimilarity(V1, V2)
        dist = numpy.trace(C) / numpy.linalg.norm(C)

        self.assertAlmostEquals(distance[1], -dist, 4)
        self.assertAlmostEquals(distance[2], -dist, 4)

        permutation, distance, time = GraphMatch(algorithm="U",
                                                 alpha=alpha).match(
                                                     self.graph1, graph1)
        self.assertEquals(
            numpy.linalg.norm(self.graph1.getWeightMatrix())**2, distance[0])
        self.assertAlmostEquals(distance[1], -dist, 4)
        self.assertAlmostEquals(distance[2], -dist, 4)

        #Test one graph which is a subgraph of another
        p = 0.2
        k = 10
        numVertices = 20
        generator = SmallWorldGenerator(p, k)
        graph = SparseGraph(VertexList(numVertices, 2))
        graph = generator.generate(graph)

        subgraphInds = numpy.random.permutation(numVertices)[0:10]
        subgraph = graph.subgraph(subgraphInds)

        matcher = GraphMatch(algorithm="U", alpha=0.0)
        permutation, distance, time = matcher.match(graph, subgraph)
        distance = matcher.distance(graph, subgraph, permutation, True, True)

        self.assertTrue(distance < 1)
示例#12
0
    def testDistance2(self):
        permutation = numpy.arange(self.numVertices)
        dist = GraphMatch(alpha=0.0).distance2(self.graph1, self.graph1,
                                               permutation)
        self.assertEquals(dist, 0.0)

        dist = GraphMatch(alpha=0.0).distance2(self.graph1, self.graph2,
                                               permutation)
        dist2 = GraphMatch(alpha=0.0).distance(self.graph1, self.graph2,
                                               permutation, True)
        self.assertAlmostEquals(dist, dist2)

        permutation = numpy.arange(self.numVertices)
        permutation[8] = 9
        permutation[9] = 8
        dist = GraphMatch(alpha=0.0).distance2(self.graph1, self.graph2,
                                               permutation)
        dist2 = GraphMatch(alpha=0.0).distance(self.graph1, self.graph2,
                                               permutation, True)
        self.assertAlmostEquals(dist, dist2)

        #Try graphs of unequal size
        graph3 = self.graph1.subgraph(range(8))
        permutation = numpy.arange(self.numVertices)
        dist1 = GraphMatch(alpha=0.0).distance2(self.graph1, graph3,
                                                permutation)
        dist1a = GraphMatch(alpha=0.0).distance2(graph3, self.graph1,
                                                 permutation)
        self.assertEquals(dist1, dist1a)

        graph3 = self.graph1.subgraph(range(5))
        dist2 = GraphMatch(alpha=0.0).distance2(self.graph1, graph3,
                                                permutation)
        dist2a = GraphMatch(alpha=0.0).distance2(graph3, self.graph1,
                                                 permutation)
        self.assertEquals(dist2, dist2a)
        self.assertTrue(dist1 < dist2)

        #Test case where alpha!=0
        alpha = 1.0
        permutation = numpy.arange(self.numVertices)
        distance = GraphMatch(alpha=alpha).distance2(self.graph1, self.graph1,
                                                     permutation)
        self.assertEquals(distance, 0.0)

        #Check distances are between 0 and 1
        for i in range(100):
            alpha = numpy.random.rand()
            permutation = numpy.random.permutation(self.numVertices)

            distance = GraphMatch(alpha=alpha).distance2(
                self.graph1, self.graph1, permutation)
            self.assertTrue(0 <= distance <= 1)
示例#13
0
    def testDistance(self):
        permutation = numpy.arange(self.numVertices)
        dist = GraphMatch(alpha=0.0).distance(self.graph1, self.graph1,
                                              permutation)
        self.assertEquals(dist, 0.0)

        dist = GraphMatch(alpha=0.0).distance(self.graph1, self.graph2,
                                              permutation)
        self.assertAlmostEquals(dist, 50.0)

        permutation = numpy.arange(self.numVertices)
        permutation[8] = 9
        permutation[9] = 8
        dist = GraphMatch(alpha=0.0).distance(self.graph1, self.graph2,
                                              permutation)
        self.assertAlmostEquals(dist, 54.0)

        #Try graphs of unequal size
        graph3 = self.graph1.subgraph(range(8))
        permutation = numpy.arange(self.numVertices)
        dist1 = GraphMatch(alpha=0.0).distance(self.graph1, graph3,
                                               permutation)
        dist1a = GraphMatch(alpha=0.0).distance(graph3, self.graph1,
                                                permutation)
        self.assertEquals(dist1, dist1a)

        graph3 = self.graph1.subgraph(range(5))
        dist2 = GraphMatch(alpha=0.0).distance(self.graph1, graph3,
                                               permutation)
        dist2a = GraphMatch(alpha=0.0).distance(graph3, self.graph1,
                                                permutation)
        self.assertEquals(dist2, dist2a)
        self.assertTrue(dist1 < dist2)

        #Test case where alpha!=0
        alpha = 1.0
        permutation = numpy.arange(self.numVertices)
        distance = GraphMatch(alpha=alpha).distance(self.graph1, self.graph2,
                                                    permutation, False)
        C = GraphMatch(alpha=alpha).vertexSimilarities(self.graph1,
                                                       self.graph2)
        distance2 = -numpy.trace(C)
        self.assertEquals(distance, distance2)

        #Check case where we want non negativve distance even when alpha!=0
        distance = GraphMatch(alpha=alpha).distance(self.graph1, self.graph2,
                                                    permutation, True, True)
        self.assertTrue(distance >= 0)

        permutation = numpy.arange(self.numVertices)
        distance = GraphMatch(alpha=alpha).distance(self.graph1, self.graph1,
                                                    permutation, True, True)
        self.assertEquals(distance, 0)

        #Check case where both graphs are empty
        graph1 = SparseGraph(VertexList(0, 0))
        graph2 = SparseGraph(VertexList(0, 0))

        permutation = numpy.array([], numpy.int)
        distance = GraphMatch(alpha=alpha).distance(graph1, graph1,
                                                    permutation, True, True)
        self.assertEquals(distance, 0)

        #Now, just one graph is empty
        #Distance is always 1 due to normalisations
        alpha = 0.0
        permutation = numpy.arange(10, dtype=numpy.int)
        distance = GraphMatch(alpha=alpha).distance(self.graph1, graph1,
                                                    permutation, True, True)
        self.assertEquals(distance, 1.0)

        permutation = numpy.arange(10, dtype=numpy.int)
        distance = GraphMatch(alpha=alpha).distance(self.graph2, graph1,
                                                    permutation, True, True)
        self.assertEquals(distance, 1.0)

        #distance = GraphMatch(alpha=alpha).distance(self.graph1, graph1, permutation, False, False)
        #self.assertEquals(distance, numpy.linalg.norm(self.graph1.getWeightMatrix())**2)

        alpha = 0.9
        matcher = GraphMatch("U", alpha=alpha)
        permutation, distanceVector, time = matcher.match(self.graph2, graph1)
        distance = matcher.distance(self.graph2, graph1, permutation, True,
                                    True)
        self.assertEquals(distance, 1.0)

        alpha = 1.0
        permutation = numpy.arange(10, dtype=numpy.int)
        distance = GraphMatch(alpha=alpha).distance(self.graph1, graph1,
                                                    permutation, True, True)
        self.assertEquals(distance, 1.0)

        permutation = numpy.arange(10, dtype=numpy.int)
        distance = GraphMatch(alpha=alpha).distance(self.graph2, graph1,
                                                    permutation, True, True)
        self.assertEquals(distance, 1.0)

        alpha = 0.5
        permutation = numpy.arange(10, dtype=numpy.int)
        distance = GraphMatch(alpha=alpha).distance(self.graph2, graph1,
                                                    permutation, True, True)
        self.assertEquals(distance, 1.0)

        #Test on unequal graphs and compare against distance from graphm
        alpha = 0.5
        matcher = GraphMatch(alpha=alpha)
        permutation, distanceVector, time = matcher.match(
            self.graph1, self.graph2)
        distance = matcher.distance(self.graph1, self.graph2, permutation,
                                    True, False)

        self.assertAlmostEquals(distanceVector[1], distance, 3)