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.

Example dependency structure matrix (DSM) A.

Figure 19 Example dependency structure matrix (DSM) A.#

Example dependency structure matrix (DSM) B.

Figure 20 Example dependency structure matrix (DSM) B.#

Example dependency structure matrix (DSM) C.

Figure 21 Example dependency structure matrix (DSM) C.#

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.

Delta DSM.

Figure 22 Delta DSM showing the differences and commonalities between graph_a and graph_b.#

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.

Delta DSM.

Figure 23 Delta DSM showing the differences and commonalities between graph_a and graph_c.#

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.

Sigma DSM.

Figure 24 Sigma DSM showing edge count fractions.#

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.

Sigma DSM.

Figure 25 Sigma DSM showing absolute edge counts.#

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.

Sigma DSM.

Figure 26 Sigma DSM showing edge label counts.#