Strange error when trying to solve a set of ODEs
Show older comments
i ran into a strange error when trying to solve a set of odes. when my code was working fine, i tried changing one of my parameters that appear in the equations from 1 to some higher value (say 2 for example) and i get the following error:
Error using horzcat Dimensions of matrices being concatenated are not consistent.
Error in ode15s (line 821) ieout = [ieout, ie];
Error in test (line 149) (test is my file name)
im not sure what this error means, and what is the cause of it, since for exactly the same code i get no such error when one of my parameters is slightly lower. i also noted that if assign this parameter a much higher value like 100 or 1000 the code will run without giving me error, so i have no idea what is wrong since the code was working fine. i also see no reason as to why 1 or 100 would be good values and 2 or 10 wouldn't, since this parameter (lets call it alpha) will play the following role ( this isnt exact, but close to the exact solution ): one of my function will behave as follows:
y(x)=A*exp( alpha*(x-x_0) )+B
where A,B,x_0 are constants and alpha is my parameter. so if alpha=1,100 is fine why wouldnt alpha=2,10 be fine? makes no sense to me.
i have my suspicions as to what is causing the probelm. i opened another thread regarding things related to that, and i have not received an answer yet. so i think it would be of great help if you can answer me here:
i am solving for x>0 and x<0 separetly because i have an initial condition for x=0, and i want the solution in both x>0 and x<0. the discontinuities are actually in the points where the function Gamma_tilde_a(y(4))=1 or Gamma_tilde_a(y(5))=1 as i specified in the event function:
function Gamma_tilde_a=Gamma_tilde_a(u_tilde_a) % a function that expresses the normalized gamma factor (normalized with Gamma_thr) in terms of u_tilde_a %
Gamma_tilde_a=(Gamma_thr^-2+u_tilde_a.^2).^(1/2);
end
function [condition_pp,indicator_terminate_pp,direction_pp]=pair_production_and_stopping_points(x,y) % the event that specify for the ode solver when pair production occurs , applied for both the positrons and electrons after the 1st pair production had already occured %
condition_pp=[Gamma_tilde_a(y(4))-1,Gamma_tilde_a(y(5))-1,abs(y(4))-u_tilde_a_stop_tol,abs(y(5))-u_tilde_a_stop_tol]; % for the first two components of this vector : when this value is zero, the pair production event occurs , the last two component of this vector: checking for the stopping point of the positrons (which for them will occur in the s_tilde>0 zone) and the electrons (which for them will occur in the s_tilde<0 zone) %
indicator_terminate_pp=[0,0,1,1]; % 0 - the solver does not terminate when the event occurs , 1 - the solver does terminate when the event occurs %
direction_pp=[0,0,0,0]; % 0 - all zeros are to be located, regardless if the event function is increasing or decreasing , +1 - only for zeros where the event function is increasing , -1 - only for zeros where the event function is decreasing %
end
say the first event point is x_0, so in my code i first solve from x=0 to x=x_0 (using the event function to terminate the integration at x=x_0) then i solve again from x_0 to some final x value x_final. after this is done, i do the exact same thing for the x<0 zone. the error message occurs when solving for x>0 and just a little after x=x_0 (so this is before even reaching the part where it solves for x<0).
now the thing is, as i said, when i solve from x=0 to x_0 i make sure i terminate at x=x_0 using the event function, because i want to enforce a new initial condition at the point x=x_0. when i then continue to solve from x=x_0 to x_final i don't really want to terminate at any point, but the condition Gamma_tilde_a(y(4)=1 or Gamma_tilde_a(y(5))=1 may still happen so i may end up with more discontinuous points. for this reason, i used the event function and specified the events Gamma_tilde_a(y(4))=1, Gamma_tilde_a(y(5))=1 , but i didnt make it terminate. now i need to know if specifying the discontinuous points as an event in itself actually does anything in regards to dealing with the discontinuities, or do i have to terminate each time an event occurs (without knowing in advance how many times the event might occur)? so maybe i should try making a while loop that will make the integration terminate at each event point, and as long as the numel(y_event) for the y_event the ode solver returns from each time it stopped at an event point isnt zero, it will continue to integrate and terminate at each event point??
by the way, just to make things clearer, the reason that those event points are discontinuous is because i have the function:
function alpha_tilde_a=alpha_tilde_a(u_tilde_a) % a function for alpha_tilde_a that appears in the expressions for the source terms %
if Gamma_tilde_a(u_tilde_a)<=1
alpha_tilde_a=0;
else
alpha_tilde_a=alpha_parameter;
end
end
which appears in my equations.
Answers (2)
Star Strider
on 18 Jan 2016
1 vote
If it works in some situations and not others, it usually means that the row or column of the vector being added contains an empty value, so the length of the vector is less than the others. It will probably be worthwhile to use the debugging tools to see where the problem occurs.
31 Comments
tensorisation
on 19 Jan 2016
Edited: tensorisation
on 19 Jan 2016
Star Strider
on 19 Jan 2016
Edited: Star Strider
on 19 Jan 2016
I don’t have your code, so I can only assume that there could be a find call or other such operation that could return an empty value. An Inf or NaN value might throw an error, but they are legitimate numerical values (as far as the IEEE standard is concerned), so I doubt they would cause that problem. Logical operations would return a logical 0 or 1 that would convert to a numerical value when used in a calculation.
tensorisation
on 19 Jan 2016
Star Strider
on 19 Jan 2016
Did you do any of the debugging steps?
What was the result?
I have no real desire to run all that when I have no idea what you’re doing. You have to take some initiative in using the debugging tools (for example dbstop).
tensorisation
on 19 Jan 2016
Star Strider
on 19 Jan 2016
It is extremely difficult for me to follow that code. Functions have their own workspaces, so you would have to save (or print to the Command Window) the interim values of the vector ‘D_eqs_after_1st_pp’ creates as the first step in troubleshooting your code. Perhaps just saving (or printing) the length of the vector and the (x,y) values you use to calculate it would be enough.
One problem could be that the vector you’re returning is the same name as your function, since this could create recursion problems:
D_eqs_after_1st_pp=D_eqs_after_1st_pp(x,y)
although that might not explain why it works with some parameter values and not others.
tensorisation
on 19 Jan 2016
Edited: tensorisation
on 20 Jan 2016
Star Strider
on 19 Jan 2016
That is one option. I would start with:
fprintf(1, '\n\tAt x = %f\t\tLength ''D_eqs_before_1st_pp'' = %.0f\n', x, length(D_eqs_before_1st_pp));
rather than writing out the entire vector. You can re-run your code and write out the entire vector if this function turns out to be the problem. You don’t yet know what that is.
tensorisation
on 20 Jan 2016
Edited: tensorisation
on 20 Jan 2016
Star Strider
on 20 Jan 2016
I noticed the preallocation, but had previously done this little experiment:
V = zeros(5,1);
V(3) = [];
LenV = length(V)
so if one element is for whatever reason set to ‘empty’, the length of the vector will shorten by one. That could throw the error you’re seeing.
I get the impression that your function did not throw the error while you were monitoring its activity. As for the time steps, the MATLAB ODE solvers are adaptive, so similar time steps are to be expected. (I haven’t delved into the solver codes to see exactly how they work.)
I noticed that ‘D_eqs_before_1st_pp’ has two if blocks, and no ODE solver handles significant discontinuities well. It is extremely difficult to follow your code, and while discontinuities are not differentiable, some are ‘close enough’ to not cause significant problems. If yours are significant, I would break the code up into two ode15s calls, one with x<0 and one with x>0. Use the last values of the x<0 solutions as the initial conditions for the x>0 ode15s call. I didn’t mention that before because that function did not seem to be throwing the error.
I haven’t used event functions in a while, so I can’t comment other than to say the discontinuities could very well be causing problems. I can’t say that their interactions with your event functions are causing the concatenation error.
tensorisation
on 20 Jan 2016
Edited: tensorisation
on 20 Jan 2016
Star Strider
on 20 Jan 2016
This is clearly beyond my ability. I will delete my Answer in a few hours, since I’m not solving your problem.
tensorisation
on 20 Jan 2016
Star Strider
on 21 Jan 2016
OK. They would. I’ll keep it up for a week or so, in case someone else lends their expertise. You can always copy your comments (use the ‘Edit’ option to get the original text with formatting), and save them as a text file in ‘notepad’ or another basic text editor. Don’t use Word.
I’ll give a go at your questions:
1. That the problem occurs inside ode15s means that it occurs somewhere in your ODE functions. The ODE solvers attempt to append the solved values of your dependent variables to the existing ones, and since the new vector is not the same length as the previous, it throws an error. That’s my best guess, at least.
2. It may be that the function you are monitoring is not the function that is causing the error.
3. I can’t answer that. I haven’t delved into the code for the ODE solvers.
4. You would have to open the file before you called the function, and then close it afterwards. Opening it and immediately closing it would have it print only one line. I would use a .mat file instead, using save or matfile, as appropriate.
5. My impression is that an ‘event’ should interrupt the function so it can the restart with different essential parameters. You might also want to monitor the variable that is triggering the event, and see what the variables are up to that value of ‘x’.
I apologise, but that’s the best I can do. I didn’t run your code because it deals with astrophysics and cosmology that I have not a prayer of understanding with the requisite depth, so I would not be able to determine where the problem is. (I’m a physician and biomedical engineer, and while I have some experience with ODEs and the ODE solvers, need to understand the ODE itself to figure out what the problem might be. I only encounter black holes on PBS shows, and occasional reading.)
tensorisation
on 22 Jan 2016
Edited: tensorisation
on 22 Jan 2016
Star Strider
on 22 Jan 2016
First, what I get out of deleting Answers is that others don’t respond to them months or years later when I’ve completely forgotten about them. I also delete nearly all my Answers that aren’t Accepted or Voted, for the same reason. Others do as well.
Second, it has been years since I’ve used event functions. I can’t even find the code I wrote that uses them so that I can test some ideas I have.
Third, unless ‘my_event’ is a nested function (function within another function), it has no idea what ‘tol’ is.
Fourth, I believe the ‘indicator_terminate’ is an ‘or’ situation, so that if any of the conditions are satisfied, the solver take the appropriate action. The documentation isn’t clear on that, and I haven’t tested it.
Fifth — and this may be important — in the documentation, all the vectors in the event functions are column vectors. You have them as row vectors, and while that may seem to be a trivial distinction, it is occasionally important in the way MATLAB evaluates them. If your events function is not working as it should, transpose the vectors to column vectors and see if that makes a difference.
tensorisation
on 23 Jan 2016
Edited: tensorisation
on 23 Jan 2016
Star Strider
on 23 Jan 2016
1. I figured as much, since you did not report that it threw an error.
2. I can’t answer that. I can’t follow your code. However if that appears to be the origin of your concatenation inconsistency, that’s where I’d look to fix it. I have no idea what the appropriate fix would be. You will likely have to go through your code and experiment. Remember, your code is both complicated and beyond my areas of expertise.
3. I simply noticed that in the documentation they use column vectors, and I know from prior experience that sometimes the orientation of the vector is important. I suggested that as a possibility. Row vectors may work, but most of the ODE functions like column vectors for everything else.
Long week, late night here.
tensorisation
on 23 Jan 2016
Edited: tensorisation
on 23 Jan 2016
Star Strider
on 23 Jan 2016
I don’t understand it either, but one fix could be:
x_span_i=[x_event_prev(end),x_final];
That would use the very last element of ‘x_event_prev’ (if that’s what you want to do), so the ‘x_span’ vector would then have the correct dimensions. (If you want to also update ‘x_final’ each time, you could do so as well.)
tensorisation
on 24 Jan 2016
Edited: tensorisation
on 24 Jan 2016
Star Strider
on 24 Jan 2016
My impression from your description of the event behaviour is that your ODE is for some reason getting ‘stuck’, and keeps triggering events spaced very close in terms of ‘x’. Since your code works correctly with some parameters and not with others, there is always the possibility that there is some sort of computational problem involved. My computer science background is not sufficient to address those possibilities. My knowledge of the mathematics of astrophysics and cosmology are essentially nonexistent.
I am long since out of all ideas as to what could be causing your problem, and have long since exhausted my expertise. I was hoping that one of the other contributors with significant experience and expertise in the differential equation solvers would chime in with other ideas, but no one has.
tensorisation
on 25 Jan 2016
Star Strider
on 25 Jan 2016
The only way to handle discontinuities is to avoid them. I believe I previously suggested integrating to a discontinuity, stopping, and restarting with the previous values (or slightly changed values for them) as the new initial conditions. That is how the event functions are supposed to work.
I doubt any ODE solver handles discontinuities well, and the MATLAB solvers, for all their robustness, do not.
tensorisation
on 25 Jan 2016
Edited: tensorisation
on 25 Jan 2016
Star Strider
on 25 Jan 2016
I quite definitely do not understand the physics you are modeling, so I can only give a qualitative reply. I don’t know what the dynamics of your system are, or what your discontinuities represent. You could start after each discontinuity by changing specific values of the previous solution that characterise the discontinuity to different values, or starting over with completely new initial conditions (not related to the previous solution) to see where the dynamics of your system lead.
For an ‘unknown number of discontinuities at f(y)=1’, my first approach would be to determine the number of discontinuities, and the variables they represented. I would want to know what was going on in the system I was modeling. (For example, would taking the eigenvalues of the system in the region of the discontinuities be appropriate?) Then I would do what I could to develop a way of dealing with them.
If you are doing original research with your system (rather than reproducing previously published results), it could be that your model does not correctly describe the actual system, or the specific parameters you’re using that do not work (as opposed to the others that do) are not realistic or appropriate.
tensorisation
on 26 Jan 2016
Edited: tensorisation
on 26 Jan 2016
Star Strider
on 26 Jan 2016
‘Do you think it's a good idea to open a new thread about this?’
Yes. This has evolved over time to something far different from your original Question, and it’s quite likely others haven’t looked at it.
Be as specific as you can in your Question, and attach all your code.
tensorisation
on 28 Jan 2016
Edited: tensorisation
on 28 Jan 2016
Star Strider
on 28 Jan 2016
That’s the problem with difficult Questions. There are a few MathWorks staffers who show up here, but the rest of us are unpaid volunteers.
You can use the ‘Contact Support’ link (See ‘Contact Us’ at the top right corner of this page), and see if MathWorks can help. They will if it’s a question about a specific function (in this instance the ‘event’ option in your ODE solver, if that’s actually the problem), so putting it in those terms could help. Reference the URL to this thread in your question to them so they don’t have to search for it and so you don’t have to repeat all of it. I haven’t seen your other post, so you may want to reference it as well.
That’s the best I can do.
Nicolas Mira Gebauer
on 6 Aug 2020
Hi, I am getting a very similar problem, although 4 and a half years later... How did you solve your problem?
Thank you very much
John BG
on 18 Jan 2016
0 votes
could you please start by hanging the complete code you use?
the one that results into the error code you have already described in detail.
Awaiting answer
John
2 Comments
tensorisation
on 19 Jan 2016
Edited: tensorisation
on 19 Jan 2016
John BG
on 20 Feb 2016
If you don't supply THE code that brought you to the error you are seeking help for, the readers cannot reproduce the problem. In the script you supplied,
1.- You are defining functions with function names exactly the same as the output variables of such functions. Do you really expect such habit to have your script, or any script, working without errors?
2.- The code you supplied give basic syntax errors. removed some of them, gave up 15min later.
3.- The following are variables NOT defined in the supplied script:
h_tilde_a=Gamma_thr
u_tilde_a=Gamma_thr
n_tilde_lab_a=Gamma_thr
n_tilde_lab_plus=Gamma_thr
u_tilde_plus= Gamma_thr
n_tilde_lab_minus= Gamma_thr
in an attempt to have the supplied script reaching the error originating this question I gave the undefined variables the above errors, no way through the syntax errors.
4.- Something as basic as the variable x, not defined I did x=xi, and at this point is a good moment to ask, noch mal:
please hang the code that produces the error originating this question, not a chunk of it, not an earlier version that produces earlier errors, not the code without variables ..
5.- Would it be possible to make the script available as attached file instead?
And for the record: MATLAB CENTRAL readers, or for the case, any reader of any document, ever, tend to give up reading when either
1.- do not want to read further: not interested, boring, already know, something better to read
2.- find it difficult to read further.
my guess your question falls in case 2.
Regards
John
Categories
Find more on Ordinary Differential Equations in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!