| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
Codecov Report❌ Patch coverage is 86.02151% with 13 lines in your changes missing coverage. Please review.
|
Sorry, something went wrong.
There was a problem hiding this comment.
Overall I'm not fully convinced by the interface of exponential(!), especially in its current form and implementation this looks slightly strange.
LinearAlgebra uses an in-place version, i.e. it reuses the input array to return exp!, and looking at the different implementations you have here, it is not obvious that trying to fit this into a exponentiate!(A, expA, alg) signature is really helping us - on the contrary, all this is really doing is creating an additional copy at the end just to make sure that it is allocated in the provided output.
As we discussed for your previous PR, this really is not the purpose of being able to provide the output argument.
For the algorithms, thinking a bit ahead, it might be appropriate to just call these something along the lines of matrix functions via eig, since presumably these approaches are actually generic for all of these implementations.
Sorry, something went wrong.
The idea of putting it in this framework is to allow for different sorts of algorithms, i.e. ones that would also work for BigFloats. I get that in the BLASFloat case, we should avoid extra allocations, but could you elaborate on your suggestion for ExponentialViaLA? Do you just want to get rid of the preallocated output?
I may be missing your point here, but that was the idea behind the ExponentialViaEigh and ExponentialViaEig naming conventions? Or do you really want separate names for each eig_alg? |
Sorry, something went wrong.
I am indeed referring to the preallocated output, not the algorithms part. It really only makes sense to have the option of giving a preallocated output if we are actually able to use this, and for the current implementations you have this is not saving us any work, rather it is increasing it because you add an extra allocation at the beginning and an extra copy at the end. While it is definitely possible to have initialize_output(exponentiate!, A) = A to just allocate the result in-place, I still wonder if it is then useful to have to implement the boiler plate for fitting it in a framework that we are mostly going to bypass anyways.
Sorry I should have explained that better, I meant that I would like to avoid having to also define SqrtViaEig, SinViaEig, ..., and simply have some algorithm that signifies "solve this by doing an eigenvalue decomposition". |
Sorry, something went wrong.
Is your suggestion then to just skip the whole @ functiondef and other general frameworks we have to define exponentiate and exponentiate!, or to keep the current framework somewhat, but just remove the preallocated output argument?
Okay, I see. I agree and will change this. |
Sorry, something went wrong.
|
Regarding the algorithm names, I agree with Lukas and also think we want to have a general Regarding the role of the output arguments, I only partially agree. The whole point of why we started MatrixAlgebraKit.jl, is because in TensorKit we first want to define the output tensor, and then compute block per block the result, where we want to store the result in the corresponding block of the output tensor. Ideally, yes, the computation is such that we also use that output data as storage during the computation, in such a way that the end result "naturally" ends up there, but if that is difficult, a final copy! can still be useful. We can then always try to improve this later on behind the scenes, but at least TensorKit can be agnostic about this. Note that the LinearAlgebra exp! is also cheating, and typically also ends up just copying the final result back into A. There is no way to actually compute exp(A) fully in-place. The typical approach via Pade approximations has a ton of allocations. I think I actually have a slightly allocation-friendlier implementation lying around for some things we did in CMPSKit.jl |
Sorry, something went wrong.
|
Regardless of the comment about general matrix functions, it is a fact that the exponential is by far the most useful and common one that we need, so I am also not opposed to first thinking carefully about this one, and having some part of the implementation be specific for matrix exponentials. In particular, one important consideration that we might want to include in this design, that is specific to our use case, is that we also might be interested in computing exp(-im* δt*H) for real time evolution, where it is probably useful to use eigh for the Hermitian matrix H, but still the end result will be complex. Julia has a cis function for cis(x) = exp(im * x), but unfortunately that comes without a minus sign in the argument. But maybe cis(-δt * H) is not too bad. |
Sorry, something went wrong.
|
To comment on the TensorKit interaction, I definitely agree with the purpose, but this is not actually currently the design we ended up with. So basically there are two comments I have: On the one hand, there is the question about whether or not there are implementations that benefit from providing an additional output array. On the other hand, given that interface, if there is no way of naturally making the output end up in the provided destination, I would really like to avoid ending up with a final copy!(provided_dest, computed_exp) at the end, even as a "for now" implementation that we can improve on later. |
Sorry, something went wrong.
|
I guess I am a bit confused, because most of the implementations now do actually perform the final step in the calculation in such a way that the result is directly stored in the output array, no? It is only the algorithm that goes via Base/LinearAlgebra that requires the extra copy! step, and that implementation I will happily replace with my own Pade implementation. But it is also true that, by the time the final step of the calculation is reached; the memory of A, which has already been destroyed and is no longer containing active information, can be reclaimed to store the result, so initialize_output(...) = A could indeed be the right design choice. |
Sorry, something went wrong.
change name to `MatrixFunctionViaEig` etc change `decompositions` to `matrixfunctions` add default algorithm for Diagonal matrices add input checks add @testthrows to catch non-hermitian matrices being given to MatrixFunctionViaEigh change default exponential algorithm to e.g. `MatrixFunctionViaEig` of the default `eig_alg`
Co-authored-by: Jutho <Jutho@users.noreply.github.com>
Co-authored-by: Jutho <Jutho@users.noreply.github.com>
Co-authored-by: Jutho <Jutho@users.noreply.github.com>
|
I think all comments are now taken care of (except for the discussion of whether to use 1 or one(eltype(A)), where I've chosen the latter.) |
Sorry, something went wrong.
There was a problem hiding this comment.
sorry for being a bit slow on this, but I just realized that probably exponential!((tau, D)) is enough instead of the exponential!((tau, D), D, DiagonalAlgorithm()), which should make a lot of the code more generic and might allow us to just have it work for the TensorMap's instead.
Sorry, something went wrong.
Co-authored-by: Lukas Devos <ldevos98@gmail.com>
Co-authored-by: Lukas Devos <ldevos98@gmail.com>
Co-authored-by: Lukas Devos <ldevos98@gmail.com>
Co-authored-by: Lukas Devos <ldevos98@gmail.com>
Co-authored-by: Lukas Devos <ldevos98@gmail.com>
Co-authored-by: Lukas Devos <ldevos98@gmail.com>
Co-authored-by: Lukas Devos <ldevos98@gmail.com>
Co-authored-by: Lukas Devos <ldevos98@gmail.com>
| exponential!(A, expA, alg::MatrixFunctionViaEigh) = exponential!((one(eltype(A)), A), expA, alg) | ||
| exponential!(A::AbstractMatrix, expA::AbstractMatrix, alg::MatrixFunctionViaEig) = exponential!((one(eltype(A)), A), expA, alg) |
There was a problem hiding this comment.
Why does one have an ::AbstractMatrix restriction on the first two arguments and the other not?
Sorry, something went wrong.
There was a problem hiding this comment.
I don't think there's a special reason except for overlooking it, I'll patch this in a bit :)
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
This implements the exponential of a matrix for both BLASFloats and BigFloats.
I have named these functions exponential and exponential!, instead of the usual exp and exp! from LinearAlgebra. Extending these methods while keeping the current structure using @algdef and @ functiondef results in some naming conflicts. The default for BLASFloats is to use LinearAlgebra.exp!. In TensorKit, we can still stick to the exp naming convention.