import os
from contextlib import contextmanager
from collections import namedtuple
__name__ = "infomap"
__version__ = "1.6.0"
__description__ = "Infomap network clustering algorithm"
__author__ = "mapequation"
__email__ = "mapequation@gmail.com"
__license__ = "AGPL-3.0-or-later"
__homepage__ = "https://www.mapequation.org/infomap"
__url__ = "https://mapequation.github.io/infomap/"
__repo__ = "https://github.com/mapequation/infomap.git"
__issues__ = "https://github.com/mapequation/infomap/issues"
__keywords__ = "map-equation network-analysis community-detection clustering-algorithm"
__classifiers__ = [
    'Development Status :: 5 - Production/Stable',
    'Intended Audience :: Science/Research',
    'Topic :: Scientific/Engineering :: Information Analysis',
    'License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)',
    'Programming Language :: Python :: 3']
# This file was automatically generated by SWIG (http://www.swig.org).
# Version 4.0.2
#
# Do not make changes to this file unless you know what you are doing--modify
# the SWIG interface file instead.

from sys import version_info as _swig_python_version_info
if _swig_python_version_info < (2, 7, 0):
    raise RuntimeError("Python 2.7 or later required")

# Import the low-level C/C++ module
if __package__ or "." in __name__:
    from . import _infomap
else:
    import _infomap

try:
    import builtins as __builtin__
except ImportError:
    import __builtin__


def _swig_repr(self):
    try:
        strthis = "proxy of " + self.this.__repr__()
    except __builtin__.Exception:
        strthis = ""
    return "<%s.%s; %s >" % (self.__class__.__module__,
                             self.__class__.__name__, strthis,)


def _swig_setattr_nondynamic_instance_variable(set):
    def set_instance_attr(self, name, value):
        if name == "thisown":
            self.this.own(value)
        elif name == "this":
            set(self, name, value)
        elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
            set(self, name, value)
        else:
            raise AttributeError(
                "You cannot add instance attributes to %s" %
                self)
    return set_instance_attr


def _swig_setattr_nondynamic_class_variable(set):
    def set_class_attr(cls, name, value):
        if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
            set(cls, name, value)
        else:
            raise AttributeError("You cannot add class attributes to %s" % cls)
    return set_class_attr


