Skip to content

Improvements and test coverage for line.py#6215

Merged
MridulS merged 8 commits intonetworkx:mainfrom
Aufinal:line.py-test-cov
Jan 2, 2023
Merged

Improvements and test coverage for line.py#6215
MridulS merged 8 commits intonetworkx:mainfrom
Aufinal:line.py-test-cov

Conversation

@Aufinal
Copy link
Copy Markdown
Contributor

@Aufinal Aufinal commented Nov 14, 2022

Changes to line.py itself:

  • due to the discussion in the documentation of line_graph, line graphs are generated with no loops.
    It makes therefore sense to exclude graphs with loops from inverse_line_graphs
  • we can always pop u from partitioned_vertices since the cell new_cell contains all the neighbors of u,
    and thus deg_u = 0 after line 403.
  • we only ever use the length of ac_edges and bc_edges
  • the only way to have len(triangle_nodes) != s+2 is if G has self-loops (otherwise each odd triangle contributes
    exactly one new vertex to triangle_nodes).

Test changes:

  • adds coverage for working inverse line graph examples
  • adds a bunch of negative examples (the whole list of forbidden subgraphs of L.W.Beineke), which also covers all possible branches
  • adds some very basic tests for private internal functions

Ludovic Stephan added 2 commits November 13, 2022 21:21
  * due to the discussion in the documentation of `line_graph`, line graphs are generated with no loops.
    It makes therefore sense to exclude graphs with loops from `inverse_line_graphs`
  * we can always pop u from `partitioned_vertices` since the cell `new_cell` contains all the neighbors of u,
    and thus `deg_u = 0` after line 403.
  * we only ever use the length of ac_edges and bc_edges
  * the only way to have `len(triangle_nodes) != s+2` is if `G` has self-loops (otherwise each odd triangle contributes
    exactly one new vertex to `triangle_nodes`).
@Aufinal
Copy link
Copy Markdown
Contributor Author

Aufinal commented Nov 14, 2022

Notes :

  • I had missed Testing improvement in generators/line.py #6204 when working on that (sorry...), but I do have a test that hits those lines, so they are not unreachable as claimed.
  • Maybe throwing an error when self-loops exist is too big of a change since it might break existing code, but the current situation isn't right either: the function throws an error on [(0, 0), (0, 1), (0, 2), (1, 2)], and it definitely shouldn't... A possible compromise could be to remove the self-loops, throw a warning and continue on the simple graph.

Fixes #6191

@rossbar
Copy link
Copy Markdown
Contributor

rossbar commented Nov 14, 2022

I had missed #6204 when working on that (sorry...), but I do have a test that hits those lines, so they are not unreachable as claimed.

No worries @Aufinal , thanks for pointing this out. @Mjh9122 want to take a look at this one?

@Mjh9122
Copy link
Copy Markdown
Contributor

Mjh9122 commented Nov 14, 2022

Yep definitely looks a lot more put together than mine. I closed mine and also took a second to add matches to all of the exceptions on this one. IDK about the best way to solve the self loop issue either but I made a quick fix warning based on @Aufinal 's suggestion. What would be the best way to make those changes, can I do it on this PR or should I make a new one?

@Aufinal
Copy link
Copy Markdown
Contributor Author

Aufinal commented Nov 15, 2022

I'm not sure that matching on the precise error messages is meaningful: they depend on a lot of hidden details, such as the order of edges in G and even the order of vertices in edges, so a lot of unrelated API changes could cause the tests to fail. That's also why there are a lot of redundant negative examples, to try and make sure the coverage will stay OK no matter what.

With that in mind, I've replaced some tests with one less dependent on the precise API. I welcome any suggestions about the self-loop behavior, but I don't know the best way to proceed either...

@Aufinal
Copy link
Copy Markdown
Contributor Author

Aufinal commented Nov 19, 2022

Changed the behavior for self-loops (and the associated tests) to a simple warning. I am making a copy of G to avoid removing edges in-place, is that the correct to deal with such cases @rossbar ?

Copy link
Copy Markdown
Member

@dschult dschult left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've looked through this and it looks good.

The only question I have is about whether warnings are the right way to handle graphs with selfloops. I worry that many users have warnings set so they don't show up. Did we discuss the possibility of raising a NetworkXError with a message telling the user what happened and suggesting that they remove selfloops before calling this function?

@rossbar
Copy link
Copy Markdown
Contributor

rossbar commented Dec 11, 2022

The only question I have is about whether warnings are the right way to handle graphs with selfloops.

Agreed - let's avoid warnings. inverse_line_graph currently raises at least for some subset of cases involving self-loops:

