def __init__(self,
                 vertex1Indices,
                 vertex2Indices,
                 converters,
                 undirected=True):
        """
        vertex1Indices is a list of fields for the first vertex, with the 1st index
        being the ID. 
        """
        if len(vertex1Indices) < 1 or len(vertex1Indices) < 1:
            raise ValueError("vertexIndices must have at least 1 index")
        if len(vertex1Indices) != len(vertex2Indices):
            raise ValueError("len(vertex1Indices)=" +
                             str(len(vertex1Indices)) +
                             "and len(vertex2Indices)=" + len(vertex2Indices))

        Parameter.checkList(vertex1Indices, Parameter.checkInt,
                            [0, float('inf')])
        Parameter.checkList(vertex2Indices, Parameter.checkInt,
                            [0, float('inf')])

        self.vertex1IdIndex = vertex1Indices[0]
        self.vertex2IdIndex = vertex2Indices[0]

        self.vertex1Indices = copy.copy(vertex1Indices)
        self.vertex2Indices = copy.copy(vertex2Indices)
        self.vertex1Indices.remove(self.vertex1IdIndex)
        self.vertex2Indices.remove(self.vertex2IdIndex)
        self.converters = converters
        self.undirected = undirected
        self.edgeWeight = 1
    def __init__(self, vertex1Indices, vertex2Indices, converters, undirected=True):
        """
        vertex1Indices is a list of fields for the first vertex, with the 1st index
        being the ID. 
        """
        if len(vertex1Indices) < 1 or len(vertex1Indices) < 1:
            raise ValueError("vertexIndices must have at least 1 index")
        if len(vertex1Indices) != len(vertex2Indices):
            raise ValueError("len(vertex1Indices)=" + str(len(vertex1Indices)) + "and len(vertex2Indices)=" + len(vertex2Indices))

        Parameter.checkList(vertex1Indices, Parameter.checkInt, [0, float('inf')])
        Parameter.checkList(vertex2Indices, Parameter.checkInt, [0, float('inf')])

        self.vertex1IdIndex = vertex1Indices[0]
        self.vertex2IdIndex = vertex2Indices[0]



        self.vertex1Indices = copy.copy(vertex1Indices)
        self.vertex2Indices = copy.copy(vertex2Indices)
        self.vertex1Indices.remove(self.vertex1IdIndex)
        self.vertex2Indices.remove(self.vertex2IdIndex)
        self.converters = converters
        self.undirected = undirected
        self.edgeWeight = 1
    def setVertices(self, vertices, indices=None):
        """
        Set the vertices to the given list of vertices. If indices = None then
        all vertices are replaced, and if not the given indices are used. 

        :param vertices: a list of vertices..
        :type vertices: :class:`list`

        :param indices: a list of indices of the same length as vertices or None for all indices in this object.
        :type indices: :class:`list`
        """
        if indices != None:
            Parameter.checkList(indices, Parameter.checkIndex,
                                [0, len(self.V)])
            if len(vertices) != len(indices):
                raise ValueError(
                    "Length of indices list must be same as that of vertices list"
                )
        if indices == None and len(vertices) != len(self.V):
            raise ValueError("Incorrect number of vertices " +
                             str(len(vertices)) + ", expecting " +
                             str(len(self.V)))

        if indices == None:
            for i in range(len(vertices)):
                self.V[i] = vertices[i]
        else:
            for i in range(len(indices)):
                self.V[indices[i]] = vertices[i]
    def sequenceVectorStats(self,
                            graph,
                            subgraphIndices,
                            treeStats=False,
                            eigenStats=True):
        """
        Pass in a list of graphs are returns a series of statistics. Each list
        element is a dict of vector statistics. 
        """
        Parameter.checkClass(graph, AbstractMatrixGraph)
        for inds in subgraphIndices:
            Parameter.checkList(inds, Parameter.checkInt,
                                [0, graph.getNumVertices()])
        Parameter.checkBoolean(treeStats)

        numGraphs = len(subgraphIndices)
        statsDictList = []

        for i in range(numGraphs):
            Util.printIteration(i, self.vectorPrintStep, numGraphs)
            subgraph = graph.subgraph(subgraphIndices[i])
            statsDictList.append(
                self.vectorStatistics(subgraph, treeStats, eigenStats))

        return statsDictList
    def sequenceScalarStats(self,
                            graph,
                            subgraphIndices,
                            slowStats=True,
                            treeStats=False):
        """
        Pass in a graph and list of subgraph indices and returns a series of statistics. Each row
        corresponds to the statistics on the subgraph. 
        """
        Parameter.checkClass(graph, AbstractMatrixGraph)
        for inds in subgraphIndices:
            Parameter.checkList(inds, Parameter.checkInt,
                                [0, graph.getNumVertices()])
        Parameter.checkBoolean(slowStats)
        Parameter.checkBoolean(treeStats)

        numGraphs = len(subgraphIndices)
        statsMatrix = numpy.zeros((numGraphs, self.numStats))

        for i in range(numGraphs):
            Util.printIteration(i, self.printStep, numGraphs)
            #logging.debug("Subgraph size: " + str(len(subgraphIndices[i])))
            subgraph = graph.subgraph(subgraphIndices[i])
            statsMatrix[i, :] = self.scalarStatistics(subgraph, slowStats,
                                                      treeStats)

        return statsMatrix
