# Varargs of vectors and scalars under modulo

**URL:** <https://discourse.julialang.org/t/varargs-of-vectors-and-scalars-under-modulo/52548>\
**Category:** Specific Domains\
**Tags:** question, math, generator\
**Created:** [December 29, 2020, 12:27am UTC](https://discourse.julialang.org/t/varargs-of-vectors-and-scalars-under-modulo/52548 "2020-12-29T00:27:27Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jakewilliami](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakewilliami/32/18945_2.png) [@jakewilliami](https://discourse.julialang.org/u/jakewilliami)\
**Post date:** [December 29, 2020, 12:27am UTC](https://discourse.julialang.org/t/varargs-of-vectors-and-scalars-under-modulo/52548/1 "2020-12-29T00:27:27Z")

</div>

How would I go about expanding the following code for any number of vectors (possibly using `Iterators` or `@nloops`)? My code below shows it working for the first three vectors.

```julia
function list_span(u̲::Vector{T}, v̲::Vector{T}, modulo::Int) where T <: Number
	span = Vector{T}[]
	
	for λ in 0:(modulo - 1), γ in 0:(modulo - 1)
		w̲ = mod.(λ*u̲ + γ*v̲, modulo)
		if w̲ ∉ span
			push!(span, w̲)
		end
	end
	
	return span
end
​
function list_span(u̲::Vector{T}, v̲::Vector{T}, t̲::Vector{T}, modulo::Int) where T <: Number
	span = Vector{T}[]
	
	for λ in 0:(modulo - 1), γ in 0:(modulo - 1), α in 0:(modulo - 1)
		w̲ = mod.(λ*u̲ + γ*v̲ + α*t̲, modulo)
		if w̲ ∉ span
			push!(span, w̲)
		end
	end
​
	return span
end

```

---

<div class="post-metadata">

**Author:** ![Ricardo\_Rosa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ricardo_rosa/32/18564_2.png) [@Ricardo\_Rosa](https://discourse.julialang.org/u/Ricardo_Rosa)\
**Post date:** [December 29, 2020, 11:22am UTC](https://discourse.julialang.org/t/varargs-of-vectors-and-scalars-under-modulo/52548/2 "2020-12-29T11:22:08Z")

</div>

I would first switch the order of `modulo` and the vectors, replace the list of vectors by a single vector argument followed by trailing dots, get the number of vectors with `length(u̲)` and replace the loop accordingly.

Something like this:

```julia
function list_span(modulo::Int, u̲::Vector{T}...) where T <: Number
	span = Vector{T}[]
    n_vec = length(u̲)

    for j in 0:modulo^n_vec-1
        λ = digits(j, base=modulo, pad=n_vec)
        w̲ =mod.(sum(λ .* u̲), modulo)
		if w̲ ∉ span
			push!(span, w̲)
		end        
    end	
	return span
end

```

---

<div class="post-metadata">

**Author:** ![Ricardo\_Rosa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ricardo_rosa/32/18564_2.png) [@Ricardo\_Rosa](https://discourse.julialang.org/u/Ricardo_Rosa)\
**Post date:** [December 29, 2020, 2:44pm UTC](https://discourse.julialang.org/t/varargs-of-vectors-and-scalars-under-modulo/52548/3 "2020-12-29T14:44:42Z")

</div>

An alternative way is to loop over the number of vectors and keep adding the multiples of each vector to the span of the previous vectors:

```julia
function list_span_alt(modulo::Int, u̲::Vector{T}...) where T <: Number
    n_vec = length(u̲)
    span = Vector{T}[zero(u̲[1])]
    for n=1:n_vec
        new_span = copy(span)
        for v in span, λ=1:modulo-1
            w̲ = mod.(v + λ * u̲[n], modulo)
            if w̲ ∉ new_span
                push!(new_span, w̲)
            end
        end
        span = new_span
    end
	return span
end

```

It seems more efficient:

```julia
julia> @btime list_span(3, [1,2,1], [3,1,2]);
  12.523 μs (106 allocations: 7.77 KiB)

julia> @btime list_span_alt(3, [1,2,1], [3,1,2]);
  2.272 μs (33 allocations: 3.47 KiB)

julia> Set(list_span(3, [1,2,1], [3,1,2])) == Set(list_span_alt(3, [1,2,1], [3,1,2]))
true

```

But the other way with `digits` and was cooler, rsrsrs.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 29, 2020, 3:34pm UTC](https://discourse.julialang.org/t/varargs-of-vectors-and-scalars-under-modulo/52548/4 "2020-12-29T15:34:29Z")

</div>

If you like the other way of ordering the input arguments, you can make an outer method

```julia
span_list(args...) = list_span(last(args), args[1:end-1])

```

and then you get to pass the modulo after all the vectors.

---

<div class="post-metadata">

**Author:** ![Ricardo\_Rosa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ricardo_rosa/32/18564_2.png) [@Ricardo\_Rosa](https://discourse.julialang.org/u/Ricardo_Rosa)\
**Post date:** [December 29, 2020, 4:37pm UTC](https://discourse.julialang.org/t/varargs-of-vectors-and-scalars-under-modulo/52548/5 "2020-12-29T16:37:17Z")

</div>

Nice.

Hmm, but then you don’t get to enforce the type of each argument.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 29, 2020, 4:45pm UTC](https://discourse.julialang.org/t/varargs-of-vectors-and-scalars-under-modulo/52548/6 "2020-12-29T16:45:57Z")

</div>

You enforce it in the inner function.