>>> G = nx.path_graph(2)
>>> L_1 = nx.inverse_line_graph(G)  # Works fine
>>> G.add_edge(0, 0)
>>> nx.inverse_line_graph(G)
Traceback (most recent call last)
   ...
NetworkXError: G is not a line graph (odd triangles do not form complete subgraph)

I would vote to preserve this behavior, though raising an exception message specific to the self-loop case would be an improvement!

@Aufinal
Copy link
Copy Markdown
Contributor Author

Aufinal commented Dec 13, 2022

Agreed with the sentiment of keeping the current behavior as much as possible. I've changed the selfloop behavior to raise an error.

Copy link
Copy Markdown
Member

@dschult dschult left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very close to being ready to merge. I have some minor suggestions below and it looks like we'll need to merge "main" into this branch. If you don't have time let me know and I'll do it.

@Aufinal
Copy link
Copy Markdown
Contributor Author

Aufinal commented Dec 26, 2022

The suggestions are applied, and I think the merge went ok :)

Copy link
Copy Markdown
Member

@dschult dschult left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me!
Thanks @Aufinal !

Copy link
Copy Markdown
Member

@MridulS MridulS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Aufinal!

@MridulS MridulS merged commit 71ad516 into networkx:main Jan 2, 2023
@jarrodmillman jarrodmillman added this to the networkx-3.0 milestone Jan 4, 2023
MridulS pushed a commit to MridulS/networkx that referenced this pull request Feb 4, 2023
* Improvements to `inverse_line_graph` function

  * due to the discussion in the documentation of `line_graph`, line graphs are generated with no loops.
    It makes therefore sense to exclude graphs with loops from `inverse_line_graphs`
  * we can always pop u from `partitioned_vertices` since the cell `new_cell` contains all the neighbors of u,
    and thus `deg_u = 0` after line 403.
  * we only ever use the length of ac_edges and bc_edges
  * the only way to have `len(triangle_nodes) != s+2` is if `G` has self-loops (otherwise each odd triangle contributes
    exactly one new vertex to `triangle_nodes`).

* New tests for line.py

* Replace test_diamond_graph by a more consistent version

* Runs one forgotten test

* Change selfloops behavior to simple warning

* Change warning to error for selfloops

* Apply suggestions from code review

Co-authored-by: Dan Schult <dschult@colgate.edu>

Co-authored-by: Ludovic Stephan <ludovic.stephan@pm.me>
Co-authored-by: Dan Schult <dschult@colgate.edu>
dschult added a commit to BrunoBaldissera/networkx that referenced this pull request Oct 23, 2023
* Improvements to `inverse_line_graph` function

  * due to the discussion in the documentation of `line_graph`, line graphs are generated with no loops.
    It makes therefore sense to exclude graphs with loops from `inverse_line_graphs`
  * we can always pop u from `partitioned_vertices` since the cell `new_cell` contains all the neighbors of u,
    and thus `deg_u = 0` after line 403.
  * we only ever use the length of ac_edges and bc_edges
  * the only way to have `len(triangle_nodes) != s+2` is if `G` has self-loops (otherwise each odd triangle contributes
    exactly one new vertex to `triangle_nodes`).

* New tests for line.py

* Replace test_diamond_graph by a more consistent version

* Runs one forgotten test

* Change selfloops behavior to simple warning

* Change warning to error for selfloops

* Apply suggestions from code review

Co-authored-by: Dan Schult <dschult@colgate.edu>

Co-authored-by: Ludovic Stephan <ludovic.stephan@pm.me>
Co-authored-by: Dan Schult <dschult@colgate.edu>
cvanelteren pushed a commit to cvanelteren/networkx that referenced this pull request Apr 22, 2024
* Improvements to `inverse_line_graph` function

  * due to the discussion in the documentation of `line_graph`, line graphs are generated with no loops.
    It makes therefore sense to exclude graphs with loops from `inverse_line_graphs`
  * we can always pop u from `partitioned_vertices` since the cell `new_cell` contains all the neighbors of u,
    and thus `deg_u = 0` after line 403.
  * we only ever use the length of ac_edges and bc_edges
  * the only way to have `len(triangle_nodes) != s+2` is if `G` has self-loops (otherwise each odd triangle contributes
    exactly one new vertex to `triangle_nodes`).

* New tests for line.py

* Replace test_diamond_graph by a more consistent version

* Runs one forgotten test

* Change selfloops behavior to simple warning

* Change warning to error for selfloops

* Apply suggestions from code review

Co-authored-by: Dan Schult <dschult@colgate.edu>

Co-authored-by: Ludovic Stephan <ludovic.stephan@pm.me>
Co-authored-by: Dan Schult <dschult@colgate.edu>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

6 participants