Skip to content

How best to fix similar for triangular matrices? #271

Closed
@artkuo

Description

@artkuo

In response to #258, the bug was traced to mean which relies on similar (through reducedim) to prepare an array for its output, e.g. mean of a 4x3 matrix along dim 1 should yield a 1x3. It ends up calling something like similar(triangularmatrix, LowerTriangular, (1,3)) (the template matrix, the desired type, and the dimensions), which fails because a 1x3 triangular matrix doesn't make sense. In this context, similar means "give me a matrix with the same eltype" not "give me another triangular just like this one."

  1. An easy fix (@tkelman) is to adjust similar so that when optional dimensions are used, it automatically drops the triangular, which results in AbstractMatrix. When no dimension is given, it could yield a lower triangular. This actually works, and even preserves sparsity automatically. I find this a bit yucky, because the return type depends implicitly on how the call is made.
  2. Another fix is to change similar to always drop the triangular, again preserving sparsity where applicable. I've tried this fix and it doesn't break any existing tests (other than needing a new test for similar). Downside is it is a potentially breaking change for user code where similar is intended to mean "give me another of same structure." Yucky as well.
  3. Yet another possibility is to delve into the details of how similar is called and root out the problem at the level of reducedim. Where appropriate, it could be replaced by sameeltype, meaning a more explicit version of what is meant already. In other cases, the replacement might be samecontainer or samestructure or some such. Idea is to make explicit what you really want. This seems like a longer term solution, because similar occurs 600+ times in julia project (between method calls and definitions) and it may not be straightforward to know what is intended when.

Previous discussions have complained about similar JuliaLang/julia#11574 (comment) and JuliaLang/julia#10064. The problem is that similar is vague. Present docs say that behavior for special types should be decided case by case. Right now similar for triangulars is undocumented, so the user must guess or look at the source code. Might be better to clarify and perhaps split off a sameeltype or samestructure in the long run.

There are safe, conservative ways to do option 2, such as when triangular is input, to return a matrix that's not triangular but whose off-triangle has been zeroed. This makes it safe for the user expecting a triangular back and for the most part won't blow up on them. (Triangulars store a full matrix in their .data field, so there is potential danger if things are not zeroed.)

What is the right solution?

Metadata

Metadata

Assignees

Labels

needs decisionA decision on this change is needed

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions