I tried to run Julia-1.6.0 dev version in my laptop. When running the LinearMap function, I encountered an error, which I have attached along with this query. I would like any suggestions to improve.
Thanks in advance,
Sai Krishna
I tried to run Julia-1.6.0 dev version in my laptop. When running the LinearMap function, I encountered an error, which I have attached along with this query. I would like any suggestions to improve.
Thanks in advance,
Sai Krishna
Please try to avoid posting screenshots and quote your code instead, as this makes it much easier to help you. Also try to make sure, you provide a complete working example, as you didn’t define multiplyHPsi
anywhere. This thread may be helpful to you:
That said, does your code work on a previous version of Julia? What version of LinearMaps.jl
are you using? (You can find that out with ]st LinearMaps
in the REPL.)
Thank you for your reply. I will quote the entire working example now. The LinearMaps.jl version is 2.6.1.
The code is as follows:
function multiplyHPsi!(nPsi::Vector, Psi::Vector) # requires H2 to have been defined
length(nPsi)==length(Psi) || throw(DimensionMismatch())
dimN = length(Psi) # Dimension of the vector space
N = convert(Int64,log2(dimN)) # Number of spins
dimPsi = tuple(fill(2::Int,1,N)…) # dimsPsi =(2,2,2, …, 2)
a = collect(2:N)
a = [a;1]
cyclperm = tuple(a…) #tuple for cyclic permutation cyclperm = (2, 3, … N, 1)
Psi = reshape(Psi,dimPsi)
nPsi = zeros(dimPsi)
for n=1:N
Psi = reshape(Psi,(4,2^(N-2)))
nPsi = reshape(nPsi,(4,2^(N-2)))
nPsi += H2*Psi
Psi = reshape(Psi,dimPsi)
nPsi = reshape(nPsi,dimPsi)
Psi = permutedims(Psi,cyclperm)
nPsi = permutedims(nPsi,cyclperm)
end
nPsi = reshape(nPsi,dimN)
return nPsi
end
function buildIsing(h=1.0) # Ising model with transverse magnetic field h (critical h=1 by default)
X = [0 1; 1 0]
Z = [1 0; 0 -1]
I = diagm(0 => ones(2))
XX = kron(X,X)
ZI = kron(Z,I)
IZ = kron(I,Z)
H2 = -(XX + h/2*(ZI+IZ))
return H2
end
function buildXX(h=0.0) # XX model with magnetix field h (h=0 by default)
X = [0. 1; 1 0]
Y = [0. -1; 1 0] # we avoid using complex numbers
Z = [1 0; 0 -1]
I = diagm(0 => ones(2))
ZI = kron(Z,I)
IZ = kron(I,Z)
H2 = -(kron(X,X)-kron(Y,Y)) + h/2*(ZI+IZ) # sXsX+sYsY + hZ
return H2
end
display(buildIsing())
display(buildXX())
h = 1
H2 = buildIsing(h) # Hamiltonian
H2 = buildXX()
D,U = eigen(H2)
shiftE = D[end]
H2 = H2 - shiftE*diagm(0 => ones(4)) # remember to re-shift the energy later on!
N = 10 # number of spins
Psi = rand(2^N)
nPsi = rand(2^N)
Psi = Psi/norm(Psi)
init_steps = 1
energy = ones(0)
initial_step=1
Nsteps = 0
@time nPsi = multiplyHPsi!(nPsi, Psi) # N = 20 took 4 seconds;
initial_step += Nsteps
Nsteps = 10
final_step = initial_step + Nsteps-1
for n=initial_step:final_step
nPsi = multiplyHPsi!(nPsi,Psi)
newenergy = real(Psi’nPsi)[1] + shiftEN
energy = [energy; newenergy]
Psi = nPsi/norm(nPsi)
print(n-initial_step+1, “:”, Nsteps, " ")
end
figure(“Power_method”,figsize=(14,4))
subplot(121) # Create the 1st axis of a 2x2 arrax of axes
grid(“on”) # Create a grid on the axis
title(“Power method”)
ax = gca()
xlabel(“all iterations”)
ylabel(“Energy”)
plot(energy, marker = “o”)
subplot(122) # Create the 1st axis of a 2x2 arrax of axes
grid(“on”) # Create a grid on the axis
title(“Power method”)
ax = gca()
xlabel(“most recent iterations”)
ylabel(“Energy”)
plot(initial_step:final_step, energy[initial_step:final_step], marker = “o”)
using LinearMaps; using Arpack
N = 14 # N=14 took 4.5 sec; N=16 took 35 sec; N=18 took 122 sec
m = 1 # how many states?
H = LinearMap{Float64}(multiplyHPsi!, 2^N; isreal = true, ismutating = true) # use this for real symmetric H
#H = LinearMap(multiplyHPsi!, 2^N, isreal=false, ismutating=true, ishermitian=true) # use this for complex hermitian H
@time u, v = eigs(H; nev=m, which=:SR) #:SR stands for smallest real part
Energy = real(u[1] + shiftE*N) # let us undo the shift in energy
Psi = v
E = Energy
Note that isreal
is not a keyword argument of LinearMap
, that’s also the complaint of the MethodError
. You should specify the eltype
of your map as you do with LinearMap{Float64}
. Just leave out the isreal
will probably resolve your problem.
Thank you for the suggestion but I ran into the following error after removing the isreal. And how do you specify the eltype of the map. Please let me know that.
The following is the error:
syntax: invalid keyword argument syntax “true” around In[66]:4
Stacktrace:
[1] top-level scope at none:1
I am guessing, that you left a semicolon before the positional argument isreal
instead of a comma. Replacing that with a comma should fix this error. It’s a bit of a confusing error message though, because 1.5 has a new feature, where variables after a semicolon in a function call are interpreted as x=x
, i.e. a keyword argument where the value is that variable in the current scope. Do you want to open an issue on GitHub, because this should probably throw a more helpful error for true
and false
?
I was assuming that you understand a bit the basic concepts in Julia. When I said, leave out the keyword argument isreal
, this implies also its value:
H = LinearMap{Float64}(multiplyHPsi!, 2^N; ismutating = true)
The eltype
is what you put in between the curly braces here, LinearMap{ eltype }
.
In this case, as it seems you want to diagonalize quantum Hamiltonians, it might be useful to specify that this is a symmetric (or hermitian) operator, i.e.
H = LinearMap{Float64}(multiplyHPsi!, 2^N; ismutating = true, issymmetric = true)
But once I removed the isreal argument, I got the same error.
Can you post the line which you entered just before the error was thrown, and the error.
This is the line which I entered before the error :
H = LinearMap{Float64}(multiplyHPsi!; 2^N, true) # use this for real symmetric H
This is the error:
MethodError: no method matching (LinearMaps.FunctionMap{Float64,F1,F2} where F2 where F1)(::typeof(multiplyHPsi!), ::Int64, ::Bool)
Closest candidates are:
(LinearMaps.FunctionMap{T,F1,F2} where F2 where F1)(::Any, ::Int64; kwargs…) where T at /home/sai/.julia/packages/LinearMaps/RjB5x/src/functionmap.jl:20
(LinearMaps.FunctionMap{T,F1,F2} where F2 where F1)(::Any, ::Int64, !Matched::Int64; kwargs…) where T at /home/sai/.julia/packages/LinearMaps/RjB5x/src/functionmap.jl:21
(LinearMaps.FunctionMap{T,F1,F2} where F2 where F1)(::Any, ::Any, !Matched::Int64; kwargs…) where T at /home/sai/.julia/packages/LinearMaps/RjB5x/src/functionmap.jl:22
…
Stacktrace:
[1] LinearMap{Float64}(::Function, ::Int64, ::Vararg{Any,N} where N; kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at /home/sai/.julia/packages/LinearMaps/RjB5x/src/LinearMaps.jl:164
[2] LinearMap{Float64}(::Function, ::Int64, ::Vararg{Any,N} where N) at /home/sai/.julia/packages/LinearMaps/RjB5x/src/LinearMaps.jl:164
[3] top-level scope at In[84]:4
I am sorry for my mistake about the error. The actual error is:
syntax: invalid keyword argument syntax “true” around In[88]:4
Stacktrace:
[1] top-level scope at none:1
Why did you not copy the code I posted?
H = LinearMap{Float64}(multiplyHPsi!, 2^N; ismutating = true)
I think you want to read a bit about basic julia syntax.
Thanks for your reply. I have used the syntax and read about the LinearMap function. Now, I need to use the eigs function to decompose the resulting matrix. The code is as follows:
N = 14 # N=14 took 4.5 sec; N=16 took 35 sec; N=18 took 122 sec
m = 1 # how many states?
H = LinearMap(multiplyHPsi!, 2^N, ismutating = true, ishermitian = true)
#H = LinearMap(multiplyHPsi!, 2^N, isreal=false, ismutating=true, ishermitian=true) # use this for complex hermitian H
@time u, v = eigs(H; nev=m, which=:SR) #:SR stands for smallest real part
#Energy = real(u[1] + shiftE*N) # let us undo the shift in energy
#Psi = v
#E = Energy
The error thrown is:
MethodError: no method matching multiplyHPsi!(::SubArray{Float64,1,Array{Float64,1},Tuple{UnitRange{Int64}},true}, ::SubArray{Float64,1,Array{Float64,1},Tuple{UnitRange{Int64}},true})
Stacktrace:
[1] A_mul_B!(::SubArray{Float64,1,Array{Float64,1},Tuple{UnitRange{Int64}},true}, ::LinearMaps.FunctionMap{Float64,typeof(multiplyHPsi!),Nothing}, ::SubArray{Float64,1,Array{Float64,1},Tuple{UnitRange{Int64}},true}) at /home/sai/.julia/packages/LinearMaps/RjB5x/src/functionmap.jl:112
[2] mul!(::SubArray{Float64,1,Array{Float64,1},Tuple{UnitRange{Int64}},true}, ::LinearMaps.FunctionMap{Float64,typeof(multiplyHPsi!),Nothing}, ::SubArray{Float64,1,Array{Float64,1},Tuple{UnitRange{Int64}},true}, ::Bool, ::Bool) at /home/sai/.julia/packages/LinearMaps/RjB5x/src/LinearMaps.jl:78
[3] mul! at /home/sai/.julia/packages/LinearMaps/RjB5x/src/LinearMaps.jl:76 [inlined]
[4] (::Arpack.var"#matvecA!#24"{LinearMaps.FunctionMap{Float64,typeof(multiplyHPsi!),Nothing}})(::SubArray{Float64,1,Array{Float64,1},Tuple{UnitRange{Int64}},true}, ::SubArray{Float64,1,Array{Float64,1},Tuple{UnitRange{Int64}},true}) at /home/sai/.julia/packages/Arpack/o35I5/src/Arpack.jl:156
[5] aupd_wrapper(::Type{T} where T, ::Arpack.var"#matvecA!#24"{LinearMaps.FunctionMap{Float64,typeof(multiplyHPsi!),Nothing}}, ::Arpack.var"#18#25", ::Arpack.var"#19#26", ::Int64, ::Bool, ::Bool, ::String, ::Int64, ::Int64, ::String, ::Float64, ::Int64, ::Int64, ::Array{Float64,1}) at /home/sai/.julia/packages/Arpack/o35I5/src/libarpack.jl:83
[6] _eigs(::LinearMaps.FunctionMap{Float64,typeof(multiplyHPsi!),Nothing}, ::UniformScaling{Bool}; nev::Int64, ncv::Int64, which::Symbol, tol::Float64, maxiter::Int64, sigma::Nothing, v0::Array{Float64,1}, ritzvec::Bool) at /home/sai/.julia/packages/Arpack/o35I5/src/Arpack.jl:181
[7] #eigs#16 at /home/sai/.julia/packages/Arpack/o35I5/src/Arpack.jl:66 [inlined]
[8] #eigs#9 at /home/sai/.julia/packages/Arpack/o35I5/src/Arpack.jl:45 [inlined]
[9] macro expansion at ./timing.jl:174 [inlined]
[10] top-level scope at ./In[195]:4
Sorry my mistake. I forgot write the function to accept AbstractVector instead Vector. This solved the issue.
Thank you everyone for your valuable time and inputs.
Hi! I’m following Vidal’s PSI online course too.
Do you succeed in this notebook?
I found the following strange behavior.
If I define LinearMap like this:
H = LinearMap{Float64}(multiplyHPsi!, 2^N; ismutating=true, issymmetric = true)
I need to check whether it does what it should, so I test
Psi = randn(2^N)
nPsi = randn(2^N)
Psi = Psi / norm(Psi)
nPsi1 = multiplyHPsi!(nPsi, Psi)
nPsi2 = H(Psi)
Now, the result nPsi1
is OK and looks correct; however, nPsi2
looks like random outcomes and looks nothing close to nPsi1
, as it should.
I’m confused what goes wrong here.
That’s odd; could you post the full code that gives you the issue, including a working version of multiplyHPsi!
. You can also put it in a gist and just paste the link here.
Hi Jutho!
Thank you very much for the reply.
I’ve create and .jl file to reproduce the above-mentioned issue.
Here is the link:
https://gist.github.com/brucelyu/b038114b507ab5ca241f78a3f93eb0f2