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
type MyType{T<:Number}
coords::Vector{T}
name::String
some_field::OtherType
etc.
I have defined methods for MyType e.g.
length(X::MyType) = length(X.coords)
Now I noticed that it would be nice to have coords stored as SparseVector.
How should I sparsifyMyType? 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:
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??
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.)
Ok, so I’ve run into some problems: well maybe not problems, but…
previously I had (the warn is important to me)
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
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
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.
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) is merged. We’re all hoping that this can be merged in time for Julia 0.6.
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
type MyType{T}
coords::Vector{T}
...
end
as the size of problems is too small to justify usage of sparse vectors