forked from SciML/ExponentialUtilities.jl
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexp.jl
More file actions
82 lines (62 loc) · 2.55 KB
/
exp.jl
File metadata and controls
82 lines (62 loc) · 2.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#
# Fallback
"""
cache=alloc_mem(A,method)
Pre-allocates memory associated with matrix exponential function `method` and matrix `A`. To be used in combination with [`exponential!`](@ref).
"""
function alloc_mem(A, method)
return nothing
end
@deprecate _exp! exponential!
@deprecate exp_generic exponential!
exponential!(A) = exponential!(A, ExpMethodHigham2005(A));
"""
exponential!(A::GPUArraysCore.AbstractGPUArray)
Computes the matrix exponential for GPU arrays. Automatically disables balancing
for GPU arrays as it is not supported on GPU devices.
See also: [`exponential!`](@ref)
"""
function exponential!(A::GPUArraysCore.AbstractGPUArray)
exponential!(A, ExpMethodHigham2005(false))
end;
## The diagonalization based
"""
ExpMethodDiagonalization(enforce_real=true)
Matrix exponential method corresponding to the diagonalization with `eigen` possibly by removing imaginary part introduced by the numerical approximation.
"""
struct ExpMethodDiagonalization
enforce_real::Bool
end
ExpMethodDiagonalization() = ExpMethodDiagonalization(true);
"""
E=exponential!(A,[method [cache]])
Computes the matrix exponential with the method specified in `method`. The contents of `A` are modified, allowing for fewer allocations. The `method` parameter specifies the implementation and implementation parameters, e.g. [`ExpMethodNative`](@ref), [`ExpMethodDiagonalization`](@ref), [`ExpMethodGeneric`](@ref), [`ExpMethodHigham2005`](@ref). Memory
needed can be preallocated and provided in the parameter `cache` such that the memory can be recycled when calling `exponential!` several times. The preallocation is done with the command [`alloc_mem`](@ref): `cache=alloc_mem(A,method)`.
`A` may not be sparse matrix type, since exp(A) is likely to be dense.
Example
```julia-repl
julia> A = randn(50, 50);
julia> B = A * 2;
julia> method = ExpMethodHigham2005();
julia> cache = ExponentialUtilities.alloc_mem(A, method); # Main allocation done here
julia> E1 = exponential!(A, method, cache) # Very little allocation here
julia> E2 = exponential!(B, method, cache) # Very little allocation here
```
"""
function exponential!(A, method::ExpMethodDiagonalization, cache = nothing)
F = eigen!(A)
E = F.vectors * Diagonal(exp.(F.values)) / F.vectors
if (method.enforce_real && isreal(A))
E = real.(E)
end
copyto!(A, E)
return A
end
"""
ExpMethodNative()
Matrix exponential method corresponding to calling `Base.exp`.
"""
struct ExpMethodNative end
function exponential!(A, method::ExpMethodNative, cache = nothing)
return exp(A)
end