# Unexpected behavior of similar

**URL:** <https://discourse.julialang.org/t/unexpected-behavior-of-similar/68318>\
**Category:** General Usage\
**Tags:** arrays\
**Created:** [September 17, 2021, 7:53am UTC](https://discourse.julialang.org/t/unexpected-behavior-of-similar/68318 "2021-09-17T07:53:26Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)\
**Post date:** [September 17, 2021, 7:53am UTC](https://discourse.julialang.org/t/unexpected-behavior-of-similar/68318/1 "2021-09-17T07:53:26Z")

</div>

I find this behavior of similar unexpected:

```julia
julia> r = [rand(2, 2) for i in 1:3]

julia> x = similar(r)
3-element Vector{Matrix{Float64}}:
 #undef
 #undef
 #undef

julia> x[1]
ERROR: UndefRefError: access to undefined reference
Stacktrace:
 [1] getindex(A::Vector{Matrix{Float64}}, i1::Int64)
   @ Base ./array.jl:801
 [2] top-level scope
   @ REPL[5]:1

```

That’s fine because `x[1]` is `undef`. But if I specify the type of the elements, I still get these `undef` that I can’t access to overwrite:

```julia
julia> x = similar(r, Matrix{Float64})
3-element Vector{Matrix{Float64}}:
 #undef
 #undef
 #undef

```

How can I fill `x`? What I am trying to do is something like this:

```julia
r = [rand(2, 2) for i in 1:3]
x = similar(r)
for i in 1:3
    x[i] .= rand(2, 2)
end

```

---

<div class="post-metadata">

**Author:** ![sostock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sostock/32/5546_2.png) [@sostock](https://discourse.julialang.org/u/sostock)\
**Post date:** [September 17, 2021, 8:08am UTC](https://discourse.julialang.org/t/unexpected-behavior-of-similar/68318/2 "2021-09-17T08:08:46Z")

</div>

> [@amrods](#):
>
> What I am trying to do is something like this:
> 
> ```julia
> r = [rand(2, 2) for i in 1:3]
> x = similar(r)
> for i in 1:3
> x[i] .= rand(2, 2)
> end
> 
> ```

Just do `x[i] = rand(2, 2)` (without the dot) instead of `x[i] .= rand(2, 2)`. That way you are making the element `x[i]` point to the new matrix that is created by `rand(2, 2)`. By using broadcasting, you try to overwrite _the values in the matrix `x[i]`_, but it fails because the matrix `x[i]` does not exist.

> [@amrods](#):
>
> But if I specify the type of the elements, I still get these `undef` that I can’t access to overwrite

Maybe I am misunderstanding you, but why do you think that specifying the element type would change things here? Since the original element type is already `Matrix{Float64}`, specifying it again doesn’t change anything.

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [September 17, 2021, 8:08am UTC](https://discourse.julialang.org/t/unexpected-behavior-of-similar/68318/3 "2021-09-17T08:08:49Z")

</div>

Maybe just

```julia
julia> similar.(r)
3-element Vector{Matrix{Float64}}:
 [0.0 1.37471521e-315; 1.376029345e-315 0.0]
 [0.0 1.37471521e-315; 1.376029345e-315 0.0]
 [0.0 1.37471521e-315; 1.376029345e-315 0.0]

```

---

<div class="post-metadata">

**Author:** ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)\
**Post date:** [September 17, 2021, 8:40am UTC](https://discourse.julialang.org/t/unexpected-behavior-of-similar/68318/4 "2021-09-17T08:40:32Z")

</div>

What I had in mind was to apply this function to a vector like `x`:

```julia
function claytonsample!(matkk, τ; randmat=randmat)
    matkk .= randmat
    τ == 0 && return matkk

    n = size(matkk, 1)
    for i in 1:n
        v = matkk[i, 2]
        u = matkk[i, 1]
        matkk[i, 2] = (1 - u^(-τ) + u^(-τ)*v^(-(τ/(1 + τ))))^(-1/τ)
    end
    return matkk
end

randmat = rand(10, 2)
matkk = similar(randmat)

#this works:
claytonsample!(matkk, 0.3; randmat=randmat)

#this doesn't:
randmat2 = [rand(10, 2) for i in 1:3]
matkk2 = similar(randmat2)

for i in 1:3
    claytonsample!(matkk2[i], 0.3; randmat=randmat2[i])
end

```

With @nilshg proposal, it now works:

```julia
randmat2 = [rand(10, 2) for i in 1:3]
matkk2 = similar.(randmat2)

for i in 1:3
    claytonsample!(matkk2[i], 0.3; randmat=randmat2[i])
end

```