예제 #6
0
    def subList(self, indices):
        """
        Returns a subset of this object, indicated by the given indices.
        """
        Parameter.checkList(indices, Parameter.checkIndex, (0, self.getNumVertices()))
        vList = VertexList(len(indices), self.getNumFeatures())
        vList.setVertices(self.getVertices(indices))

        return vList 
    def subList(self, indices):
        """
        Returns a subset of this object, indicated by the given indices.
        """
        Parameter.checkList(indices, Parameter.checkIndex,
                            (0, self.getNumVertices()))
        vList = GeneralVertexList(len(indices))
        vList.setVertices(self.getVertices(indices))

        return vList
    def setOutDegSequence(self, outDegSequence):
        """
        Set the (out)degree sequence of this object.

        :param outDegSequence: a vector of degrees for each vertex in the graph.
        :type outDegSequence: :class:`numpy.ndarray`
        """
        Parameter.checkClass(outDegSequence, numpy.ndarray)
        if outDegSequence.ndim != 1:
            raise ValueError("Degree sequence must be one dimensional")
        Parameter.checkList(outDegSequence, Parameter.checkInt, [0, outDegSequence.shape[0]])

        self.outDegSequence = outDegSequence
예제 #9
0
    def setOutDegSequence(self, outDegSequence):
        '''
        Set the (out)degree sequence of this object.

        :param outDegSequence: a vector of degrees for each vertex in the graph.
        :type outDegSequence: :class:`numpy.ndarray`
        '''
        Parameter.checkClass(outDegSequence, numpy.ndarray)
        if outDegSequence.ndim != 1:
            raise ValueError("Degree sequence must be one dimensional")
        Parameter.checkList(outDegSequence, Parameter.checkInt,
                            [0, outDegSequence.shape[0]])

        self.outDegSequence = outDegSequence
    def setInDegSequence(self, inDegSequence):
        """
        Set the (in)degree sequence of this object.

        :param inDegSequence: a vector of degrees for each vertex in the graph.
        :type inDegSequence: :class:`numpy.ndarray`
        """
        Parameter.checkClass(inDegSequence, numpy.ndarray)
        if inDegSequence.ndim != 1:
            raise ValueError("Degree sequence must be one dimensional")
        if inDegSequence.shape[0] != self.outDegSequence.shape[0]:
            raise ValueError("In-degree sequence must be same length as out-degree sequence")
        Parameter.checkList(inDegSequence, Parameter.checkInt, [0, inDegSequence.shape[0]])

        self.inDegSequence = inDegSequence
