-
Notifications
You must be signed in to change notification settings - Fork 152
/-Operator for LU #583
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
/-Operator for LU #583
Conversation
src/lu.jl
Outdated
\(F::LU, B::AbstractMatrix) = F.U \ (F.L \ B[F.p,:]) | ||
|
||
function /(B::AbstractMatrix, F::LU) | ||
pivot = similar(F.p) |
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.
Will this allocation be elided?
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.
By elided you mean omitted? (Sorry, I'm not familiar with the technical terms).
If that's the case, than I think no. It is needed for the next step to be accessed at the indices F.p.
The problem is that the pivot indices cannot be used the same was as in \. I wrote down the whole operation with matrices and the difference is that in case of / the P-matrix is multiplied from the right, while it is normally from the left (as is case of \). So the p-indices (F.p) have to be ordered differently. There might exist a smarter way to do this but I don't know it.
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, in this context, "elided" means "optimized away".
This operation with the indices looks like Base.invperm()
. I'd suggest adding the following utility function:
Base.@propagate_inbounds function Base.invperm(p::StaticVector)
ip = similar(p)
ip[p] = 1:length(p)
similar_type(p)(ip)
end
Checking with @code_native
indicates that the MVector
which is created here by similar
is optimized away :-D And so is the range object, which is very cool and kind of surprising.
Then inside your function, use pivot = @inbounds invperm(F.p)
(we can use @inbounds
because we know that F.p
is a permutation).
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.
Thanks, I was not aware of this function.
I added your suggestion to util. The performance increases a bit by using @inbounds.
However, in Base invperm also checks if p is a valid pivot vector (by checking if every value is unique). This might be worth implementing though it probably adds computation time.
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 think we just have to assume the data in the LU
is correct (that the pivot vector is a valid permutation).
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.
@c42f I'm not sure when to "trust" the optimizer - my understanding is that once the function is inlined into a more complex one, these optimizations may or may not occur (I'd love to know what is guaranteed...).
src/util.jl
Outdated
@inline drop_sdims(a::StaticArrayLike) = TrivialView(a) | ||
@inline drop_sdims(a) = a | ||
|
||
Base.@propagate_inbounds function Base.invperm(p::StaticVector) |
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 think you need to make this just an internal-facing static arrays utility function (not an overload of Base.invperm
because I feel that one should check the permutation is valid).
I found the time to remove the overloading of Base.invperm. Not sure why the checks are failing though. Probably due to incompatibility to code changes from the last months? |
The test errors look like they might be real. At least, they're related to the LU tests and fail on all julia versions. |
I'd love to merge this but we need to understand / fix the test failures. Do you have any time to investigate? |
I found some time and I think I know the problem and possibly a solution:
So for now I changed the type of the test to float. Maybe a different kind of test would be advisable? |
Just curious: is there something left to do? |
Thanks for bumping this, I must have missed your previous update.
Actually It would be nice to understand why that was failing but it's hard to imagine it's related to this PR. |
PR to add the /-Operator for LU-Types refering to this.
I'm fairly new to julia, so it is likely that there is a better way to calculate pivot (line 146/147 of lu.jl).
The PR also includes a testset for the division with LU.
Feel free to suggest improvements.
Fixes #582