Custom Iterator with one big computation at the begin + in place operation at every iterations

I am trying to build a custom iterator for the QuasiMonteCarlo.jl package.

I did not find an example doing the kind of things I want.

  1. I need first to generate 3 big matrices

for 1:M

  1. “randomize” in place these matrices

  2. compute something with the result and store the result

end

I don’t know how to build an iterator that store something and then use it at every iteration.

Here is a very simplified version of the problematic

# Iteration 0 -> create a matrix

N = d*n

X = reshape(range(0, step = π, length = N) .% 1, d, n)

# Iteration 1:M -> do something in place on the matrix

shuffle!(X)

Ideally, once the iterator is defined, application would look like

mean(X for MyIterator(M, args))

From the docs on iterators I cannot figure out, how to store and use an X in the iterator.

Define a data structure (a struct) that stores whatever you need, then define an iterate method for it.

For example, the Sobol.jl package defines a SobolSeq data structure, and then has an iterate method for it.

Thanks!
I used your piece of code + that which looks simpler (and maybe more up to date according to docs?).

using Random
struct MyIterator{T <: Real}
    X::Matrix{T}
    count::Int
end

MyIterator(n::Integer, d::Integer, M::Integer) = MyIterator(reshape(range(0, step = π, length = d*n), d, n).%1, M)

Base.length(s::MyIterator) = s.count
Base.iterate(s::MyIterator{T}, state=1) where {T} = state > s.count ? nothing : (shuffle!(@view(s.X[:,:])), state+1) # view for in place modification of s.X
Base.eltype(::Type{MyIterator{T}}) where {T} = Matrix{T}

# it works
for i in MyIterator(5,2,3) println(i) end
collect(MyIterator(5,2,3))