예제 #11
0
    def getVertices(self, vertexIndices=None):
        """
        Returns a set of vertices specified by vertexIndices. If vertexIndices
        is None then all vertices are returned. 

        :param vertexIndices: a list of vertex indices.
        :type vertexIndices: :class:`list`

        :returns: A set of vertices corresponding to the input indices. 
        """
        if vertexIndices == None:
            return self.V
        else:
            Parameter.checkList(vertexIndices, Parameter.checkIndex, (0, self.V.shape[0]))
            return self.V[vertexIndices]
    def getVertices(self, vertexIndices=None):
        """
        Returns a set of vertices specified by vertexIndices. If vertexIndices
        is None then all vertices are returned. 

        :param vertexIndices: a list of vertex indices.
        :type vertexIndices: :class:`list`

        :returns: A set of vertices corresponding to the input indices. 
        """
        if vertexIndices == None:
            return self.V
        else:
            Parameter.checkList(vertexIndices, Parameter.checkIndex,
                                (0, self.V.shape[0]))
            return self.V[vertexIndices]
    def subgraph(self, vertexIndices):
        """
        Pass in a list or set of vertexIndices and returns the subgraph containing
        those vertices only, and edges between them.

        :param vertexIndices: the indices of the subgraph vertices.
        :type vertexIndices: :class:`list`
        """
        Parameter.checkList(vertexIndices, Parameter.checkIndex, (0, self.getNumVertices()))
        vertexIndices = numpy.unique(numpy.array(vertexIndices)).tolist()
        vList = self.vList.subList(vertexIndices)

        subGraph = CsArrayGraph(vList, self.undirected, self.W.dtype)
        subGraph.W = self.W[vertexIndices, :][:, vertexIndices]

        return subGraph
    def subgraph(self, vertexIndices):
        """
        Pass in a list or set of vertexIndices and returns the subgraph containing
        those vertices only, and edges between them.

        :param vertexIndices: the indices of the subgraph vertices.
        :type vertexIndices: :class:`list`
        """
        Parameter.checkList(vertexIndices, Parameter.checkIndex,
                            (0, self.getNumVertices()))
        vertexIndices = numpy.unique(numpy.array(vertexIndices)).tolist()
        vList = self.vList.subList(vertexIndices)

        subGraph = DenseGraph(vList, self.undirected, self.W.dtype)
        subGraph.W = self.W[vertexIndices, :][:, vertexIndices]

        return subGraph
예제 #15
0
    def expandIntArray(v):
        """
        Take a vector of integers and expand it into a vector with counts of the
        corresponding integers. For example, with v = [1, 3, 2, 4], the expanded
        vector is [0, 1, 1, 1, 2, 2, 3, 3, 3, 3]. 
        """
        Parameter.checkClass(v, numpy.ndarray)
        Parameter.checkList(v, Parameter.checkInt, [0, float('inf')])

        w = numpy.zeros(numpy.sum(v), numpy.int)
        currentInd = 0

        for i in range(v.shape[0]):
            w[currentInd:currentInd + v[i]] = i
            currentInd += v[i]

        return w
예제 #16
0
파일: Util.py 프로젝트: omosola/APGL
    def expandIntArray(v):
        """
        Take a vector of integers and expand it into a vector with counts of the
        corresponding integers. For example, with v = [1, 3, 2, 4], the expanded
        vector is [0, 1, 1, 1, 2, 2, 3, 3, 3, 3]. 
        """
        Parameter.checkClass(v, numpy.ndarray)
        Parameter.checkList(v, Parameter.checkInt, [0, float('inf')])
        
        w = numpy.zeros(numpy.sum(v), numpy.int)
        currentInd = 0
        
        for i in range(v.shape[0]):
            w[currentInd:currentInd+v[i]] = i
            currentInd += v[i]

        return w
예제 #17
0
    def harmonicGeodesicDistance(self, P=None, vertexInds=None):
        """
        Compute the "harmonic mean" geodesic distance for a graph. This is
        denoted by the inverse of 1/(1/2 n(n+1)) \sum_{i<=j} d_ij^-1 where d_ij is the
        shortest path length between i and j for an undirected graph. The distance from a
        node to itself is infinite. For a directed graph, the inverse distance is
        1/n^2 sum_{i,j} d_ij^-1.

        :param P: An optional nxn matrix whose ijth entry is the shortest path from i to j.
        :type P: :class:`ndarray`

        :param vertexInds: An optional list of vertices used to compute the mean geodesic distance. If this list is none, then all vertices are used.
        :type vertexInds: :class:`list`

        :returns:  The mean harmonic geodesic distance of this graph. 
        """
        if P!=None and (type(P) != numpy.ndarray or P.shape != (self.getNumVertices(), self.getNumVertices())):
            raise ValueError("P must be array of same size as weight matrix of graph")
        if vertexInds!=None:
            Parameter.checkList(vertexInds, Parameter.checkInt, [0, self.getNumVertices()])
        if self.getNumVertices() == 0 or (vertexInds != None and len(vertexInds)==0):
            return 0

        if P == None:
            P = self.floydWarshall(True)
        else:
            P = P.copy()

        if vertexInds != None:
            P = P[vertexInds, :][:, vertexInds]

        n = P.shape[0]
        P = 1/(P + numpy.diag(numpy.ones(n)*numpy.inf))

        if self.isUndirected(): 
            distanceSum = numpy.sum(numpy.triu(P))
            if distanceSum != 0:
                return (n*(n+1))/(2*distanceSum)
        else: 
            distanceSum = numpy.sum(P)
            if distanceSum != 0: 
                return n**2/distanceSum

        #Means that all vertices are disconnected 
        return float('inf')
