# Comparison#

In engineering design it is common practice to compare different architectures. For example, to highlight the architectural differences and commonalities between different conceptual designs, different generations of a system, or different products within a portfolio.

Hence we have developed the `comparison`

module which contains
the basic analysis classes `DeltaAnalysis`

and
`SigmaAnalysis`

.

To illustrate usage of these classes the example dependency structure matrix (DSM)
models show in Figure 19, Figure 20,
Figure 21. The data behind these models is stored in three
`Graph`

objects named `graph_a`

, `graph_b`

and `graph_c`

.

Note that the elements on the the rows and columns of the DSMs, i.e. the nodes of the
graphs, and the dependencies between these elements, i.e. the edges of the graphs,
partially overlap between the three different models. For example, elements `c`

,
`d`

, `e`

, en `f`

are part of all three DSMs. Similarly, all three DSMs contain a
dependency between `c`

and `d`

with labels `electrical`

, `information`

, and
`mechanical`

.

## Delta analysis#

If one is interested in the differences and commonalities between two graphs one can
perform a delta analysis using the `DeltaAnalysis`

class, which you can easily instantiate using the code below:

```
>>> from ragraph.analysis.comparison import DeltaAnalysis
>>> da = DeltaAnalysis(graph_a=graph_a, graph_b=graph_b)
```

In this case, `graph_a`

, shown in Figure 19, is compared with
`graph_b`

, shown in Figure 20. Internally, the
`DeltaAnalysis`

object creates nodes and edges that
can reflect the differences and commonalities between the provided graphs. You can
visualize these nodes and edges using the regular `mdm`

method:

```
>>> fig = ragraph.plot.mdm(
... leafs=da.nodes,
... edges=da.edges,
... style=ragraph.plot.Style(
... piemap={
... "mode": "relative",
... },
... ),
... )
>>> fig.write_image(delta_dsm_path_1)
```

which yields Figure 22. Note that the rows and columns are divided into
three domains by dashed lines. The first domain, containing only node `a`

, contains
those nodes that are unique to `graph_a`

. The second domain (rows, cols 2-5) contains
those nodes that are part of both graphs. The third domain, containing only node `g`

,
contains those nodes that are unique to `graph_b`

.

The graph contains three edge kinds. Edges that are unique to `graph_a`

(orange),
edges that are unique to `graph_b`

(green), and edges that are part of both graphs
(blue). In case, there are four edges that are common in both graphs.

Note that element `e`

is part of both graphs, yet none of its edges are common. In
both graphs, `e`

has a dependency with element `c`

. However, the assigned labels
differ.

Similarly, the differences and commonalities between `graph_a`

and `graph_c`

can be visualized:

```
>>> from ragraph.analysis.comparison import DeltaAnalysis
>>> da = DeltaAnalysis(graph_a=graph_a, graph_b=graph_c)
>>> fig = ragraph.plot.mdm(
... leafs=da.nodes,
... edges=da.edges,
... style=ragraph.plot.Style(
... piemap={
... "mode": "relative",
... },
... ),
... )
>>> fig.write_image(delta_dsm_path_2)
```

which results in Figure 23. In this case, the first domain contains nodes
`a`

and `b`

. The third domain contains nodes `g`

and `h`

. Nodes `c`

,
`d`

, `e`

, and `f`

are common among both graphs.

## Sigma analysis#

When you’re interested in identifying the commonalities between \(N\) graphs the sigma analysis enables you to do so. For example, to find the ‘common core’ architecture of a group of products within a product portfolio.

You can perform a sigma analysis by instantiating the
`SigmaAnalysis`

with a list of graphs as arguments:

```
>>> from ragraph.analysis.comparison import SigmaAnalysis
>>> sa = SigmaAnalysis(graphs=[graph_a, graph_b, graph_c])
```

In this case, we perform a sigma analysis on `graph_a`

, `graph_b`

, and `graph_c`

.
Internally, the `SigmaAnalysis`

object creates nodes
and edges that can reflect the commonalities between the provided graphs. You can
visualize these nodes and edges using the regular `mdm`

method:

```
>>> fig = ragraph.plot.mdm(
... leafs=sa.nodes,
... edges=sa.edges,
... style=ragraph.plot.Style(
... piemap={
... "mode": "relative",
... "display": "weights",
... "fields": ["_count"]
... },
... legend={"height": 6, "n_ticks": 3},
... ),
... )
>>> fig.write_image(sigma_dsm_path_1)
```

which results in Figure 24. This figure displays the `_count`

edge count
as a fraction of the number of provided graphs. A value of 1 implies that the respective
edge is present within all of the provided graphs. A value of 0.33 implies that the edge
is only present in one-third of the provided graphs. In computing the `_count`

edge
count differences in edge labels are ignored.

If you want to visualize the absolute edge counts, you can simply set the
`mode`

property to “absolute”:

```
>>> sa.mode = "absolute"
```

and subsequently re-visualize the nodes and edges:

```
>>> fig = ragraph.plot.mdm(
... leafs=sa.nodes,
... edges=sa.edges,
... style=ragraph.plot.Style(
... piemap={
... "mode": "relative",
... "display": "weights",
... "fields": ["_count"]
... },
... legend={"height": 6, "n_ticks": 3},
... ),
... )
>>> fig.write_image(sigma_dsm_path_2)
```

yielding Figure 25. This figure displays the `_count`

edge counts as
absolute numbers.

Besides visualizing `_count`

edge counts, you can visualize edge `label`

counts as
well. You only have change the `fields`

property within the piemap style options:

```
>>> fig = ragraph.plot.mdm(
... leafs=sa.nodes,
... edges=sa.edges,
... style=ragraph.plot.Style(
... piemap={
... "mode": "relative",
... "display": "weights",
... "fields": [
... "electric",
... "information",
... "mechanical"
... ]
... },
... legend={"height": 6, "n_ticks": 3},
... ),
... )
>>> fig.write_image(sigma_dsm_path_3)
```

which yields Figure 26. This figure shows the absolute edge label counts.
The edges between `c`

and `e`

are, for example, present within two out of three
graphs. In both graphs the edge has label `mechanical`

, yet in only
one graph it has labels `information`

and `electric`

.