Another note about why I want to do this.

I want to define another type with constructors that look like this 
(haven’t finalized this design, but this captures the idea):

type LinearGaussianSSM
    F::TimeVaryingParam
    V::TimeVaryingParam
    G::TimeVaryingParam
    W::TimeVaryingParam
end

function LinearGaussianSSM(F::Union{TimeVaryingParam, Matrix},
                           V::Union{TimeVaryingParam, Matrix},
                           G::Union{TimeVaryingParam, Matrix},
                           W::Union{TimeVaryingParam, Matrix})
    F, V, G, W = map(x->convert(TimeVaryingParam, x), Any[F, V, G, W])
    return LinearGaussianSSM(F, V, G, W)
end

using the convert methods

convert(::Type{TimeVaryingParam}, x::Matrix) = TimeVaryingParam((x, Colon()))
convert(::Type{TimeVaryingParam}, x::TimeVaryingParam) = x

I will then implement various smoothers/filters on this type. I would like 
to make this general enough to support time-invaraint matrices F, V, G, W, 
but if one or more matrices happen to be constant, I don’t want the user to 
have to worry about specifying for which time periods the matrices apply.
On Thursday, November 13, 2014 10:24:44 AM UTC-5, Spencer Lyon wrote:

I am trying to construct a type with this definition:
>
> # are two ranges disjoint?
> isdisjoint(r1::UnitRange, r2::UnitRange) = isempty(intersect(r1, r2))
>
> # are a collection of ranges all disjoint?
> function all_disjoint(rs::UnitRange...)
>     n = length(rs)
>     for i=1:n, j=i+1:n
>         if !(isdisjoint(rs[i], rs[j]))
>             return false
>         end
>     end
>     return true
> end
>
> type TimeVaryingParam{T<:Real, S<:Integer}
>     mats::Vector{Matrix{T}}
>     ranges::Vector{UnitRange{S}}
>
>     function TimeVaryingParam(mats, ranges)
>         if !(all_disjoint(ranges...))
>             throw(ArugumentError("Ranges are overlapping"))
>         end
>         new(mats, ranges)
>     end
> end
>
> function TimeVaryingParam{T<:Real, S<:Integer}(mats::Vector{Matrix{T}},
>                                                ranges::Vector{UnitRange{S}})
>     TimeVaryingParam{T, S}(mats, ranges)
> end
>
> # constructor of the form (mat, period_range), (mat2, period_range2)
> function TimeVaryingParam{T<:Real, S<:Integer}(input::(Matrix{T}, 
> UnitRange{S})...)
>     mats = Matrix{T}[]
>     ranges = UnitRange{S}[]
>     for t in input
>         push!(mats, t[1])
>         push!(ranges, t[2])
>     end
>     TimeVaryingParam(mats, ranges)
> end
>
> function getindex(tvp::TimeVaryingParam, t::Int)
>     # b/c all ranges are disjoint, ind has exactly zero or one elements
>     ind = find(x->t in x, tvp.ranges)
>     isempty(ind) && error("Invalid index. t=$t not in any supplied ranges")
>     return tvp.mats[ind[1]]
> end
>
> The application is to be able to represent time-varying coefficient 
> matrices of a linear state space system without having to make explicit 
> copies of the matrices when they are the same for multiple periods.
>
> What I am trying to figure out is a convenient way for users to specify 
> that a given matrix is the same for all periods. In other words, if the 
> user was going to use the outer constructor I provided, I would like the 
> following behavior to be true:
>
> a = [1 2; 3 4]
> tva = TimeVaryingParam((a, Colon()))
> t = rand(1:10000)   # really just any integer
> tva[t] == a  # returns true
>
> Now for the question/title of the post. I don’t know how : gets parsed in 
> an indexing expression, so I don’t know how to enable this functionality. 
> Can anyone help with this?
>
> Also, if someone has a better idea for how to enable this kind of 
> functionality (i.e. an approach that doesn’t rely on Colon()) I am very 
> happy to hear about it.
>
> Thanks!
> ​
>
​

Reply via email to