예제 #18
0
    def setInDegSequence(self, inDegSequence):
        '''
        Set the (in)degree sequence of this object.

        :param inDegSequence: a vector of degrees for each vertex in the graph.
        :type inDegSequence: :class:`numpy.ndarray`
        '''
        Parameter.checkClass(inDegSequence, numpy.ndarray)
        if inDegSequence.ndim != 1:
            raise ValueError("Degree sequence must be one dimensional")
        if inDegSequence.shape[0] != self.outDegSequence.shape[0]:
            raise ValueError(
                "In-degree sequence must be same length as out-degree sequence"
            )
        Parameter.checkList(inDegSequence, Parameter.checkInt,
                            [0, inDegSequence.shape[0]])

        self.inDegSequence = inDegSequence
예제 #19
0
    def sequenceVectorStats(self, graph, subgraphIndices, treeStats=False, eigenStats=True):
        """
        Pass in a list of graphs are returns a series of statistics. Each list
        element is a dict of vector statistics. 
        """
        Parameter.checkClass(graph, AbstractMatrixGraph)
        for inds in subgraphIndices:
            Parameter.checkList(inds, Parameter.checkInt, [0, graph.getNumVertices()])
        Parameter.checkBoolean(treeStats)

        numGraphs = len(subgraphIndices)
        statsDictList = []

        for i in range(numGraphs):
            Util.printIteration(i, self.vectorPrintStep, numGraphs)
            subgraph = graph.subgraph(subgraphIndices[i])
            statsDictList.append(self.vectorStatistics(subgraph, treeStats, eigenStats))

        return statsDictList
    def getVertices(self, vertexIndices=None):
        """
        Returns a list of vertices specified by vertexIndices, or all vertices if
        vertexIndices == None. 

        :param vertexIndices: a list of vertex indices.
        :type vertexIndices: :class:`list`

        :returns: A set of vertices corresponding to the input indices. 
        """
        if vertexIndices != None:
            Parameter.checkList(vertexIndices, Parameter.checkIndex, (0, len(self.V)))
        else:
            vertexIndices = range(len(self.V))

        vertices = []
        for i in vertexIndices:
            vertices.append(self.V[i])

        return vertices
    def subgraph(self, vertexIndices):
        """
        Pass in a list or set of vertexIndices and returns the subgraph containing
        those vertices only, and edges between them.

        :param vertexIndices: the indices of the subgraph vertices.
        :type vertexIndices: :class:`list`

        :returns: A new PySparseGraph containing only vertices and edges from vertexIndices
        """
        Parameter.checkList(vertexIndices, Parameter.checkIndex, (0, self.getNumVertices()))
        vertexIndices = numpy.unique(numpy.array(vertexIndices))
        vList = self.vList.subList(vertexIndices.tolist())

        subGraph = PySparseGraph(vList, self.undirected)
        
        if len(vertexIndices) != 0:
            subGraph.W = self.W[vertexIndices, vertexIndices]

        return subGraph
