-
Notifications
You must be signed in to change notification settings - Fork 11
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
add support to linear maps #30
Conversation
Thanks! Looks reasonable and useful. Did you do any benchmarks by any chance? |
@acroy From the output time in test for a 1000 x 1000 sparse matrix, the time consumption decreased by an order when the program fall back to using default Do you know what may explain this counter intuitive result? |
Hard to say. How did you do the test? |
It is in
The second run uses |
You have to run those tests at least twice to get a realistic timing. Following #29 it might be good to use |
using LinearMaps
using Compat, BenchmarkTools
using Expokit
n = 1000
sp = sprand(n,n,0.01)
A = LinearMap{ComplexF64}(x->sp*x, n)
v = eye(n,1)[:]+0im*eye(n,1)[:] @benchmark Expokit.expmv(1.0, $A, $v, anorm=$(Compat.opnorm(sp, Inf)))
@benchmark Expokit.expmv(1.0, $A, $v, anorm=1.0)
CPU info: |
Interesting. So it is more a factor of 2. I guess the algorithm takes different numbers of iterations depending on It is probably a “feature” of the original algorithm ... Maybe you could open a separate issue for this? |
It is somehow related to the stopping criteria, but I haven't thuroully read the reference yet and can not have a conclusion. I have opened an issue here #31 . |
Great! I will have a look when I have access to a computer again. I thought about the default behavior of the new keyword. Wouldn’t it be easier to take |
I agree that the program should have consistent behavior. We should find out whether |
@acroy https://github.com/QuantumBFS/Yao.jl It will be helpful if you would consider revising and merging this PR at the time when Julia 1.0 releases. By the way, do you know the bechmark in |
Don't worry I am certainly going to merge this feature. However, I think you misunderstood me: In your PR the default value of |
OK, got it. I think we should provide more meaningful error information.
is better than
because, with the second error, user still does not know what to do. Or, we can
Warning or error, Which do you prefer? |
Fair enough, instead of silently setting |
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.
Looks fine. I just have few minor remarks.
src/expmv.jl
Outdated
@@ -1,5 +1,20 @@ | |||
export expmv, expmv! | |||
|
|||
function default_anorm(A) | |||
try | |||
norm(A, Inf) |
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 would suggest Compat.opnorm
here.
src/expmv.jl
Outdated
@@ -13,7 +28,7 @@ function expmv{T}( t::Number, | |||
A, vec::Vector{T}; | |||
tol::Real=1e-7, | |||
m::Int=min(30, size(A, 1)), | |||
norm=Base.norm, anorm::Real=0) | |||
norm=Base.norm, anorm=nothing) |
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.
And here just anorm=default_anorm(A)
(and everywhere else as well).
Hi, I'm maintaining https://github.com/matteoacrossi/ExpmV.jl that @GiggleLiu mentioned above. I actually forked from https://github.com/marcusps/ExpmV.jl which was inactive, because I needed to extend the ExpmV is a translation of a more recent algorithm published by Al-Mohy and Higham in 2010, (the original MATLAB implementation is here https://github.com/higham/expmv), which is not based on Krylov subspace projection. In the paper they compare it to Expokit and discuss pros and cons of both algorithms. I think it would be interesting to implement the same real-life benchmarks for both packages to have a detailed comparison (I've seen that in PR #28 @mforets has added some). One could even think of merging the two packages (or create a wrapper package) and then give the user the option to choose which algorithm to use. |
It would also be nice to test the numerical accuracy, and time, on different functions. @MSeeker1340 did a bunch of accuracy tests with ExponentialUtilities.jl during its development in OrdinaryDiffEq.jl and it would be nice to have a comparison to help with further development. |
@matteoacrossi Great to hear that ExpmV is alive and being take care of. As I already wrote we had some discussions about the Krylov method and the AH approach in #1. Basically, I created Expokit.jl because I needed the functionality back then and I wanted to provide a port of I like the idea of setting up a (sparate) package/repo to collect benchmarks and compare different approaches and packages. This could be quite interesting and helpful. Maybe we should continue to discuss this in a separate issue (#21) though? |
@@ -1,6 +1,22 @@ | |||
using Expokit | |||
using Base.Test | |||
|
|||
struct LinearOp | |||
m | |||
end |
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.
wouldn't this be better as:
struct LinearOp{T}
m::T
end
Unless there is a recent development I am missing, I believe m
will be of type Any
without this change.
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.
You're right, thanks for pointing this out, add a type parameter can increase type stability a lot.
Since this LinearOp
is only used for testing and this branch has been merged, I probability won't fix it right now. Users are suggested to use the LinearMaps.jl package. LinearMap
type in this package is much more powerful and supports many abstract operations.
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. Let me explain a bit more why I asked. Since there is no documentation in this pull request, I looked at the code because I was a bit confused how to use this functionality. Although the pull request mentions LinearMaps, I actually mistakenly started to think that support for LinearMaps had been removed during the review process of this pull request in favor of LinearOp
.
That said, why not add LinearMaps
to test/REQUIRE
and use it in the tests if the goal is to support 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.
I think the title of the PR was a bit misleading. Basically, a new keyword anorm
was added which also lifts the need for A
to support norm/opnorm and hence allows using LinearMaps
. As @GiggleLiu says the test is not really an example for using LinearMaps
.
Maybe it would be a good a idea to add such an example to README or somewhere else, though?
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.
It is a good idea to add some examples. Also, it is the time to maintain a document using Documenter, rather than adding more examples into README.
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.
@GiggleLiu Sure, it is on the list. OTOH there isn't that much to document ...
Thanks 💯 for the clarifications. Does the merging of this mean that #29 can be closed? |
I changed the interface slightly to weaken the dependancy of
norm(A, Inf)
, in order toLinearMaps.jl
package. LinearMaps maps a matrix vector multiplication to a linear operator.norm
of input matrix, which can be expensive for some user defined matrices.The value of norm will not affect the correctness of result, thus it is proper to take a default value, e.g. 1.0.
Now a linear operator requires the following 3 interfaces