Substitute the nonlinearity in the linear system
3 次查看(过去 30 天)
显示 更早的评论
Hello everyone! I have a question about possibility of substituting some nonlinear function in system of lode’s.
For example, I have a system:
iN=1;%line
jN=2;%row
Nonlinearity=@(x) x^2;
[T,X]=ode45(@(t,x) odesys(t,x,Nonlinearity,iN,jN), [0 2],[0 0.1]
function RPF=odesys(t,x,Nonlinearity, iN, jN)
A=[0 1;0 -1];
B=[0 1];
A(iN,jN)=A(iN,jN)*Nonlinearity(x(jN))/x(jN);
RPF=A*x+B;
end
Obviously this works only if x(jN) does’nt equal zero during the integration progress, and I may suppose that this will produce some calculating errors because of dividing.
So I want to know is there better way to do this.
Thank you in advance!
0 个评论
采纳的回答
Walter Roberson
2020-7-30
If you do encounter a division by 0 during calculations, then odesys will end up returning a value that includes either infinite or nan (or both). That will typically not be noticed immediately, but instead the next call to odesys will very likely end up returning mostly or all nan. Everything will fall apart from there.
There are narrow circumstances under which ode45() will notice the big value and recover smoothly, just saying "Oh, I guess that step failed" -- but for that to happen, you have to get lucky enough that the division by 0 was on the very last of the 6 odefun calls per iteration that ode45 makes. Much more typical is that you just start going haywire and figuring out why can be a pain.
So... What you should can is a test such as
RPF(~isfinite(RPF)) = 1e100; %some big value that is going to be far from normal values
This will eliminate some of the problems, allowing for a cleaner recover.
You should also, however, add an event function through the options structure, and the event function should be marked as Terminal, and Both Directions, and the value to test should be x(2) . An event function such as that will go as close to the border where x(2) becomes 0 as it can, and then will exit ode45 early. You can tell that the exit was early by checking the last time returned.
This particular exception is probably not "removable": if x(jN) becomes 0 because it must due to the initial conditions, then there is not much you can do except quit. There are a lot of other cases where when the exception is detected, that you want to change the boundary conditions. I recommend Mathwork's example ballode which shows how to use events to cause a ball to "bounce" when it hits the floor (it reverses the velocity and then restarts ode45() )
7 个评论
Walter Roberson
2020-7-30
If your nonlinear function is continuous and twice differentiable, then if you have the Symbolic Toolbox, you could probably construct the forms symbolically and then use odeFunction() to create the anonymous function.
This will not work without a bit of twisting if the function includes min() or max() or mod() : the symbolic versions of those usually do not do what is desired. (On the other hand, those are not differentiable.)
If the nonlinear function has iteration based upon getting down to some particular absolute or relative error, then there could be a problem using symbolic variables with it.
If the nonlinear function compares the inputs to values then a bit of redesign could be needed (but such cases are typically not twice differentiable unless they are carefully constructed.)
更多回答(1 个)
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!