예제 #22
0
    def __init__(self, initialGraph, k):
        """
        Initialise with a starting graph, and number of iterations k. The weights
        of the initial graph correspond to probabilities. 

        :param initialGraph: The intial graph to use.
        :type initialGraph: :class:`apgl.graph.AbstractMatrixGraph`

        :param k: The number of iterations.
        :type k: :class:`int`
        """
        Parameter.checkInt(k, 1, float('inf'))
        edgeVals = initialGraph.getEdgeValues(initialGraph.getAllEdges())
        Parameter.checkList(edgeVals, Parameter.checkFloat, [0.0, 1.0])

        W = initialGraph.getWeightMatrix()
        if (numpy.diag(W) == numpy.zeros(W.shape[0])).any():
            raise ValueError("Initial graph must have all self-edges")

        self.initialGraph = initialGraph
        self.k = k
    def getVertices(self, vertexIndices=None):
        """
        Returns a list of vertices specified by vertexIndices, or all vertices if
        vertexIndices == None. 

        :param vertexIndices: a list of vertex indices.
        :type vertexIndices: :class:`list`

        :returns: A set of vertices corresponding to the input indices. 
        """
        if vertexIndices != None:
            Parameter.checkList(vertexIndices, Parameter.checkIndex,
                                (0, len(self.V)))
        else:
            vertexIndices = range(len(self.V))

        vertices = []
        for i in vertexIndices:
            vertices.append(self.V[i])

        return vertices
    def __init__(self, initialGraph, k):
        """
        Initialise with a starting graph, and number of iterations k. The weights
        of the initial graph correspond to probabilities. 

        :param initialGraph: The intial graph to use.
        :type initialGraph: :class:`apgl.graph.AbstractMatrixGraph`

        :param k: The number of iterations.
        :type k: :class:`int`
        """
        Parameter.checkInt(k, 1, float('inf'))
        edgeVals = initialGraph.getEdgeValues(initialGraph.getAllEdges())
        Parameter.checkList(edgeVals, Parameter.checkFloat, [0.0, 1.0])

        W = initialGraph.getWeightMatrix()
        if (numpy.diag(W)==numpy.zeros(W.shape[0])).any():
            raise ValueError("Initial graph must have all self-edges")

        self.initialGraph = initialGraph
        self.k = k
    def subgraph(self, vertexIndices):
        """
        Pass in a list or set of vertexIndices and returns the subgraph containing
        those vertices only, and edges between them.

        :param vertexIndices: the indices of the subgraph vertices.
        :type vertexIndices: :class:`list`

        :returns: A new PySparseGraph containing only vertices and edges from vertexIndices
        """
        Parameter.checkList(vertexIndices, Parameter.checkIndex,
                            (0, self.getNumVertices()))
        vertexIndices = numpy.unique(numpy.array(vertexIndices))
        vList = self.vList.subList(vertexIndices.tolist())

        subGraph = PySparseGraph(vList, self.undirected)

        if len(vertexIndices) != 0:
            subGraph.W = self.W[vertexIndices, vertexIndices]

        return subGraph
예제 #26
0
    def categoricalToIndicator(self, X, indices):
        """
        Convert a set of categorical variables to indicator ones.
        """
        Parameter.checkList(indices, Parameter.checkIndex, (0, X.shape[1]))

        X2 = numpy.zeros((X.shape[0], 0)) 

        for i in range(X.shape[1]):
            if i in indices:
                categories = numpy.unique(X[:, i])
                Z = numpy.zeros((X.shape[0], categories.shape[0]))

                for j in range(categories.shape[0]):
                    Z[:, j] = X[:, i] == categories[j]

                X2 = numpy.c_[X2, Z]
            else:
                X2 = numpy.c_[X2, X[:, i]]

        return X2
예제 #27
0
    def sequenceScalarStats(self, graph, subgraphIndices, slowStats=True, treeStats=False):
        """
        Pass in a graph and list of subgraph indices and returns a series of statistics. Each row
        corresponds to the statistics on the subgraph. 
        """
        Parameter.checkClass(graph, AbstractMatrixGraph)
        for inds in subgraphIndices:
            Parameter.checkList(inds, Parameter.checkInt, [0, graph.getNumVertices()])
        Parameter.checkBoolean(slowStats)
        Parameter.checkBoolean(treeStats)

        numGraphs = len(subgraphIndices)
        statsMatrix = numpy.zeros((numGraphs, self.numStats))

        for i in range(numGraphs):
            Util.printIteration(i, self.printStep, numGraphs)
            logging.debug("Subgraph size: " + str(len(subgraphIndices[i])))
            subgraph = graph.subgraph(subgraphIndices[i])
            statsMatrix[i, :] = self.scalarStatistics(subgraph, slowStats, treeStats)

        return statsMatrix
    def testCheckList(self):
        lst = [1, 2, 3, 2, 2]
        Parameter.checkList(lst, Parameter.checkInt, [1, 3])

        lst = [1, 2, 3, 2, 4]
        self.assertRaises(ValueError, Parameter.checkList, lst, Parameter.checkInt, [1, 3])

        lst = [1, 2, 3, 2, 0]
        self.assertRaises(ValueError, Parameter.checkList, lst, Parameter.checkInt, [1, 3])

        lst = [1, 2, 3, 2, 1.2]
        self.assertRaises(ValueError, Parameter.checkList, lst, Parameter.checkInt, [1, 3])

        lst = "a"
        self.assertRaises(ValueError, Parameter.checkList, lst, Parameter.checkInt, [1, 3])

        lst = [0.1, 0.6, 1.4]
        Parameter.checkList(lst, Parameter.checkFloat, [0.1, 3.0])

        #Test use of array 
        lst = numpy.array([0.1, 0.6, 1.4])
        Parameter.checkList(lst, Parameter.checkFloat, [0.1, 3.0])

        lst = numpy.array([[0.1, 0.6, 1.4]])
        self.assertRaises(ValueError, Parameter.checkList, lst, Parameter.checkFloat, [0.1, 3.0])
