# `Yog.IO.MatrixMarket`
[🔗](https://github.com/code-shoily/yog_ex/blob/v1.0.0/lib/yog/io/matrix_market.ex#L1)

Matrix Market (.mtx) format serialization support.

Provides functions to serialize and deserialize graphs in the Matrix Market
exchange format, a common format for sharing sparse and dense matrices in
scientific computing and graph theory.

## Format Overview

Matrix Market files start with a header:
`%%MatrixMarket matrix <format> <field> <symmetry>`

- **Format**: `coordinate` (sparse) or `array` (dense) - Currently `coordinate` is primary.
- **Field**: `real`, `integer`, `pattern`, or `complex`.
- **Symmetry**: `general`, `symmetric`, `skew-symmetric`, or `hermitian`.

For graph representation:
- Rows and Columns represent nodes.
- Matrix indices are **1-based**.
- Symmetric matrices are often used for undirected graphs.

## Example

    iex> graph = Yog.directed()
    ...> |> Yog.add_node(1, nil)
    ...> |> Yog.add_node(2, nil)
    ...> |> Yog.add_edge_ensure(from: 1, to: 2, with: 5.0)
    iex>
    iex> mtx_string = Yog.IO.MatrixMarket.serialize(graph)
    iex> String.contains?(mtx_string, "%%MatrixMarket matrix coordinate real general")
    true
    iex> String.contains?(mtx_string, "1 2 5.0")
    true

## Default Configurations

Default behavior:
- Node data: Ignored during serialization (Matrix Market only stores matrix values)
- Edge weights: Converted to float or integer

# `default_options`

```elixir
@spec default_options() :: tuple()
```

Returns default Matrix Market serialization options.

- `weight_formatter` - Function to convert edge weights to strings (default: `&Yog.Utils.to_weight_label/1`)
- `edge_formatter`: `Yog.Utils.safe_string/1`
- `node_formatter`: `Yog.Utils.safe_string/1`

# `options_with`

```elixir
@spec options_with(
  (any() -&gt; any()),
  keyword()
) :: tuple()
```

Creates Matrix Market options with custom configurations.

Raises `ArgumentError` if `weight_formatter` is not an arity-1 function or `opts` is invalid.

# `parse`

```elixir
@spec parse(String.t(), atom() | nil) ::
  {:ok, {:matrix_market_result, Yog.graph(), list()}} | {:error, term()}
```

Parses a Matrix Market string into a graph.

Raises `ArgumentError` if `input` is not a binary string or `g_type` is invalid.

Time complexity: $\mathcal{O}(V + E)$ where $V$ is node count and $E$ is edge count.

## Parameters

- `input`: Matrix Market format string
- `g_type`: `:directed` or `:undirected` (overrides header symmetry if provided)

## Returns

- `{:ok, {:matrix_market_result, graph, warnings}}` on success
- `{:error, reason}` on parsing failure

# `parse_with`

```elixir
@spec parse_with(String.t(), atom() | nil, (any() -&gt; any()), (any() -&gt; any())) ::
  {:ok, {:matrix_market_result, Yog.graph(), list()}} | {:error, term()}
```

Parses a Matrix Market string with custom node and edge parsers.

Raises `ArgumentError` if `input` is not a binary string or parsers/g_type are invalid.

Time complexity: $\mathcal{O}(V + E)$ where $V$ is node count and $E$ is edge count.

# `read`

```elixir
@spec read(String.t(), atom() | nil) ::
  {:ok, {:matrix_market_result, Yog.graph(), list()}} | {:error, term()}
```

Reads a graph from a Matrix Market file.

Raises `ArgumentError` if `path` is not a binary string.

# `read_with`

```elixir
@spec read_with(String.t(), atom() | nil, (any() -&gt; any()), (any() -&gt; any())) ::
  {:ok, {:matrix_market_result, Yog.graph(), list()}} | {:error, term()}
```

Reads a graph from a Matrix Market file with custom parsers.

Raises `ArgumentError` if `path` is not a binary string.

# `serialize`

```elixir
@spec serialize(Yog.graph()) :: String.t()
```

Serializes a graph to Matrix Market coordinate format.

Raises `ArgumentError` if `graph` is not a `Yog.Graph` or `Yog.DAG` struct.

Time complexity: $\mathcal{O}(V + E)$ where $V$ is node count and $E$ is edge count.

## Example

    iex> graph = Yog.directed()
    ...> |> Yog.add_node(1, nil)
    ...> |> Yog.add_node(2, nil)
    ...> |> Yog.add_edge_ensure(from: 1, to: 2, with: 1.5)
    iex> mtx = Yog.IO.MatrixMarket.serialize(graph)
    iex> String.contains?(mtx, "1 2 1.5")
    true

# `serialize_with`

```elixir
@spec serialize_with(tuple(), Yog.graph()) :: String.t()
```

Serializes a graph to Matrix Market format with custom options.

Raises `ArgumentError` if `options` or `graph` are invalid.

Time complexity: $\mathcal{O}(V + E)$ where $V$ is node count and $E$ is edge count.

# `write`

```elixir
@spec write(String.t(), Yog.graph()) :: :ok | {:error, atom()}
```

Writes a graph to a Matrix Market file.

Raises `ArgumentError` if `path` is not a binary string or `graph` is invalid.

# `write_with`

```elixir
@spec write_with(String.t(), tuple(), Yog.graph()) :: :ok | {:error, atom()}
```

Writes a graph to a Matrix Market file with custom options.

Raises `ArgumentError` if `path` is not a binary string or options/graph are invalid.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
