-
Notifications
You must be signed in to change notification settings - Fork 120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve printing of problems, constraints, and variables #325
Conversation
I'll merge this in 48 hours if I don't hear any objections before then. These changes are orthogonal to eg MOI, global variables, etc, so this should be easily revertible in case it turns out there are strong objections to the AbstractTrees dependency. |
@matbesancon I'd be happy to get a review if you have a chance :). If you want to review but don't have time in the next few days, I don't mind holding off merging, either; the 48 hours I mention above was just an arbitrary 1-week wait that I thought was a suitable time to wait for comments in case some were coming. |
Sorry about the delay on this, and thanks for that work.
|
@@ -71,3 +72,28 @@ and .travis.yml contain code copied from the Transducers.jl package | |||
>LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
>OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
>SOFTWARE. | |||
|
|||
The `TreePrint` module contains code from the AbstractTrees.jl package |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is needed, AbstractTrees
is a dependency, you did not copy code directly right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I did copy code directly in the TreePrint
module, just to use JuliaCollections/AbstractTrees.jl#38 on our side. We can delete the module and the copied code once that PR is merged, but I don't think it will be soon since the repo seems pretty inactive.
Thanks! Regarding the I could make these dots take a bit less space by using the same ellipsis character from what gets printed when the tree exceeds its maxdepth ( What do you think? |
Co-Authored-By: Mathieu Besançon <[email protected]>
Ok thanks for the precision, if it's not too complex 123...465 would be perfect to understand that the id has been truncated, but it might be me being slow to understand 😬 |
That's a great idea, I think that'll make it really clear. I'll push a commit with that change in a minute. |
I find myself usually ignoring the printing of problems, because it's quite verbose while not being very informative. Here, I propose new printing that I think helps with both problems.
Old printing:
After:
It's both shorter and much more informative: the old printing does not recurse down the tree. So for example, for the last constraint in the above problem, with the old way of printing you see
which doesn't tell you what is being indexed. Now you see
which tells you what variable is being indexed. This is only compounded for large problems. Note, we only recurse three levels down by default, so recursion shouldn't cause problems if a huge problem gets printed. This can be controlled by
Convex.MAXDEPTH[] = 5
e.g., for users who wish to customize this.I think the new printing will often be shorter than the current printing even accounting for recursion: adding a constraint in the current method of printing means 10 more lines get printed when the problem is printed. With the recursion depth set to three, it is possible to add a constraint yielding more lines, but the worst case is 15 lines (nested binary operators all the way down on both sides):
and most times it will be less (unary operators, or reaching a leaf such as a variable or constant).
Why am I trying to justify the improvements so much? Because it doesn't come for free: I'm using Keno's AbstractTrees.jl to do the hard work of printing these nice trees, so we would need to take on a dependency on that package. It's 700 lines of Julia with no dependencies, so it's quite a light dependency. It also means Convex problems can be treated as trees in other packages that respect the AbstractTrees API. For example, using GraphRecipes master and this branch, one can do
where
p::Problem
is a Convex.jl problem. It doesn't look perfect though:(overlapping nodes etc).
Still, it's kind of cool that it's easily integrated, and maybe stuff like that can be improved on the GraphRecipes side. Another example of what you can do is one I added to the docs: use
AbstractTrees
to iterate over the problem in various orders, or iterate over the "leaves" of the problem, and so forth. For exampleyields
One can also iterate over the problem in various orders, as shown in the docs in this PR. I imagine these iterators could be useful for figuring out what's going on in a problem. For example, one could count how many of a certain kind of atom is in the problem, etc, particularly if parts of the problem are being programatically generated, which might be the case for DSLs sitting on top of Convex. Note, however, we don't recurse into the internal structure of an atom, and some atoms create internal variables and constraints etc in the conic form; this doesn't help for seeing into that.
This is optional item 1 of the list in #320. I initially wasn't sold on adding a dependency to Convex, nor complicating the printing of its objects, but after using this, it's hard to go back.
Note: AbstractTrees.jl does not actually respect the
maxdepth
argument forprint_tree
(it looks like it's just not implemented). I made a PR to fix that (JuliaCollections/AbstractTrees.jl#38), but it might be some time before that gets merged, judging by the repo's activity. So I vendoredtree_print
with the changes from that PR to a submodule inutilities/tree_print.jl
. When the PR to AbstractTrees (or equivalent) eventually goes through, we can just replace allTreePrint.print_tree
byAbstractTrees.print_tree
, and delete the fileutilities/tree_print.jl
.Fun note: somehow I've been very into improving printing the past few days-- a kind of sibling PR to this is pretty printing for MOI optimizers: jump-dev/MathOptInterface.jl#864.