def _swig_add_metaclass(metaclass):
    """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""
    def wrapper(cls):
        return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())
    return wrapper


class _SwigNonDynamicMeta(type):
    """Meta class to enforce nondynamic attributes (no new attributes) for a class"""
    __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)


class FlowModel(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr
    undirected = _infomap.FlowModel_undirected
    directed = _infomap.FlowModel_directed
    undirdir = _infomap.FlowModel_undirdir
    outdirdir = _infomap.FlowModel_outdirdir
    rawdir = _infomap.FlowModel_rawdir
    value = property(
        _infomap.FlowModel_value_get,
        _infomap.FlowModel_value_set)

    def __init__(self, val):
        _infomap.FlowModel_swiginit(self, _infomap.new_FlowModel(val))
    __swig_destroy__ = _infomap.delete_FlowModel


# Register FlowModel in _infomap:
_infomap.FlowModel_swigregister(FlowModel)


def __lshift__(out, f):
    return _infomap.__lshift__(out, f)


class OptimizationLevel(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr
    FullCoarseTune = _infomap.OptimizationLevel_FullCoarseTune
    FastCoarseTune = _infomap.OptimizationLevel_FastCoarseTune
    NoTune = _infomap.OptimizationLevel_NoTune
    NoAggregationNoTune = _infomap.OptimizationLevel_NoAggregationNoTune
    value = property(_infomap.OptimizationLevel_value_get,
                     _infomap.OptimizationLevel_value_set)

    def __init__(self):
        _infomap.OptimizationLevel_swiginit(
            self, _infomap.new_OptimizationLevel())
    __swig_destroy__ = _infomap.delete_OptimizationLevel


# Register OptimizationLevel in _infomap:
_infomap.OptimizationLevel_swigregister(OptimizationLevel)


class Config(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr
    isCLI = property(_infomap.Config_isCLI_get, _infomap.Config_isCLI_set)
    networkFile = property(
        _infomap.Config_networkFile_get,
        _infomap.Config_networkFile_set)
    additionalInput = property(
        _infomap.Config_additionalInput_get,
        _infomap.Config_additionalInput_set)
    inputFormat = property(
        _infomap.Config_inputFormat_get,
        _infomap.Config_inputFormat_set)
    memoryInput = property(
        _infomap.Config_memoryInput_get,
        _infomap.Config_memoryInput_set)
    multilayerInput = property(
        _infomap.Config_multilayerInput_get,
        _infomap.Config_multilayerInput_set)
    weightThreshold = property(
        _infomap.Config_weightThreshold_get,
        _infomap.Config_weightThreshold_set)
    unweightedPaths = property(
        _infomap.Config_unweightedPaths_get,
        _infomap.Config_unweightedPaths_set)
    pathMarkovOrder = property(
        _infomap.Config_pathMarkovOrder_get,
        _infomap.Config_pathMarkovOrder_set)
    bipartite = property(
        _infomap.Config_bipartite_get,
        _infomap.Config_bipartite_set)
    skipAdjustBipartiteFlow = property(
        _infomap.Config_skipAdjustBipartiteFlow_get,
        _infomap.Config_skipAdjustBipartiteFlow_set)
    bipartiteTeleportation = property(
        _infomap.Config_bipartiteTeleportation_get,
        _infomap.Config_bipartiteTeleportation_set)
    hardPartitions = property(
        _infomap.Config_hardPartitions_get,
        _infomap.Config_hardPartitions_set)
    parseWithoutIOStreams = property(
        _infomap.Config_parseWithoutIOStreams_get,
        _infomap.Config_parseWithoutIOStreams_set)
    zeroBasedNodeNumbers = property(
        _infomap.Config_zeroBasedNodeNumbers_get,
        _infomap.Config_zeroBasedNodeNumbers_set)
    includeSelfLinks = property(
        _infomap.Config_includeSelfLinks_get,
        _infomap.Config_includeSelfLinks_set)
    ignoreEdgeWeights = property(
        _infomap.Config_ignoreEdgeWeights_get,
        _infomap.Config_ignoreEdgeWeights_set)
    nodeLimit = property(
        _infomap.Config_nodeLimit_get,
        _infomap.Config_nodeLimit_set)
    preClusterMultilayer = property(
        _infomap.Config_preClusterMultilayer_get,
        _infomap.Config_preClusterMultilayer_set)
    clusterDataFile = property(
        _infomap.Config_clusterDataFile_get,
        _infomap.Config_clusterDataFile_set)
    metaDataFile = property(
        _infomap.Config_metaDataFile_get,
        _infomap.Config_metaDataFile_set)
    metaDataRate = property(
        _infomap.Config_metaDataRate_get,
        _infomap.Config_metaDataRate_set)
    unweightedMetaData = property(
        _infomap.Config_unweightedMetaData_get,
        _infomap.Config_unweightedMetaData_set)
    numMetaDataDimensions = property(
        _infomap.Config_numMetaDataDimensions_get,
        _infomap.Config_numMetaDataDimensions_set)
    clusterDataIsHard = property(
        _infomap.Config_clusterDataIsHard_get,
        _infomap.Config_clusterDataIsHard_set)
    assignToNeighbouringModule = property(
        _infomap.Config_assignToNeighbouringModule_get,
        _infomap.Config_assignToNeighbouringModule_set)
    noInfomap = property(
        _infomap.Config_noInfomap_get,
        _infomap.Config_noInfomap_set)
    flowModel = property(
        _infomap.Config_flowModel_get,
        _infomap.Config_flowModel_set)
    directed = property(
        _infomap.Config_directed_get,
        _infomap.Config_directed_set)
    undirdir = property(
        _infomap.Config_undirdir_get,
        _infomap.Config_undirdir_set)
    outdirdir = property(
        _infomap.Config_outdirdir_get,
        _infomap.Config_outdirdir_set)
    rawdir = property(_infomap.Config_rawdir_get, _infomap.Config_rawdir_set)
    useNodeWeightsAsFlow = property(
        _infomap.Config_useNodeWeightsAsFlow_get,
        _infomap.Config_useNodeWeightsAsFlow_set)
    teleportToNodes = property(
        _infomap.Config_teleportToNodes_get,
        _infomap.Config_teleportToNodes_set)
    selfTeleportationProbability = property(
        _infomap.Config_selfTeleportationProbability_get,
        _infomap.Config_selfTeleportationProbability_set)
    markovTime = property(
        _infomap.Config_markovTime_get,
        _infomap.Config_markovTime_set)
    multilayerRelaxRate = property(
        _infomap.Config_multilayerRelaxRate_get,
        _infomap.Config_multilayerRelaxRate_set)
    multilayerRelaxLimit = property(
        _infomap.Config_multilayerRelaxLimit_get,
        _infomap.Config_multilayerRelaxLimit_set)
    multilayerRelaxLimitUp = property(
        _infomap.Config_multilayerRelaxLimitUp_get,
        _infomap.Config_multilayerRelaxLimitUp_set)
    multilayerRelaxLimitDown = property(
        _infomap.Config_multilayerRelaxLimitDown_get,
        _infomap.Config_multilayerRelaxLimitDown_set)
    multilayerJSRelaxRate = property(
        _infomap.Config_multilayerJSRelaxRate_get,
        _infomap.Config_multilayerJSRelaxRate_set)
    multilayerRelaxByJensenShannonDivergence = property(
        _infomap.Config_multilayerRelaxByJensenShannonDivergence_get,
        _infomap.Config_multilayerRelaxByJensenShannonDivergence_set)
    multilayerJSRelaxLimit = property(
        _infomap.Config_multilayerJSRelaxLimit_get,
        _infomap.Config_multilayerJSRelaxLimit_set)
    twoLevel = property(
        _infomap.Config_twoLevel_get,
        _infomap.Config_twoLevel_set)
    noCoarseTune = property(
        _infomap.Config_noCoarseTune_get,
        _infomap.Config_noCoarseTune_set)
    directedEdges = property(
        _infomap.Config_directedEdges_get,
        _infomap.Config_directedEdges_set)
    recordedTeleportation = property(
        _infomap.Config_recordedTeleportation_get,
        _infomap.Config_recordedTeleportation_set)
    teleportationProbability = property(
        _infomap.Config_teleportationProbability_get,
        _infomap.Config_teleportationProbability_set)
    preferredNumberOfModules = property(
        _infomap.Config_preferredNumberOfModules_get,
        _infomap.Config_preferredNumberOfModules_set)
    seedToRandomNumberGenerator = property(
        _infomap.Config_seedToRandomNumberGenerator_get,
        _infomap.Config_seedToRandomNumberGenerator_set)
    numTrials = property(
        _infomap.Config_numTrials_get,
        _infomap.Config_numTrials_set)
    minimumCodelengthImprovement = property(
        _infomap.Config_minimumCodelengthImprovement_get,
        _infomap.Config_minimumCodelengthImprovement_set)
    minimumSingleNodeCodelengthImprovement = property(
        _infomap.Config_minimumSingleNodeCodelengthImprovement_get,
        _infomap.Config_minimumSingleNodeCodelengthImprovement_set)
    randomizeCoreLoopLimit = property(
        _infomap.Config_randomizeCoreLoopLimit_get,
        _infomap.Config_randomizeCoreLoopLimit_set)
    coreLoopLimit = property(
        _infomap.Config_coreLoopLimit_get,
        _infomap.Config_coreLoopLimit_set)
    levelAggregationLimit = property(
        _infomap.Config_levelAggregationLimit_get,
        _infomap.Config_levelAggregationLimit_set)
    tuneIterationLimit = property(
        _infomap.Config_tuneIterationLimit_get,
        _infomap.Config_tuneIterationLimit_set)
    minimumRelativeTuneIterationImprovement = property(
        _infomap.Config_minimumRelativeTuneIterationImprovement_get,
        _infomap.Config_minimumRelativeTuneIterationImprovement_set)
    fastCoarseTunePartition = property(
        _infomap.Config_fastCoarseTunePartition_get,
        _infomap.Config_fastCoarseTunePartition_set)
    alternateCoarseTuneLevel = property(
        _infomap.Config_alternateCoarseTuneLevel_get,
        _infomap.Config_alternateCoarseTuneLevel_set)
    coarseTuneLevel = property(
        _infomap.Config_coarseTuneLevel_get,
        _infomap.Config_coarseTuneLevel_set)
    superLevelLimit = property(
        _infomap.Config_superLevelLimit_get,
        _infomap.Config_superLevelLimit_set)
    onlySuperModules = property(
        _infomap.Config_onlySuperModules_get,
        _infomap.Config_onlySuperModules_set)
    fastHierarchicalSolution = property(
        _infomap.Config_fastHierarchicalSolution_get,
        _infomap.Config_fastHierarchicalSolution_set)
    fastFirstIteration = property(
        _infomap.Config_fastFirstIteration_get,
        _infomap.Config_fastFirstIteration_set)
    preferModularSolution = property(
        _infomap.Config_preferModularSolution_get,
        _infomap.Config_preferModularSolution_set)
    innerParallelization = property(
        _infomap.Config_innerParallelization_get,
        _infomap.Config_innerParallelization_set)
    outDirectory = property(
        _infomap.Config_outDirectory_get,
        _infomap.Config_outDirectory_set)
    outName = property(
        _infomap.Config_outName_get,
        _infomap.Config_outName_set)
    outputFormats = property(
        _infomap.Config_outputFormats_get,
        _infomap.Config_outputFormats_set)
    originallyUndirected = property(
        _infomap.Config_originallyUndirected_get,
        _infomap.Config_originallyUndirected_set)
    printTree = property(
        _infomap.Config_printTree_get,
        _infomap.Config_printTree_set)
    printFlowTree = property(
        _infomap.Config_printFlowTree_get,
        _infomap.Config_printFlowTree_set)
    printNewick = property(
        _infomap.Config_printNewick_get,
        _infomap.Config_printNewick_set)
    printJson = property(
        _infomap.Config_printJson_get,
        _infomap.Config_printJson_set)
    printCsv = property(
        _infomap.Config_printCsv_get,
        _infomap.Config_printCsv_set)
    printMap = property(
        _infomap.Config_printMap_get,
        _infomap.Config_printMap_set)
    printClu = property(
        _infomap.Config_printClu_get,
        _infomap.Config_printClu_set)
    cluLevel = property(
        _infomap.Config_cluLevel_get,
        _infomap.Config_cluLevel_set)
    printNodeRanks = property(
        _infomap.Config_printNodeRanks_get,
        _infomap.Config_printNodeRanks_set)
    printFlowNetwork = property(
        _infomap.Config_printFlowNetwork_get,
        _infomap.Config_printFlowNetwork_set)
    printPajekNetwork = property(
        _infomap.Config_printPajekNetwork_get,
        _infomap.Config_printPajekNetwork_set)
    printStateNetwork = property(
        _infomap.Config_printStateNetwork_get,
        _infomap.Config_printStateNetwork_set)
    printBinaryTree = property(
        _infomap.Config_printBinaryTree_get,
        _infomap.Config_printBinaryTree_set)
    printBinaryFlowTree = property(
        _infomap.Config_printBinaryFlowTree_get,
        _infomap.Config_printBinaryFlowTree_set)
    noFileOutput = property(
        _infomap.Config_noFileOutput_get,
        _infomap.Config_noFileOutput_set)
    verbosity = property(
        _infomap.Config_verbosity_get,
        _infomap.Config_verbosity_set)
    verboseNumberPrecision = property(
        _infomap.Config_verboseNumberPrecision_get,
        _infomap.Config_verboseNumberPrecision_set)
    silent = property(_infomap.Config_silent_get, _infomap.Config_silent_set)
    benchmark = property(
        _infomap.Config_benchmark_get,
        _infomap.Config_benchmark_set)
    hideBipartiteNodes = property(
        _infomap.Config_hideBipartiteNodes_get,
        _infomap.Config_hideBipartiteNodes_set)
    maxNodeIndexVisible = property(
        _infomap.Config_maxNodeIndexVisible_get,
        _infomap.Config_maxNodeIndexVisible_set)
    minBipartiteNodeIndex = property(
        _infomap.Config_minBipartiteNodeIndex_get,
        _infomap.Config_minBipartiteNodeIndex_set)
    startDate = property(
        _infomap.Config_startDate_get,
        _infomap.Config_startDate_set)
    version = property(
        _infomap.Config_version_get,
        _infomap.Config_version_set)
    parsedString = property(
        _infomap.Config_parsedString_get,
        _infomap.Config_parsedString_set)
    parsedOptions = property(
        _infomap.Config_parsedOptions_get,
        _infomap.Config_parsedOptions_set)
    error = property(_infomap.Config_error_get, _infomap.Config_error_set)

    def __init__(self, *args):
        _infomap.Config_swiginit(self, _infomap.new_Config(*args))

    def cloneAsNonMain(self, other):
        return _infomap.Config_cloneAsNonMain(self, other)

    def setOptimizationLevel(self, level):
        return _infomap.Config_setOptimizationLevel(self, level)

    def adaptDefaults(self):
        return _infomap.Config_adaptDefaults(self)

    def setMemoryInput(self):
        return _infomap.Config_setMemoryInput(self)

    def setMultilayerInput(self):
        return _infomap.Config_setMultilayerInput(self)

    def isUndirectedClustering(self):
        return _infomap.Config_isUndirectedClustering(self)

    def isUndirectedFlow(self):
        return _infomap.Config_isUndirectedFlow(self)

    def printAsUndirected(self):
        return _infomap.Config_printAsUndirected(self)

    def is3gram(self):
        return _infomap.Config_is3gram(self)

    def isPath(self):
        return _infomap.Config_isPath(self)

    def isMultilayerNetwork(self):
        return _infomap.Config_isMultilayerNetwork(self)

    def isStateNetwork(self):
        return _infomap.Config_isStateNetwork(self)

    def isBipartite(self):
        return _infomap.Config_isBipartite(self)

    def haveMemory(self):
        return _infomap.Config_haveMemory(self)

    def haveMetaData(self):
        return _infomap.Config_haveMetaData(self)

    def haveOutput(self):
        return _infomap.Config_haveOutput(self)

    def haveModularResultOutput(self):
        return _infomap.Config_haveModularResultOutput(self)
    __swig_destroy__ = _infomap.delete_Config


# Register Config in _infomap:
_infomap.Config_swigregister(Config)


class FlowData(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _infomap.FlowData_swiginit(self, _infomap.new_FlowData(*args))
    flow = property(_infomap.FlowData_flow_get, _infomap.FlowData_flow_set)
    enterFlow = property(
        _infomap.FlowData_enterFlow_get,
        _infomap.FlowData_enterFlow_set)
    exitFlow = property(
        _infomap.FlowData_exitFlow_get,
        _infomap.FlowData_exitFlow_set)

    def __iadd__(self, other):
        return _infomap.FlowData___iadd__(self, other)

    def __isub__(self, other):
        return _infomap.FlowData___isub__(self, other)

    @property
    def enter_flow(self):
        """Get the flow entering the node."""
        return self.enterFlow

    @property
    def exit_flow(self):
        """Get the flow exiting the node."""
        return self.exitFlow

    __swig_destroy__ = _infomap.delete_FlowData


# Register FlowData in _infomap:
_infomap.FlowData_swigregister(FlowData)


class DeltaFlow(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr
    module = property(
        _infomap.DeltaFlow_module_get,
        _infomap.DeltaFlow_module_set)
    deltaExit = property(
        _infomap.DeltaFlow_deltaExit_get,
        _infomap.DeltaFlow_deltaExit_set)
    deltaEnter = property(
        _infomap.DeltaFlow_deltaEnter_get,
        _infomap.DeltaFlow_deltaEnter_set)
    count = property(
        _infomap.DeltaFlow_count_get,
        _infomap.DeltaFlow_count_set)
    __swig_destroy__ = _infomap.delete_DeltaFlow

    def __init__(self, *args):
        _infomap.DeltaFlow_swiginit(self, _infomap.new_DeltaFlow(*args))

    def __iadd__(self, other):
        return _infomap.DeltaFlow___iadd__(self, other)

    def reset(self):
        return _infomap.DeltaFlow_reset(self)


# Register DeltaFlow in _infomap:
_infomap.DeltaFlow_swigregister(DeltaFlow)


class MemDeltaFlow(DeltaFlow):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr
    sumDeltaPlogpPhysFlow = property(
        _infomap.MemDeltaFlow_sumDeltaPlogpPhysFlow_get,
        _infomap.MemDeltaFlow_sumDeltaPlogpPhysFlow_set)
    sumPlogpPhysFlow = property(
        _infomap.MemDeltaFlow_sumPlogpPhysFlow_get,
        _infomap.MemDeltaFlow_sumPlogpPhysFlow_set)

    def __init__(self, *args):
        _infomap.MemDeltaFlow_swiginit(self, _infomap.new_MemDeltaFlow(*args))

    def __iadd__(self, other):
        return _infomap.MemDeltaFlow___iadd__(self, other)

    def reset(self):
        return _infomap.MemDeltaFlow_reset(self)
    __swig_destroy__ = _infomap.delete_MemDeltaFlow


# Register MemDeltaFlow in _infomap:
_infomap.MemDeltaFlow_swigregister(MemDeltaFlow)


class PhysData(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _infomap.PhysData_swiginit(self, _infomap.new_PhysData(*args))
    physNodeIndex = property(
        _infomap.PhysData_physNodeIndex_get,
        _infomap.PhysData_physNodeIndex_set)
    sumFlowFromM2Node = property(
        _infomap.PhysData_sumFlowFromM2Node_get,
        _infomap.PhysData_sumFlowFromM2Node_set)
    __swig_destroy__ = _infomap.delete_PhysData


# Register PhysData in _infomap:
_infomap.PhysData_swigregister(PhysData)


class SwigPyIterator(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __repr__ = _swig_repr
    __swig_destroy__ = _infomap.delete_SwigPyIterator

    def value(self):
        return _infomap.SwigPyIterator_value(self)

    def incr(self, n=1):
        return _infomap.SwigPyIterator_incr(self, n)

    def decr(self, n=1):
        return _infomap.SwigPyIterator_decr(self, n)

    def distance(self, x):
        return _infomap.SwigPyIterator_distance(self, x)

    def equal(self, x):
        return _infomap.SwigPyIterator_equal(self, x)

    def copy(self):
        return _infomap.SwigPyIterator_copy(self)

    def next(self):
        return _infomap.SwigPyIterator_next(self)

    def __next__(self):
        return _infomap.SwigPyIterator___next__(self)

    def previous(self):
        return _infomap.SwigPyIterator_previous(self)

    def advance(self, n):
        return _infomap.SwigPyIterator_advance(self, n)

    def __eq__(self, x):
        return _infomap.SwigPyIterator___eq__(self, x)

    def __ne__(self, x):
        return _infomap.SwigPyIterator___ne__(self, x)

    def __iadd__(self, n):
        return _infomap.SwigPyIterator___iadd__(self, n)

    def __isub__(self, n):
        return _infomap.SwigPyIterator___isub__(self, n)

    def __add__(self, n):
        return _infomap.SwigPyIterator___add__(self, n)

    def __sub__(self, *args):
        return _infomap.SwigPyIterator___sub__(self, *args)

    def __iter__(self):
        return self


# Register SwigPyIterator in _infomap:
_infomap.SwigPyIterator_swigregister(SwigPyIterator)


class vector_uint(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def iterator(self):
        return _infomap.vector_uint_iterator(self)

    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        return _infomap.vector_uint___nonzero__(self)

    def __bool__(self):
        return _infomap.vector_uint___bool__(self)

    def __len__(self):
        return _infomap.vector_uint___len__(self)

    def __getslice__(self, i, j):
        return _infomap.vector_uint___getslice__(self, i, j)

    def __setslice__(self, *args):
        return _infomap.vector_uint___setslice__(self, *args)

    def __delslice__(self, i, j):
        return _infomap.vector_uint___delslice__(self, i, j)

    def __delitem__(self, *args):
        return _infomap.vector_uint___delitem__(self, *args)

    def __getitem__(self, *args):
        return _infomap.vector_uint___getitem__(self, *args)

    def __setitem__(self, *args):
        return _infomap.vector_uint___setitem__(self, *args)

    def pop(self):
        return _infomap.vector_uint_pop(self)

    def append(self, x):
        return _infomap.vector_uint_append(self, x)

    def empty(self):
        return _infomap.vector_uint_empty(self)

    def size(self):
        return _infomap.vector_uint_size(self)

    def swap(self, v):
        return _infomap.vector_uint_swap(self, v)

    def begin(self):
        return _infomap.vector_uint_begin(self)

    def end(self):
        return _infomap.vector_uint_end(self)

    def rbegin(self):
        return _infomap.vector_uint_rbegin(self)

    def rend(self):
        return _infomap.vector_uint_rend(self)

    def clear(self):
        return _infomap.vector_uint_clear(self)

    def get_allocator(self):
        return _infomap.vector_uint_get_allocator(self)

    def pop_back(self):
        return _infomap.vector_uint_pop_back(self)

    def erase(self, *args):
        return _infomap.vector_uint_erase(self, *args)

    def __init__(self, *args):
        _infomap.vector_uint_swiginit(self, _infomap.new_vector_uint(*args))

    def push_back(self, x):
        return _infomap.vector_uint_push_back(self, x)

    def front(self):
        return _infomap.vector_uint_front(self)

    def back(self):
        return _infomap.vector_uint_back(self)

    def assign(self, n, x):
        return _infomap.vector_uint_assign(self, n, x)

    def resize(self, *args):
        return _infomap.vector_uint_resize(self, *args)

    def insert(self, *args):
        return _infomap.vector_uint_insert(self, *args)

    def reserve(self, n):
        return _infomap.vector_uint_reserve(self, n)

    def capacity(self):
        return _infomap.vector_uint_capacity(self)
    __swig_destroy__ = _infomap.delete_vector_uint


# Register vector_uint in _infomap:
_infomap.vector_uint_swigregister(vector_uint)


class InfoNode(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr
    data = property(_infomap.InfoNode_data_get, _infomap.InfoNode_data_set)
    index = property(_infomap.InfoNode_index_get, _infomap.InfoNode_index_set)
    stateId = property(
        _infomap.InfoNode_stateId_get,
        _infomap.InfoNode_stateId_set)
    physicalId = property(
        _infomap.InfoNode_physicalId_get,
        _infomap.InfoNode_physicalId_set)
    layerId = property(
        _infomap.InfoNode_layerId_get,
        _infomap.InfoNode_layerId_set)
    metaData = property(
        _infomap.InfoNode_metaData_get,
        _infomap.InfoNode_metaData_set)
    owner = property(_infomap.InfoNode_owner_get, _infomap.InfoNode_owner_set)
    parent = property(
        _infomap.InfoNode_parent_get,
        _infomap.InfoNode_parent_set)
    previous = property(
        _infomap.InfoNode_previous_get,
        _infomap.InfoNode_previous_set)
    next = property(_infomap.InfoNode_next_get, _infomap.InfoNode_next_set)
    firstChild = property(
        _infomap.InfoNode_firstChild_get,
        _infomap.InfoNode_firstChild_set)
    lastChild = property(
        _infomap.InfoNode_lastChild_get,
        _infomap.InfoNode_lastChild_set)
    collapsedFirstChild = property(
        _infomap.InfoNode_collapsedFirstChild_get,
        _infomap.InfoNode_collapsedFirstChild_set)
    collapsedLastChild = property(
        _infomap.InfoNode_collapsedLastChild_get,
        _infomap.InfoNode_collapsedLastChild_set)
    codelength = property(
        _infomap.InfoNode_codelength_get,
        _infomap.InfoNode_codelength_set)
    dirty = property(_infomap.InfoNode_dirty_get, _infomap.InfoNode_dirty_set)
    physicalNodes = property(
        _infomap.InfoNode_physicalNodes_get,
        _infomap.InfoNode_physicalNodes_set)
    metaCollection = property(
        _infomap.InfoNode_metaCollection_get,
        _infomap.InfoNode_metaCollection_set)
    stateNodes = property(
        _infomap.InfoNode_stateNodes_get,
        _infomap.InfoNode_stateNodes_set)

    def __init__(self, *args):
        _infomap.InfoNode_swiginit(self, _infomap.new_InfoNode(*args))
    __swig_destroy__ = _infomap.delete_InfoNode

    def getMetaData(self, dimension=0):
        return _infomap.InfoNode_getMetaData(self, dimension)

    def getInfomap(self):
        return _infomap.InfoNode_getInfomap(self)

    def setInfomap(self, arg2):
        return _infomap.InfoNode_setInfomap(self, arg2)

    def getInfomapRoot(self, *args):
        return _infomap.InfoNode_getInfomapRoot(self, *args)

    def disposeInfomap(self):
        return _infomap.InfoNode_disposeInfomap(self)

    def numPhysicalNodes(self):
        return _infomap.InfoNode_numPhysicalNodes(self)

    def begin(self, *args):
        return _infomap.InfoNode_begin(self, *args)

    def end(self, *args):
        return _infomap.InfoNode_end(self, *args)

    def begin_child(self, *args):
        return _infomap.InfoNode_begin_child(self, *args)

    def end_child(self, *args):
        return _infomap.InfoNode_end_child(self, *args)

    def children(self, *args):
        return _infomap.InfoNode_children(self, *args)

    def infomap_children(self, *args):
        return _infomap.InfoNode_infomap_children(self, *args)

    def begin_post_depth_first(self):
        return _infomap.InfoNode_begin_post_depth_first(self)

    def begin_leaf_nodes(self):
        return _infomap.InfoNode_begin_leaf_nodes(self)

    def begin_leaf_modules(self):
        return _infomap.InfoNode_begin_leaf_modules(self)

    def begin_tree(self, *args):
        return _infomap.InfoNode_begin_tree(self, *args)

    def end_tree(self, *args):
        return _infomap.InfoNode_end_tree(self, *args)

    def infomapTree(self, *args):
        return _infomap.InfoNode_infomapTree(self, *args)

    def begin_outEdge(self):
        return _infomap.InfoNode_begin_outEdge(self)

    def end_outEdge(self):
        return _infomap.InfoNode_end_outEdge(self)

    def begin_inEdge(self):
        return _infomap.InfoNode_begin_inEdge(self)

    def end_inEdge(self):
        return _infomap.InfoNode_end_inEdge(self)

    def outEdges(self):
        return _infomap.InfoNode_outEdges(self)

    def inEdges(self):
        return _infomap.InfoNode_inEdges(self)

    def childDegree(self):
        return _infomap.InfoNode_childDegree(self)

    def isLeaf(self):
        return _infomap.InfoNode_isLeaf(self)

    def isLeafModule(self):
        return _infomap.InfoNode_isLeafModule(self)

    def isRoot(self):
        return _infomap.InfoNode_isRoot(self)

    def depth(self):
        return _infomap.InfoNode_depth(self)

    def firstDepthBelow(self):
        return _infomap.InfoNode_firstDepthBelow(self)

    def numLeafMembers(self):
        return _infomap.InfoNode_numLeafMembers(self)

    def isDangling(self):
        return _infomap.InfoNode_isDangling(self)

    def outDegree(self):
        return _infomap.InfoNode_outDegree(self)

    def inDegree(self):
        return _infomap.InfoNode_inDegree(self)

    def degree(self):
        return _infomap.InfoNode_degree(self)

    def isFirst(self):
        return _infomap.InfoNode_isFirst(self)

    def isLast(self):
        return _infomap.InfoNode_isLast(self)

    def childIndex(self):
        return _infomap.InfoNode_childIndex(self)

    def calculatePath(self):
        return _infomap.InfoNode_calculatePath(self)

    def infomapChildDegree(self):
        return _infomap.InfoNode_infomapChildDegree(self)

    def id(self):
        return _infomap.InfoNode_id(self)

    def __eq__(self, rhs):
        return _infomap.InfoNode___eq__(self, rhs)

    def __ne__(self, rhs):
        return _infomap.InfoNode___ne__(self, rhs)

    def initClean(self):
        return _infomap.InfoNode_initClean(self)

    def sortChildrenOnFlow(self, recurse=True):
        return _infomap.InfoNode_sortChildrenOnFlow(self, recurse)

    def collapseChildren(self):
        return _infomap.InfoNode_collapseChildren(self)

    def expandChildren(self):
        return _infomap.InfoNode_expandChildren(self)

    def setChildDegree(self, value):
        return _infomap.InfoNode_setChildDegree(self, value)

    def setNumLeafNodes(self, value):
        return _infomap.InfoNode_setNumLeafNodes(self, value)

    def addChild(self, child):
        return _infomap.InfoNode_addChild(self, child)

    def releaseChildren(self):
        return _infomap.InfoNode_releaseChildren(self)

    def replaceChildrenWithOneNode(self):
        return _infomap.InfoNode_replaceChildrenWithOneNode(self)

    def replaceWithChildren(self):
        return _infomap.InfoNode_replaceWithChildren(self)

    def replaceWithChildrenDebug(self):
        return _infomap.InfoNode_replaceWithChildrenDebug(self)

    def replaceChildrenWithGrandChildren(self):
        return _infomap.InfoNode_replaceChildrenWithGrandChildren(self)

    def replaceChildrenWithGrandChildrenDebug(self):
        return _infomap.InfoNode_replaceChildrenWithGrandChildrenDebug(self)

    def remove(self, removeChildren):
        return _infomap.InfoNode_remove(self, removeChildren)

    def deleteChildren(self):
        return _infomap.InfoNode_deleteChildren(self)

    def addOutEdge(self, target, weight, flow=0.0):
        return _infomap.InfoNode_addOutEdge(self, target, weight, flow)

    @property
    def node_id(self):
        """Get the physical node id.

        Returns
        -------
        int
                The node id
        """
        return self.physicalId

    @property
    def state_id(self):
        """Get the state id of the node.

        Returns
        -------
        int
                The state id
        """
        return self.stateId

    @property
    def flow(self):
        """Get the flow of the node.

        Returns
        -------
        float
                The flow
        """
        return self.data.flow

    @property
    def layer_id(self):
        """Get the layer id of a multilayer node.

        Returns
        -------
        int
                The layer id
        """
        return self.layerId

    @property
    def child_degree(self):
        """The number of children.

        Returns
        -------
        int
                Number of children
        """
        return self.childDegree()

    @property
    def is_leaf(self):
        """True if the node has no children.

        Returns
        -------
        bool
                Is leaf node
        """
        return self.isLeaf()

    @property
    def is_leaf_module(self):
        """True if the node has children but no grandchildren.

        Returns
        -------
        bool
                Is leaf module
        """
        return self.isLeafModule()

    @property
    def is_root(self):
        """True if the node has no parent.

        Returns
        -------
        bool
                Is root
        """
        return self.isRoot()

    @property
    def meta_data(self):
        """Meta data (on first dimension if more).

        Returns
        -------
        int
                The meta data
        """
        return self.getMetaData()

    def get_meta_data(self, dimension=0):
        """Get meta data on a specific dimension.

        Parameters
        ----------
        dimension : int
                The dimension (default 0)

        Returns
        -------
        int
                The meta data
        """
        return self.getMetaData(dimension)


# Register InfoNode in _infomap:
_infomap.InfoNode_swigregister(InfoNode)


class deque_uint(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def iterator(self):
        return _infomap.deque_uint_iterator(self)

    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        return _infomap.deque_uint___nonzero__(self)

    def __bool__(self):
        return _infomap.deque_uint___bool__(self)

    def __len__(self):
        return _infomap.deque_uint___len__(self)

    def __getslice__(self, i, j):
        return _infomap.deque_uint___getslice__(self, i, j)

    def __setslice__(self, *args):
        return _infomap.deque_uint___setslice__(self, *args)

    def __delslice__(self, i, j):
        return _infomap.deque_uint___delslice__(self, i, j)

    def __delitem__(self, *args):
        return _infomap.deque_uint___delitem__(self, *args)

    def __getitem__(self, *args):
        return _infomap.deque_uint___getitem__(self, *args)

    def __setitem__(self, *args):
        return _infomap.deque_uint___setitem__(self, *args)

    def pop(self):
        return _infomap.deque_uint_pop(self)

    def append(self, x):
        return _infomap.deque_uint_append(self, x)

    def empty(self):
        return _infomap.deque_uint_empty(self)

    def size(self):
        return _infomap.deque_uint_size(self)

    def swap(self, v):
        return _infomap.deque_uint_swap(self, v)

    def begin(self):
        return _infomap.deque_uint_begin(self)

    def end(self):
        return _infomap.deque_uint_end(self)

    def rbegin(self):
        return _infomap.deque_uint_rbegin(self)

    def rend(self):
        return _infomap.deque_uint_rend(self)

    def clear(self):
        return _infomap.deque_uint_clear(self)

    def get_allocator(self):
        return _infomap.deque_uint_get_allocator(self)

    def pop_back(self):
        return _infomap.deque_uint_pop_back(self)

    def erase(self, *args):
        return _infomap.deque_uint_erase(self, *args)

    def __init__(self, *args):
        _infomap.deque_uint_swiginit(self, _infomap.new_deque_uint(*args))

    def push_back(self, x):
        return _infomap.deque_uint_push_back(self, x)

    def front(self):
        return _infomap.deque_uint_front(self)

    def back(self):
        return _infomap.deque_uint_back(self)

    def assign(self, n, x):
        return _infomap.deque_uint_assign(self, n, x)

    def resize(self, *args):
        return _infomap.deque_uint_resize(self, *args)

    def insert(self, *args):
        return _infomap.deque_uint_insert(self, *args)

    def pop_front(self):
        return _infomap.deque_uint_pop_front(self)

    def push_front(self, x):
        return _infomap.deque_uint_push_front(self, x)
    __swig_destroy__ = _infomap.delete_deque_uint


# Register deque_uint in _infomap:
_infomap.deque_uint_swigregister(deque_uint)


class InfomapIterator(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _infomap.InfomapIterator_swiginit(
            self, _infomap.new_InfomapIterator(*args))
    __swig_destroy__ = _infomap.delete_InfomapIterator

    def current(self, *args):
        return _infomap.InfomapIterator_current(self, *args)

    def __ref__(self, *args):
        return _infomap.InfomapIterator___ref__(self, *args)

    def __deref__(self, *args):
        return _infomap.InfomapIterator___deref__(self, *args)

    def __eq__(self, other):
        return _infomap.InfomapIterator___eq__(self, other)

    def __ne__(self, other):
        return _infomap.InfomapIterator___ne__(self, other)

    def stepForward(self):
        return _infomap.InfomapIterator_stepForward(self)

    def path(self):
        return _infomap.InfomapIterator_path(self)

    def moduleIndex(self):
        return _infomap.InfomapIterator_moduleIndex(self)

    def moduleId(self):
        return _infomap.InfomapIterator_moduleId(self)

    def childIndex(self):
        return _infomap.InfomapIterator_childIndex(self)

    def depth(self):
        return _infomap.InfomapIterator_depth(self)

    def isEnd(self):
        return _infomap.InfomapIterator_isEnd(self)

    def __iter__(self):
        self._firstYielded = False
        return self

    def __next__(self):
        if not self._firstYielded:
            self._firstYielded = True
        else:
            self.stepForward()

        if self.isEnd():
            raise StopIteration

        return self

    @property
    def module_id(self):
        """Get the module id of the node.

        Returns
        -------
        int
                The module id
        """
        return self.moduleId()

    _path = path

    @property
    def path(self):
        """Get the path to the node in the tree.

        Returns
        -------
        tuple of ints
                The path
        """
        return self._path()

    _depth = depth

    @property
    def depth(self):
        """Get the depth.

        Returns
        -------
        int
                The depth
        """
        return self._depth()

    @property
    def child_index(self):
        """Get the child index.

        Returns
        -------
        int
                The child index
        """
        return self.childIndex()

    # Forward to the node it currently points to
    def __getattr__(self, name):
        return getattr(self.current(), name)

    data = property(
        _infomap.InfomapIterator_data_get,
        _infomap.InfomapIterator_data_set)
    index = property(
        _infomap.InfomapIterator_index_get,
        _infomap.InfomapIterator_index_set)
    stateId = property(
        _infomap.InfomapIterator_stateId_get,
        _infomap.InfomapIterator_stateId_set)
    physicalId = property(
        _infomap.InfomapIterator_physicalId_get,
        _infomap.InfomapIterator_physicalId_set)
    layerId = property(
        _infomap.InfomapIterator_layerId_get,
        _infomap.InfomapIterator_layerId_set)
    metaData = property(
        _infomap.InfomapIterator_metaData_get,
        _infomap.InfomapIterator_metaData_set)
    owner = property(
        _infomap.InfomapIterator_owner_get,
        _infomap.InfomapIterator_owner_set)
    parent = property(
        _infomap.InfomapIterator_parent_get,
        _infomap.InfomapIterator_parent_set)
    previous = property(
        _infomap.InfomapIterator_previous_get,
        _infomap.InfomapIterator_previous_set)
    next = property(
        _infomap.InfomapIterator_next_get,
        _infomap.InfomapIterator_next_set)
    firstChild = property(
        _infomap.InfomapIterator_firstChild_get,
        _infomap.InfomapIterator_firstChild_set)
    lastChild = property(
        _infomap.InfomapIterator_lastChild_get,
        _infomap.InfomapIterator_lastChild_set)
    collapsedFirstChild = property(
        _infomap.InfomapIterator_collapsedFirstChild_get,
        _infomap.InfomapIterator_collapsedFirstChild_set)
    collapsedLastChild = property(
        _infomap.InfomapIterator_collapsedLastChild_get,
        _infomap.InfomapIterator_collapsedLastChild_set)
    codelength = property(
        _infomap.InfomapIterator_codelength_get,
        _infomap.InfomapIterator_codelength_set)
    dirty = property(
        _infomap.InfomapIterator_dirty_get,
        _infomap.InfomapIterator_dirty_set)
    physicalNodes = property(
        _infomap.InfomapIterator_physicalNodes_get,
        _infomap.InfomapIterator_physicalNodes_set)
    metaCollection = property(
        _infomap.InfomapIterator_metaCollection_get,
        _infomap.InfomapIterator_metaCollection_set)
    stateNodes = property(
        _infomap.InfomapIterator_stateNodes_get,
        _infomap.InfomapIterator_stateNodes_set)

    def getMetaData(self, dimension=0):
        return _infomap.InfomapIterator_getMetaData(self, dimension)

    def getInfomap(self):
        return _infomap.InfomapIterator_getInfomap(self)

    def setInfomap(self, arg2):
        return _infomap.InfomapIterator_setInfomap(self, arg2)

    def getInfomapRoot(self, *args):
        return _infomap.InfomapIterator_getInfomapRoot(self, *args)

    def disposeInfomap(self):
        return _infomap.InfomapIterator_disposeInfomap(self)

    def numPhysicalNodes(self):
        return _infomap.InfomapIterator_numPhysicalNodes(self)

    def begin(self, *args):
        return _infomap.InfomapIterator_begin(self, *args)

    def end(self, *args):
        return _infomap.InfomapIterator_end(self, *args)

    def begin_child(self, *args):
        return _infomap.InfomapIterator_begin_child(self, *args)

    def end_child(self, *args):
        return _infomap.InfomapIterator_end_child(self, *args)

    def children(self, *args):
        return _infomap.InfomapIterator_children(self, *args)

    def infomap_children(self, *args):
        return _infomap.InfomapIterator_infomap_children(self, *args)

    def begin_post_depth_first(self):
        return _infomap.InfomapIterator_begin_post_depth_first(self)

    def begin_leaf_nodes(self):
        return _infomap.InfomapIterator_begin_leaf_nodes(self)

    def begin_leaf_modules(self):
        return _infomap.InfomapIterator_begin_leaf_modules(self)

    def begin_tree(self, *args):
        return _infomap.InfomapIterator_begin_tree(self, *args)

    def end_tree(self, *args):
        return _infomap.InfomapIterator_end_tree(self, *args)

    def infomapTree(self, *args):
        return _infomap.InfomapIterator_infomapTree(self, *args)

    def begin_outEdge(self):
        return _infomap.InfomapIterator_begin_outEdge(self)

    def end_outEdge(self):
        return _infomap.InfomapIterator_end_outEdge(self)

    def begin_inEdge(self):
        return _infomap.InfomapIterator_begin_inEdge(self)

    def end_inEdge(self):
        return _infomap.InfomapIterator_end_inEdge(self)

    def outEdges(self):
        return _infomap.InfomapIterator_outEdges(self)

    def inEdges(self):
        return _infomap.InfomapIterator_inEdges(self)

    def childDegree(self):
        return _infomap.InfomapIterator_childDegree(self)

    def isLeaf(self):
        return _infomap.InfomapIterator_isLeaf(self)

    def isLeafModule(self):
        return _infomap.InfomapIterator_isLeafModule(self)

    def isRoot(self):
        return _infomap.InfomapIterator_isRoot(self)

    def firstDepthBelow(self):
        return _infomap.InfomapIterator_firstDepthBelow(self)

    def numLeafMembers(self):
        return _infomap.InfomapIterator_numLeafMembers(self)

    def isDangling(self):
        return _infomap.InfomapIterator_isDangling(self)

    def outDegree(self):
        return _infomap.InfomapIterator_outDegree(self)

    def inDegree(self):
        return _infomap.InfomapIterator_inDegree(self)

    def degree(self):
        return _infomap.InfomapIterator_degree(self)

    def isFirst(self):
        return _infomap.InfomapIterator_isFirst(self)

    def isLast(self):
        return _infomap.InfomapIterator_isLast(self)

    def calculatePath(self):
        return _infomap.InfomapIterator_calculatePath(self)

    def infomapChildDegree(self):
        return _infomap.InfomapIterator_infomapChildDegree(self)

    def id(self):
        return _infomap.InfomapIterator_id(self)

    def initClean(self):
        return _infomap.InfomapIterator_initClean(self)

    def sortChildrenOnFlow(self, recurse=True):
        return _infomap.InfomapIterator_sortChildrenOnFlow(self, recurse)

    def collapseChildren(self):
        return _infomap.InfomapIterator_collapseChildren(self)

    def expandChildren(self):
        return _infomap.InfomapIterator_expandChildren(self)

    def setChildDegree(self, value):
        return _infomap.InfomapIterator_setChildDegree(self, value)

    def setNumLeafNodes(self, value):
        return _infomap.InfomapIterator_setNumLeafNodes(self, value)

    def addChild(self, child):
        return _infomap.InfomapIterator_addChild(self, child)

    def releaseChildren(self):
        return _infomap.InfomapIterator_releaseChildren(self)

    def replaceChildrenWithOneNode(self):
        return _infomap.InfomapIterator_replaceChildrenWithOneNode(self)

    def replaceWithChildren(self):
        return _infomap.InfomapIterator_replaceWithChildren(self)

    def replaceWithChildrenDebug(self):
        return _infomap.InfomapIterator_replaceWithChildrenDebug(self)

    def replaceChildrenWithGrandChildren(self):
        return _infomap.InfomapIterator_replaceChildrenWithGrandChildren(self)

    def replaceChildrenWithGrandChildrenDebug(self):
        return _infomap.InfomapIterator_replaceChildrenWithGrandChildrenDebug(
            self)

    def remove(self, removeChildren):
        return _infomap.InfomapIterator_remove(self, removeChildren)

    def deleteChildren(self):
        return _infomap.InfomapIterator_deleteChildren(self)

    def addOutEdge(self, target, weight, flow=0.0):
        return _infomap.InfomapIterator_addOutEdge(self, target, weight, flow)


# Register InfomapIterator in _infomap:
_infomap.InfomapIterator_swigregister(InfomapIterator)


class InfomapModuleIterator(InfomapIterator):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _infomap.InfomapModuleIterator_swiginit(
            self, _infomap.new_InfomapModuleIterator(*args))

    def childIndex(self):
        return _infomap.InfomapModuleIterator_childIndex(self)

    def current(self, *args):
        return _infomap.InfomapModuleIterator_current(self, *args)

    def depth(self):
        return _infomap.InfomapModuleIterator_depth(self)

    def path(self):
        return _infomap.InfomapModuleIterator_path(self)
    __swig_destroy__ = _infomap.delete_InfomapModuleIterator


# Register InfomapModuleIterator in _infomap:
_infomap.InfomapModuleIterator_swigregister(InfomapModuleIterator)


class InfomapLeafModuleIterator(InfomapIterator):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _infomap.InfomapLeafModuleIterator_swiginit(
            self, _infomap.new_InfomapLeafModuleIterator(*args))

    def init(self):
        return _infomap.InfomapLeafModuleIterator_init(self)

    def childIndex(self):
        return _infomap.InfomapLeafModuleIterator_childIndex(self)

    def current(self, *args):
        return _infomap.InfomapLeafModuleIterator_current(self, *args)

    def depth(self):
        return _infomap.InfomapLeafModuleIterator_depth(self)

    def path(self):
        return _infomap.InfomapLeafModuleIterator_path(self)

    def __iter__(self):
        self._firstYielded = False
        return self

    def __next__(self):
        if not self._firstYielded:
            self._firstYielded = True
        else:
            self.stepForward()

        if self.isEnd():
            raise StopIteration

        return self

    @property
    def module_id(self):
        """Get the module id of the node.

        Returns
        -------
        int
                The module id
        """
        return self.moduleId()

    _path = path

    @property
    def path(self):
        """Get the path to the node in the tree.

        Returns
        -------
        tuple of ints
                The path
        """
        return self._path()

    _depth = depth

    @property
    def depth(self):
        """Get the depth.

        Returns
        -------
        int
                The depth
        """
        return self._depth()

    @property
    def child_index(self):
        """Get the child index.

        Returns
        -------
        int
                The child index
        """
        return self.childIndex()

    # Forward to the node it currently points to
    def __getattr__(self, name):
        return getattr(self.current(), name)

    __swig_destroy__ = _infomap.delete_InfomapLeafModuleIterator


# Register InfomapLeafModuleIterator in _infomap:
_infomap.InfomapLeafModuleIterator_swigregister(InfomapLeafModuleIterator)


class InfomapLeafIterator(InfomapIterator):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _infomap.InfomapLeafIterator_swiginit(
            self, _infomap.new_InfomapLeafIterator(*args))

    def init(self):
        return _infomap.InfomapLeafIterator_init(self)

    def childIndex(self):
        return _infomap.InfomapLeafIterator_childIndex(self)

    def current(self, *args):
        return _infomap.InfomapLeafIterator_current(self, *args)

    def depth(self):
        return _infomap.InfomapLeafIterator_depth(self)

    def path(self):
        return _infomap.InfomapLeafIterator_path(self)

    def __iter__(self):
        self._firstYielded = False
        return self

    def __next__(self):
        if not self._firstYielded:
            self._firstYielded = True
        else:
            self.stepForward()

        if self.isEnd():
            raise StopIteration

        return self

    @property
    def module_id(self):
        """Get the module id of the node.

        Returns
        -------
        int
                The module id
        """
        return self.moduleId()

    _path = path

    @property
    def path(self):
        """Get the path to the node in the tree.

        Returns
        -------
        tuple of ints
                The path
        """
        return self._path()

    _depth = depth

    @property
    def depth(self):
        """Get the depth.

        Returns
        -------
        int
                The depth
        """
        return self._depth()

    @property
    def child_index(self):
        """Get the child index.

        Returns
        -------
        int
                The child index
        """
        return self.childIndex()

    # Forward to the node it currently points to
    def __getattr__(self, name):
        return getattr(self.current(), name)

    __swig_destroy__ = _infomap.delete_InfomapLeafIterator


# Register InfomapLeafIterator in _infomap:
_infomap.InfomapLeafIterator_swigregister(InfomapLeafIterator)


class InfomapIteratorPhysical(InfomapIterator):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _infomap.InfomapIteratorPhysical_swiginit(
            self, _infomap.new_InfomapIteratorPhysical(*args))

    def childIndex(self):
        return _infomap.InfomapIteratorPhysical_childIndex(self)

    def current(self, *args):
        return _infomap.InfomapIteratorPhysical_current(self, *args)

    def depth(self):
        return _infomap.InfomapIteratorPhysical_depth(self)

    def path(self):
        return _infomap.InfomapIteratorPhysical_path(self)

    def __iter__(self):
        self._firstYielded = False
        return self

    def __next__(self):
        if not self._firstYielded:
            self._firstYielded = True
        else:
            self.stepForward()

        if self.isEnd():
            raise StopIteration

        return self

    @property
    def module_id(self):
        """Get the module id of the node.

        Returns
        -------
        int
                The module id
        """
        return self.moduleId()

    _path = path

    @property
    def path(self):
        """Get the path to the node in the tree.

        Returns
        -------
        tuple of ints
                The path
        """
        return self._path()

    _depth = depth

    @property
    def depth(self):
        """Get the depth.

        Returns
        -------
        int
                The depth
        """
        return self._depth()

    @property
    def child_index(self):
        """Get the child index.

        Returns
        -------
        int
                The child index
        """
        return self.childIndex()

    # Forward to the node it currently points to
    def __getattr__(self, name):
        return getattr(self.current(), name)

    __swig_destroy__ = _infomap.delete_InfomapIteratorPhysical


# Register InfomapIteratorPhysical in _infomap:
_infomap.InfomapIteratorPhysical_swigregister(InfomapIteratorPhysical)


class InfomapLeafIteratorPhysical(InfomapIteratorPhysical):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _infomap.InfomapLeafIteratorPhysical_swiginit(
            self, _infomap.new_InfomapLeafIteratorPhysical(*args))

    def init(self):
        return _infomap.InfomapLeafIteratorPhysical_init(self)

    def childIndex(self):
        return _infomap.InfomapLeafIteratorPhysical_childIndex(self)

    def current(self, *args):
        return _infomap.InfomapLeafIteratorPhysical_current(self, *args)

    def depth(self):
        return _infomap.InfomapLeafIteratorPhysical_depth(self)

    def path(self):
        return _infomap.InfomapLeafIteratorPhysical_path(self)

    def __iter__(self):
        self._firstYielded = False
        return self

    def __next__(self):
        if not self._firstYielded:
            self._firstYielded = True
        else:
            self.stepForward()

        if self.isEnd():
            raise StopIteration

        return self

    @property
    def module_id(self):
        """Get the module id of the node.

        Returns
        -------
        int
                The module id
        """
        return self.moduleId()

    _path = path

    @property
    def path(self):
        """Get the path to the node in the tree.

        Returns
        -------
        tuple of ints
                The path
        """
        return self._path()

    _depth = depth

    @property
    def depth(self):
        """Get the depth.

        Returns
        -------
        int
                The depth
        """
        return self._depth()

    @property
    def child_index(self):
        """Get the child index.

        Returns
        -------
        int
                The child index
        """
        return self.childIndex()

    # Forward to the node it currently points to
    def __getattr__(self, name):
        return getattr(self.current(), name)

    __swig_destroy__ = _infomap.delete_InfomapLeafIteratorPhysical


# Register InfomapLeafIteratorPhysical in _infomap:
_infomap.InfomapLeafIteratorPhysical_swigregister(InfomapLeafIteratorPhysical)


class InfomapParentIterator(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _infomap.InfomapParentIterator_swiginit(
            self, _infomap.new_InfomapParentIterator(*args))
    __swig_destroy__ = _infomap.delete_InfomapParentIterator

    def current(self, *args):
        return _infomap.InfomapParentIterator_current(self, *args)

    def __ref__(self, *args):
        return _infomap.InfomapParentIterator___ref__(self, *args)

    def __deref__(self, *args):
        return _infomap.InfomapParentIterator___deref__(self, *args)

    def __eq__(self, other):
        return _infomap.InfomapParentIterator___eq__(self, other)

    def __ne__(self, other):
        return _infomap.InfomapParentIterator___ne__(self, other)

    def stepForward(self):
        return _infomap.InfomapParentIterator_stepForward(self)

    def isEnd(self):
        return _infomap.InfomapParentIterator_isEnd(self)
    data = property(_infomap.InfomapParentIterator_data_get,
                    _infomap.InfomapParentIterator_data_set)
    index = property(_infomap.InfomapParentIterator_index_get,
                     _infomap.InfomapParentIterator_index_set)
    stateId = property(
        _infomap.InfomapParentIterator_stateId_get,
        _infomap.InfomapParentIterator_stateId_set)
    physicalId = property(
        _infomap.InfomapParentIterator_physicalId_get,
        _infomap.InfomapParentIterator_physicalId_set)
    layerId = property(
        _infomap.InfomapParentIterator_layerId_get,
        _infomap.InfomapParentIterator_layerId_set)
    metaData = property(
        _infomap.InfomapParentIterator_metaData_get,
        _infomap.InfomapParentIterator_metaData_set)
    owner = property(_infomap.InfomapParentIterator_owner_get,
                     _infomap.InfomapParentIterator_owner_set)
    parent = property(
        _infomap.InfomapParentIterator_parent_get,
        _infomap.InfomapParentIterator_parent_set)
    previous = property(
        _infomap.InfomapParentIterator_previous_get,
        _infomap.InfomapParentIterator_previous_set)
    next = property(_infomap.InfomapParentIterator_next_get,
                    _infomap.InfomapParentIterator_next_set)
    firstChild = property(
        _infomap.InfomapParentIterator_firstChild_get,
        _infomap.InfomapParentIterator_firstChild_set)
    lastChild = property(
        _infomap.InfomapParentIterator_lastChild_get,
        _infomap.InfomapParentIterator_lastChild_set)
    collapsedFirstChild = property(
        _infomap.InfomapParentIterator_collapsedFirstChild_get,
        _infomap.InfomapParentIterator_collapsedFirstChild_set)
    collapsedLastChild = property(
        _infomap.InfomapParentIterator_collapsedLastChild_get,
        _infomap.InfomapParentIterator_collapsedLastChild_set)
    codelength = property(
        _infomap.InfomapParentIterator_codelength_get,
        _infomap.InfomapParentIterator_codelength_set)
    dirty = property(_infomap.InfomapParentIterator_dirty_get,
                     _infomap.InfomapParentIterator_dirty_set)
    physicalNodes = property(
        _infomap.InfomapParentIterator_physicalNodes_get,
        _infomap.InfomapParentIterator_physicalNodes_set)
    metaCollection = property(
        _infomap.InfomapParentIterator_metaCollection_get,
        _infomap.InfomapParentIterator_metaCollection_set)
    stateNodes = property(
        _infomap.InfomapParentIterator_stateNodes_get,
        _infomap.InfomapParentIterator_stateNodes_set)

    def getMetaData(self, dimension=0):
        return _infomap.InfomapParentIterator_getMetaData(self, dimension)

    def getInfomap(self):
        return _infomap.InfomapParentIterator_getInfomap(self)

    def setInfomap(self, arg2):
        return _infomap.InfomapParentIterator_setInfomap(self, arg2)

    def getInfomapRoot(self, *args):
        return _infomap.InfomapParentIterator_getInfomapRoot(self, *args)

    def disposeInfomap(self):
        return _infomap.InfomapParentIterator_disposeInfomap(self)

    def numPhysicalNodes(self):
        return _infomap.InfomapParentIterator_numPhysicalNodes(self)

    def begin(self, *args):
        return _infomap.InfomapParentIterator_begin(self, *args)

    def end(self, *args):
        return _infomap.InfomapParentIterator_end(self, *args)

    def begin_child(self, *args):
        return _infomap.InfomapParentIterator_begin_child(self, *args)

    def end_child(self, *args):
        return _infomap.InfomapParentIterator_end_child(self, *args)

    def children(self, *args):
        return _infomap.InfomapParentIterator_children(self, *args)

    def infomap_children(self, *args):
        return _infomap.InfomapParentIterator_infomap_children(self, *args)

    def begin_post_depth_first(self):
        return _infomap.InfomapParentIterator_begin_post_depth_first(self)

    def begin_leaf_nodes(self):
        return _infomap.InfomapParentIterator_begin_leaf_nodes(self)

    def begin_leaf_modules(self):
        return _infomap.InfomapParentIterator_begin_leaf_modules(self)

    def begin_tree(self, *args):
        return _infomap.InfomapParentIterator_begin_tree(self, *args)

    def end_tree(self, *args):
        return _infomap.InfomapParentIterator_end_tree(self, *args)

    def infomapTree(self, *args):
        return _infomap.InfomapParentIterator_infomapTree(self, *args)

    def begin_outEdge(self):
        return _infomap.InfomapParentIterator_begin_outEdge(self)

    def end_outEdge(self):
        return _infomap.InfomapParentIterator_end_outEdge(self)

    def begin_inEdge(self):
        return _infomap.InfomapParentIterator_begin_inEdge(self)

    def end_inEdge(self):
        return _infomap.InfomapParentIterator_end_inEdge(self)

    def outEdges(self):
        return _infomap.InfomapParentIterator_outEdges(self)

    def inEdges(self):
        return _infomap.InfomapParentIterator_inEdges(self)

    def childDegree(self):
        return _infomap.InfomapParentIterator_childDegree(self)

    def isLeaf(self):
        return _infomap.InfomapParentIterator_isLeaf(self)

    def isLeafModule(self):
        return _infomap.InfomapParentIterator_isLeafModule(self)

    def isRoot(self):
        return _infomap.InfomapParentIterator_isRoot(self)

    def depth(self):
        return _infomap.InfomapParentIterator_depth(self)

    def firstDepthBelow(self):
        return _infomap.InfomapParentIterator_firstDepthBelow(self)

    def numLeafMembers(self):
        return _infomap.InfomapParentIterator_numLeafMembers(self)

    def isDangling(self):
        return _infomap.InfomapParentIterator_isDangling(self)

    def outDegree(self):
        return _infomap.InfomapParentIterator_outDegree(self)

    def inDegree(self):
        return _infomap.InfomapParentIterator_inDegree(self)

    def degree(self):
        return _infomap.InfomapParentIterator_degree(self)

    def isFirst(self):
        return _infomap.InfomapParentIterator_isFirst(self)

    def isLast(self):
        return _infomap.InfomapParentIterator_isLast(self)

    def childIndex(self):
        return _infomap.InfomapParentIterator_childIndex(self)

    def calculatePath(self):
        return _infomap.InfomapParentIterator_calculatePath(self)

    def infomapChildDegree(self):
        return _infomap.InfomapParentIterator_infomapChildDegree(self)

    def id(self):
        return _infomap.InfomapParentIterator_id(self)

    def initClean(self):
        return _infomap.InfomapParentIterator_initClean(self)

    def sortChildrenOnFlow(self, recurse=True):
        return _infomap.InfomapParentIterator_sortChildrenOnFlow(self, recurse)

    def collapseChildren(self):
        return _infomap.InfomapParentIterator_collapseChildren(self)

    def expandChildren(self):
        return _infomap.InfomapParentIterator_expandChildren(self)

    def setChildDegree(self, value):
        return _infomap.InfomapParentIterator_setChildDegree(self, value)

    def setNumLeafNodes(self, value):
        return _infomap.InfomapParentIterator_setNumLeafNodes(self, value)

    def addChild(self, child):
        return _infomap.InfomapParentIterator_addChild(self, child)

    def releaseChildren(self):
        return _infomap.InfomapParentIterator_releaseChildren(self)

    def replaceChildrenWithOneNode(self):
        return _infomap.InfomapParentIterator_replaceChildrenWithOneNode(self)

    def replaceWithChildren(self):
        return _infomap.InfomapParentIterator_replaceWithChildren(self)

    def replaceWithChildrenDebug(self):
        return _infomap.InfomapParentIterator_replaceWithChildrenDebug(self)

    def replaceChildrenWithGrandChildren(self):
        return _infomap.InfomapParentIterator_replaceChildrenWithGrandChildren(
            self)

    def replaceChildrenWithGrandChildrenDebug(self):
        return _infomap.InfomapParentIterator_replaceChildrenWithGrandChildrenDebug(
            self)

    def remove(self, removeChildren):
        return _infomap.InfomapParentIterator_remove(self, removeChildren)

    def deleteChildren(self):
        return _infomap.InfomapParentIterator_deleteChildren(self)

    def addOutEdge(self, target, weight, flow=0.0):
        return _infomap.InfomapParentIterator_addOutEdge(
            self, target, weight, flow)


# Register InfomapParentIterator in _infomap:
_infomap.InfomapParentIterator_swigregister(InfomapParentIterator)


class StateNetwork(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _infomap.StateNetwork_swiginit(self, _infomap.new_StateNetwork(*args))
    __swig_destroy__ = _infomap.delete_StateNetwork

    def setConfig(self, config):
        return _infomap.StateNetwork_setConfig(self, config)

    def getConfig(self):
        return _infomap.StateNetwork_getConfig(self)

    def addStateNode(self, *args):
        return _infomap.StateNetwork_addStateNode(self, *args)

    def addNode(self, *args):
        return _infomap.StateNetwork_addNode(self, *args)

    def addPhysicalNode(self, *args):
        return _infomap.StateNetwork_addPhysicalNode(self, *args)

    def addName(self, id, arg3):
        return _infomap.StateNetwork_addName(self, id, arg3)

    def addLink(self, *args):
        return _infomap.StateNetwork_addLink(self, *args)

    def removeLink(self, sourceId, targetId):
        return _infomap.StateNetwork_removeLink(self, sourceId, targetId)

    def undirectedToDirected(self):
        return _infomap.StateNetwork_undirectedToDirected(self)

    def calculateFlow(self):
        return _infomap.StateNetwork_calculateFlow(self)

    def clear(self):
        return _infomap.StateNetwork_clear(self)

    def clearLinks(self):
        return _infomap.StateNetwork_clearLinks(self)

    def nodes(self):
        return _infomap.StateNetwork_nodes(self)

    def numNodes(self):
        return _infomap.StateNetwork_numNodes(self)

    def numPhysicalNodes(self):
        return _infomap.StateNetwork_numPhysicalNodes(self)

    def nodeLinkMap(self, *args):
        return _infomap.StateNetwork_nodeLinkMap(self, *args)

    def numLinks(self):
        return _infomap.StateNetwork_numLinks(self)

    def sumLinkWeight(self):
        return _infomap.StateNetwork_sumLinkWeight(self)

    def sumSelfLinkWeight(self):
        return _infomap.StateNetwork_sumSelfLinkWeight(self)

    def outWeights(self):
        return _infomap.StateNetwork_outWeights(self)

    def names(self, *args):
        return _infomap.StateNetwork_names(self, *args)

    def haveDirectedInput(self):
        return _infomap.StateNetwork_haveDirectedInput(self)

    def haveMemoryInput(self):
        return _infomap.StateNetwork_haveMemoryInput(self)

    def isBipartite(self):
        return _infomap.StateNetwork_isBipartite(self)

    def bipartiteStartId(self):
        return _infomap.StateNetwork_bipartiteStartId(self)

    def setBipartiteStartId(self, value):
        return _infomap.StateNetwork_setBipartiteStartId(self, value)

    def writeStateNetwork(self, filename):
        return _infomap.StateNetwork_writeStateNetwork(self, filename)

    def writePajekNetwork(self, filename, printFlow=False):
        return _infomap.StateNetwork_writePajekNetwork(
            self, filename, printFlow)


# Register StateNetwork in _infomap:
_infomap.StateNetwork_swigregister(StateNetwork)


class Network(StateNetwork):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _infomap.Network_swiginit(self, _infomap.new_Network(*args))
    __swig_destroy__ = _infomap.delete_Network

    def clear(self):
        return _infomap.Network_clear(self)

    def readInputData(self, *args):
        return _infomap.Network_readInputData(self, *args)

    def readMetaData(self, filename):
        return _infomap.Network_readMetaData(self, filename)

    def numMetaDataColumns(self):
        return _infomap.Network_numMetaDataColumns(self)

    def metaData(self):
        return _infomap.Network_metaData(self)

    def isMultilayerNetwork(self):
        return _infomap.Network_isMultilayerNetwork(self)

    def generateStateNetworkFromMultilayer(self):
        return _infomap.Network_generateStateNetworkFromMultilayer(self)

    def generateStateNetworkFromMultilayerWithInterLinks(self):
        return _infomap.Network_generateStateNetworkFromMultilayerWithInterLinks(
            self)

    def generateStateNetworkFromMultilayerWithSimulatedInterLinks(self):
        return _infomap.Network_generateStateNetworkFromMultilayerWithSimulatedInterLinks(
            self)

    def simulateInterLayerLinks(self):
        return _infomap.Network_simulateInterLayerLinks(self)

    def addMultilayerLink(self, layer1, n1, layer2, n2, weight):
        return _infomap.Network_addMultilayerLink(
            self, layer1, n1, layer2, n2, weight)

    def addMultilayerIntraLink(self, layer, n1, n2, weight):
        return _infomap.Network_addMultilayerIntraLink(
            self, layer, n1, n2, weight)

    def addMultilayerInterLink(self, layer1, n, layer2, interWeight):
        return _infomap.Network_addMultilayerInterLink(
            self, layer1, n, layer2, interWeight)

    def addMetaData(self, *args):
        return _infomap.Network_addMetaData(self, *args)


# Register Network in _infomap:
_infomap.Network_swigregister(Network)


class LayerNode(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr
    layer = property(
        _infomap.LayerNode_layer_get,
        _infomap.LayerNode_layer_set)
    node = property(_infomap.LayerNode_node_get, _infomap.LayerNode_node_set)

    def __init__(self, layer=0, node=0):
        _infomap.LayerNode_swiginit(self, _infomap.new_LayerNode(layer, node))

    def __lt__(self, other):
        return _infomap.LayerNode___lt__(self, other)
    __swig_destroy__ = _infomap.delete_LayerNode


# Register LayerNode in _infomap:
_infomap.LayerNode_swigregister(LayerNode)


class Bigram(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr
    first = property(_infomap.Bigram_first_get, _infomap.Bigram_first_set)
    second = property(_infomap.Bigram_second_get, _infomap.Bigram_second_set)

    def __init__(self, first=0, second=0):
        _infomap.Bigram_swiginit(self, _infomap.new_Bigram(first, second))

    def __lt__(self, other):
        return _infomap.Bigram___lt__(self, other)
    __swig_destroy__ = _infomap.delete_Bigram


# Register Bigram in _infomap:
_infomap.Bigram_swigregister(Bigram)


class BipartiteLink(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr
    featureNode = property(
        _infomap.BipartiteLink_featureNode_get,
        _infomap.BipartiteLink_featureNode_set)
    node = property(
        _infomap.BipartiteLink_node_get,
        _infomap.BipartiteLink_node_set)
    swapOrder = property(
        _infomap.BipartiteLink_swapOrder_get,
        _infomap.BipartiteLink_swapOrder_set)

    def __init__(self, featureNode=0, node=0, swapOrder=False):
        _infomap.BipartiteLink_swiginit(
            self, _infomap.new_BipartiteLink(
                featureNode, node, swapOrder))

    def __lt__(self, other):
        return _infomap.BipartiteLink___lt__(self, other)
    __swig_destroy__ = _infomap.delete_BipartiteLink


# Register BipartiteLink in _infomap:
_infomap.BipartiteLink_swigregister(BipartiteLink)


class Weight(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr
    weight = property(_infomap.Weight_weight_get, _infomap.Weight_weight_set)

    def __init__(self, weight=0):
        _infomap.Weight_swiginit(self, _infomap.new_Weight(weight))

    def __iadd__(self, w):
        return _infomap.Weight___iadd__(self, w)
    __swig_destroy__ = _infomap.delete_Weight


# Register Weight in _infomap:
_infomap.Weight_swigregister(Weight)


class Triple(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _infomap.Triple_swiginit(self, _infomap.new_Triple(*args))

    def __lt__(self, other):
        return _infomap.Triple___lt__(self, other)

    def __eq__(self, other):
        return _infomap.Triple___eq__(self, other)
    n1 = property(_infomap.Triple_n1_get, _infomap.Triple_n1_set)
    n2 = property(_infomap.Triple_n2_get, _infomap.Triple_n2_set)
    n3 = property(_infomap.Triple_n3_get, _infomap.Triple_n3_set)
    __swig_destroy__ = _infomap.delete_Triple


# Register Triple in _infomap:
_infomap.Triple_swigregister(Triple)


class map_uint_uint(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def iterator(self):
        return _infomap.map_uint_uint_iterator(self)

    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        return _infomap.map_uint_uint___nonzero__(self)

    def __bool__(self):
        return _infomap.map_uint_uint___bool__(self)

    def __len__(self):
        return _infomap.map_uint_uint___len__(self)

    def __iter__(self):
        return self.key_iterator()

    def iterkeys(self):
        return self.key_iterator()

    def itervalues(self):
        return self.value_iterator()

    def iteritems(self):
        return self.iterator()

    def __getitem__(self, key):
        return _infomap.map_uint_uint___getitem__(self, key)

    def __delitem__(self, key):
        return _infomap.map_uint_uint___delitem__(self, key)

    def has_key(self, key):
        return _infomap.map_uint_uint_has_key(self, key)

    def keys(self):
        return _infomap.map_uint_uint_keys(self)

    def values(self):
        return _infomap.map_uint_uint_values(self)

    def items(self):
        return _infomap.map_uint_uint_items(self)

    def __contains__(self, key):
        return _infomap.map_uint_uint___contains__(self, key)

    def key_iterator(self):
        return _infomap.map_uint_uint_key_iterator(self)

    def value_iterator(self):
        return _infomap.map_uint_uint_value_iterator(self)

    def __setitem__(self, *args):
        return _infomap.map_uint_uint___setitem__(self, *args)

    def asdict(self):
        return _infomap.map_uint_uint_asdict(self)

    def __init__(self, *args):
        _infomap.map_uint_uint_swiginit(
            self, _infomap.new_map_uint_uint(*args))

    def empty(self):
        return _infomap.map_uint_uint_empty(self)

    def size(self):
        return _infomap.map_uint_uint_size(self)

    def swap(self, v):
        return _infomap.map_uint_uint_swap(self, v)

    def begin(self):
        return _infomap.map_uint_uint_begin(self)

    def end(self):
        return _infomap.map_uint_uint_end(self)

    def rbegin(self):
        return _infomap.map_uint_uint_rbegin(self)

    def rend(self):
        return _infomap.map_uint_uint_rend(self)

    def clear(self):
        return _infomap.map_uint_uint_clear(self)

    def get_allocator(self):
        return _infomap.map_uint_uint_get_allocator(self)

    def count(self, x):
        return _infomap.map_uint_uint_count(self, x)

    def erase(self, *args):
        return _infomap.map_uint_uint_erase(self, *args)

    def find(self, x):
        return _infomap.map_uint_uint_find(self, x)

    def lower_bound(self, x):
        return _infomap.map_uint_uint_lower_bound(self, x)

    def upper_bound(self, x):
        return _infomap.map_uint_uint_upper_bound(self, x)
    __swig_destroy__ = _infomap.delete_map_uint_uint


# Register map_uint_uint in _infomap:
_infomap.map_uint_uint_swigregister(map_uint_uint)


class vector_double(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def iterator(self):
        return _infomap.vector_double_iterator(self)

    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        return _infomap.vector_double___nonzero__(self)

    def __bool__(self):
        return _infomap.vector_double___bool__(self)

    def __len__(self):
        return _infomap.vector_double___len__(self)

    def __getslice__(self, i, j):
        return _infomap.vector_double___getslice__(self, i, j)

    def __setslice__(self, *args):
        return _infomap.vector_double___setslice__(self, *args)

    def __delslice__(self, i, j):
        return _infomap.vector_double___delslice__(self, i, j)

    def __delitem__(self, *args):
        return _infomap.vector_double___delitem__(self, *args)

    def __getitem__(self, *args):
        return _infomap.vector_double___getitem__(self, *args)

    def __setitem__(self, *args):
        return _infomap.vector_double___setitem__(self, *args)

    def pop(self):
        return _infomap.vector_double_pop(self)

    def append(self, x):
        return _infomap.vector_double_append(self, x)

    def empty(self):
        return _infomap.vector_double_empty(self)

    def size(self):
        return _infomap.vector_double_size(self)

    def swap(self, v):
        return _infomap.vector_double_swap(self, v)

    def begin(self):
        return _infomap.vector_double_begin(self)

    def end(self):
        return _infomap.vector_double_end(self)

    def rbegin(self):
        return _infomap.vector_double_rbegin(self)

    def rend(self):
        return _infomap.vector_double_rend(self)

    def clear(self):
        return _infomap.vector_double_clear(self)

    def get_allocator(self):
        return _infomap.vector_double_get_allocator(self)

    def pop_back(self):
        return _infomap.vector_double_pop_back(self)

    def erase(self, *args):
        return _infomap.vector_double_erase(self, *args)

    def __init__(self, *args):
        _infomap.vector_double_swiginit(
            self, _infomap.new_vector_double(*args))

    def push_back(self, x):
        return _infomap.vector_double_push_back(self, x)

    def front(self):
        return _infomap.vector_double_front(self)

    def back(self):
        return _infomap.vector_double_back(self)

    def assign(self, n, x):
        return _infomap.vector_double_assign(self, n, x)

    def resize(self, *args):
        return _infomap.vector_double_resize(self, *args)

    def insert(self, *args):
        return _infomap.vector_double_insert(self, *args)

    def reserve(self, n):
        return _infomap.vector_double_reserve(self, n)

    def capacity(self):
        return _infomap.vector_double_capacity(self)
    __swig_destroy__ = _infomap.delete_vector_double


# Register vector_double in _infomap:
_infomap.vector_double_swigregister(vector_double)


class InfomapConfigInfomapBase(Config):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _infomap.InfomapConfigInfomapBase_swiginit(
            self, _infomap.new_InfomapConfigInfomapBase(*args))
    __swig_destroy__ = _infomap.delete_InfomapConfigInfomapBase

    def getConfig(self, *args):
        return _infomap.InfomapConfigInfomapBase_getConfig(self, *args)

    def setConfig(self, conf):
        return _infomap.InfomapConfigInfomapBase_setConfig(self, conf)

    def setNonMainConfig(self, conf):
        return _infomap.InfomapConfigInfomapBase_setNonMainConfig(self, conf)

    def setNumTrials(self, N):
        return _infomap.InfomapConfigInfomapBase_setNumTrials(self, N)

    def setVerbosity(self, level):
        return _infomap.InfomapConfigInfomapBase_setVerbosity(self, level)

    def setTwoLevel(self, value):
        return _infomap.InfomapConfigInfomapBase_setTwoLevel(self, value)

    def setTuneIterationLimit(self, value):
        return _infomap.InfomapConfigInfomapBase_setTuneIterationLimit(
            self, value)

    def setFastHierarchicalSolution(self, level):
        return _infomap.InfomapConfigInfomapBase_setFastHierarchicalSolution(
            self, level)

    def setOnlySuperModules(self, value):
        return _infomap.InfomapConfigInfomapBase_setOnlySuperModules(
            self, value)

    def setNoCoarseTune(self, value):
        return _infomap.InfomapConfigInfomapBase_setNoCoarseTune(self, value)

    def setNoInfomap(self, value=True):
        return _infomap.InfomapConfigInfomapBase_setNoInfomap(self, value)

    def setMarkovTime(self, codeRate):
        return _infomap.InfomapConfigInfomapBase_setMarkovTime(self, codeRate)

    def reseed(self, seed):
        return _infomap.InfomapConfigInfomapBase_reseed(self, seed)


# Register InfomapConfigInfomapBase in _infomap:
_infomap.InfomapConfigInfomapBase_swigregister(InfomapConfigInfomapBase)


class InfomapBase(InfomapConfigInfomapBase):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __repr__ = _swig_repr
    __swig_destroy__ = _infomap.delete_InfomapBase

    def network(self, *args):
        return _infomap.InfomapBase_network(self, *args)

    def root(self, *args):
        return _infomap.InfomapBase_root(self, *args)

    def iterTree(self, maxClusterLevel=1):
        return _infomap.InfomapBase_iterTree(self, maxClusterLevel)

    def iterTreePhysical(self, maxClusterLevel=1):
        return _infomap.InfomapBase_iterTreePhysical(self, maxClusterLevel)

    def iterModules(self, maxClusterLevel=1):
        return _infomap.InfomapBase_iterModules(self, maxClusterLevel)

    def iterLeafModules(self, maxClusterLevel=1):
        return _infomap.InfomapBase_iterLeafModules(self, maxClusterLevel)

    def iterLeafNodes(self, maxClusterLevel=1):
        return _infomap.InfomapBase_iterLeafNodes(self, maxClusterLevel)

    def iterLeafNodesPhysical(self, maxClusterLevel=1):
        return _infomap.InfomapBase_iterLeafNodesPhysical(
            self, maxClusterLevel)

    def begin(self, maxClusterLevel=1):
        return _infomap.InfomapBase_begin(self, maxClusterLevel)

    def end(self):
        return _infomap.InfomapBase_end(self)

    def numLeafNodes(self):
        return _infomap.InfomapBase_numLeafNodes(self)

    def leafNodes(self):
        return _infomap.InfomapBase_leafNodes(self)

    def numTopModules(self):
        return _infomap.InfomapBase_numTopModules(self)

    def numActiveModules(self):
        return _infomap.InfomapBase_numActiveModules(self)

    def numNonTrivialTopModules(self):
        return _infomap.InfomapBase_numNonTrivialTopModules(self)

    def haveModules(self):
        return _infomap.InfomapBase_haveModules(self)

    def haveNonTrivialModules(self):
        return _infomap.InfomapBase_haveNonTrivialModules(self)

    def numLevels(self):
        return _infomap.InfomapBase_numLevels(self)

    def maxTreeDepth(self):
        return _infomap.InfomapBase_maxTreeDepth(self)

    def getCodelength(self):
        return _infomap.InfomapBase_getCodelength(self)

    def getMetaCodelength(self, unweighted=False):
        return _infomap.InfomapBase_getMetaCodelength(self, unweighted)

    def codelength(self):
        return _infomap.InfomapBase_codelength(self)

    def codelengths(self):
        return _infomap.InfomapBase_codelengths(self)

    def getIndexCodelength(self):
        return _infomap.InfomapBase_getIndexCodelength(self)

    def getModuleCodelength(self):
        return _infomap.InfomapBase_getModuleCodelength(self)

    def getHierarchicalCodelength(self):
        return _infomap.InfomapBase_getHierarchicalCodelength(self)

    def getOneLevelCodelength(self):
        return _infomap.InfomapBase_getOneLevelCodelength(self)

    def getRelativeCodelengthSavings(self):
        return _infomap.InfomapBase_getRelativeCodelengthSavings(self)

    def isFullNetwork(self):
        return _infomap.InfomapBase_isFullNetwork(self)

    def isFirstLoop(self):
        return _infomap.InfomapBase_isFirstLoop(self)

    def getNewInfomapInstance(self):
        return _infomap.InfomapBase_getNewInfomapInstance(self)

    def getNewInfomapInstanceWithoutMemory(self):
        return _infomap.InfomapBase_getNewInfomapInstanceWithoutMemory(self)

    def getSubInfomap(self, node):
        return _infomap.InfomapBase_getSubInfomap(self, node)

    def getSuperInfomap(self, node):
        return _infomap.InfomapBase_getSuperInfomap(self, node)

    def setIsMain(self, isMain):
        return _infomap.InfomapBase_setIsMain(self, isMain)

    def setSubLevel(self, level):
        return _infomap.InfomapBase_setSubLevel(self, level)

    def isTopLevel(self):
        return _infomap.InfomapBase_isTopLevel(self)

    def isSuperLevelOnTopLevel(self):
        return _infomap.InfomapBase_isSuperLevelOnTopLevel(self)

    def isMainInfomap(self):
        return _infomap.InfomapBase_isMainInfomap(self)

    def haveHardPartition(self):
        return _infomap.InfomapBase_haveHardPartition(self)

    def activeNetwork(self):
        return _infomap.InfomapBase_activeNetwork(self)

    def toString(self, out):
        return _infomap.InfomapBase_toString(self, out)

    def getInitialPartition(self):
        return _infomap.InfomapBase_getInitialPartition(self)

    def calcEntropyRate(self):
        return _infomap.InfomapBase_calcEntropyRate(self)

    def setInitialPartition(self, moduleIds):
        return _infomap.InfomapBase_setInitialPartition(self, moduleIds)

    def run(self, *args):
        return _infomap.InfomapBase_run(self, *args)

    def generateSubNetwork(self, *args):
        return _infomap.InfomapBase_generateSubNetwork(self, *args)

    def initMetaData(self, metaDataFile):
        return _infomap.InfomapBase_initMetaData(self, metaDataFile)

    def initTree(self, tree):
        return _infomap.InfomapBase_initTree(self, tree)

    def init(self):
        return _infomap.InfomapBase_init(self)

    def runPartition(self):
        return _infomap.InfomapBase_runPartition(self)

    def restoreHardPartition(self):
        return _infomap.InfomapBase_restoreHardPartition(self)

    def sortTreeOnFlow(self):
        return _infomap.InfomapBase_sortTreeOnFlow(self)

    def writeResult(self):
        return _infomap.InfomapBase_writeResult(self)

    def hierarchicalPartition(self):
        return _infomap.InfomapBase_hierarchicalPartition(self)

    def partition(self):
        return _infomap.InfomapBase_partition(self)

    def initEnterExitFlow(self):
        return _infomap.InfomapBase_initEnterExitFlow(self)

    def aggregateFlowValuesFromLeafToRoot(self):
        return _infomap.InfomapBase_aggregateFlowValuesFromLeafToRoot(self)

    def initNetwork(self, *args):
        return _infomap.InfomapBase_initNetwork(self, *args)

    def initSuperNetwork(self):
        return _infomap.InfomapBase_initSuperNetwork(self)

    def calcCodelength(self, parent):
        return _infomap.InfomapBase_calcCodelength(self, parent)

    def calcCodelengthOnTree(self, includeRoot=True):
        return _infomap.InfomapBase_calcCodelengthOnTree(self, includeRoot)

    def setActiveNetworkFromLeafs(self):
        return _infomap.InfomapBase_setActiveNetworkFromLeafs(self)

    def setActiveNetworkFromChildrenOfRoot(self):
        return _infomap.InfomapBase_setActiveNetworkFromChildrenOfRoot(self)

    def initPartition(self, *args):
        return _infomap.InfomapBase_initPartition(self, *args)

    def findTopModulesRepeatedly(self, maxLevels):
        return _infomap.InfomapBase_findTopModulesRepeatedly(self, maxLevels)

    def fineTune(self):
        return _infomap.InfomapBase_fineTune(self)

    def coarseTune(self):
        return _infomap.InfomapBase_coarseTune(self)

    def optimizeActiveNetwork(self):
        return _infomap.InfomapBase_optimizeActiveNetwork(self)

    def moveActiveNodesToPredefinedModules(self, modules):
        return _infomap.InfomapBase_moveActiveNodesToPredefinedModules(
            self, modules)

    def consolidateModules(self, replaceExistingModules=True):
        return _infomap.InfomapBase_consolidateModules(
            self, replaceExistingModules)

    def calculateNumNonTrivialTopModules(self):
        return _infomap.InfomapBase_calculateNumNonTrivialTopModules(self)

    def calculateMaxDepth(self):
        return _infomap.InfomapBase_calculateMaxDepth(self)

    def restoreConsolidatedOptimizationPointIfNoImprovement(
            self, forceRestore=False):
        return _infomap.InfomapBase_restoreConsolidatedOptimizationPointIfNoImprovement(
            self, forceRestore)

    def findHierarchicalSuperModules(self, *args):
        return _infomap.InfomapBase_findHierarchicalSuperModules(self, *args)

    def findHierarchicalSuperModulesFast(self, *args):
        return _infomap.InfomapBase_findHierarchicalSuperModulesFast(
            self, *args)

    def transformNodeFlowToEnterFlow(self, parent):
        return _infomap.InfomapBase_transformNodeFlowToEnterFlow(self, parent)

    def resetFlowOnModules(self):
        return _infomap.InfomapBase_resetFlowOnModules(self)

    def removeModules(self):
        return _infomap.InfomapBase_removeModules(self)

    def removeSubModules(self, recalculateCodelengthOnTree):
        return _infomap.InfomapBase_removeSubModules(
            self, recalculateCodelengthOnTree)

    def recursivePartition(self):
        return _infomap.InfomapBase_recursivePartition(self)

    def queueTopModules(self, partitionQueue):
        return _infomap.InfomapBase_queueTopModules(self, partitionQueue)

    def queueLeafModules(self, partitionQueue):
        return _infomap.InfomapBase_queueLeafModules(self, partitionQueue)

    def processPartitionQueue(self, queue, nextLevel):
        return _infomap.InfomapBase_processPartitionQueue(
            self, queue, nextLevel)

    def getOutputFileHeader(self):
        return _infomap.InfomapBase_getOutputFileHeader(self)

    def writeTree(self, *args):
        return _infomap.InfomapBase_writeTree(self, *args)

    def writeFlowTree(self, *args):
        return _infomap.InfomapBase_writeFlowTree(self, *args)

    def writeNewickTree(self, *args):
        return _infomap.InfomapBase_writeNewickTree(self, *args)

    def writeJsonTree(self, *args):
        return _infomap.InfomapBase_writeJsonTree(self, *args)

    def writeCsvTree(self, *args):
        return _infomap.InfomapBase_writeCsvTree(self, *args)

    def writeClu(self, *args):
        return _infomap.InfomapBase_writeClu(self, *args)

    def printPerLevelCodelength(self, out):
        return _infomap.InfomapBase_printPerLevelCodelength(self, out)

    def aggregatePerLevelCodelength(self, *args):
        return _infomap.InfomapBase_aggregatePerLevelCodelength(self, *args)

    def printDebug(self):
        return _infomap.InfomapBase_printDebug(self)


# Register InfomapBase in _infomap:
_infomap.InfomapBase_swigregister(InfomapBase)


class PerLevelStat(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def codelength(self):
        return _infomap.PerLevelStat_codelength(self)

    def numNodes(self):
        return _infomap.PerLevelStat_numNodes(self)
    numModules = property(
        _infomap.PerLevelStat_numModules_get,
        _infomap.PerLevelStat_numModules_set)
    numLeafNodes = property(
        _infomap.PerLevelStat_numLeafNodes_get,
        _infomap.PerLevelStat_numLeafNodes_set)
    indexLength = property(
        _infomap.PerLevelStat_indexLength_get,
        _infomap.PerLevelStat_indexLength_set)
    leafLength = property(
        _infomap.PerLevelStat_leafLength_get,
        _infomap.PerLevelStat_leafLength_set)

    def __init__(self):
        _infomap.PerLevelStat_swiginit(self, _infomap.new_PerLevelStat())
    __swig_destroy__ = _infomap.delete_PerLevelStat


# Register PerLevelStat in _infomap:
_infomap.PerLevelStat_swigregister(PerLevelStat)


class PartitionQueue(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def swap(self, other):
        return _infomap.PartitionQueue_swap(self, other)

    def size(self):
        return _infomap.PartitionQueue_size(self)

    def resize(self, size):
        return _infomap.PartitionQueue_resize(self, size)
    level = property(
        _infomap.PartitionQueue_level_get,
        _infomap.PartitionQueue_level_set)
    numNonTrivialModules = property(
        _infomap.PartitionQueue_numNonTrivialModules_get,
        _infomap.PartitionQueue_numNonTrivialModules_set)
    flow = property(
        _infomap.PartitionQueue_flow_get,
        _infomap.PartitionQueue_flow_set)
    nonTrivialFlow = property(
        _infomap.PartitionQueue_nonTrivialFlow_get,
        _infomap.PartitionQueue_nonTrivialFlow_set)
    skip = property(
        _infomap.PartitionQueue_skip_get,
        _infomap.PartitionQueue_skip_set)
    indexCodelength = property(
        _infomap.PartitionQueue_indexCodelength_get,
        _infomap.PartitionQueue_indexCodelength_set)
    leafCodelength = property(
        _infomap.PartitionQueue_leafCodelength_get,
        _infomap.PartitionQueue_leafCodelength_set)
    moduleCodelength = property(
        _infomap.PartitionQueue_moduleCodelength_get,
        _infomap.PartitionQueue_moduleCodelength_set)

    def __init__(self):
        _infomap.PartitionQueue_swiginit(self, _infomap.new_PartitionQueue())
    __swig_destroy__ = _infomap.delete_PartitionQueue


# Register PartitionQueue in _infomap:
_infomap.PartitionQueue_swigregister(PartitionQueue)


class MapEquation(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _infomap.MapEquation_swiginit(self, _infomap.new_MapEquation(*args))
    __swig_destroy__ = _infomap.delete_MapEquation

    def getIndexCodelength(self):
        return _infomap.MapEquation_getIndexCodelength(self)

    def getModuleCodelength(self):
        return _infomap.MapEquation_getModuleCodelength(self)

    def getCodelength(self):
        return _infomap.MapEquation_getCodelength(self)

    def _print(self, arg2):
        return _infomap.MapEquation__print(self, arg2)

    def init(self, config):
        return _infomap.MapEquation_init(self, config)

    def initNetwork(self, root):
        return _infomap.MapEquation_initNetwork(self, root)

    def initSuperNetwork(self, root):
        return _infomap.MapEquation_initSuperNetwork(self, root)

    def initSubNetwork(self, root):
        return _infomap.MapEquation_initSubNetwork(self, root)

    def initPartition(self, nodes):
        return _infomap.MapEquation_initPartition(self, nodes)

    def calcCodelength(self, parent):
        return _infomap.MapEquation_calcCodelength(self, parent)

    def addMemoryContributions(self, *args):
        return _infomap.MapEquation_addMemoryContributions(self, *args)

    def getDeltaCodelengthOnMovingNode(
            self,
            current,
            oldModuleDelta,
            newModuleDelta,
            moduleFlowData,
            moduleMembers):
        return _infomap.MapEquation_getDeltaCodelengthOnMovingNode(
            self, current, oldModuleDelta, newModuleDelta, moduleFlowData, moduleMembers)

    def updateCodelengthOnMovingNode(
            self,
            current,
            oldModuleDelta,
            newModuleDelta,
            moduleFlowData,
            moduleMembers):
        return _infomap.MapEquation_updateCodelengthOnMovingNode(
            self, current, oldModuleDelta, newModuleDelta, moduleFlowData, moduleMembers)

    def consolidateModules(self, modules):
        return _infomap.MapEquation_consolidateModules(self, modules)

    def printDebug(self):
        return _infomap.MapEquation_printDebug(self)
    codelength = property(
        _infomap.MapEquation_codelength_get,
        _infomap.MapEquation_codelength_set)
    indexCodelength = property(
        _infomap.MapEquation_indexCodelength_get,
        _infomap.MapEquation_indexCodelength_set)
    moduleCodelength = property(
        _infomap.MapEquation_moduleCodelength_get,
        _infomap.MapEquation_moduleCodelength_set)


# Register MapEquation in _infomap:
_infomap.MapEquation_swigregister(MapEquation)


class MemMapEquation(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _infomap.MemMapEquation_swiginit(
            self, _infomap.new_MemMapEquation(*args))
    __swig_destroy__ = _infomap.delete_MemMapEquation

    def getIndexCodelength(self):
        return _infomap.MemMapEquation_getIndexCodelength(self)

    def getModuleCodelength(self):
        return _infomap.MemMapEquation_getModuleCodelength(self)

    def getCodelength(self):
        return _infomap.MemMapEquation_getCodelength(self)

    def _print(self, out):
        return _infomap.MemMapEquation__print(self, out)

    def init(self, config):
        return _infomap.MemMapEquation_init(self, config)

    def initNetwork(self, root):
        return _infomap.MemMapEquation_initNetwork(self, root)

    def initSuperNetwork(self, root):
        return _infomap.MemMapEquation_initSuperNetwork(self, root)

    def initSubNetwork(self, root):
        return _infomap.MemMapEquation_initSubNetwork(self, root)

    def initPartition(self, nodes):
        return _infomap.MemMapEquation_initPartition(self, nodes)

    def calcCodelength(self, parent):
        return _infomap.MemMapEquation_calcCodelength(self, parent)

    def addMemoryContributions(self, current, oldModuleDelta, moduleDeltaFlow):
        return _infomap.MemMapEquation_addMemoryContributions(
            self, current, oldModuleDelta, moduleDeltaFlow)

    def getDeltaCodelengthOnMovingNode(
            self,
            current,
            oldModuleDelta,
            newModuleDelta,
            moduleFlowData,
            moduleMembers):
        return _infomap.MemMapEquation_getDeltaCodelengthOnMovingNode(
            self, current, oldModuleDelta, newModuleDelta, moduleFlowData, moduleMembers)

    def updateCodelengthOnMovingNode(
            self,
            current,
            oldModuleDelta,
            newModuleDelta,
            moduleFlowData,
            moduleMembers):
        return _infomap.MemMapEquation_updateCodelengthOnMovingNode(
            self, current, oldModuleDelta, newModuleDelta, moduleFlowData, moduleMembers)

    def consolidateModules(self, modules):
        return _infomap.MemMapEquation_consolidateModules(self, modules)

    def printDebug(self):
        return _infomap.MemMapEquation_printDebug(self)
    codelength = property(
        _infomap.MemMapEquation_codelength_get,
        _infomap.MemMapEquation_codelength_set)
    indexCodelength = property(
        _infomap.MemMapEquation_indexCodelength_get,
        _infomap.MemMapEquation_indexCodelength_set)
    moduleCodelength = property(
        _infomap.MemMapEquation_moduleCodelength_get,
        _infomap.MemMapEquation_moduleCodelength_set)


# Register MemMapEquation in _infomap:
_infomap.MemMapEquation_swigregister(MemMapEquation)


class MemNodeSet(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _infomap.MemNodeSet_swiginit(self, _infomap.new_MemNodeSet(*args))
    numMemNodes = property(
        _infomap.MemNodeSet_numMemNodes_get,
        _infomap.MemNodeSet_numMemNodes_set)
    sumFlow = property(
        _infomap.MemNodeSet_sumFlow_get,
        _infomap.MemNodeSet_sumFlow_set)
    __swig_destroy__ = _infomap.delete_MemNodeSet


# Register MemNodeSet in _infomap:
_infomap.MemNodeSet_swigregister(MemNodeSet)


class MetaMapEquation(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _infomap.MetaMapEquation_swiginit(
            self, _infomap.new_MetaMapEquation(*args))
    __swig_destroy__ = _infomap.delete_MetaMapEquation

    def getIndexCodelength(self):
        return _infomap.MetaMapEquation_getIndexCodelength(self)

    def getModuleCodelength(self):
        return _infomap.MetaMapEquation_getModuleCodelength(self)

    def getCodelength(self):
        return _infomap.MetaMapEquation_getCodelength(self)

    def getMetaCodelength(self, unweighted=False):
        return _infomap.MetaMapEquation_getMetaCodelength(self, unweighted)

    def _print(self, out):
        return _infomap.MetaMapEquation__print(self, out)

    def init(self, config):
        return _infomap.MetaMapEquation_init(self, config)

    def initNetwork(self, root):
        return _infomap.MetaMapEquation_initNetwork(self, root)

    def initSuperNetwork(self, root):
        return _infomap.MetaMapEquation_initSuperNetwork(self, root)

    def initSubNetwork(self, root):
        return _infomap.MetaMapEquation_initSubNetwork(self, root)

    def initPartition(self, nodes):
        return _infomap.MetaMapEquation_initPartition(self, nodes)

    def calcCodelength(self, parent):
        return _infomap.MetaMapEquation_calcCodelength(self, parent)

    def addMemoryContributions(self, current, oldModuleDelta, moduleDeltaFlow):
        return _infomap.MetaMapEquation_addMemoryContributions(
            self, current, oldModuleDelta, moduleDeltaFlow)

    def getDeltaCodelengthOnMovingNode(
            self,
            current,
            oldModuleDelta,
            newModuleDelta,
            moduleFlowData,
            moduleMembers):
        return _infomap.MetaMapEquation_getDeltaCodelengthOnMovingNode(
            self, current, oldModuleDelta, newModuleDelta, moduleFlowData, moduleMembers)

    def updateCodelengthOnMovingNode(
            self,
            current,
            oldModuleDelta,
            newModuleDelta,
            moduleFlowData,
            moduleMembers):
        return _infomap.MetaMapEquation_updateCodelengthOnMovingNode(
            self, current, oldModuleDelta, newModuleDelta, moduleFlowData, moduleMembers)

    def consolidateModules(self, modules):
        return _infomap.MetaMapEquation_consolidateModules(self, modules)

    def printDebug(self):
        return _infomap.MetaMapEquation_printDebug(self)
    codelength = property(
        _infomap.MetaMapEquation_codelength_get,
        _infomap.MetaMapEquation_codelength_set)
    indexCodelength = property(
        _infomap.MetaMapEquation_indexCodelength_get,
        _infomap.MetaMapEquation_indexCodelength_set)
    moduleCodelength = property(
        _infomap.MetaMapEquation_moduleCodelength_get,
        _infomap.MetaMapEquation_moduleCodelength_set)


# Register MetaMapEquation in _infomap:
_infomap.MetaMapEquation_swigregister(MetaMapEquation)


class InfomapCore(InfomapBase):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _infomap.InfomapCore_swiginit(self, _infomap.new_InfomapCore(*args))
    __swig_destroy__ = _infomap.delete_InfomapCore

    def toString(self, out):
        return _infomap.InfomapCore_toString(self, out)

    def getCodelength(self):
        return _infomap.InfomapCore_getCodelength(self)

    def getIndexCodelength(self):
        return _infomap.InfomapCore_getIndexCodelength(self)

    def getModuleCodelength(self):
        return _infomap.InfomapCore_getModuleCodelength(self)

    def getMetaCodelength(self, unweighted=False):
        return _infomap.InfomapCore_getMetaCodelength(self, unweighted)


# Register InfomapCore in _infomap:
_infomap.InfomapCore_swigregister(InfomapCore)


class map_uint_vector_uint(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def iterator(self):
        return _infomap.map_uint_vector_uint_iterator(self)

    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        return _infomap.map_uint_vector_uint___nonzero__(self)

    def __bool__(self):
        return _infomap.map_uint_vector_uint___bool__(self)

    def __len__(self):
        return _infomap.map_uint_vector_uint___len__(self)

    def __iter__(self):
        return self.key_iterator()

    def iterkeys(self):
        return self.key_iterator()

    def itervalues(self):
        return self.value_iterator()

    def iteritems(self):
        return self.iterator()

    def __getitem__(self, key):
        return _infomap.map_uint_vector_uint___getitem__(self, key)

    def __delitem__(self, key):
        return _infomap.map_uint_vector_uint___delitem__(self, key)

    def has_key(self, key):
        return _infomap.map_uint_vector_uint_has_key(self, key)

    def keys(self):
        return _infomap.map_uint_vector_uint_keys(self)

    def values(self):
        return _infomap.map_uint_vector_uint_values(self)

    def items(self):
        return _infomap.map_uint_vector_uint_items(self)

    def __contains__(self, key):
        return _infomap.map_uint_vector_uint___contains__(self, key)

    def key_iterator(self):
        return _infomap.map_uint_vector_uint_key_iterator(self)

    def value_iterator(self):
        return _infomap.map_uint_vector_uint_value_iterator(self)

    def __setitem__(self, *args):
        return _infomap.map_uint_vector_uint___setitem__(self, *args)

    def asdict(self):
        return _infomap.map_uint_vector_uint_asdict(self)

    def __init__(self, *args):
        _infomap.map_uint_vector_uint_swiginit(
            self, _infomap.new_map_uint_vector_uint(*args))

    def empty(self):
        return _infomap.map_uint_vector_uint_empty(self)

    def size(self):
        return _infomap.map_uint_vector_uint_size(self)

    def swap(self, v):
        return _infomap.map_uint_vector_uint_swap(self, v)

    def begin(self):
        return _infomap.map_uint_vector_uint_begin(self)

    def end(self):
        return _infomap.map_uint_vector_uint_end(self)

    def rbegin(self):
        return _infomap.map_uint_vector_uint_rbegin(self)

    def rend(self):
        return _infomap.map_uint_vector_uint_rend(self)

    def clear(self):
        return _infomap.map_uint_vector_uint_clear(self)

    def get_allocator(self):
        return _infomap.map_uint_vector_uint_get_allocator(self)

    def count(self, x):
        return _infomap.map_uint_vector_uint_count(self, x)

    def erase(self, *args):
        return _infomap.map_uint_vector_uint_erase(self, *args)

    def find(self, x):
        return _infomap.map_uint_vector_uint_find(self, x)

    def lower_bound(self, x):
        return _infomap.map_uint_vector_uint_lower_bound(self, x)

    def upper_bound(self, x):
        return _infomap.map_uint_vector_uint_upper_bound(self, x)
    __swig_destroy__ = _infomap.delete_map_uint_vector_uint


# Register map_uint_vector_uint in _infomap:
_infomap.map_uint_vector_uint_swigregister(map_uint_vector_uint)


class map_uint_string(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def iterator(self):
        return _infomap.map_uint_string_iterator(self)

    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        return _infomap.map_uint_string___nonzero__(self)

    def __bool__(self):
        return _infomap.map_uint_string___bool__(self)

    def __len__(self):
        return _infomap.map_uint_string___len__(self)

    def __iter__(self):
        return self.key_iterator()

    def iterkeys(self):
        return self.key_iterator()

    def itervalues(self):
        return self.value_iterator()

    def iteritems(self):
        return self.iterator()

    def __getitem__(self, key):
        return _infomap.map_uint_string___getitem__(self, key)

    def __delitem__(self, key):
        return _infomap.map_uint_string___delitem__(self, key)

    def has_key(self, key):
        return _infomap.map_uint_string_has_key(self, key)

    def keys(self):
        return _infomap.map_uint_string_keys(self)

    def values(self):
        return _infomap.map_uint_string_values(self)

    def items(self):
        return _infomap.map_uint_string_items(self)

    def __contains__(self, key):
        return _infomap.map_uint_string___contains__(self, key)

    def key_iterator(self):
        return _infomap.map_uint_string_key_iterator(self)

    def value_iterator(self):
        return _infomap.map_uint_string_value_iterator(self)

    def __setitem__(self, *args):
        return _infomap.map_uint_string___setitem__(self, *args)

    def asdict(self):
        return _infomap.map_uint_string_asdict(self)

    def __init__(self, *args):
        _infomap.map_uint_string_swiginit(
            self, _infomap.new_map_uint_string(*args))

    def empty(self):
        return _infomap.map_uint_string_empty(self)

    def size(self):
        return _infomap.map_uint_string_size(self)

    def swap(self, v):
        return _infomap.map_uint_string_swap(self, v)

    def begin(self):
        return _infomap.map_uint_string_begin(self)

    def end(self):
        return _infomap.map_uint_string_end(self)

    def rbegin(self):
        return _infomap.map_uint_string_rbegin(self)

    def rend(self):
        return _infomap.map_uint_string_rend(self)

    def clear(self):
        return _infomap.map_uint_string_clear(self)

    def get_allocator(self):
        return _infomap.map_uint_string_get_allocator(self)

    def count(self, x):
        return _infomap.map_uint_string_count(self, x)

    def erase(self, *args):
        return _infomap.map_uint_string_erase(self, *args)

    def find(self, x):
        return _infomap.map_uint_string_find(self, x)

    def lower_bound(self, x):
        return _infomap.map_uint_string_lower_bound(self, x)

    def upper_bound(self, x):
        return _infomap.map_uint_string_upper_bound(self, x)
    __swig_destroy__ = _infomap.delete_map_uint_string


# Register map_uint_string in _infomap:
_infomap.map_uint_string_swigregister(map_uint_string)


class pair_uint_uint(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _infomap.pair_uint_uint_swiginit(
            self, _infomap.new_pair_uint_uint(*args))
    first = property(
        _infomap.pair_uint_uint_first_get,
        _infomap.pair_uint_uint_first_set)
    second = property(
        _infomap.pair_uint_uint_second_get,
        _infomap.pair_uint_uint_second_set)

    def __len__(self):
        return 2

    def __repr__(self):
        return str((self.first, self.second))

    def __getitem__(self, index):
        if not (index % 2):
            return self.first
        else:
            return self.second

    def __setitem__(self, index, val):
        if not (index % 2):
            self.first = val
        else:
            self.second = val
    __swig_destroy__ = _infomap.delete_pair_uint_uint


# Register pair_uint_uint in _infomap:
_infomap.pair_uint_uint_swigregister(pair_uint_uint)


class map_pair_uint_uint_double(object):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def iterator(self):
        return _infomap.map_pair_uint_uint_double_iterator(self)

    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        return _infomap.map_pair_uint_uint_double___nonzero__(self)

    def __bool__(self):
        return _infomap.map_pair_uint_uint_double___bool__(self)

    def __len__(self):
        return _infomap.map_pair_uint_uint_double___len__(self)

    def __iter__(self):
        return self.key_iterator()

    def iterkeys(self):
        return self.key_iterator()

    def itervalues(self):
        return self.value_iterator()

    def iteritems(self):
        return self.iterator()

    def __getitem__(self, key):
        return _infomap.map_pair_uint_uint_double___getitem__(self, key)

    def __delitem__(self, key):
        return _infomap.map_pair_uint_uint_double___delitem__(self, key)

    def has_key(self, key):
        return _infomap.map_pair_uint_uint_double_has_key(self, key)

    def keys(self):
        return _infomap.map_pair_uint_uint_double_keys(self)

    def values(self):
        return _infomap.map_pair_uint_uint_double_values(self)

    def items(self):
        return _infomap.map_pair_uint_uint_double_items(self)

    def __contains__(self, key):
        return _infomap.map_pair_uint_uint_double___contains__(self, key)

    def key_iterator(self):
        return _infomap.map_pair_uint_uint_double_key_iterator(self)

    def value_iterator(self):
        return _infomap.map_pair_uint_uint_double_value_iterator(self)

    def __setitem__(self, *args):
        return _infomap.map_pair_uint_uint_double___setitem__(self, *args)

    def asdict(self):
        return _infomap.map_pair_uint_uint_double_asdict(self)

    def __init__(self, *args):
        _infomap.map_pair_uint_uint_double_swiginit(
            self, _infomap.new_map_pair_uint_uint_double(*args))

    def empty(self):
        return _infomap.map_pair_uint_uint_double_empty(self)

    def size(self):
        return _infomap.map_pair_uint_uint_double_size(self)

    def swap(self, v):
        return _infomap.map_pair_uint_uint_double_swap(self, v)

    def begin(self):
        return _infomap.map_pair_uint_uint_double_begin(self)

    def end(self):
        return _infomap.map_pair_uint_uint_double_end(self)

    def rbegin(self):
        return _infomap.map_pair_uint_uint_double_rbegin(self)

    def rend(self):
        return _infomap.map_pair_uint_uint_double_rend(self)

    def clear(self):
        return _infomap.map_pair_uint_uint_double_clear(self)

    def get_allocator(self):
        return _infomap.map_pair_uint_uint_double_get_allocator(self)

    def count(self, x):
        return _infomap.map_pair_uint_uint_double_count(self, x)

    def erase(self, *args):
        return _infomap.map_pair_uint_uint_double_erase(self, *args)

    def find(self, x):
        return _infomap.map_pair_uint_uint_double_find(self, x)

    def lower_bound(self, x):
        return _infomap.map_pair_uint_uint_double_lower_bound(self, x)

    def upper_bound(self, x):
        return _infomap.map_pair_uint_uint_double_upper_bound(self, x)
    __swig_destroy__ = _infomap.delete_map_pair_uint_uint_double


# Register map_pair_uint_uint_double in _infomap:
_infomap.map_pair_uint_uint_double_swigregister(map_pair_uint_uint_double)


class InfomapWrapper(InfomapCore):
    thisown = property(
        lambda x: x.this.own(),
        lambda x,
        v: x.this.own(v),
        doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        _infomap.InfomapWrapper_swiginit(
            self, _infomap.new_InfomapWrapper(*args))
    __swig_destroy__ = _infomap.delete_InfomapWrapper

    def readInputData(self, *args):
        return _infomap.InfomapWrapper_readInputData(self, *args)

    def addNode(self, *args):
        return _infomap.InfomapWrapper_addNode(self, *args)

    def addName(self, id, name):
        return _infomap.InfomapWrapper_addName(self, id, name)

    def getName(self, id):
        return _infomap.InfomapWrapper_getName(self, id)

    def getNames(self):
        return _infomap.InfomapWrapper_getNames(self)

    def addPhysicalNode(self, *args):
        return _infomap.InfomapWrapper_addPhysicalNode(self, *args)

    def addStateNode(self, id, physId):
        return _infomap.InfomapWrapper_addStateNode(self, id, physId)

    def addLink(self, *args):
        return _infomap.InfomapWrapper_addLink(self, *args)

    def addMultilayerLink(self, layer1, n1, layer2, n2, weight=1.0):
        return _infomap.InfomapWrapper_addMultilayerLink(
            self, layer1, n1, layer2, n2, weight)

    def setBipartiteStartId(self, startId):
        return _infomap.InfomapWrapper_setBipartiteStartId(self, startId)

    def getLinks(self, flow):
        return _infomap.InfomapWrapper_getLinks(self, flow)

    def getModules(self, level=1, states=False):
        return _infomap.InfomapWrapper_getModules(self, level, states)

    def getMultilevelModules(self, states=False):
        return _infomap.InfomapWrapper_getMultilevelModules(self, states)

    def codelength(self):
        return _infomap.InfomapWrapper_codelength(self)

    def iterLeafNodes(self, *args):
        return _infomap.InfomapWrapper_iterLeafNodes(self, *args)

    def iterTree(self, *args):
        return _infomap.InfomapWrapper_iterTree(self, *args)

    def run(self, *args):
        return _infomap.InfomapWrapper_run(self, *args)

    def getModules(self, level=1, states=False):
        return dict(_infomap.InfomapWrapper_getModules(self, level, states))

    def getMultilevelModules(self, states=False):
        return dict(_infomap.InfomapWrapper_getMultilevelModules(self, states))

    def getNames(self):
        return dict(_infomap.InfomapWrapper_getNames(self))

    def getLinks(self, flow=False):
        return dict(_infomap.InfomapWrapper_getLinks(self, flow))


# Register InfomapWrapper in _infomap:
_infomap.InfomapWrapper_swigregister(InfomapWrapper)


try:
    from math import log2
except ImportError:
    # Python < 3.3
    from math import log

    def log2(p):
        return log(p, 2.0)

if __name__ != "__main__":
    try:
        import pandas
    except ImportError:
        pandas = None


MultilayerNode = namedtuple("MultilayerNode", "layer_id, node_id")


def plogp(p):
    return (x * log2(x) if x > 0 else 0 for x in p)


def entropy(p):
    return -sum(plogp(p))


def perplexity(p):
    return 2 ** entropy(p)


_DEFAULT_META_DATA_RATE = 1
_DEFAULT_VERBOSITY_LEVEL = 1
_DEFAULT_TELEPORTATION_PROB = 0.15
_DEFAULT_MULTILAYER_RELAX_RATE = 0.15
_DEFAULT_SEED = 123
_DEFAULT_CORE_LOOP_CODELENGTH_THRESHOLD = 1e-10
_DEFAULT_TUNE_ITER_RELATIVE_THRESHOLD = 1e-5


def _construct_args(args=None,
                    # input
                    cluster_data=None,
                    no_infomap=False,
                    input_format=None,
                    skip_adjust_bipartite_flow=False,
                    bipartite_teleportation=False,
                    weight_threshold=None,
                    include_self_links=False,
                    node_limit=None,
                    assign_to_neighbouring_module=False,
                    meta_data=None,
                    meta_data_rate=_DEFAULT_META_DATA_RATE,
                    meta_data_unweighted=False,
                    # output
                    tree=False,
                    ftree=False,
                    clu=False,
                    verbosity_level=_DEFAULT_VERBOSITY_LEVEL,
                    silent=False,
                    out_name=None,
                    no_file_output=False,
                    clu_level=None,
                    output=None,
                    hide_bipartite_nodes=False,
                    # algorithm
                    two_level=False,
                    flow_model=None,
                    directed=False,
                    use_node_weights_as_flow=False,
                    to_nodes=False,
                    teleportation_probability=_DEFAULT_TELEPORTATION_PROB,
                    markov_time=1,
                    preferred_number_of_modules=None,
                    multilayer_relax_rate=_DEFAULT_MULTILAYER_RELAX_RATE,
                    multilayer_relax_limit=-1,
                    multilayer_relax_limit_up=-1,
                    multilayer_relax_limit_down=-1,
                    multilayer_relax_by_jsd=False,
                    # accuracy
                    seed=_DEFAULT_SEED,
                    num_trials=1,
                    core_loop_limit=10,
                    core_level_limit=None,
                    tune_iteration_limit=None,
                    core_loop_codelength_threshold=_DEFAULT_CORE_LOOP_CODELENGTH_THRESHOLD,
                    tune_iteration_relative_threshold=_DEFAULT_TUNE_ITER_RELATIVE_THRESHOLD,
                    fast_hierarchical_solution=None,
                    prefer_modular_solution=False,
                    inner_parallelization=False):
    if args is None:
        args = ""

# input
    if cluster_data is not None:
        args += " --cluster-data {}".format(cluster_data)

    if no_infomap:
        args += " --no-infomap"

    if input_format is not None:
        args += " --input-format {}".format(input_format)

    if skip_adjust_bipartite_flow:
        args += " --skip-adjust-bipartite-flow"

    if bipartite_teleportation:
        args += " --bipartite-teleportation"

    if weight_threshold is not None:
        args += " --weight-threshold {}".format(weight_threshold)

    if include_self_links:
        args += " --include-self-links"

    if node_limit is not None:
        args += " --node-limit {}".format(node_limit)

    if assign_to_neighbouring_module:
        args += " --assign-to-neightbouring-module"

    if meta_data is not None:
        args += " --meta-data {}".format(meta_data)

    if meta_data_rate != _DEFAULT_META_DATA_RATE:
        args += " --meta-data-rate {}".format(meta_data_rate)

    if meta_data_unweighted:
        args += " --meta-data-unweighted"

# output
    if tree:
        args += " --tree"

    if ftree:
        args += " --ftree"

    if clu:
        args += " --clu"

    if verbosity_level > 1:
        args += " -{}".format("v" * verbosity_level)

    if silent:
        args += " --silent"

    if out_name is not None:
        args += " --out-name {}".format(out_name)

    if no_file_output:
        args += " --no-file-output"

    if clu_level is not None:
        args += " --clu-level {}".format(clu_level)

    if output is not None:
        args += " --output {}".format(",".join(output))

    if hide_bipartite_nodes:
        args += " --hide-bipartite-nodes"

# algorithm
    if two_level:
        args += " --two-level"

    if flow_model is not None:
        args += " --flow-model {}".format(flow_model)

    if directed:
        args += " --directed"

    if use_node_weights_as_flow:
        args += " --use-node-weights-as-flow"

    if to_nodes:
        args += " --to-nodes"

    if teleportation_probability != _DEFAULT_TELEPORTATION_PROB:
        args += " --teleportation-probability {}".format(
            teleportation_probability)

    if markov_time != 1:
        args += " --markov-time {}".format(markov_time)

    if preferred_number_of_modules is not None:
        args += " --preferred-number-of-modules {}".format(
            preferred_number_of_modules)

    if multilayer_relax_rate != _DEFAULT_MULTILAYER_RELAX_RATE:
        args += " --multilayer-relax-rate {}".format(multilayer_relax_rate)

    if multilayer_relax_limit != -1:
        args += " --multilayer-relax-limit {}".format(multilayer_relax_limit)

    if multilayer_relax_limit_up != -1:
        args += " --multilayer-relax-limit-up {}".format(
            multilayer_relax_limit_up)

    if multilayer_relax_limit_down != -1:
        args += " --multilayer-relax-limit-down {}".format(
            multilayer_relax_limit_down)

    if multilayer_relax_by_jsd:
        args += " --multilayer-relax-by-jsd"

# accuracy
    if seed != _DEFAULT_SEED:
        args += " --seed {}".format(seed)

    if num_trials != 1:
        args += " --num-trials {}".format(num_trials)

    if core_loop_limit != 10:
        args += " --core-loop-limit {}".format(core_loop_limit)

    if core_level_limit is not None:
        args += " --core-level-limit {}".format(core_level_limit)

    if tune_iteration_limit is not None:
        args += " --tune-iteration-limit {}".format(tune_iteration_limit)

    if core_loop_codelength_threshold != _DEFAULT_CORE_LOOP_CODELENGTH_THRESHOLD:
        args += " --core-loop-codelength-threshold {}".format(
            core_loop_codelength_threshold)

    if tune_iteration_relative_threshold != _DEFAULT_TUNE_ITER_RELATIVE_THRESHOLD:
        args += " --tune-iteration-relative-threshold {}".format(
            tune_iteration_relative_threshold)

    if fast_hierarchical_solution is not None:
        args += " -{}".format("F" * fast_hierarchical_solution)

    if prefer_modular_solution:
        args += " --prefer-modular-solution"

    if inner_parallelization:
        args += " --inner-parallelization"

    return args


class Infomap(InfomapWrapper):
    """Infomap

    This class is a thin wrapper around Infomap C++ compiled with SWIG.

    Examples
    --------
    Create an instance and add nodes and links:

    >>> from infomap import Infomap
    >>> im = Infomap(silent=True)
    >>> im.add_node(1)
    >>> im.add_node(2)
    >>> im.add_link(1, 2)
    >>> im.run()
    >>> im.codelength
    1.0


    Create an instance and read a network file:

    >>> from infomap import Infomap
    >>> im = Infomap(silent=True, num_trials=10)
    >>> im.read_file("ninetriangles.net")
    >>> im.run()
    >>> tol = 1e-4
    >>> abs(im.codelength - 3.4622731375264144) < tol
    True


    For more examples, see the examples directory.
    """

    def __init__(self, args=None, **kwargs):
        """Create a new Infomap instance.

        Parameters
        ----------
        args : str, optional
            String of Infomap arguments.

        Keyword Arguments
        -----------------
        cluster_data : str, optional
            Provide an initial two-level (clu format) or multi-layer (tree
            format) solution.
        no_infomap : bool, optional
            Don't run the optimizer. Useful to calculate codelength of provided
            cluster data or to print non-modular statistics.
        input_format : str, optional
            Override automatically recognized types. Options: pajek, link-list,
            bipartite, multilayer, states.
        skip_adjust_bipartite_flow : bool, optional
            Skip distributing all flow from the bipartite nodes to the primary
            nodes.
        bipartite_teleportation : bool, optional
            Teleport like the bipartite flow instead of two-step (unipartite)
            teleportation.
        weight_threshold : float, optional
            Limit the number of links to read from the network. Ignore links
            with less weight than the threshold.
        include_self_links : bool, optional
            Include links with the same source and target node.
        node_limit : int, optional
            Limit the number of nodes to read from the network. Ignore links
            connected to ignored nodes.
        assign_to_neighbouring_module : bool, optional
            Assign nodes without module assignments (from ``cluster_data``) to
            the module assignment of a neighbouring node if possible.
        meta_data : str, optional
            Provide meta data (clu format) that should be encoded.
        meta_data_rate : float, optional
            Metadata encoding rate. Default is to encode each step.
        meta_data_unweighted : bool, optional
            Don't weight meta data by node flow.
        tree : bool, optional
            Write a tree file with the modular hierarchy. Automatically enabled
            if no other output is specified.
        ftree : bool, optional
            Write a ftree file with the modular hierarchy including aggregated
            links between (nested) modules.
        clu : bool, optional
            Write a clu file with the top cluster ids for each node.
        verbosity_level : int, optional
            Verbose output on the console.
        silent : bool, optional
            No output on the console.
        out_name : str, optional
            Name for the output files, e.g.
            ``"[output_directory]/[out-name].tree"``
        no_file_output : bool, optional
            Don't write output to file.
        clu_level : int, optional
            For clu output, print modules at specified depth from root.
            Use ``-1`` for bottom level modules.
        output : list(str), optional
            List of output formats.
            Options: clu, tree, ftree, newick, json, csv, network, states.
        hide_bipartite_nodes : bool, optional
            Project bipartite solution to unipartite.
        two_level : bool, optional
            Optimize a two-level partition of the network.
            Default (``false``) is multi-level.
        flow_model : str, optional
            Specify flow model.
            Options: undirected, directed, undirdir, outdirdir, rawdir.
        directed : bool, optional
            Assume directed links. Shorthand for ``flow_model="directed"``.
        use_node_weights_as_flow : bool, optional
            Use node weights (from api or after names in Pajek format) as flow,
            normalized to sum to 1.
        to_nodes : bool, optional
            Teleport to nodes instead of to links, assuming uniform node
            weights if no such input data.
        teleportation_probability : float, optional
            Probability of teleporting to a random node or link.
        markov_time : float, optional
            Scales link flow to change the cost of moving between modules.
            Higher values results in fewer modules.
        preferred_number_of_modules : int, optional
            Penalize solutions the more they differ from this number.
        multilayer_relax_rate : float, optional
            Probability to relax the constraint to move only in the current
            layer.
        multilayer_relax_limit : int, optional
            Number of neighboring layers in each direction to relax to.
            If negative, relax to any layer.
        multilayer_relax_limit_up : int, optional
            Number of neighboring layers with higher id to relax to.
            If negative, relax to any layer.
        multilayer_relax_limit_down : int, optional
            Number of neighboring layers with lower id to relax to.
            If negative, relax to any layer.
        multilayer_relax_by_jsd : bool, optional
            Relax proportional to the out-link similarity measured by the
            Jensen-Shannon divergence.
        seed : int, optional
            A seed (integer) to the random number generator for reproducible
            results.
        num_trials : int, optional
            Number of outer-most loops to run before picking the best solution.
        core_loop_limit : int, optional
            Limit the number of loops that tries to move each node into the
            best possible module.
        core_level_limit : int, optional
            Limit the number of times the core loops are reapplied on existing
            modular network to search bigger structures.
        tune_iteration_limit : int, optional
            Limit the number of main iterations in the two-level partition
            algorithm. 0 means no limit.
        core_loop_codelength_threshold : float, optional
            Minimum codelength threshold for accepting a new solution in core
            loop.
        tune_iteration_relative_threshold : float, optional
            Set codelength improvement threshold of each new tune iteration to
            ``f`` times the initial two-level codelength.
        fast_hierarchical_solution : int, optional
            Find top modules fast. Use ``2`` to keep all fast levels.
            Use ``3`` to skip recursive part.
        prefer_modular_solution : bool, optional
            Prefer modular solutions even if they are worse than putting all
            nodes in one module.
        inner_parallelization : bool, optional
            Parallelize the inner-most loop for greater speed.
            This may give some accuracy tradeoff.
        """
        super().__init__(_construct_args(args, **kwargs))

# ----------------------------------------
# Input
# ----------------------------------------

    def read_file(self, filename, accumulate=True):
        """Read network data from file.

        Parameters
        ----------
        filename : str
        accumulate : bool, optional
            If the network data should be accumulated to already added
            nodes and links. Default ``True``.
        """
        return super().readInputData(filename, accumulate)

    def add_node(self, node_id, name=None, teleportation_weight=None):
        """Add a node.

        See Also
        --------
        set_name
        add_nodes

        Parameters
        ----------
        node_id : int
        name : str, optional
        teleportation_weight : float, optional
            Used for teleporting between layers in multilayer networks.
        """
        if name is None:
            name = ""

        if len(name) and teleportation_weight is not None:
            return super().addNode(node_id, name, teleportation_weight)
        elif len(name) and teleportation_weight is None:
            return super().addNode(node_id, name)
        elif not len(name) and teleportation_weight is not None:
            return super().addNode(node_id, teleportation_weight)

        return super().addNode(node_id)

    def add_nodes(self, nodes):
        """Add several nodes.

        See Also
        --------
        add_node

        Examples
        --------
        Add nodes

        >>> from infomap import Infomap
        >>> im = Infomap()
        >>> im.add_nodes(range(4))


        Add named nodes

        >>> from infomap import Infomap
        >>> im = Infomap()
        >>> nodes = (
        ...     (1, "Node 1"),
        ...     (2, "Node 2"),
        ...     (3, "Node 3")
        ... )
        >>> im.add_nodes(nodes)


        Parameters
        ----------
        nodes : iterable of tuples or iterable of int
            Iterable of tuples on the form
            ``(node_id, [name], [teleportation_weight])``
        """
        for node in nodes:
            if isinstance(node, int):
                self.add_node(node)
            else:
                self.add_node(*node)

    def add_state_node(self, state_id, node_id):
        """Add a state node.

        Notes
        -----
        If a physical node with id node_id does not exist, it will be created.
        If you want to name the physical node, use ``set_name``.

        Parameters
        ----------
        state_id : int
        node_id : int
            Id of the physical node the state node should be added to.
        """
        return super().addStateNode(state_id, node_id)

    def add_state_nodes(self, state_nodes):
        """Add several state nodes.

        See Also
        --------
        add_state_node

        Examples
        --------

        >>> from infomap import Infomap
        >>> im = Infomap()
        >>> states = (
        ...     (1, 1),
        ...     (2, 1),
        ...     (3, 2)
        ... )
        >>> im.add_state_nodes(states)


        Parameters
        ----------
        state_nodes : iterable of tuples
            Iterable of tuples of the form ``(state_id, node_id)``
        """
        for node in state_nodes:
            self.add_state_node(*node)

    def set_name(self, node_id, name):
        """Set the name of a node.

        Parameters
        ----------
        node_id : int
        name : str
        """
        if name is None:
            name = ""
        return super().addName(node_id, name)

    def set_names(self, names):
        """Set names to several nodes at once.

        Examples
        --------

        >>> from infomap import Infomap
        >>> im = Infomap()
        >>> names = (
        ...     (1, "Node 1"),
        ...     (2, "Node 2")
        ... )
        >>> im.set_names(names)


        See Also
        --------
        set_name

        Parameters
        ----------
        names : iterable of tuples
            Iterable of tuples on the form ``(node_id, name)``.
        """
        for name in names:
            self.set_name(*name)

    def add_link(self, source_id, target_id, weight=1.0):
        """Add a link.

        Notes
        -----
        If the source or target nodes does not exist, they will be created.

        See Also
        --------
        remove_link

        Parameters
        ----------
        source_id : int
        target_id : int
        weight : float, optional
        """
        return super().addLink(source_id, target_id, weight)

    def add_links(self, links):
        """Add several links.

        Examples
        --------

        >>> from infomap import Infomap
        >>> im = Infomap()
        >>> links = (
        ...     (1, 2),
        ...     (1, 3)
        ... )
        >>> im.add_links(links)


        See Also
        --------
        add_link
        remove_link

        Parameters
        ----------
        links : iterable of tuples
            Iterable of tuples of int of the form
            ``(source_id, target_id, [weight])``
        """
        for link in links:
            self.add_link(*link)

    def remove_link(self, source_id, target_id):
        """Remove a link.

        Notes
        -----
        Removing links will not remove nodes if they become disconnected.

        See Also
        --------
        add_link

        Parameters
        ----------
        source_id : int
        target_id : int
        """
        return self.network.removeLink(source_id, target_id)

    def remove_links(self, links):
        """Remove several links.

        Examples
        --------

        >>> from infomap import Infomap
        >>> im = Infomap()
        >>> links = (
        ...     (1, 2),
        ...     (1, 3)
        ... )
        >>> im.add_links(links)
        >>> im.remove_links(links)
        >>> im.num_links
        0


        See Also
        --------
        remove_link

        Parameters
        ----------
        links : iterable of tuples
            Iterable of tuples of the form ``(source_id, target_id)``
        """
        for link in links:
            self.remove_link(*link)

    def add_multilayer_link(
            self,
            source_multilayer_node,
            target_multilayer_node,
            weight=1.0):
        """Add a multilayer link.

        Adds a link between layers in a multilayer network.

        Parameters
        ----------
        source_multilayer_node : tuple of int, or MultilayerNode
            If passed a tuple, it should be of the format
            ``(layer_id, node_id)``.
        target_multilayer_node : tuple of int, or MultilayerNode
            If passed a tuple, it should be of the format
            ``(layer_id, node_id)``.
        weight : float, optional

        Examples
        --------
        Usage with tuples:

        >>> from infomap import Infomap
        >>> im = Infomap()
        >>> source_multilayer_node = (0, 1) # layer_id, node_id
        >>> target_multilayer_node = (1, 2) # layer_id, node_id
        >>> im.add_multilayer_link(source_multilayer_node, target_multilayer_node)


        Usage with MultilayerNode

        >>> from infomap import Infomap, MultilayerNode
        >>> im = Infomap()
        >>> source_multilayer_node = MultilayerNode(layer_id=0, node_id=1)
        >>> target_multilayer_node = MultilayerNode(layer_id=1, node_id=2)
        >>> im.add_multilayer_link(source_multilayer_node, target_multilayer_node)


        """
        source_layer_id, source_node_id = source_multilayer_node
        target_layer_id, target_node_id = target_multilayer_node
        return super().addMultilayerLink(source_layer_id,
                                         source_node_id,
                                         target_layer_id,
                                         target_node_id,
                                         weight)

    def add_multilayer_links(self, links):
        """Add several multilayer links.

        Examples
        --------

        >>> from infomap import Infomap
        >>> im = Infomap()
        >>> links = (
        ...     ((0, 1), (1, 2)),
        ...     ((0, 3), (1, 2))
        ... )
        >>> im.add_multilayer_links(links)


        See Also
        --------
        add_multilayer_link

        Parameters
        ----------
        links : iterable of tuples
            Iterable of tuples of the form
            ``(source_node, target_node, [weight])``
        """
        for link in links:
            self.add_multilayer_link(*link)

    def remove_multilayer_link(self):
        raise NotImplementedError

    def set_meta_data(self, node_id, meta_category):
        """Set meta data to a node.

        Parameters
        ----------
        node_id : int
        meta_category : int
        """
        return self.network.addMetaData(node_id, meta_category)

    def add_networkx_graph(self, g, weight="weight"):
        """Add NetworkX graph

        Examples
        --------

        >>> import networkx as nx
        >>> from infomap import Infomap
        >>> G = nx.Graph([("a", "b"), ("a", "c")])
        >>> im = Infomap(silent=True)
        >>> mapping = im.add_networkx_graph(G)
        >>> mapping
        {0: 'a', 1: 'b', 2: 'c'}
        >>> im.run()
        >>> for node in im.nodes:
        ...     print(node.node_id, node.module_id, node.flow, mapping[node.node_id])
        0 1 0.5 a
        1 1 0.25 b
        2 1 0.25 c

        Notes
        -----
        Transforms non-int labels to unique int ids.
        Assumes that all nodes are of the same type.
        If node type is string, they are added as names
        to Infomap.

        Parameters
        ----------
        g : nx.Graph
            A NetworkX graph
        weight : str, optional
            Key to lookup link weight in edge data if present.
            Default ``"weight"``.

        Returns
        -------
        dict
            Dict with the node ids as keys and labels as values.
        """
        try:
            first = next(iter(g.nodes))
        except StopIteration:
            return dict()

        if isinstance(first, int):
            node_map = {node: node for node in g.nodes}
        else:
            node_map = {label: node for node, label in enumerate(g.nodes)}

        is_string_id = isinstance(first, str)

        for label, node in node_map.items():
            self.add_node(node, name=label if is_string_id else None)

        for source, target, data in g.edges(data=True):
            u, v = node_map[source], node_map[target]
            w = data[weight] if weight is not None and weight in data else 1.0
            self.add_link(u, v, w)

        return {node: label for label, node in node_map.items()}

# ----------------------------------------
# Run
# ----------------------------------------

    @property
    def bipartite_start_id(self):
        """Get or set the bipartite start id.

        Examples
        --------

        >>> from infomap import Infomap
        >>> im = Infomap(silent=True, num_trials=10)
        >>> im.add_node(1, "Left 1")
        >>> im.add_node(2, "Left 2")
        >>> im.bipartite_start_id = 3
        >>> im.add_node(3, "Right 3")
        >>> im.add_node(4, "Right 4")
        >>> im.add_link(1, 3)
        >>> im.add_link(1, 4)
        >>> im.add_link(2, 4)
        >>> im.run()
        >>> tol = 1e-4
        >>> abs(im.codelength - 0.9182958340544896) < tol
        True


        Parameters
        ----------
        start_id : int
            The node id where the second node type starts.

        Returns
        -------
        int
            The node id where the second node type starts.
        """
        return self.network.bipartiteStartId()

    @bipartite_start_id.setter
    def bipartite_start_id(self, start_id):
        super().setBipartiteStartId(start_id)

    @property
    def initial_partition(self):
        """Get or set the initial partition.

        This is a initial configuration of nodes into modules where Infomap
        will start the optimizer.

        Examples
        --------

        >>> from infomap import Infomap
        >>> im = Infomap(silent=True)
        >>> im.add_node(1)
        >>> im.add_node(2)
        >>> im.add_node(3)
        >>> im.add_node(4)
        >>> im.add_link(1, 2)
        >>> im.add_link(1, 3)
        >>> im.add_link(2, 3)
        >>> im.add_link(2, 4)
        >>> im.initial_partition = {
        ...     1: 0,
        ...     2: 0,
        ...     3: 1,
        ...     4: 1
        ... }
        >>> im.no_infomap = True
        >>> im.run()
        >>> tol = 1e-4
        >>> abs(im.codelength - 3.4056390622295662) < tol
        True


        Notes
        -----
        The initial partition is saved between runs.
        If you want to use an initial partition for one run only,
        use ``run(initial_partition=partition)``.

        Parameters
        ----------
        module_ids : dict of int, or None
            Dict with node ids as keys and module ids as values.

        Returns
        -------
        dict of int
            Dict with node ids as keys and module ids as values.
        """
        return super().getInitialPartition()

    @initial_partition.setter
    def initial_partition(self, module_ids):
        if module_ids is None:
            module_ids = {}
        super().setInitialPartition(module_ids)

    @contextmanager
    def _initial_partition(self, partition):
        # Internal use only
        # Store the possiply set initial partition
        # and use the new initial partition for one run only.
        old_partition = self.initial_partition
        try:
            self.initial_partition = partition
            yield
        finally:
            self.initial_partition = old_partition

    @property
    def no_infomap(self):
        """Set wether the optimizer should run or not.

        Parameters
        ----------
        no_infomap : bool
        """
        return super().noInfomap

    @no_infomap.setter
    def no_infomap(self, no_infomap):
        super().setNoInfomap(no_infomap)

    def run(self, args=None, initial_partition=None, **kwargs):
        """Run Infomap.

        Parameters
        ----------
        args : str, optional
            Space delimited parameter list (see Infomap documentation).
        initial_partition : dict, optional
            Initial partition to start optimizer from.
            (See ``initial_partition``).

        Keyword Arguments
        -----------------
        tree : bool, optional
            Write a tree file with the modular hierarchy. Automatically enabled
            if no other output is specified.
        ftree : bool, optional
            Write a ftree file with the modular hierarchy including aggregated
            links between (nested) modules.
        clu : bool, optional
            Write a clu file with the top cluster ids for each node.
        verbosity_level : int, optional
            Verbose output on the console.
        silent : bool, optional
            No output on the console.
        out_name : str, optional
            Name for the output files, e.g.
            ``"[output_directory]/[out-name].tree"``
        no_file_output : bool, optional
            Don't write output to file.
        clu_level : int, optional
            For clu output, print modules at specified depth from root.
            Use ``-1`` for bottom level modules.
        output : list(str), optional
            List of output formats.
            Options: clu, tree, ftree, newick, json, csv, network, states.
        hide_bipartite_nodes : bool, optional
            Project bipartite solution to unipartite.
        two_level : bool, optional
            Optimize a two-level partition of the network.
            Default (``false``) is multi-level.
        flow_model : str, optional
            Specify flow model.
            Options: undirected, directed, undirdir, outdirdir, rawdir.
        directed : bool, optional
            Assume directed links. Shorthand for ``flow_model="directed"``.
        use_node_weights_as_flow : bool, optional
            Use node weights (from api or after names in Pajek format) as flow,
            normalized to sum to 1.
        to_nodes : bool, optional
            Teleport to nodes instead of to links, assuming uniform node
            weights if no such input data.
        teleportation_probability : float, optional
            Probability of teleporting to a random node or link.
        markov_time : float, optional
            Scales link flow to change the cost of moving between modules.
            Higher values results in fewer modules.
        preferred_number_of_modules : int, optional
            Penalize solutions the more they differ from this number.
        multilayer_relax_rate : float, optional
            Probability to relax the constraint to move only in the current
            layer.
        multilayer_relax_limit : int, optional
            Number of neighboring layers in each direction to relax to.
            If negative, relax to any layer.
        multilayer_relax_limit_up : int, optional
            Number of neighboring layers with higher id to relax to.
            If negative, relax to any layer.
        multilayer_relax_limit_down : int, optional
            Number of neighboring layers with lower id to relax to.
            If negative, relax to any layer.
        multilayer_relax_by_jsd : bool, optional
            Relax proportional to the out-link similarity measured by the
            Jensen-Shannon divergence.
        seed : int, optional
            A seed (integer) to the random number generator for reproducible
            results.
        num_trials : int, optional
            Number of outer-most loops to run before picking the best solution.
        core_loop_limit : int, optional
            Limit the number of loops that tries to move each node into the
            best possible module.
        core_level_limit : int, optional
            Limit the number of times the core loops are reapplied on existing
            modular network to search bigger structures.
        tune_iteration_limit : int, optional
            Limit the number of main iterations in the two-level partition
            algorithm. 0 means no limit.
        core_loop_codelength_threshold : float, optional
            Minimum codelength threshold for accepting a new solution in core
            loop.
        tune_iteration_relative_threshold : float, optional
            Set codelength improvement threshold of each new tune iteration to
            ``f`` times the initial two-level codelength.
        fast_hierarchical_solution : int, optional
            Find top modules fast. Use ``2`` to keep all fast levels.
            Use ``3`` to skip recursive part.
        prefer_modular_solution : bool, optional
            Prefer modular solutions even if they are worse than putting all
            nodes in one module.
        inner_parallelization : bool, optional
            Parallelize the inner-most loop for greater speed.
            This may give some accuracy tradeoff.

        See Also
        --------
        initial_partition
        """
        args = _construct_args(args, **kwargs)

        if initial_partition:
            with self._initial_partition(initial_partition):
                return super().run(args)

        return super().run(args)

# ----------------------------------------
# Iterators/Output
# ----------------------------------------

    def get_modules(self, depth_level=1, states=False):
        """Get the modules for a given depth in the hierarchical tree.

        Parameters
        ----------
        depth_level : int, optional
            The level in the hierarchical tree. Set to ``1`` (default) to
            return the top modules (coarsest level). Set to ``2`` for second
            coarsest level etc. Set to ``-1`` to return the bottom level
            modules (finest level). Default ``1``.
        states : bool, optional
            For higher-order networks, if ``states`` is True, it will iterate
            over state nodes. Otherwise it will iterate over physical nodes,
            merging state nodes with same ``node_id`` if they are in the same
            module. Note that the same physical node may end up on different
            paths in the tree.
            See notes on ``physical_tree``. Default ``false``.

        Returns
        -------
        dict of int
            Dict with node ids as keys and module ids as values.
        """
        return super().getModules(depth_level, states)

    def get_multilevel_modules(self, states=False):
        """Get all the modules.

        Parameters
        ----------
        states : bool, optional
            For higher-order networks, if ``states`` is True, it will iterate
            over state nodes. Otherwise it will iterate over physical nodes,
            merging state nodes with same ``node_id`` if they are in the same
            module. Note that the same physical node may end up on different
            paths in the tree.
            See notes on ``physical_tree``. Default ``false``.

        Returns
        -------
        dict of list of int
            Dict with node ids as keys and list of module ids as values.
        """
        return super().getMultilevelModules(states)

    @property
    def modules(self):
        """A view of the (top-level) modules, mapping
        ``node_id`` to ``module_id``.

        Notes
        -----
        In a higher-order network, a physical node (defined by ``node_id``)
        may partially exist in multiple modules. However, the ``node_id``
        can not exist multiple times as a key in the node-to-module map,
        so only one occurrence of a physical node will be retrieved.
        To get all states, use ``get_modules(states=True)``.

        See Also
        --------
        get_modules

        Examples
        --------
        >>> from infomap import Infomap
        >>> im = Infomap(silent=True, num_trials=5)
        >>> im.read_file("ninetriangles.net")
        >>> im.run()
        >>> for node_id, module_id in im.modules:
        ...     print(node_id, module_id)
        ...
        1 2
        2 2
        3 2
        4 2
        5 2
        6 2
        7 2
        8 2
        9 2
        10 3
        11 3
        12 3
        13 5
        14 5
        15 5
        16 4
        17 4
        18 4
        19 1
        20 1
        21 1
        22 1
        23 1
        24 1
        25 1
        26 1
        27 1

        See Also
        --------
        get_modules

        Yields
        -------
        tuple of int, int
            An iterator of ``(node_id, module_id)`` pairs.
        """
        return self.get_modules(depth_level=1, states=False).items()

    def get_tree(self, depth_level=1, states=False):
        """A view of the tree

        Parameters
        ----------
        depth_level : int, optional
            The module level returned by ``iterator.module_id``. Set to ``1``
            (default) to return the top modules (coarsest level). Set to ``2``
            for second coarsest level etc. Set to ``-1`` to return the bottom
            level modules (finest level).
        states : bool, optional
            For higher-order networks, if ``states`` is True, it will iterate
            over state nodes. Otherwise it will iterate over physical nodes,
            merging state nodes with same ``node_id`` if they are in the same
            module. Note that the same physical node may end up on different
            paths in the tree.
            See notes on ``physical_tree``. Default ``false``.

        Notes
        ----
        For higher-order networks, each node is represented by a set of state
        nodes with the same ``node_id``, where each state node represents a
        different memory constraining the random walker. This enables
        overlapping modules, where state nodes with the same ``node_id`` end up
        in different modules. However, the state nodes with the same
        ``node_id`` within each module are only visible as one (partial)
        physical node (if ``states = False``).

        Returns
        -------
        InfomapIterator or InfomapIteratorPhysical
            An iterator over each node in the tree, depth first from the root
        """
        if states:
            return super().iterTree(depth_level)
        return super().iterTreePhysical(depth_level)

    def get_nodes(self, depth_level=1, states=False):
        """A view of the tree

        Parameters
        ----------
        depth_level : int, optional
            The module level returned by ``iterator.module_id``. Set to ``1``
            (default) to return the top modules (coarsest level). Set to ``2``
            for second coarsest level etc. Set to ``-1`` to return the bottom
            level modules (finest level). Default ``1``.
        states : bool, optional
            For higher-order networks, if ``states`` is True, it will iterate
            over state nodes. Otherwise it will iterate over physical nodes,
            merging state nodes with same ``node_id`` if they are in the same
            module. Note that the same physical node may end up on different
            paths in the tree.
            See notes on ``physical_tree``. Default ``false``.

        Notes
        -----
        For higher-order networks, each node is represented by a set of state
        nodes with the same ``node_id``, where each state node represents a
        different memory constraining the random walker. This enables
        overlapping modules, where state nodes with the same ``node_id`` end up
        in different modules. However, the state nodes with the same
        ``node_id`` within each module are only visible as one (partial)
        physical node (if ``states = False``).

        Returns
        -------
        InfomapIterator or InfomapIteratorPhysical
            An iterator over each node in the tree, depth first from the root
        """
        if states:
            return super().iterLeafNodes(depth_level)
        return super().iterLeafNodesPhysical(depth_level)

    @property
    def tree(self):
        """A view of the tree

        See Also
        --------
        get_tree
        InfomapIterator

        Returns
        -------
        InfomapIterator
            An iterator over each node in the tree, depth first from the root
        """
        return self.get_tree(depth_level=1, states=True)

    @property
    def physical_tree(self):
        """A view of the tree where that state nodes of the same
        ``node_id`` are merged to one physical node

        See Also
        --------
        get_tree
        InfomapIteratorPhysical

        Returns
        -------
        InfomapIteratorPhysical
            An iterator over each physical node in the tree, depth first from
            the root
        """
        return self.get_tree(depth_level=1, states=False)

    @property
    def leaf_modules(self):
        """A view of the leaf modules, i.e. the bottom modules containing leaf nodes.

        See Also
        --------
        get_modules
        InfomapLeafModuleIterator

        Returns
        -------
        InfomapLeafModuleIterator
            An iterator over each leaf module in the tree, depth first from the
            root
        """
        return super().iterLeafModules()

    @property
    def nodes(self):
        """A view of the leaf nodes with the top level module ids

        See Also
        --------
        get_nodes
        InfomapLeafIterator

        Returns
        -------
        InfomapLeafIterator
            An iterator over each leaf node in the tree, depth first from the
            root
        """
        return self.get_nodes(depth_level=1, states=True)

    @property
    def physical_nodes(self):
        """A view of the physical leaf nodes with the top level module ids

        See Also
        --------
        get_nodes
        InfomapLeafIteratorPhysical

        Returns
        -------
        InfomapLeafIteratorPhysical
            An iterator over each physical leaf node in the tree, depth first
            from the root
        """
        return self.get_nodes(depth_level=1, states=False)

    def get_dataframe(self, columns=["path", "flow", "name", "node_id"]):
        """Get a Pandas DataFrame with the selected columns.

        Examples
        --------

        >>> from infomap import Infomap
        >>> im = Infomap(silent=True)
        >>> im.read_file("twotriangles.net")
        >>> im.run()
        >>> im.get_dataframe()
             path      flow name  node_id
        0  (1, 1)  0.214286    C        3
        1  (1, 2)  0.142857    A        1
        2  (1, 3)  0.142857    B        2
        3  (2, 1)  0.214286    D        4
        4  (2, 2)  0.142857    E        5
        5  (2, 3)  0.142857    F        6
        >>> im.get_dataframe(columns=["node_id", "module_id"])
           node_id  module_id
        0        3          1
        1        1          1
        2        2          1
        3        4          2
        4        5          2
        5        6          2


        See Also
        --------
        InfoNode

        Parameters
        ---------
        columns : list(str)
            A list of columns that should be extracted from each node.
            Must be available as an attribute of ``InfoNode``, with the
            exception of ``"name"`` which is looked up internally.
            Default ``["path", "flow", "name", "node_id"]``.

        Raises
        ------
        ImportError
            If the pandas package is not available.
        AttributeError
            If a column name is not available as an ``InfoNode`` attribute.

        Returns
        -------
        pandas.DataFrame
            A DataFrame containing the selected columns.
        """
        if pandas is None:
            raise ImportError("Cannot import package 'pandas'")

        return pandas.DataFrame([[getattr(node, attr) if attr != "name"
                                  else self.get_name(node.node_id,
                                                     default=node.node_id)
                                  for attr in columns]
                                 for node in self.nodes],
                                columns=columns)

    def get_name(self, node_id, default=None):
        """Get the name of a node.

        Notes
        -----
        If the node name is an empty string,
        the ``default`` will be returned.

        See Also
        --------
        set_name
        names

        Parameters
        ----------
        node_id : int
        default : str, optional
            The return value if the node name is missing, default ``None``

        Returns
        -------
        str
            The node name if it exists, else the ``default``.
        """
        name = super().getName(node_id)
        if name == "":
            return default
        return name

    def get_names(self):
        """Get all node names.

        See Also
        --------
        names
        get_name

        Returns
        -------
        dict of string
            A dict with node ids as keys and node names as values.
        """
        return super().getNames()

    @property
    def names(self):
        """Get all node names.

        Short-hand for ``get_names``.

        See Also
        --------
        get_names
        get_name

        Returns
        -------
        dict of string
            A dict with node ids as keys and node names as values.
        """
        return super().getNames()

    def get_links(self, data="weight"):
        """A view of the currently assigned links and their weights or flow.

        The sources and targets are state ids when we have a
        state or multilayer network.

        Examples
        --------

        >>> from infomap import Infomap
        >>> im = Infomap(silent=True)
        >>> im.read_file("twotriangles.net")
        >>> im.run()
        >>> for link in im.get_links():
        ...     print(link)
        (1, 2, 1.0)
        (1, 3, 1.0)
        (2, 3, 1.0)
        (3, 4, 1.0)
        (4, 5, 1.0)
        (4, 6, 1.0)
        (5, 6, 1.0)
        >>> for link in im.get_links(data="flow"):
        ...     print(link)
        (1, 2, 0.14285714285714285)
        (1, 3, 0.14285714285714285)
        (2, 3, 0.14285714285714285)
        (3, 4, 0.14285714285714285)
        (4, 5, 0.14285714285714285)
        (4, 6, 0.14285714285714285)
        (5, 6, 0.14285714285714285)


        See Also
        --------
        links
        flow_links

        Parameters
        ----------
        data : str
            The kind of data to return, one of ``"weight"`` or ``"flow"``.
            Default ``"weight"``.

        Returns
        -------
        tuple of int, int, float
            An iterator of source, target, weight/flow tuples.
        """
        if data not in ("weight", "flow"):
            raise RuntimeError("data must one of \"weight\" or \"flow\"")

        return ((source, target, value) for (source, target),
                value in self.getLinks(data != "weight").items())

    @property
    def links(self):
        """A view of the currently assigned links and their weights.

        The sources and targets are state ids when we have a
        state or multilayer network.

        Examples
        --------

        >>> from infomap import Infomap
        >>> im = Infomap(silent=True)
        >>> im.read_file("twotriangles.net")
        >>> im.run()
        >>> for link in im.links:
        ...     print(link)
        (1, 2, 1.0)
        (1, 3, 1.0)
        (2, 3, 1.0)
        (3, 4, 1.0)
        (4, 5, 1.0)
        (4, 6, 1.0)
        (5, 6, 1.0)


        See Also
        --------
        flow_links

        Returns
        -------
        tuple of int, int, float
            An iterator of source, target, weight tuples.
        """
        return self.get_links()

    @property
    def flow_links(self):
        """A view of the currently assigned links and their flow.

        The sources and targets are state ids when we have a
        state or multilayer network.

        Examples
        --------

        >>> from infomap import Infomap
        >>> im = Infomap(silent=True)
        >>> im.read_file("twotriangles.net")
        >>> im.run()
        >>> for link in im.flow_links:
        ...     print(link)
        (1, 2, 0.14285714285714285)
        (1, 3, 0.14285714285714285)
        (2, 3, 0.14285714285714285)
        (3, 4, 0.14285714285714285)
        (4, 5, 0.14285714285714285)
        (4, 6, 0.14285714285714285)
        (5, 6, 0.14285714285714285)


        See Also
        --------
        links

        Returns
        -------
        tuple of int, int, float
            An iterator of source, target, flow tuples.
        """
        return self.get_links(data="flow")

    @property
    def network(self):
        """Get the internal network."""
        return super().network()

# ----------------------------------------
# num_* getters
# ----------------------------------------

    @property
    def num_nodes(self):
        """The number of state nodes if we have a higher order network, or the
        number of physical nodes.

        See Also
        --------
        num_physical_nodes

        Returns
        -------
        int
            The number of nodes
        """
        return self.network.numNodes()

    @property
    def num_links(self):
        """The number of links.

        Returns
        -------
        int
            The number of links
        """
        return self.network.numLinks()

    @property
    def num_physical_nodes(self):
        """The number of physical nodes.

        See Also
        --------
        num_nodes

        Returns
        -------
        int
            The number of nodes
        """
        return self.network.numPhysicalNodes()

    @property
    def num_top_modules(self):
        """Get the number of top modules in the tree

        Returns
        -------
        int
            The number of top modules
        """
        return super().numTopModules()

    @property
    def num_non_trivial_top_modules(self):
        """Get the number of non-trivial top modules in the tree

        A trivial module is a module with either one or all nodes within.

        Returns
        -------
        int
            The number of non-trivial top modules
        """
        return super().numNonTrivialTopModules()

    @property
    def num_leaf_modules(self):
        """Get the number of leaf modules in the tree

        Returns
        -------
        int
            The number of leaf modules
        """
        num_leaf_modules = 0
        for _ in self.leaf_modules:
            num_leaf_modules += 1
        return num_leaf_modules

    def get_effective_num_modules(self, depth_level=1):
        """The flow weighted effective number of modules.

        Measured as the perplexity of the module flow distribution.

        Parameters
        ----------
        depth_level : int, optional
            The module level returned by ``iterator.depth``.
            Set to ``1`` (default) to return the top modules (coarsest level).
            Set to ``2`` for second coarsest level etc. Set to ``-1`` to return
            the bottom level modules (finest level).

        Returns
        -------
        float
            The effective number of modules
        """
        return perplexity([module.flow for module in self.get_tree(
            depth_level) if depth_level == -1 and module.is_leaf_module or module.depth == depth_level])

    @property
    def effective_num_top_modules(self):
        """The flow weighted effective number of top modules.

        Measured as the perplexity of the module flow distribution.

        Returns
        -------
        float
            The effective number of top modules
        """
        return self.get_effective_num_modules(depth_level=1)

    @property
    def effective_num_leaf_modules(self):
        """The flow weighted effective number of leaf modules.

        Measured as the perplexity of the module flow distribution.

        Returns
        -------
        float
            The effective number of top modules
        """
        return self.get_effective_num_modules(depth_level=-1)

    @property
    def max_depth(self):
        """Get the max depth of the hierarchical tree.

        Returns
        -------
        int
            The max depth
        """
        return super().maxTreeDepth()

# ----------------------------------------
# Codelength
# ----------------------------------------

    @property
    def codelength(self):
        """Get the total (hierarchical) codelength.

        See Also
        --------
        index_codelength
        module_codelength

        Returns
        -------
        float
            The codelength
        """
        return super().codelength()

    @property
    def codelengths(self):
        """Get the total (hierarchical) codelength for each trial.

        See Also
        --------
        codelength

        Returns
        -------
        tuple of float
            The codelengths for each trial
        """
        return super().codelengths()

    @property
    def index_codelength(self):
        """Get the two-level index codelength.

        See Also
        --------
        codelength
        module_codelength

        Returns
        -------
        float
            The two-level index codelength
        """
        return super().getIndexCodelength()

    @property
    def module_codelength(self):
        """Get the total codelength of the modules.

        The module codelength is defined such that
        ``codelength = index_codelength + module_codelength``

        For a hierarchical solution, the module codelength
        is the sum of codelengths for each top module.

        See Also
        --------
        codelength
        index_codelength

        Returns
        -------
        float
            The module codelength
        """
        return super().getModuleCodelength()

    @property
    def one_level_codelength(self):
        """Get the one-level codelength.

        See Also
        --------
        codelength

        Returns
        -------
        float
            The one-level codelength
        """
        return super().getOneLevelCodelength()

    @property
    def relative_codelength_savings(self):
        """Get the relative codelength savings.

        This is defined as the reduction in codelength
        relative to the non-modular one-level solution::

            S_L = 1 - L / L_1

        where ``L`` is the ``codelength`` and ``L_1``
        the ``one_level_codelength``.

        See Also
        --------
        codelength
        one_level_codelength

        Returns
        -------
        float
            The relative codelength savings
        """
        return super().getRelativeCodelengthSavings()

    @property
    def meta_codelength(self):
        """Get the meta codelength.

        This is the meta entropy times the meta data rate.

        See Also
        --------
        meta_entropy

        Returns
        -------
        float
            The meta codelength
        """
        return super().getMetaCodelength()

    @property
    def meta_entropy(self):
        """Get the meta entropy (unweighted by meta data rate).

        See Also
        --------
        meta_codelength

        Returns
        -------
        float
            The meta entropy
        """
        return super().getMetaCodelength(True)

# ----------------------------------------
# Write Results
# ----------------------------------------

    def write(self, filename, *args, **kwargs):
        """Write results to file.

        Raises
        ------
        NotImplementedError
            If the file format is not supported.

        Parameters
        ----------
        filename : str
            The filename.
        """
        _, ext = os.path.splitext(filename)

# remove the dot
        ext = ext[1:]

        if ext == "ftree":
            ext = "flow_tree"
        elif ext == "nwk":
            ext = "newick"
        elif ext == "net":
            ext = "pajek"

        writer = "write_{}".format(ext)

        if hasattr(self, writer):
            return getattr(self, writer)(filename, *args, **kwargs)

        raise NotImplementedError(
            "No method found for writing {} files".format(ext))

    def write_clu(self, filename, states=False, depth_level=1):
        """Write result to a clu file.

        See Also
        --------
        write_tree
        write_flow_tree

        Parameters
        ----------
        filename : str
        states : bool, optional
            If the state nodes should be included. Default ``False``.
        depth_level : int, optional
            The depth in the hierarchical tree to write.
        """
        return self.writeClu(filename, states, depth_level)

    def write_tree(self, filename, states=False):
        """Write result to a tree file.

        See Also
        --------
        write_clu
        write_flow_tree

        Parameters
        ----------
        filename : str
        states : bool, optional
            If the state nodes should be included. Default ``False``.
        """
        return self.writeTree(filename, states)

    def write_flow_tree(self, filename, states=False):
        """Write result to a ftree file.

        See Also
        --------
        write_clu
        write_tree

        Parameters
        ----------
        filename : str
        states : bool, optional
            If the state nodes should be included. Default ``False``.
        """
        return self.writeFlowTree(filename, states)

    def write_newick(self, filename, states=False):
        """Write result to a Newick file.

        See Also
        --------
        write_clu
        write_tree

        Parameters
        ----------
        filename : str
        states : bool, optional
            If the state nodes should be included. Default ``False``.
        """
        return self.writeNewickTree(filename, states)

    def write_json(self, filename, states=False):
        """Write result to a JSON file.

        See Also
        --------
        write_clu
        write_tree

        Parameters
        ----------
        filename : str
        states : bool, optional
            If the state nodes should be included. Default ``False``.
        """
        return self.writeJsonTree(filename, states)

    def write_csv(self, filename, states=False):
        """Write result to a CSV file.

        See Also
        --------
        write_clu
        write_tree

        Parameters
        ----------
        filename : str
        states : bool, optional
            If the state nodes should be included. Default ``False``.
        """
        return self.writeCsvTree(filename, states)

    def write_state_network(self, filename):
        """Write internal state network to file.

        See Also
        --------
        write_pajek

        Parameters
        ----------
        filename : str
        """
        return self.network.writeStateNetwork(filename)

    def write_pajek(self, filename, flow=False):
        """Write network to a Pajek file.

        See Also
        --------
        write_state_network

        Parameters
        ----------
        filename : str
        flow : bool, optional
            If the flow should be included. Default ``False``.
        """
        return self.network.writePajekNetwork(filename, flow)


def main():
    import sys

    args = " ".join(sys.argv[1:])
    conf = Config(args, True)
    im = Infomap(conf)
    im.run()


if __name__ == '__main__':
    main()
