-
Notifications
You must be signed in to change notification settings - Fork 12
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
Optimize using in-place math; small cleanups #6
base: master
Are you sure you want to change the base?
Changes from 4 commits
3d389aa
73ba460
f3cf785
c2f33b4
3eced9f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,20 @@ | ||
export expmv | ||
|
||
function expmv(t, A, b; M = [], prec = "double", shift = false, full_term = false, prnt = false) | ||
function expmv(t, A, b; M::Array{Float64, 2} = Array(Float64, 0, 0), prec = "double", shift = false, full_term = false, prnt = false) | ||
# bal = false, | ||
|
||
#EXPMV Matrix exponential times vector or matrix. | ||
# [F,S,M,MV,MVD] = EXPMV(t,A,B,[],PREC) computes EXPM(t*A)*B without | ||
# [F,S,M] = EXPMV(t,A,B,[],PREC) computes EXPM(t*A)*B without | ||
# explicitly forming EXPM(t*A). PREC is the required accuracy, 'double', | ||
# 'single' or 'half', and defaults to CLASS(A). | ||
# | ||
# A total of MV products with A or A^* are used, of which MVD are | ||
# for norm estimation. | ||
# | ||
# The full syntax is | ||
# | ||
# [f,s,m,mv,mvd,unA] = expmv(t,A,b,M,prec,shift,bal,full_term,prnt). | ||
# | ||
# unA = 1 if the alpha_p were used instead of norm(A). | ||
# f = expmv(t,A,b,M,prec,shift,bal,full_term,prnt). | ||
# | ||
# If repeated invocation of EXPMV is required for several values of t | ||
# or B, it is recommended to provide M as an external parameter as | ||
# M = SELECT_TAYLOR_DEGREE(A,m_max,p_max,prec,shift,bal,true). | ||
# M = SELECT_TAYLOR_DEGREE(A,b_columns,m_max,p_max,prec,shift,bal,true). | ||
# This also allows choosing different m_max and p_max. | ||
|
||
# Reference: A. H. Al-Mohy and N. J. Higham, Computing the action of | ||
|
@@ -41,31 +36,27 @@ function expmv(t, A, b; M = [], prec = "double", shift = false, full_term = fals | |
n = size(A,1) | ||
|
||
if shift | ||
mu = trace(A)/n | ||
#mu = full(mu) # Much slower without the full! | ||
mu = trace(A)/n | ||
A = A-mu*speye(n) | ||
end | ||
|
||
if isempty(M) | ||
tt = 1 | ||
(M,mvd,alpha,unA) = select_taylor_degree(t*A,b) | ||
mv = mvd | ||
tt = 1.0 | ||
M = select_taylor_degree(t * A, size(b, 2)) | ||
else | ||
tt = t | ||
mv = 0 | ||
mvd = 0 | ||
end | ||
|
||
tol = | ||
if prec == "double" | ||
2.0^(-53) | ||
tol = | ||
if prec == "half" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While it won't affect performance really, I think to match common Julia syntax these should be symbols instead of strings. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have a working branch that tries to address these style issues (and also implements proper 1 norm estimation). Since so much code is shared, I am still not dispatching on the type, but rather branching on the type (instead of having precision specified as a argument, I take precision to be implicitly specified based on use of |
||
2.0^(-10) | ||
elseif prec == "single" | ||
2.0^(-24) | ||
elseif prec == "half" | ||
2.0^(-10) | ||
else | ||
2.0^(-53) | ||
end | ||
|
||
s = 1; | ||
s = 1.0; | ||
|
||
if t == 0 | ||
m = 0; | ||
|
@@ -83,15 +74,13 @@ function expmv(t, A, b; M = [], prec = "double", shift = false, full_term = fals | |
cost,m = findmin(C); # when C is one column. Happens if p_max = 2. | ||
end | ||
if cost == Inf | ||
cost = 0 | ||
cost = 0.0 | ||
end | ||
s = max(cost/m,1); | ||
s = max(cost/m,1.0); | ||
end | ||
|
||
eta = 1; | ||
|
||
if shift | ||
eta = exp(t*mu/s) | ||
eta = exp(t * mu / s) | ||
end | ||
|
||
f = b; | ||
|
@@ -104,7 +93,6 @@ function expmv(t, A, b; M = [], prec = "double", shift = false, full_term = fals | |
c1 = norm(b,Inf); | ||
for k = 1:m | ||
b = (t/(s*k))*(A*b); | ||
mv = mv + 1; | ||
f = f + b; | ||
c2 = norm(b,Inf); | ||
if !full_term | ||
|
@@ -118,7 +106,9 @@ function expmv(t, A, b; M = [], prec = "double", shift = false, full_term = fals | |
end | ||
|
||
end | ||
f = eta*f | ||
if shift | ||
f = eta*f | ||
end | ||
b = f | ||
end | ||
|
||
|
@@ -130,6 +120,5 @@ function expmv(t, A, b; M = [], prec = "double", shift = false, full_term = fals | |
# f = D*f | ||
#end | ||
|
||
#return (f,s,m,mv,mvd,unA) | ||
return f | ||
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.
Why not make
M
an optional argument instead so that way it dispatches. Then you can useM=nothing
vsM
a vector, and it will compile away the extranious branches whenM==nothing
.