Skip to content

Reworking the API and Docs to merge in DynamicalSystems.jl#19

Open
Datseris wants to merge 8 commits intomainfrom
complexity_api_rework
Open

Reworking the API and Docs to merge in DynamicalSystems.jl#19
Datseris wants to merge 8 commits intomainfrom
complexity_api_rework

Conversation

@Datseris
Copy link
Member

High level description: rework API so that it directly inherits and expands the types and functions from ComplexityMeasures.jl. Also re-work the docs to have the style of DynamicalSystems.jl with a main Tutorial and then a formal API page that lists all docstrings.

@gabriel-ferr
Copy link
Member

Following the todo list, I'm renaming the microstates shape types, using something like: "Rect" -> "RectMicrostate", and also removing the recurrence expression dependence from them.

However, I don't understand the item "Furthermore, they should be orthogonal inputs to the main outcome space t" ...

@gabriel-ferr
Copy link
Member

gabriel-ferr commented Jan 31, 2026

I changed the histogram input, it now uses the RecurrenceMicrostate type instead of the core. I also implemented the interface with ComplexityMeasures, but I am not sure whether it is working correctly. When I tried to test it, I got the following error:
"probabilities(rmspace, X)
ERROR: MethodError: no method matching Probabilities(::Int64, ::Int64)
The type Probabilities exists, but no method is defined for this combination of argument types when trying to construct it."

About the outcomes, I used the indices given by "eachindex(counts)". I'm not sure if it is the best approach. Other alternatives could be matrix representations, but for spatial data this can be problematic, not to mention the memory allocation cost. Another option is the binary representation, but it can be harder to read. Since the decimal representation is already used for counting the microstates when computing the histogram, the indices of eachindex(counts) are also a representation of the microstates.

Another question: What do I do with the distribution functions? Delete them, or try to adapt them and mark them as deprecated?

@Datseris
Copy link
Member Author

Datseris commented Jan 31, 2026

when reporting error messages please put the whole stack trace (and make sure to wrap it in tripple back ticks so it is formatted as code) . I don't know if your error is internal or just because you didn't pass the proper outcome space struct.

About the outcomes, I used the indices given by "eachindex(counts)". I'm not sure if it is the best approach. Other alternatives could be matrix representations, but for spatial data this can be problematic, not to mention the memory allocation cost.

This is something we can think at the end, it is not important right now. I assume that for a given N you have a unique and reversible way to encode each microstate to a unique integer. Correct?

@gabriel-ferr
Copy link
Member

Understood. I fixed it. I was returning the wrong value in the function ComplexityMeasures.counts_and_outcomes. Now it is working (I think... I'll test it more later).

This is something we can think at the end, it is not important right now. I assume that for a given N you have a unique and reversible way to encode each microstate to a unique integer. Correct?

Yes. A recurrence microstate can be interpreted as a binary number, since it is composed of 0s and 1s. When we define the microstate shape, we also define how to read this microstate as a binary number. Then, the package using the sampling process takes an initial position of the time series, $(i, j)$, and it computes the recurrence for each position starting from this initial position, following the offsets given by the function RecurrenceMicrostatesAnalysis.get_offsets(core::RMACore, shape::MicrostateShape).

Each of these recurrences are associated with a power of 2 from a power vector provided by the function RecurrenceMicrostatesAnalysis.get_power_vector(core::RMACore, shape::MicrostateShape). Using it, the package converts the binary representation of the microstate into its decimal representation while it is computing the recurrences =D , and this decimal representation is used as index to count the microstate.

And, of course, each index can be easily converted to its binary representation using digits(N - 1, base = 2). For example:

N = 55
digits(N - 1, base = 2)
0 1 1 0 1 1

For a 3x3 microstate, it is:

M = ⎡0  1  1⎤
    ⎢0  1  1⎥
    ⎣0  0  0⎦

Or for a triangle microstate with size 3 (the reading order is different):

M = ⎡0  1  0⎤
    ⎢   1  1⎥
    ⎣      1⎦

Note: N - 1 is because Julia works using 1-based indexing, but the binary ↔ decimal conversion works using 0-based.

@gabriel-ferr
Copy link
Member

I think it is working now. I had to add a probabilities overload to support CRP / two inputs, since it was throwing an error and I believe there is no such implementation in ComplexityMeasures.jl. So I added it to complexity_measures_interface:

function ComplexityMeasures.probabilities(o::RecurrenceMicrostates, x, y)
    return first(probabilities_and_outcomes(o, x, y))
end

function ComplexityMeasures.probabilities_and_outcomes(o::RecurrenceMicrostates, x, y)
    cts, outs = counts_and_outcomes(o, x, y)
    probs = Probabilities(cts, outs)
    return probs, outcomes(probs)
end

I also remove the RMACore from the user-facing API, it is now an internal structure that is automatically selected based on the input type =D

Then, the RecurrenceMicrostates struct now is:

struct RecurrenceMicrostates{MS <: MicrostateShape, RE <: RecurrenceExpression, SM <: SamplingMode} <: ComplexityMeasures.CountBasedOutcomeSpace 
    shape::MS
    expr::RE
    sampling::SM
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants