# Modularity

There are a number of modularity-related functions in `EcologicalNetworks`

. The optimal modularity structure is detected by optimizing $Q$, which returns values increasingly close to unity when the modular structure is strong. The $Q_r$ measure is also included for *a posteriori* evaluation of the modularity.

## Types

The object returned by all modularity detection functions has the type `Partition`

.

#
** EcologicalNetwork.Partition** —

*Type*.

**Community partition**

This type has three elements:

`N`

, the network`L`

, the array of (integers) module labels`Q`

, if needed, the modularity value

## Measures of modularity

#
** EcologicalNetwork.Q** —

*Function*.

**Modularity**

Q(N::EcoNetwork, L::Array{Int64, 1})

This measures modularity based on a matrix and a list of module labels. Note that this function assumes that interactions are directional, so that $A_{ij}$ represents an interaction from $i$ to $j$, but not the other way around.

**Modularity (from a Partition)**

Q(P::Partition)

This measures Barber's bipartite modularity based on a `Partition`

object, and update the object in the proccess.

In addition, there is a measure of *realized* modularity:

#
** EcologicalNetwork.Qr** —

*Function*.

**Realized modularity**

Qr(N::EcoNetwork, L::Array{Int64, 1})

Measures realized modularity, based on a a matrix and a list of module labels. Realized modularity usually takes values in the [0;1] interval, and is the proportion of interactions established *within* modules.

The realized modularity is defined as $Q_R' = 2 imes (W/E) - 1$, where $W$ is the number of links *within* modules, and $E$ is the total number of links.

Note that in some situations, `Qr`

can be *lower* than 0. This reflects a partition in which more links are established between than within modules.

**Realized modularity (from a Partition)**

Qr(P::Partition)

Measures realized modularity, based on a `Partition`

object.

## Functions for modularity detection

The first function included is `label_propagation`

, which is working well for large graphs. It can also be useful to generate an initial modular partition.

#
** EcologicalNetwork.label_propagation** —

*Function*.

**Label propagation**

label_propagation(N::EcoNetwork, L::Array{Int64, 1})

This function will optimize modularity by propagating labels along interactions. A node receives the label that is most frequent in its neighborhood. For quantitative networks, the interaction weight is taken into account. For probabilistic network, probabilities are used to draw the label.

For larger graphs (as long as they are not probabilistic), there is the `louvain`

function. It is *not* the most aggressively optimized implementation.

#
** EcologicalNetwork.louvain** —

*Function*.

**Louvain method for modularity on large networks**

louvain(N::NonProbabilisticNetwork, L::Array{Int64, 1})

TODO

Finally, there is a `brim`

function for bipartite networks.

#
** EcologicalNetwork.brim** —

*Function*.

**Bipartite Recursively Induced Modularity**

brim(P::Partition)

Returns the best partition using BRIM, based on a Partition object.

**Bipartite Recursively Induced Modularity**

brim(N::BipartiteNetwork, L::Array{Int64, 1})

Returns the best partition using BRIM, based on a network and an initial set of modules.

## Analyze modularity

#
** EcologicalNetwork.modularity** —

*Function*.

**Detect modules in a network**

modularity(N::EcoNetwork, L::Array{Int64, 1}, f::Function; replicates::Int64=100)

This function is a wrapper for the modularity code. The number of replicates is the number of times the modularity optimization should be run.

Arguments:

`N::EcoNetwork`

, the network to work on`L::Array{Int64,1}`

, an array of module identities`f::Function`

, the function to use

The function `f`

*must* (1) accept `N, L`

as arguments, and (2) return a `Partition`

as an output. Note that by default, `L`

will be set to `nothing`

, and modules will be generated at random. In unipartite networks, there can be up to one module per species. In bipartite networks, the minimum number of modules is the richness of the less speciose level.

Keywords:

`replicates::Int64`

, defaults to`100`

## Select the best partition

#
** EcologicalNetwork.best_partition** —

*Function*.

**Most modular partition**

best_partition(modpart; f::Function=Q)

Return the best partition out of a number of replicates. This returns an *array* of partitions. If there is a single partition maximizing the given function `f`

(as a keyword), the results are *still* returned as an array with a single element.

Arguments:

`modpart::Array{Partition,1}`

, an array of partitions returned by*e.g.*`modularity`

Keywords:

`f::Function`

, either`Q`

or`Qr`

(any function for which the highest value represents a more modular structure).

## Network roles

#
** EcologicalNetwork.networkroles** —

*Function*.

**Network roles based on modularity**

networkroles(P::Partition)