예제 #29
0
    def geodesicDistance(self, P=None, vertexInds=None):
        """
        Compute the mean geodesic distance for a graph. This is denoted for an 
        undirected graph by 1/(1/2 n(n+1)) \sum_{i<=j} d_ij where d_ij is the
        shortest path length between i and j. Note that if i and j are not connected
        we assume a path length of 0. If the graph is directed then the geodesic
        distance is 1/(n^2) sum_{i, j} d_ij.

        :param P: An optional nxn matrix whose ijth entry is the shortest path from i to j.
        :type P: :class:`ndarray`

        :param vertexInds: An optional list of vertices used to compute the mean geodesic distance. If this list is none, then all vertices are used.
        :type vertexInds: :class:`list`

        :returns:  The mean geodesic distance of this graph.
        """
        if P!=None and (type(P) != numpy.ndarray or P.shape != (self.getNumVertices(), self.getNumVertices())):
            raise ValueError("P must be array of same size as weight matrix of graph")
        if vertexInds!=None:
            Parameter.checkList(vertexInds, Parameter.checkInt, [0, self.getNumVertices()])
        if self.getNumVertices() == 0 or (vertexInds != None and len(vertexInds)==0):
            return 0
        
        if P == None:
            P = self.floydWarshall(True)
        else:
            P = P.copy()

        if vertexInds != None:
            P = P[vertexInds, :][:, vertexInds]

        n = P.shape[0]
        P[P==numpy.inf] = 0
        P[numpy.diag_indices(P.shape[0])] = 0.0

        distanceSum = numpy.sum(P)
        if self.isUndirected():
            return distanceSum/(n*(n+1))
        else:
            return distanceSum/(n**2)
예제 #30
0
    def testCheckList(self):
        lst = [1, 2, 3, 2, 2]
        Parameter.checkList(lst, Parameter.checkInt, [1, 3])

        lst = [1, 2, 3, 2, 4]
        self.assertRaises(ValueError, Parameter.checkList, lst,
                          Parameter.checkInt, [1, 3])

        lst = [1, 2, 3, 2, 0]
        self.assertRaises(ValueError, Parameter.checkList, lst,
                          Parameter.checkInt, [1, 3])

        lst = [1, 2, 3, 2, 1.2]
        self.assertRaises(ValueError, Parameter.checkList, lst,
                          Parameter.checkInt, [1, 3])

        lst = "a"
        self.assertRaises(ValueError, Parameter.checkList, lst,
                          Parameter.checkInt, [1, 3])

        lst = [0.1, 0.6, 1.4]
        Parameter.checkList(lst, Parameter.checkFloat, [0.1, 3.0])

        #Test use of array
        lst = numpy.array([0.1, 0.6, 1.4])
        Parameter.checkList(lst, Parameter.checkFloat, [0.1, 3.0])

        lst = numpy.array([[0.1, 0.6, 1.4]])
        self.assertRaises(ValueError, Parameter.checkList, lst,
                          Parameter.checkFloat, [0.1, 3.0])
    def setVertices(self, vertices, indices=None):
        """
        Set the vertices to the given list of vertices. If indices = None then
        all vertices are replaced, and if not the given indices are used. 

        :param vertices: a list of vertices..
        :type vertices: :class:`list`

        :param indices: a list of indices of the same length as vertices or None for all indices in this object.
        :type indices: :class:`list`
        """
        if indices!=None:
            Parameter.checkList(indices, Parameter.checkIndex, [0, len(self.V)])
            if len(vertices) != len(indices):
                raise ValueError("Length of indices list must be same as that of vertices list")
        if indices==None and len(vertices) != len(self.V):
            raise ValueError("Incorrect number of vertices " + str(len(vertices)) + ", expecting " + str(len(self.V)))

        if indices == None:
            for i in range(len(vertices)):
                self.V[i] = vertices[i]
        else:
            for i in range(len(indices)):
                self.V[indices[i]] = vertices[i]