Open mbudisic opened 9 years ago
Have you come upon a case where you needed this? Seems to me a little specialized.
Actually, this was a request from UC San Diego. They would like to use adaptive timesolvers in their dynamics and resampling the trajectories using a smallest common timestep could result in a too-large number of points in each trajectory.
I see. The "old" way, before Matt then Michael introduced the pairs-of-strand approach, was to look at all the strings at once. In that case we had an ODE solver that would get interrupted whenever two strands crossed. This would also be bad, I guess, but it does remind me that we could revive this direct ODE approach.
For instance, we might have the braid constructor take a function handle as an argument, which could then be used to call ode45
and generate the braid. But that's a separate issue from what you're talking about here: maybe I'll open a separate issue about this.
Or is this a different issue? Maybe this is the best way to solve this issue?
Example:
b = braid(@func,tspan,x0); % create braid of trajectories starting at x0
Syntax is meant to mimic ode45
. Could even pass ode options at the end. @func
though only takes one trajectory at a time.
An implementation might involve going through by pairs of strings, and setting and @events
function for when the x coordinates coincide.
But as for your original point, at least it only adds something to the constructor without changing anything else.
No, I didn't mean for anything as complicated as this.
Say that we open the constructor to accepting a structure array, where each structure element has two fields: .t (time vector) and .x ( #timestep x 2 matrix of x-y coordinates).
Everything else goes as before, but now cross2gen
(called by colorbraiding
) has to be a bit more sophisticated in detecting crossings and interpolating where the crossing actually happened. We should always assume that each trajectory can be linearly interpolated between its own two neighboring timesteps.
I think calling ode45 in the generator is way more than requested - let's let "data acquisition/generation" deal with that - when they have sufficiently precise trajectories that they are satisfied with, they can pass them to us. The only thing is that they wouldn't have to resample them using a uniform timestep anymore.
Spun off the direct-from-ODE idea to #126.
No, I understand that the ODE method is more than requested. I just got thinking about it since I had been mulling it over, and it suddenly occurred to me that it could be done w/o changing how things work otherwise. So I do like this change, since it doesn't require changing the way anything outwardly operates. You could test it out in a branch first. Please let me have a look before you merge into develop
.
Here's a suggested way to proceed: generalize colorbraiding
to take a cell array t
instead of a vector t
. Thus t{k}
would be the times for the k
th particle. The great advantage of this is that the usage databraid(XY,t)
would be the same whether t
is a vector of times or a cell array of times.
Yes, agreed. So if XY
and t
are "plain" matrices, this corresponds to common sampling times, whereas if they are cell arrays, elements XY{k}
and t{k}
together specify the k
-th trajectory.
Ah yes, I had missed that then XY
also has to be a cell array. That's kind of annoying. At least let's remember to make XY{k}
have dimension [2 n]
, to be consistent with XY(Ntimes,2,n)
.
At least this will all be mostly 'hidden'. What I worry about is that changing XY
to a cell array might make the code either significantly more complicated (in a function that's always been hard to debug), or slower.
I fully intend to have two functions - the one we have right now to deal with uniform data and a new non-uniform dealing with this case. I am also worried about speed. But we'll see.
You think two functions is the way to go? That sounds like a fair amount of code duplication.
No, no, duplicating just the inside of the double-for loop in cross2gen
. Everything else can stay.
Ok, let's see. I think we might be able to do with one function if it's not much slower.
Oh sure -- test first, burn bridges later :)
In dynamical systems that exhibit different time-scales over their domain, it would be beneficial to create
databraid
s from trajectories with their own time-vectors. This would mean that instead of(t,x)
wheret
is, say,K x 1
vector andx
aK x 2 x N
matrix of trajectories, braids could be constructed from a set ofN
pairs(t_i, x_i)
where eacht_i
would be a distinct time vector of lengthK_i
, and eachx_i
aK_i x 2
trajectory corresponding to it.This would require a redesign of the current
databraid
creation algorithm or, maybe better, and addition of an algorithm that would handle this specific case.