# LinearMap : error while running LinearMap

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.

Sai Krishna

1 Like

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.)

2 Likes

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

# Ising model

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

# XX model

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?

# this produces a linear map H that can be called from eigs

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)

``````
1 Like

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.

1 Like

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.

1 Like

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.