-
-
Notifications
You must be signed in to change notification settings - Fork 14
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
Shape of transpose(x)' differs for real and complex x #703
Comments
transpose(x)'
differs for Real
and Complex
Could you explain a bit more what you think the problem is? What did you want to happen? |
I'd guess that the unexpected part is that |
Maybe unexpected but then unexpectedly nice? If you want a vector all the time just |
I want a way to deduce The context is that I tested some code for While writing this code, I'm starting to suspect that identifying adjoint vectors with row matrices is a mistake: dual vectors should be vectors, and if you want a vector to turn into a matrix you should have to explicitly cast or reshape it. E.g:
I would prefer:
But that's a side track for the issue. |
It certainly creates lots of edge cases... I wasn't around but most other options got discussed in #42 However I wonder whether there should be a lazy |
Why not just return an eagerly conjugated vector? |
Someone could be relying on |
We did at one point have a lazy Conj wrapper in some of the initial sketch work... I don't recall all the considerations in deciding we didn't need it. |
I don't think being able to reliably mutate the original array through these kinds of mathy APIs is necessary. If you're doing this kind of operations it really implicitly treats the data as immutable mathematical objects rather than mutable containers. |
Thanks for that link. As it happens, the code I'm working on was inspired by up and down tuples. (Basic idea: an (n,m)-tensor maps m-dimensional arrays to n-dimensional ones.) I'm going to post it as soon as I tidy up the README, and ask for pointers to whatever wheel I'm reinventing. That thread might have some pointers. |
Redesigning the way dual vectors work is off the table until 2.0, but the fact that the shape of |
I feel like sometimes-aliasing behavior is worse than sometimes-column-sometimes-vector. |
Then the alternative would be to re-introduce the lazy |
@andyferris what would you think about bringing back the lazy |
The nice thing about adding a lazy Conj wrapper is that |
To play devil's advocate, there is a general problem with adding things: the number of edge cases increases geometrically with the number of things you add. If This won't be a common issue. As far as I'm concerned, it's fine if you decide this isn't worth fixing, and I add some |
Hi Andy, too :-) Numerical quantum atom optics is obviously a small world. |
Yes, we shouldn't have the behaviour of container properties like As @mbauman alluded to, one of the early implementations of this had a Bringing back As an implementation note - I used to consider one of the ℤ₂ to be transpose and the other conj and that was reflected in my implementation - but I think after "taking matrix transposes seriously" enough I was convinced (thanks Steven) that thinking of the dichotomy as adjoint × conj was more natural/productive and it would be interesting to see if the implementation is simplified by having just I can't see any other option that let's us use all the BLAS operations of adjoint/transpose/conjugation without extra copies. We might consider reducing laziness to fix
Oh, so you're that Rod, @thisrod. 😆 Hi! Indeed it is. |
Since |
My proposal was to make the group structure explicit - Ordering them in a specific way is just one way of ensuring two |
Maybe I'm not making my point well enough, let me try to be more explicit. In addition to every element being its own inverse, the group has these relations:
There are no compositions of elements that don't reduce to one of the other elements. In particular, this means that you never need to nest these structures unless there's some other intervening abstraction that prevents collapsing them. The elements adjoint(a::Conj) = transpose(a.parent)
adjoint(a::Transpose) = conj(a.parent)
adjoint(a::Adjoint) = a.parent
conj(a::Conj) = a.parent
conj(a::Transpose) = adjoint(a.parent)
conj(a::Adjoint) = transpose(a.parent)
transpose(a::Conj) = adjoint(a.parent)
transpose(a::Transpose) = a.parent
transpose(a::Adjoint) = conj(a.parent) There should never (unless you explicitly construct one) be a need for an
I don't get why ordering is a concern at all: the above shows that there's only ever a single lazy layer if we have all three lazy transforms. Yes, there's an ordering concern when there are intervening abstractions, but we can't see through that because they are, you know, abstract. Those array types themselves have to decide and define appropriate methods to move these lazy operations in or out. But they should always do so using the function forms, |
Yes, concretely that was my suggestion. (We can still export a
Yes this is the argument. :) After already attempting what you said during v0.7 development I was musing that perhaps decomposing the group of 4 into two seperate ℤ₂ wrappers would work out easier to implement and reason about, precisely with the major drawback that "one arbitrarily chosen element of the group being represented as a composite". Perhaps I am wrong but Julia is typically great at composing abstractions and felt it may be worth exploring.
Yes I was specifically addressing the case we remove
Yes, this is totally true - though from experience it becomes difficult to cover all the corner cases. The wrapper author might know all about the |
While everyone is thinking about this, here's the package I'm working on. I feel like it's ready for other people to look at, and I'd welcome any feedback before I announce it on Discourse. |
Using composition is generally a winning approach when it offers a multiplicative effect: we get every combination of things for free instead of having to handle each possible combination. In this case, it gives us exactly one thing "for free". There's no win, it's just makes things more complex for no advantage. That's why I keep harping on about how As to corner cases, let's consider the two approaches with respect to that:
Add to that the fact that it's very common that |
Has anyone considered this approach?
I'd have to think more about I'm unsure how best to implement dual vectors. |
This is annoying if you run into it. I imagine that the best fix is a special method for the
size
of this complicated type ofComplex
array.The text was updated successfully, but these errors were encountered: