Skip to content

New definition of complete_state for ProjectedDynamicalSystems #209

Closed
@awage

Description

@awage

When defining a ProjectedDynamicalSystem, the user must define a function complete_state that must returns a vector of the same dimension than the original dynamical system. Such that:

  ds = Systems.lorenz96(5)
  projection(u) = [sum(u), sqrt(u[1]^2 + u[2]^2)]
  complete_state(y) = repeat([y[1]/5], 5) 
  prods = ProjectedDynamicalSystem(ds, projection, complete_state)

The docstring says:

complete_state produces the state for the original system from
the projected state. complete_state can always be a function
that given the projected state returns a state in the original
space.

In the previous example this is not true, since the projected space is a 2D space and the complete_state function only takes the first dimension of the input vector y.

In fact the complete_state function can be a crazy input y, the only requisite is to return a valid vector on the original phase space.

I propose a minor change in the docstring and small modification of the source code:

function ProjectedDynamicalSystem(ds::DynamicalSystem, projection, complete_state)
    u0 = initial_state(ds)
    if projection isa AbstractVector{Int}
        all(1 .≤ projection .≤ dimension(ds)) || error("Dim. of projection must be in 1 ≤ np ≤ dimension(ds)")
        projection = SVector(projection...)
        y = u0[projection]
    else
        projection(u0) isa AbstractVector || error("Projected state must be an AbstracVector")
        y = projection(u0)
    end
    if complete_state isa AbstractVector
        projection isa AbstractVector{Int} || error("Projection vector must be of type Int")
        length(complete_state) + length(projection) == dimension(ds) ||
                                error("Wrong dimensions for complete_state and projection")
        remidxs = setdiff(1:dimension(ds), projection)
        !isempty(remidxs) || error("Error with the indices of the projection")
    else
        # Define a wrapper function to check the state since we do not know what will be the input y
        comp_state(y) = length(complete_state(y)) == dimension(ds) ? complete_state(y) :  error("The returned vector of complete_state must equal dimension(ds)")
        remidxs = nothing
    end
    u = zeros(dimension(ds))
	return ProjectedDynamicalSystem{
        typeof(projection), length(y), typeof(complete_state),
        typeof(remidxs), typeof(ds)}(projection, comp_state, u, remidxs, ds)
end

The change introduces a small overhead in the computation of the initial state. Maybe there is a better solution. Maybe a special error definition if the case arises that complete_state(y) != dimension(ds)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions