# Stop custom type that inherits from SparseArray getting converted to full array

**URL:** <https://discourse.julialang.org/t/stop-custom-type-that-inherits-from-sparsearray-getting-converted-to-full-array/38256>\
**Category:** General Usage\
**Tags:** sparse\
**Created:** [April 26, 2020, 7:13pm UTC](https://discourse.julialang.org/t/stop-custom-type-that-inherits-from-sparsearray-getting-converted-to-full-array/38256 "2020-04-26T19:13:15Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![james-a-mcmanus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/james-a-mcmanus/32/14368_2.png) [@james-a-mcmanus](https://discourse.julialang.org/u/james-a-mcmanus)\
**Post date:** [April 26, 2020, 7:13pm UTC](https://discourse.julialang.org/t/stop-custom-type-that-inherits-from-sparsearray-getting-converted-to-full-array/38256/1 "2020-04-26T19:13:15Z")

</div>

Hello all, I’m very new to julia and trying to essentially make a wrapper for a sparse-type array.

When I set up the type to inherit from AbstractSparseArrays, operations with non-sparse arrays output a full array.

```julia
using SparseArrays

struct SparseStruct{T,N} <: AbstractSparseArray{T,Int,N}
	data::AbstractSparseArray{T,Int,N}
	dims::NTuple{N,Int}
end

# forwarding some base methods
Base.size(A::SparseStruct) = A.dims
Base.getindex(A::SparseStruct, I::Any) = getindex(A.data, I)
Base.display(A::SparseStruct) = display(A.data)

a = SparseStruct(sprand(20,20,0.1), (20,20))

println(typeof(a * 2)) # produces full array
println(typeof(a .* sparse([2]))) # produces sparse array

```

This is different to how a normal sparse array acts:

```julia
println(typeof(a.data * 2)) # produces a sparse array.

```

My assumption was that by inheriting the AbstractSparseArray would lead to SparseArray-like functionality.

Thanks in advance

---

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [April 26, 2020, 11:47pm UTC](https://discourse.julialang.org/t/stop-custom-type-that-inherits-from-sparsearray-getting-converted-to-full-array/38256/2 "2020-04-26T23:47:25Z")

</div>

I believe you would need to implement multiplication for your struct something like:

```julia
Base.:*(a::SparseStruct, b::SparseStruct) = SparseStruct(a.data * b.data, a.dims)

```

You might want to do some error checking that the dims are equal and possibly add a where clause to ensure that T and N are the same for both inputs(if you want that).

---

<div class="post-metadata">

**Author:** ![james-a-mcmanus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/james-a-mcmanus/32/14368_2.png) [@james-a-mcmanus](https://discourse.julialang.org/u/james-a-mcmanus)\
**Post date:** [April 27, 2020, 3:25pm UTC](https://discourse.julialang.org/t/stop-custom-type-that-inherits-from-sparsearray-getting-converted-to-full-array/38256/3 "2020-04-27T15:25:32Z")

</div>

Thank you for the quick reply.

Your suggestion solved part of the problem, however i ran into a similar problem trying to define broadcasted functions.

Do you have a suggestion for the best way to bootsrap on top of SparseArrays inbuilt broadcasting behaviour?

From [Interfaces](https://docs.julialang.org/en/v1/manual/interfaces/#man-interfaces-broadcasting-1) in the manual it says you’d have to redefine Base.BroadcastingStyle and Base.Similar.

I thought I could try to get piggyback on SparseArrays with

```julia
Base.BroadcastStyle(::Type{SparseStruct{T,N}}) where {T,N} = SparseArrays.HigherOrderFns.SparseMatStyle()

```

But that gave me the following error which I can’t get my head around:

```julia
ERROR: MethodError: no method matching _copy(::SparseArrays.HigherOrderFns.var"#3#4"{typeof(*),SparseArrays.HigherOrderFns.var"#17#20"{SparseConnection{Float64,2},SparseArrays.HigherOrderFns.var"#23#26"{Int64}}})

```

And i’m similarly stuck with trying to redefine Base.similar

---

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [April 27, 2020, 6:04pm UTC](https://discourse.julialang.org/t/stop-custom-type-that-inherits-from-sparsearray-getting-converted-to-full-array/38256/4 "2020-04-27T18:04:08Z")

</div>

Uh, we’re out of my comfort zone, but based on my read of the “Customizing broadcasting” section of:  
[https://docs.julialang.org/en/v1/manual/interfaces/](https://docs.julialang.org/en/v1/manual/interfaces/)  
What I would do is:

```julia
# Your explicit call of a function might be better, I don't know.
Base.BroadcastStyle(::Type{SparseStruct{T, N}) where {T, N} =
    BroadcastStyle(AbstractSparseArray{T, Int, N})
Base.axes(x::SparseStruct) = axes(x.data)
Base.broadcastable(x::SparseStruct) = broadcastable(x.data)

```

i’m really unsure about the `similar` function. My best guess would be:

```julia
Base.similar(bc::SparseStruct{T, N}, ::Type{SparseStruct{T, N}) where {T, N} = 
    SparseStruct(similar(bc.data, typeof(bc.data)), bc.dims)

```

But that is really a guess.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [April 27, 2020, 6:09pm UTC](https://discourse.julialang.org/t/stop-custom-type-that-inherits-from-sparsearray-getting-converted-to-full-array/38256/5 "2020-04-27T18:09:19Z")

</div>

Welcome to Julia! You’re diving straight into the deep end here… and there are some sharks in the pool.

In short: subtyping of `AbstractSparseArray` isn’t magic and isn’t a fully formed and public API. You’ll probably have the most success in trying to duplicate how `SparseMatrixCSC` works, but that relies on lots of internally goodness.

---

<div class="post-metadata">

**Author:** ![james-a-mcmanus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/james-a-mcmanus/32/14368_2.png) [@james-a-mcmanus](https://discourse.julialang.org/u/james-a-mcmanus)\
**Post date:** [April 28, 2020, 10:25am UTC](https://discourse.julialang.org/t/stop-custom-type-that-inherits-from-sparsearray-getting-converted-to-full-array/38256/6 "2020-04-28T10:25:13Z")

</div>

Okay, thanks for your advice,  
In retrospect this was actually a pretty contrived way to go about what I wanted to do, subtyping a base abstract type initially seemed like a simple option, but you’re right it quickly got much more messy than I’d anticipated.
