defmodule ExLeiden do @moduledoc """ A pure Elixir implementation of the Leiden algorithm for community detection in networks. The main entry point is `call/2`, which accepts graph data as `{vertices, edges}` tuples and returns community detection results using the Leiden algorithm. See the [README](README.md) for detailed documentation, usage examples, and algorithm overview. """ # Type definitions for the public API @type vertex() :: term() @type edge() :: {vertex(), vertex()} | {vertex(), vertex(), number()} @type vertices() :: list(vertex()) @type edges() :: list(edge()) @type graph_input() :: {vertices(), edges()} @type opts() :: [ resolution: float(), quality_function: :modularity | :cpm, max_level: pos_integer(), theta: float(), gamma: float(), flatten?: boolean() ] @type community_id() :: term() @type level() :: non_neg_integer() @type graph_level() :: %{ level: level(), communities: %{community_id() => list(vertex())}, bridges: list({community_id(), community_id(), number()}), modularity: float(), cpm_score: float() | nil } @type result() :: %{ levels: list(graph_level()), metadata: %{ total_levels: pos_integer(), iterations: pos_integer(), processing_time_ms: pos_integer() } } @doc """ Detects communities in a graph using the Leiden algorithm. This is the main entry point for the ExLeiden library. It accepts graph data as a tuple of vertices and edges, with optional configuration to customize algorithm behavior. ## Parameters - `data` - Graph data in one of these formats: - `%Graph{}` - Graph struct (from libgraph library) - `[{source, target}, ...]` - List of edges (unweighted) - `[{source, target, weight}, ...]` - List of weighted edges - `{vertices, edges}` - Tuple of vertex list and edge list - `opts` - Keyword list of configuration options (see README.md for details) ## Options * `:quality_function` - Quality function to optimize (`:modularity` or `:cpm`). Defaults to `:modularity`. * `:resolution` - Resolution parameter γ controlling community granularity. Higher values favor smaller communities. Defaults to `1.0`. * `:max_level` - Maximum hierarchical levels to create. Algorithm may stop early if no improvements possible. Defaults to `5`. ## Returns - `{:ok, result}` - Success with community detection results and metadata - `{:error, reason}` - Invalid options or input validation error """ @spec call(graph_input(), opts()) :: {:ok, result()} | {:error, map()} def call(input, opts \\ []) # Catch-all pattern for invalid input types # Returns validation error for unsupported input formats. def call(%Graph{} = _graph, _opts) do {:error, %{implementation: "graph input pattern not yet implemented"}} end def call(edges, _opts) when is_list(edges) do # TODO: Implement tuple input processing # 1. Validate edges list # 2. Create graph structure from raw data # 3. Process with algorithm {:error, %{implemtation: "tuple input pattern not yet implemented"}} end def call({[], edges}, opts) when is_list(edges) do call(edges, opts) end def call({vertices, edges}, _opts) when is_list(vertices) and is_list(edges) do # TODO: Implement tuple input processing # 1. Validate vertices and edges lists # 2. Create graph structure from raw data # 3. Process with algorithm {:error, %{implemtation: "tuple input pattern not yet implemented"}} end end