Circshift() shifts array in opposite direction to circshift!()

Hi there,

I have written the following little code in Julia 1.8 to try to figure out a bug. I’m trying to simulate periodic boundary conditions, and hence using the circshift function. But for some reason, it seems like the circshift(a,1) of a vector a will shift in the opposite direction to circshift!(a,1), even though I thought (I’m pretty new to Julia) that the only difference between these functions should be that the former creates a copy of its output and leaves a unchanged, and the latter updates the array.

For example,

vector = Float64[10,20,30,40,50]
println(circshift!(vector,1))
vector = Float64[10,20,30,40,50]
println(circshift(vector,1))

Gives me the output

[20.0, 30.0, 40.0, 50.0, 10.0]
[50.0, 10.0, 20.0, 30.0, 40.0]

Why are they shifting in opposite directions?

I can’t reproduce that on Julia 1.9

julia> vector = Float64[10,20,30,40,50]
5-element Vector{Float64}:
 10.0
 20.0
 30.0
 40.0
 50.0

julia> println(circshift!(vector,1))
[50.0, 10.0, 20.0, 30.0, 40.0]

julia> vector = Float64[10,20,30,40,50]
5-element Vector{Float64}:
 10.0
 20.0
 30.0
 40.0
 50.0

julia> println(circshift(vector,1))
[50.0, 10.0, 20.0, 30.0, 40.0]

This must be the issue - it must have been changed in 1.9. On my Julia 1.8 REPL, I get

julia> vector = Float64[10,20,30,40,50]
5-element Vector{Float64}:
 10.0
 20.0
 30.0
 40.0
 50.0

julia> println(circshift!(vector,1))
[20.0, 30.0, 40.0, 50.0, 10.0]

which is the opposite of your result. I guess I need an update.

Thank you!

are you sure there’s not some other hidden state in your REPL? these things sometimes happen during interactive use

I ask because I also do not reproduce even on 1.8, so an update should not be necessary (although I might recommend you update anyway :slight_smile: for new features and performance improvements)

I just started the REPL in a terminal specifically for this task, so I assume that that cannot be the case…?

1 Like

just to triple check, so in a completely fresh REPL, pasting

julia> vector = Float64[10,20,30,40,50];
julia> circshift!(vector,1)

outputs [20.0, 30.0, 40.0, 50.0, 10.0] ? if so that is pretty strange and does not match the behavior I am seeing. do you have any packages loaded in your startup.jl ? what is the exact output of versioninfo() ?

one more: how about the output of @less circshift!(vector,1) ?

I also just checked on version 1.8.5 and v1.10.0-rc2 and on both of them circshift agrees with circshift! for me.

Ok, so I have VS code running and its own REPL, but I opened a new terminal window and typed that in and I got this:

julia> vector = Float64[10,20,30,40,50];

julia> circshift!(vector,1)
5-element Vector{Float64}:
 20.0
 30.0
 40.0
 50.0
 10.0

If the VSCode is not affecting it or anything like that, then this should be a fresh REPL.

I believe I have imported many packages, but I’m afraid I don’t really know how to look at my startup.jl file.

The output of versioninfo is

Julia Version 1.8.1
Commit afb6c60d69a (2022-09-06 15:09 UTC)
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 12 × Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-13.0.1 (ORCJIT, skylake)
  Threads: 1 on 12 virtual cores

I believe the output of the last command you mentioned, @less circshift!(vector,1), is far too long for me to add here. What am I looking for there exactly?

Sorry about this, I really didn’t expect this to take so long to figure out! Thank you very much for your help.

how about @which circshift!(vector,1)?

That gives

circshift!(a::AbstractVector, shift::Integer) in Base at abstractarray.jl:3185

this is the output of @less circshift!(vector, 1) for me:

function circshift!(a::AbstractVector, shift::Integer)
    n = length(a)
    n == 0 && return
    shift = mod(shift, n)
    shift == 0 && return
    l = lastindex(a)
    reverse!(a, firstindex(a), l-shift)
    reverse!(a, l-shift+1, lastindex(a))
    reverse!(a)
    return a
end

where it will show you the definition of the function being called, was just checking if we have the same definition

it does look like there is an issue specifically only on 1.8.1, that is not present in 1.8.0 or 1.8.5 or any other version I can find, and I can now recreate it

This issue reproduces in version 1.8.1 (sep 2022) and was fixed here:

7 Likes

It looks like you’ve found it! Thank you so much for this - I suppose I will have to update to literally any other version…

Thank you so much! I should have found that sooner before submitting my post, sorry…

1 Like

No apologies needed, this is what this forum is for :slight_smile:

The next person who has this problem would find it and the “solution” faster!

3 Likes