# Sparsification of a Type

**URL:** <https://discourse.julialang.org/t/sparsification-of-a-type/1090>\
**Category:** General Usage\
**Created:** [December 21, 2016, 12:43pm UTC](https://discourse.julialang.org/t/sparsification-of-a-type/1090 "2016-12-21T12:43:24Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![abulak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abulak/32/28314_2.png) [@abulak](https://discourse.julialang.org/u/abulak)\
**Post date:** [December 21, 2016, 12:43pm UTC](https://discourse.julialang.org/t/sparsification-of-a-type/1090/1 "2016-12-21T12:43:24Z")

</div>

My first steps in julia, and one of the first in programming;)  
I have defined `MyType` ( I need it both for `Float`, `Rational{BigInt}` and `Complex`, hence `T<:Number`

```julia
type MyType{T<:Number}
coords::Vector{T}
name::String
some_field::OtherType
etc.

```

I have defined methods for `MyType` e.g.

```julia
length(X::MyType) = length(X.coords)

```

Now I noticed that it would be nice to have coords stored as `SparseVector`.  
How should I _sparsify_ `MyType`? One obvious thing is to just rewrite everything with `X.coords::SparseVector{T}`. But there should be a better (less tedious) way… I tried to define `MyType.coords` as `AbstractArray{T,1}`. This somewhat works but (understandably) results in huge penalty in speed even for dense vectors…  
(This is probably work for julia-0.6.0, as on 0.5 eg. enumeration of a sparse vector is painfully slow)

Side question: is there a way to make julia convert `MyType` automatically to `Vector{T}` so I don’t have to define non-specific methods (e.g. `length` above) for `MyType`?? I tried to go with `convert`:

```julia
import Base: convert
convert{T<:Number}(::Type{Vector{T}}, X::MyType) = X.coords

```

but this doesn’t work…

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 21, 2016, 12:49pm UTC](https://discourse.julialang.org/t/sparsification-of-a-type/1090/2 "2016-12-21T12:49:06Z")

</div>

You could use `type MyType{T<:AbstractVector}; coords::T; ...` since e.g. `SparseVector{Float64}` is a subtype of `AbstractVector`.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 21, 2016, 12:51pm UTC](https://discourse.julialang.org/t/sparsification-of-a-type/1090/3 "2016-12-21T12:51:17Z")

</div>

If you want to make sure that non-real element types cannot be used, you can do:

```julia
typealias CoordVector{T<:Real} AbstractVector{T}
type MyType{T<:CoordVector}
    coords::T
    ...
end

```

---

<div class="post-metadata">

**Author:** ![abulak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abulak/32/28314_2.png) [@abulak](https://discourse.julialang.org/u/abulak)\
**Post date:** [December 21, 2016, 11:19pm UTC](https://discourse.julialang.org/t/sparsification-of-a-type/1090/4 "2016-12-21T23:19:15Z")

</div>

Thanks for the answers;

I tried

```julia
typealias CoordinateVector{T<:Number} AbstractVector{T}

type MyType{T<:Number}
    coords::CoordinateVector{T}

```

but then Julia has problems inferring type of `X.coords` and plenty of ANY springs in the `@code_warntype` when using e.g `zeros(X.coords)`. This is more or less the same what happened when I replaced coords by `AbstractVector{T}`.

Or does that actually comes from me insisting `MyType` to be parametrised by the type of **elements** of coords??

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 21, 2016, 11:59pm UTC](https://discourse.julialang.org/t/sparsification-of-a-type/1090/5 "2016-12-21T23:59:17Z")

</div>

> [@abulak](#):
>
> type MyType{T\<:Number}  
> coords::CoordinateVector{T}

That won’t work because `coords` is still an abstract type. What about my suggestion?

---

<div class="post-metadata">

**Author:** ![abulak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abulak/32/28314_2.png) [@abulak](https://discourse.julialang.org/u/abulak)\
**Post date:** [December 22, 2016, 1:51am UTC](https://discourse.julialang.org/t/sparsification-of-a-type/1090/6 "2016-12-22T01:51:54Z")

</div>

I’m still trying to implement it, but this somehow requires more changes to the codebase;

I’m implementing an algebraic structure (ala polynomial ring), so thinking of `MyType` as  
parametrised by the type of coefficients is very natural, whereas parametrising by type of coords list is inintuitive (but I’m fighting with this right now)

Since I already’ve answered:

This new parametrisation means that I have to change every definition (e.g.)

```julia
(+){S<:Number, T<:Number}(X::MyType{S},Y::MyType{T}) = ...

```

to

```julia
(+){S<:CoordinateVector, T<:CoordinateVector}(X::MyType{S},Y::MyType{T}) = ...

```

and more… before simple `(+){S,T}(X::MyType{S},Y::MyType{T}) = ...` was sufficient. Do You know why?

---

<div class="post-metadata">

**Author:** ![abulak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abulak/32/28314_2.png) [@abulak](https://discourse.julialang.org/u/abulak)\
**Post date:** [December 22, 2016, 11:29am UTC](https://discourse.julialang.org/t/sparsification-of-a-type/1090/7 "2016-12-22T11:29:00Z")

</div>

Ok, so I’ve run into some problems: well maybe not problems, but…  
previously I had (the warn is important to me)

```julia
function (*){T<:Number, S<:Number}(a::T, X::MyType{S})
   T<:S || warn("coords and scalar are in different rings!")
   return MyType(a*X.coords)
end

```

Now I can not think of anything better than

```julia
function (*){<:Number, S<:CoordinateVector}(a::T, X::MyType{S})
    W = typeof(X.coordinates[1])
    T <: W || warn("coords and scalar are in different rings!")
    return MyType(a*X.coords)
end

```

which feels clunky…

---

<div class="post-metadata">

**Author:** ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)\
**Post date:** [December 22, 2016, 10:09pm UTC](https://discourse.julialang.org/t/sparsification-of-a-type/1090/8 "2016-12-22T22:09:20Z")

</div>

> [@abulak](#):
>
> I’m implementing an algebraic structure (ala polynomial ring), so thinking of MyType asparametrised by the type of coefficients is very natural, whereas parametrising by type of coords list is inintuitive (but I’m fighting with this right now)

If you wabt to dispatch by the type of coefficient, you can add another type parameter:

```julia
typealias CoordVector{T<:Real} AbstractVector{T}
type MyType{T<:Real,V<:CoordVector}
    coords::V
    ...
end
MyType(coords,...) = MyType{eltype(coords),typeof(coords)}(coords,...)

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 22, 2016, 10:19pm UTC](https://discourse.julialang.org/t/sparsification-of-a-type/1090/9 "2016-12-22T22:19:29Z")

</div>

What you really want, it sounds like, is to parameterize on the type of coefficient, but also to ensure that your vector uses the same type, e.g.

```nohighlight
type MyType{T<:Number,V<:AbstractVector{T}}
    coords::V
    ... other stuff depending on T ...
end

```

Unfortunately, this kind of type declaration (in which `T` appears twice in the parameters) is not currently possible. The good news is that it should be available soonish, once @JeffBezanson’s new subtyping branch ([https://github.com/JuliaLang/julia/pull/18457](https://github.com/JuliaLang/julia/pull/18457)) is merged. We’re all hoping that this can be merged in time for Julia 0.6.

---

<div class="post-metadata">

**Author:** ![abulak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abulak/32/28314_2.png) [@abulak](https://discourse.julialang.org/u/abulak)\
**Post date:** [December 22, 2016, 10:51pm UTC](https://discourse.julialang.org/t/sparsification-of-a-type/1090/10 "2016-12-22T22:51:00Z")

</div>

This was exactly what I tried after Your hint on the parametrisation by the type of coordinates/coefficients; glad to hear that something like this is on the list.

At the moment I went back to standard

```julia
type MyType{T}
    coords::Vector{T}
    ...
end

```

as the size of problems is too small to justify usage of sparse vectors

Thanks!
