# Deepsimilar()?

**URL:** <https://discourse.julialang.org/t/deepsimilar/86466>\
**Category:** Internals & Design\
**Created:** [August 28, 2022, 6:34pm UTC](https://discourse.julialang.org/t/deepsimilar/86466 "2022-08-28T18:34:42Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![nicolas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nicolas/32/26439_2.png) [@nicolas](https://discourse.julialang.org/u/nicolas)\
**Post date:** [August 28, 2022, 6:34pm UTC](https://discourse.julialang.org/t/deepsimilar/86466/1 "2022-08-28T18:34:42Z")

</div>

I am writing an optimization package where users can input arrays of arrays. For simple arrays, initialization can be done using `similar()` without copying values. For arrays of arrays however, I haven’t found anything other than `deepcopy()` to initialize them. Since I only need the memory allocated with the appropriate structure, something like `deepsimilar()` would seem cleaner and save some time. Does it already exist? Is it too specific to be useful?

---

<div class="post-metadata">

**Author:** ![ToucheSir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/touchesir/32/14411_2.png) [@ToucheSir](https://discourse.julialang.org/u/ToucheSir)\
**Post date:** [August 28, 2022, 6:40pm UTC](https://discourse.julialang.org/t/deepsimilar/86466/2 "2022-08-28T18:40:21Z")

</div>

Depending on how many levels of nesting your array has, `map(similar, array_of_arrays)` does the trick. This assumes none of the inner arrays are the same, e.g. (`x = [...]; array_of_arrays = [x, x]`).

On that note, many packages which expose specialized types for arrays of arrays also implement this for you. Here is how [RecursiveArrayTools does it](https://github.com/SciML/RecursiveArrayTools.jl/blob/master/src/vector_of_array.jl#L246).

---

<div class="post-metadata">

**Author:** ![nicolas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nicolas/32/26439_2.png) [@nicolas](https://discourse.julialang.org/u/nicolas)\
**Post date:** [August 28, 2022, 6:47pm UTC](https://discourse.julialang.org/t/deepsimilar/86466/3 "2022-08-28T18:47:34Z")

</div>

> [@ToucheSir](#):
>
> map(similar, array\_of\_arrays)

Thanks that works! Always amazed seeing answers coming in faster than the time it took to write my question 🙂.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [August 28, 2022, 7:14pm UTC](https://discourse.julialang.org/t/deepsimilar/86466/4 "2022-08-28T19:14:09Z")

</div>

> [@ToucheSir](#):
>
> This assumes none of the inner arrays are the same,

why does this limitation exist? I think even there’s aliasing in the inner arrays, when you “deep similar”, you probably don’t want the new array to keep the aliasing structure anyway?

---

<div class="post-metadata">

**Author:** ![nicolas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nicolas/32/26439_2.png) [@nicolas](https://discourse.julialang.org/u/nicolas)\
**Post date:** [August 29, 2022, 1:24am UTC](https://discourse.julialang.org/t/deepsimilar/86466/5 "2022-08-29T01:24:15Z")

</div>

As you pointed out, it depends on how many levels `x` has. `map(similar, x)` works for arrays of arrays, but not for arrays of arrays of arrays (and deeper). And RecursiveArrayTools works for vectors of arrays. I think your solution can be made to work for an arbitrary number of levels this way:

```julia
deepsimilar(x) = eltype(x) == eltype(eltype(x)) ? similar(x) : map(deepsimilar, x)

```

---

<div class="post-metadata">

**Author:** ![nicolas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nicolas/32/26439_2.png) [@nicolas](https://discourse.julialang.org/u/nicolas)\
**Post date:** [August 29, 2022, 8:08pm UTC](https://discourse.julialang.org/t/deepsimilar/86466/6 "2022-08-29T20:08:48Z")

</div>

By the way, the code for deepsimilar will create independent elements even when the initial arrays all pointed to the same object:

```julia
julia> deepsimilar(x) = eltype(x) == eltype(eltype(x)) ? similar(x) : map(deepsimilar, x)
deepsimilar (generic function with 1 method)

julia> x = [1,2];

julia> y = [x,x];

julia> z = [y,y]
2-element Vector{Vector{Vector{Int64}}}:
 [[1, 2], [1, 2]]
 [[1, 2], [1, 2]]

julia> deepsimilar(z)
2-element Vector{Vector{Vector{Int64}}}:
 [[234558320, 234558208], [287367152, 1976577520]]
 [[287367152, 2094960320], [287367152, 1976577520]]

```

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [August 29, 2022, 8:10pm UTC](https://discourse.julialang.org/t/deepsimilar/86466/7 "2022-08-29T20:10:29Z")

</div>

that’s what I want to know, is there any reason to NOT do this?

---

<div class="post-metadata">

**Author:** ![ToucheSir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/touchesir/32/14411_2.png) [@ToucheSir](https://discourse.julialang.org/u/ToucheSir)\
**Post date:** [August 29, 2022, 10:56pm UTC](https://discourse.julialang.org/t/deepsimilar/86466/8 "2022-08-29T22:56:59Z")

</div>

There are cases where you want structural sharing in a collection of arrays (e.g. tied weights in ML models), but I’m not aware of any for arrays of arrays. The note about inner arrays was mostly added for completeness.
