-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Potential issue in extending tipping_probabilities
to attraction basins computed on non-uniform grid
#36
Comments
Hi! Do you have a reference of what you are trying to achieve? If I understand correctly you want to extend the computation to non-uniform grid steps. What does this multiplication of grid points implies: |
@awage You are right. Indeed the grid should have been replaced by the equivalent step. Here is a temporary edit. I need to test it yet. Unfortunately, I am running out of memory as mentioned before, and I won't have access to HPC resources before the next three weeks. In my case, I have 4D system, and I am calling the grid steps by function my_tipping_probabilities(basins_before, basins_after, grid)
@assert size(basins_before) == size(basins_after)
bid, aid = unique.((basins_before, basins_after))
P = zeros(length(bid), length(aid))
# Make -1 last entry in bid, aid, if it exists
put_minus_1_at_end!(bid); put_minus_1_at_end!(aid)
## We now compute all the differences across all elements of the grid, so that we can compute all voxels accordingly
## Compute incremental steps of grid
dg = diff(grid[1])
df = diff(grid[2])
da = diff(grid[3])
dc = diff(grid[4])
# Notice: the following loops could be optimized with smarter boolean operations,
# however they are so fast that everything should be done within milliseconds even
# on a potato
for (i, ι) in enumerate(bid)
B_i = findall(isequal(ι), basins_before)
μ_B_i = 0
for ind in B_i
# μ = measure on non-unitary grid
## The condition is required because diff is length-1 the original vectors for the state variables upon which grid is defined
if (ind[1]<length(dg))&&(ind[2]<length(df))&&(ind[3]<length(da))&&(ind[4]<length(dc))
μ_B_i += dg[ind[1]]*df[ind[2]]*da[ind[3]]*dc[ind[4]]
end
end
# μ_B_i = length(B_i) # μ = measure
for (j, ξ) in enumerate(aid)
overlap = findall(x->x.>0,(basins_pre.==ξ).&(basins_pst.==ξ))
μ_overlap = 0
for ind in overlap
if (ind[1]<length(dg))&&(ind[2]<length(df))&&(ind[3]<length(da))&&(ind[4]<length(dc))
μ_overlap += dg[ind[1]]*df[ind[2]]*da[ind[3]]*dc[ind[4]]
end
end
P[i, j] = μ_overlap/μ_B_i
end
end
return P
end |
I see. I will think of a way to extend the computation to Ndim non uniform grids. |
I have a solution but it is untested and will not work at first. Can you please think of a test unit? I leave the code. The idea is to restrict the size of the basins (with Another solution is to have a convention for the element of the grid step missing. In some application the last step is repeated (in filtering for example). function my_tipping_probabilities(basins_before, basins_after, grid)
@assert size(basins_before) == size(basins_after)
bid, aid = unique.((basins_before, basins_after))
P = zeros(length(bid), length(aid))
# Make -1 last entry in bid, aid, if it exists
put_minus_1_at_end!(bid); put_minus_1_at_end!(aid)
## We now compute all the differences across all elements of the grid, so that we can compute all voxels accordingly
## Compute incremental steps of grid
dg = diff.(grid)
ng = ntuple(i -> 1:length(grid[i])-1, length(grid))
bb = view(basins_before, ng...)
ba = biew(basins_after, ng...)
# Notice: the following loops could be optimized with smarter boolean operations,
# however they are so fast that everything should be done within milliseconds even
# on a potato
for (i, ι) in enumerate(bid)
B_i = findall(isequal(ι), bb)
μ_B_i = 0
for ind in B_i
μ_B_i += prod(getindex.(dg, Tuple(ind)))
end
for (j, ξ) in enumerate(aid)
overlap = findall(x->x.>0,(bb.==ξ).&(ba.==ξ))
μ_overlap = 0
for ind in overlap
μ_overlap += prod(getindex.(dg, Tuple(ind)))
end
P[i, j] = μ_overlap/μ_B_i
end
end
return P
end
|
Corrected some typos and put a dumb example: function my_tipping_probabilities(basins_before, basins_after, grid)
@assert size(basins_before) == size(basins_after)
bid, aid = unique.((basins_before, basins_after))
P = zeros(length(bid), length(aid))
# Make -1 last entry in bid, aid, if it exists
put_minus_1_at_end!(bid); put_minus_1_at_end!(aid)
## We now compute all the differences across all elements of the grid, so that we can compute all voxels accordingly
## Compute incremental steps of grid
dg = diff.(grid)
ng = ntuple(i -> 1:length(grid[i])-1, length(grid))
bb = view(basins_before, ng...)
ba = view(basins_after, ng...)
# Notice: the following loops could be optimized with smarter boolean operations,
# however they are so fast that everything should be done within milliseconds even
# on a potato
for (i, ι) in enumerate(bid)
B_i = findall(isequal(ι), bb)
μ_B_i = 0
for ind in B_i
μ_B_i += prod(getindex.(dg, Tuple(ind)))
end
for (j, ξ) in enumerate(aid)
overlap = findall(x->x.>0,(bb.==ξ).&(ba.==ξ))
μ_overlap = 0
for ind in overlap
μ_overlap += prod(getindex.(dg, Tuple(ind)))
end
P[i, j] = μ_overlap/μ_B_i
end
end
return P
end
function put_minus_1_at_end!(bid)
if -1 ∈ bid
sort!(bid)
popfirst!(bid)
push!(bid, -1)
end
end
# Random basins 3 dim grid
bas1 = rand(1:4,(10,10,10))
bas2 = rand(1:4,(10,10,10))
grid = (1:10, 1:10, 1:10)
P = my_tipping_probabilities(bas1, bas2, grid)
|
@awage thanks. I need to test it on my data sets to be able to give you consistent feedback. I am currently building the data, but, as I mentioned earlier, I will have access to reasonable computing resources only in a couple of weeks. Thanks for your patience. |
@awage Thank you for your patience. I got my laptop stolen and had to rewrite the code from scratch. I am testing your code on dummy data, and it works so far. Unfortunately, I am waiting to build the real attractors for my problem. But I am experiencing some issue that I am reporting in a separate thread. |
@awage There is a typo in the computation of the overlapping basin. The overlapping indexes were originally computed by:
should instead be estimated by:
based on the definition of tipping probabilities by Kaszás, Feudel & Tél. Tipping phenomena in typical dynamical systems subjected to parameter drift. Scientific Reports, 9(1). |
Yes, you are right, please do a PR that fixes it? |
@Datseris I am not sure how to do a PR nor what a PR is. This code is not in the current |
okay no worries, I now understand you were referring to the code Alex pasted here, not to the code in the package. |
Thanks! Do you have an example that can be tested? Also to submit a Pull Request (PR) you need to:
There are many youtube videos that will guide you through the process. |
@Datseris @awage , there is a potential issue with how
tipping_probabilities
are computed at the moment. The result is correct if the grid steps are unitary in all directions. If it is not, then the computation of the basin measure must consider the true grid size. Here is my temporary workaround:The text was updated successfully, but these errors were encountered: