Skip to content

Commit

Permalink
Documenting some lower level functions
Browse files Browse the repository at this point in the history
  • Loading branch information
andreasvarga committed Sep 23, 2024
1 parent 4f2967b commit e4dff7f
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 32 deletions.
3 changes: 3 additions & 0 deletions docs/src/pmconv.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Periodic matrix conversions

* **[`convert`](@ref)** Conversion between discrete-time and between continuous-time periodic matrix representations.
* **[`ts2hr`](@ref)** Conversion of a periodic time series matrix to a harmonic array approximation.
* **[`pfm2hr`](@ref)** Conversion of a periodic function matrix to a harmonic array representation.
* **[`ts2pfm`](@ref)** Conversion of an interpolated periodic time series matrix to a periodic function matrix.
Expand All @@ -12,6 +13,8 @@


```@docs
convert(::Type{<:PeriodicMatrix}, A::PeriodicArray{:d, T}) where T
convert(::Type{PeriodicFunctionMatrix}, ahr::HarmonicArray)
ts2hr
pfm2hr
ts2pfm
Expand Down
35 changes: 31 additions & 4 deletions docs/src/pmtypes.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,36 @@
# Constructors for periodic matrices

## Discrete-time periodic matrices

* **[`PeriodicMatrix`](@ref)** Discrete-time periodic matrix representation.
* **[`PeriodicArray`](@ref)** Discrete-time periodic array representation.
* **[`SwitchingPeriodicMatrix`](@ref)** Discrete-time switching periodic matrix representation.
* **[`SwitchingPeriodicArray`](@ref)** Discrete-time switching periodic array representation.


```@docs
PeriodicMatrix
SwitchingPeriodicMatrix
size(A::PeriodicMatrix)
length(A::PeriodicMatrix)
eltype(A::PeriodicMatrix)
getindex(A::PeriodicMatrix, ind::Int64)
getindex(A::PeriodicMatrix, inds...)
lastindex(A::PeriodicMatrix)
lastindex(A::PeriodicMatrix, dim::Int64)
PeriodicArray
SwitchingPeriodicArray
size(A::PeriodicArray)
length(A::PeriodicArray)
eltype(A::PeriodicArray)
getindex(A::PM, ind::Int64) where PM<:PeriodicArray
getindex(A::PeriodicArray, inds...)
lastindex(A::PeriodicArray)
lastindex(A::PeriodicArray, dim::Int64)
```

## Continuous-time periodic matrices

* **[`PeriodicFunctionMatrix`](@ref)** Continuous-time periodic function matrix representation.
* **[`PeriodicSymbolicMatrix`](@ref)** Continuous-time periodic symbolic matrix representation.
* **[`PeriodicTimeSeriesMatrix`](@ref)** Continuous-time periodic time series matrix representation.
Expand All @@ -12,15 +39,15 @@
* **[`PeriodicSwitchingMatrix`](@ref)** Continuous-time switching periodic matrix representation.

```@docs
PeriodicMatrix
PeriodicArray
SwitchingPeriodicMatrix
SwitchingPeriodicArray
PeriodicFunctionMatrix
PeriodicSymbolicMatrix
PeriodicTimeSeriesMatrix
HarmonicArray
HarmonicArray(A0::MT, Acos::Union{Nothing, Vector{MT}}, Asin::Union{Nothing, Vector{MT}}, period::Real) where {T<:Real, MT<:VecOrMat{T}}
FourierFunctionMatrix
PeriodicSwitchingMatrix
size(A::PeriodicFunctionMatrix)
eltype(A::PeriodicFunctionMatrix)
getindex(A::PeriodicFunctionMatrix, inds...)
lastindex(A::PeriodicFunctionMatrix, dim::Int64)
```
201 changes: 177 additions & 24 deletions src/types/PeriodicMatrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -93,25 +93,81 @@ Constancy check of a periodic matrix.
function isconstant(A::PeriodicMatrix)
(A.dperiod == 1) || all([A.M[1] == A.M[i] for i in 2:A.dperiod])
end
Base.size(A::PeriodicMatrix) = (size.(A.M,1),size.(A.M,2))
"""
size(A::PeriodicMatrix)
size(A::SwitchingPeriodicMatrix)
size(A::PeriodicMatrix[, dim])
size(A::SwitchingPeriodicMatrix[, dim])
Return a tuple of two vectors containing the dimensions of the components of the discrete-time periodic matrix `A`.
Optionally you can specify a dimension `dim` to just get the vector of lengths of that dimension.
"""
function Base.size(A::PeriodicMatrix)
(size.(A.M,1),size.(A.M,2))
end
Base.size(A::PeriodicMatrix, d::Integer) = size.(A.M,d)
Base.length(A::PeriodicMatrix) = A.dperiod
Base.eltype(A::PeriodicMatrix{:d,T}) where T = T
"""
length(A::PeriodicMatrix)
length(A::SwitchingPeriodicMatrix)
Return the number of component matrices (also called the discrete period) of the discrete-time periodic matrix `A`.
"""
function Base.length(A::PeriodicMatrix)
A.dperiod
end
"""
eltype(A::PeriodicMatrix)
eltype(A::SwitchingPeriodicMatrix)
Determine the type of the elements of component matrices of the discrete-time periodic matrix `A`.
"""
function Base.eltype(A::PeriodicMatrix)
eltype(eltype(A.M))
end
# function Base.eltype(A::PeriodicMatrix{:d,T}) where {T}
# T
# end

"""
getindex(A::PeriodicMatrix, i)
getindex(A::SwitchingPeriodicMatrix, i)
Return the `i`-th component matrix of the discrete-time periodic matrix `A`. Equivalent to the syntax `A[i]`.
"""
function Base.getindex(A::PM, ind::Int) where PM <: PeriodicMatrix
A.M[mod(ind-1,A.dperiod)+1]
end
function Base.lastindex(A::PM) where PM <: PeriodicMatrix
return A.dperiod
end
"""
getindex(A::PeriodicMatrix, ind1, ind2)
getindex(A::SwitchingPeriodicMatrix, ind1, ind2)
Return the discrete-time periodic matrix built from the selected ranges `[ind1,ind2]` of elements of the component matrices.
`ind1` and `ind2` may be integers, integer ranges or colons.
"""
function Base.getindex(A::PM, inds...) where PM <: PeriodicMatrix
size(inds, 1) != 2 &&
error("Must specify 2 indices to index a periodic matrix")
rows, cols = index2range(inds...)
PeriodicMatrix{:d,eltype(A)}([A.M[i][rows,cols] for i in 1:length(A)], A.period; nperiod = A.nperiod)
end
"""
lastindex(A::PeriodicMatrix)
lastindex(A::SwitchingPeriodicMatrix)
Return the last index of the component matrices of the discrete-time periodic matrix `A`.
The syntax `A[end]` is equivalent to `A[lastindex(A)]`.
"""
function Base.lastindex(A::PM) where PM <: PeriodicMatrix
return A.dperiod
end
"""
lastindex(A::PeriodicMatrix,dim)
lastindex(A::SwitchingPeriodicMatrix,dim)
Return the vector of last indices along dimension `dim` of the component matrices of the discrete-time periodic matrix `A`.
"""
function Base.lastindex(A::PM, dim::Int) where PM <: PeriodicMatrix
return length(A) > 0 ? minimum(lastindex.(A.M,dim)) : 0
return length(A) > 0 ? lastindex.(A.M,dim) : [0]
end


Expand Down Expand Up @@ -203,7 +259,7 @@ isconstant(A::SwitchingPeriodicMatrix) = (length(A.ns) == 1) || all([A.M[1] == A
Base.size(A::SwitchingPeriodicMatrix) = (size.(A.M,1),size.(A.M,2))
Base.size(A::SwitchingPeriodicMatrix, d::Integer) = size.(A.M,d)
Base.length(A::SwitchingPeriodicMatrix) = length(A.ns)
Base.eltype(A::SwitchingPeriodicMatrix{:d,T}) where T = T
Base.eltype(A::SwitchingPeriodicMatrix) = eltype(eltype(A.M))

function Base.getindex(A::SPM, ind::Int) where SPM <: SwitchingPeriodicMatrix
A.M[findfirst(A.ns .>= mod(ind-1,A.dperiod)+1)]
Expand All @@ -218,7 +274,7 @@ function Base.getindex(A::PM, inds...) where PM <: SwitchingPeriodicMatrix
SwitchingPeriodicMatrix{:d,eltype(A)}([A.M[i][rows,cols] for i in 1:length(A.M)], A.ns, A.period, A.nperiod)
end
function Base.lastindex(A::PM, dim::Int) where PM <: SwitchingPeriodicMatrix
return length(A) > 0 ? minimum(lastindex.(A.M,dim)) : 0
return length(A) > 0 ? lastindex.(A.M,dim) : [0]
end


Expand Down Expand Up @@ -278,23 +334,68 @@ function Base.getproperty(A::PeriodicArray, d::Symbol)
end
Base.propertynames(A::PeriodicArray) = (:dperiod, :Ts, fieldnames(typeof(A))...)
isconstant(A::PeriodicArray) = (A.dperiod == 1) || all([view(A.M,:,:,1) == view(A.M,:,:,i) for i in 2:A.dperiod])
Base.size(A::PeriodicArray) = (size(A.M,1),size(A.M,2))
"""
size(A::PeriodicArray)
size(A::SwitchingPeriodicArray)
size(A::PeriodicArray[, dim])
size(A::SwitchingPeriodicArray[, dim])
Return a tuple of two integers containing the common row and column dimensions of the components of the discrete-time periodic matrix `A`.
Optionally you can specify a dimension `dim` to just get length of that dimension.
"""
function Base.size(A::PeriodicArray)
(size(A.M,1),size(A.M,2))
end
Base.size(A::PeriodicArray, d::Integer) = size(A.M,d)
Base.length(A::PeriodicArray) = A.dperiod
Base.eltype(A::PeriodicArray{:d,T}) where T = T
"""
eltype(A::PeriodicArray)
eltype(A::SwitchingPeriodicArray)
Determine the type of the elements of component matrices of the discrete-time periodic matrix `A`.
"""
function Base.length(A::PeriodicArray)
A.dperiod
end
Base.eltype(A::PeriodicArray) = eltype(A.M)

"""
getindex(A::PeriodicArray, i)
getindex(A::SwitchingPeriodicArray, i)
Return the `i`-th component matrix of the discrete-time periodic matrix `A`. Equivalent to the syntax `A[i]`.
"""
function Base.getindex(A::PM, ind::Int) where PM <: PeriodicArray
A.M[:,:,mod(ind-1,A.dperiod)+1]
end
function Base.lastindex(A::PM) where PM <: PeriodicArray
return A.dperiod
end
"""
getindex(A::PeriodicArray, ind1, ind2)
getindex(A::SwitchingPeriodicArray, ind1, ind2)
Return the discrete-time periodic matrix built from the selected ranges `[ind1,ind2]` of elements of the component matrices.
`ind1` and `ind2` may be integers, integer ranges or colons.
"""
function Base.getindex(A::PM, inds...) where PM <: PeriodicArray
size(inds, 1) != 2 &&
error("Must specify 2 indices to index a periodic matrix")
rows, cols = index2range(inds...)
PeriodicArray{:d,eltype(A)}(A.M[rows,cols,:], A.period; nperiod = A.nperiod)
end
"""
lastindex(A::PeriodicArray)
lastindex(A::SwitchingPeriodicArray)
Return the last index of the component matrices of the discrete-time periodic matrix `A`.
The syntax `A[end]` is equivalent to `A[lastindex(A)]`.
"""
function Base.lastindex(A::PM) where PM <: PeriodicArray
return A.dperiod
end
"""
lastindex(A::PeriodicArray,dim)
lastindex(A::SwitchingPeriodicArray,dim)
Return the last index along dimension `dim` of the component matrices of the discrete-time periodic matrix `A`.
"""
function Base.lastindex(A::PM, dim::Int) where PM <: PeriodicArray
return lastindex(A.M,dim)
end
Expand Down Expand Up @@ -379,7 +480,7 @@ isconstant(A::SwitchingPeriodicArray) = (length(A.ns) == 1) || all([view(A.M,:,:
Base.size(A::SwitchingPeriodicArray) = (size(A.M,1),size(A.M,2))
Base.size(A::SwitchingPeriodicArray, d::Integer) = size(A.M,d)
Base.length(A::SwitchingPeriodicArray) = length(A.ns)
Base.eltype(A::SwitchingPeriodicArray{:d,T}) where {T} = T
Base.eltype(A::SwitchingPeriodicArray) = eltype(A.M)

function Base.getindex(A::SPM, ind::Int) where SPM <: SwitchingPeriodicArray
A.M[:,:,findfirst(A.ns .>= mod(ind-1,A.dperiod)+1)]
Expand Down Expand Up @@ -506,15 +607,50 @@ function PeriodicMatrices.isconstant(f::Function, period::Real; rtol::Float64 =
end

#isperiodic(A::PeriodicFunctionMatrix) = isconstant(A) ? true : isperiodic(A.f,A.period/A.nperiod)
Base.size(A::PeriodicFunctionMatrix) = A.dims
"""
size(A::PM)
size(A::PM[, dim])
Return a tuple of two integers containing the dimensions of the continuous-time periodic matrix `A` of type `PM`,
where `PM` is one of the types `PeriodicFunctionMatrix`, `HarmonicArray`, `PeriodicTimeSeriesMatrix`, `PeriodicSwitchingMatrix`,
`PeriodicSymbolicMatrix` or `PeriodicFunctionMatrix`.
Optionally you can specify a dimension `dim` to just get the length of that dimension.
"""
function Base.size(A::PeriodicFunctionMatrix)
A.dims
end
Base.size(A::PeriodicFunctionMatrix, d::Integer) = d <= 2 ? size(A)[d] : 1
Base.eltype(A::PeriodicFunctionMatrix{:c,T}) where T = T
"""
eltype(A::PM)
Determine the type of the elements of the continuous-time periodic matrix `A` of type `PM`,
where `PM` is one of the types `PeriodicFunctionMatrix`, `HarmonicArray`, `PeriodicTimeSeriesMatrix`, `PeriodicSwitchingMatrix`,
`PeriodicSymbolicMatrix` or `PeriodicFunctionMatrix`.
"""
function Base.eltype(A::PeriodicFunctionMatrix{:c,T}) where T
T
end
"""
getindex(A::PM, ind1, ind2)
Return the continuous-time periodic matrix built from the selected ranges `[ind1,ind2]` of the elements of the continuous-time periodic matrix `A`of type `PM`,
where `PM` is one of the types `PeriodicFunctionMatrix`, `HarmonicArray`, `PeriodicTimeSeriesMatrix`, `PeriodicSwitchingMatrix`,
`PeriodicSymbolicMatrix` or `PeriodicFunctionMatrix`.
`ind1` and `ind2` may be integers, integer ranges or colons.
"""
function Base.getindex(A::PM, inds...) where PM <: PeriodicFunctionMatrix
size(inds, 1) != 2 &&
error("Must specify 2 indices to index a periodic matrix")
rows, cols = index2range(inds...)
PeriodicFunctionMatrix{:c,eltype(A)}(t->A.f(t)[rows,cols], A.period; isconst = A._isconstant, nperiod = A.nperiod)
end
"""
lastindex(A::PM,dim)
Return the last index along dimension `dim` of the continuous-time periodic matrix `A` of type `PM`,
where `PM` is one of the types `PeriodicFunctionMatrix`, `HarmonicArray`, `PeriodicTimeSeriesMatrix`, `PeriodicSwitchingMatrix`,
`PeriodicSymbolicMatrix` or `PeriodicFunctionMatrix`.
"""
function Base.lastindex(A::PM, dim::Int) where PM <: PeriodicFunctionMatrix
lastindex(A.f(0),dim)
end
Expand Down Expand Up @@ -703,8 +839,9 @@ end
# properties
isconstant(At::PeriodicSwitchingMatrix) = length(At.values) <= 1
#isperiodic(At::PeriodicSwitchingMatrix) = true
Base.length(At::PeriodicSwitchingMatrix) = length(At.values)
Base.length(At::PeriodicSwitchingMatrix) = length(At.ts)
Base.size(At::PeriodicSwitchingMatrix) = length(At) > 0 ? size(At.values[1]) : (0,0)
Base.size(At::PeriodicSwitchingMatrix, d::Integer) = length(At) > 0 ? size(At.values[1],d) : 0
Base.eltype(At::PeriodicSwitchingMatrix{:c,T}) where {T} = T

function Base.getindex(A::PM, inds...) where PM <: PeriodicSwitchingMatrix
Expand Down Expand Up @@ -807,8 +944,17 @@ end


# conversions to discrete-time PeriodicMatrix
Base.convert(::Type{<:PeriodicMatrix}, A::PeriodicArray{:d,T}) where T =
PeriodicMatrix{:d,T}([A.M[:,:,i] for i in 1:size(A.M,3)],A.period; nperiod = A.nperiod)

"""
convert(PM1,A::PM2) -> B::PM1
Convert the discrete-time periodic matrix `A` of type `PM2` to the discrete-time periodic matrix `B` of type `PM1`,
where `PM1` and `PM2` are of types
`PeriodicMatrix`, `SwitchingPeriodicMatrix`, `PeriodicArray` or `SwitchingPeriodicArray`.
"""
function Base.convert(::Type{<:PeriodicMatrix}, A::PeriodicArray{:d,T}) where T
PeriodicMatrix{:d,T}([A.M[:,:,i] for i in 1:size(A.M,3)],A.period; nperiod = A.nperiod)
end
Base.convert(::Type{<:PeriodicMatrix}, A::SwitchingPeriodicMatrix{:d,T}) where {T} =
PeriodicMatrix{:d,T}([A[i] for i in 1:A.dperiod],A.period; nperiod = A.nperiod)
Base.convert(::Type{<:PeriodicMatrix}, A::SwitchingPeriodicArray{:d,T}) where {T} =
Expand Down Expand Up @@ -881,12 +1027,19 @@ end


# conversions to continuous-time PeriodicFunctionMatrix
"""
convert(PM1,A::PM2) -> B::PM1
Convert the continuous-time periodic matrix `A` of type `PM2` to the continuous-time periodic matrix `B` of type `PM1`,
where `PM1` and `PM2` are of types `PeriodicFunctionMatrix`, `HarmonicArray`, `PeriodicTimeSeriesMatrix`, `PeriodicSwitchingMatrix`,
`PeriodicSymbolicMatrix` or `PeriodicFunctionMatrix`.
"""
function Base.convert(::Type{PeriodicFunctionMatrix}, ahr::HarmonicArray)
PeriodicFunctionMatrix{:c,real(eltype(ahr.values))}(t::Real -> hreval(ahr,t), ahr.period, size(ahr), ahr.nperiod, isconstant(ahr))
end
function Base.convert(::Type{PeriodicFunctionMatrix{:c,T}}, A::PeriodicFunctionMatrix) where T
return eltype(A) == T ? A : PeriodicFunctionMatrix{:c,T}(x -> T.(A.f(T(x))), A.period, A.dims, A.nperiod, A._isconstant)
end

Base.convert(::Type{PeriodicFunctionMatrix}, ahr::HarmonicArray) =
PeriodicFunctionMatrix{:c,real(eltype(ahr.values))}(t::Real -> hreval(ahr,t), ahr.period, size(ahr), ahr.nperiod, isconstant(ahr))
Base.convert(::Type{PeriodicFunctionMatrix{:c,T}}, ahr::HarmonicArray) where T =
PeriodicFunctionMatrix{:c,T}(t::Real -> hreval(ahr,T(t)), ahr.period, size(ahr), ahr.nperiod, isconstant(ahr))
#Base.convert(::Type{PeriodicFunctionMatrix}, At::PeriodicTimeSeriesMatrix) = ts2pfm(At; method = "cubic")
Expand Down
1 change: 1 addition & 0 deletions src/types/PeriodicMatrix_Fourier.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ function isconstant(A::FourierFunctionMatrix)
end
#isperiodic(A::FourierFunctionMatrix) = true
Base.size(A::FourierFunctionMatrix) = (size(A.M,1),size(A.M,2))
Base.size(A::FourierFunctionMatrix, d::Integer) = d <= 2 ? size(A)[d] : 1
Base.eltype(A::FourierFunctionMatrix{:c,T}) where T = T

function Base.getindex(A::PM, inds...) where PM <: FourierFunctionMatrix
Expand Down
2 changes: 1 addition & 1 deletion src/types/PeriodicMatrix_sym.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ isconstant(A::PeriodicSymbolicMatrix) = all(length.(Symbolics.get_variables.(A.F
# end
#isperiodic(A::PeriodicSymbolicMatrix) = isconstant(A) ? true : isperiodic(A.F,A.period)
Base.size(A::PeriodicSymbolicMatrix) = size(A.F)
Base.size(A::AbstractPeriodicArray, d::Integer) = d <= 2 ? size(A)[d] : 1
Base.size(A::PeriodicSymbolicMatrix, d::Integer) = d <= 2 ? size(A)[d] : 1
Base.eltype(A::PeriodicSymbolicMatrix{:c,T}) where T = T

function Base.getindex(A::PM, inds...) where PM <: PeriodicSymbolicMatrix
Expand Down
Loading

0 comments on commit e4dff7f

Please sign in to comment.