I am trying to solve an optimization problem where the given objective function is to minimize
norm(R - R*)
where R is obtained by solving a boundary value problem (BVP) and `R* is a known value.
For example:
R = (p1 + p2*p3);
The BVP is given by
p1dot = p2 + p3 + x1;
p2dot = x2 + p1*p2;
p3dot = x3 + p1*p2*p3;
where x1, x2 and x3 are the optimized variables.
I am trying to solve this in MATLAB using fmincon where the BVP is solved in the objective function at every guess by the solver to estimate norm(R-R*).
EDIT 1 : I have a non linear inequality constraint which is a function of pi where i = 1,2,3. This is the reason for choosing fmincon
The issue I am facing is that during some guesses the BVP doesn't converge and the optimization stops. I guess the issue is some guess value to solve the BVP doesn't satisfy. If I give bounds to the variables then it solves the optimization problem. I am not really aware of the bounds on variables beforehand.
In order to overcome this I want to detect the guess when BVP is not solved, save them and force the optimization routine to not try values when it cannot be solved by going back to its previous guess. How do we implement this in fmincon routine?
EDIT 2 : I figured out the issue is with initial guess provided to the BVP solver. For smaller values of the optimization variables x this guess is good but when the magnitude of x increase this guess is not good enough.
Is there a way to update the solution of 'BVP' in the previous iteration as the initial guess for the next iteration in optimization. Intuitively this should fix it. Please let me know if there are some loop holes in this method.
Related
I have the following equation system (click to see picture)
, and would like to solve for X(t), Y(t), Z(t), hopefully using Octave/Matlab, which I'm familiar with, but I would not mind solving it by any other means necessary.
Now, Fsolve is useful for regular equation systems, and Ode45, Lsode are useful for differential equations. But, what about this particular system? Note that the differential equation at the bottom contains not only Y, but, also, both X and Z, and those are dependent on the two non-differential equations above.
To be honest, I'm not quite sure how to approach a basic code to solve this system, and after spending some time thinking, I decided to ask for help. I really appreciate any guidance to solve this problem somewhat efficiently, if it is even possible. Almost any reply would be of some use to me right now.
If you know y, you can solve for x, and this even unconditionally as the second equation in monotonous in x
x = fsolve(#(x) y^2-1413.7*x-1095.2*cos(x)+2169, 0)
Then once you know x, you can solve for z using the known inverse cosine
z = acos(0.20978-cos(x))
This may actually fail to give a result if cos(x) comes close to -1. One can artificially cut out that error, introducing a possibly wrong solution
z = acos(min(1,0.20978-cos(x)))
For simplicity, assemble these operations in a helper function
function [x,z] = solve_xz(y)
x = fsolve(#(x) y^2-1413.7*x-1095.2*cos(x)+2169, 0);
z = acos(min(1,0.20978-cos(x)));
end
Now use that to get the ODE for y
function dy = ode_y(t,y)
[x,z] = solve_xz(y(1));
dy = [ y(2); y(3); 6666.6667*(z-x)-333.3333*y(1)-33.3333*y(2)-5*y(3) ];
end
and apply the ODE solver of your choice. It is quite likely that the system is stiff, so ode45 might not be the best solver.
I need to solve this ODE using Simulink and I don't know how to make it.
I only know how to do it using ODE solvers.
y'' - y' - 2y = e^(3x)
y(0)=1, y'(0)=2.
I rewrote the equation obtaining an ODEs:
y' = f(x,y)
y(x0) = y0
y'1 = y2
y2= e^(3*x) + y' + 2y
Using ODE solver.
If someone can help me to solve this using a Simulink Model I would appreciate it.
I know how to solve it in Matlab using ODE solvers as ode23 and ode23s but I don't know how to do it using a Simulink Model.
Thanks in advance
Can you solve it in closed form? Looks doable to me. I advise anyone to have the answer in hand if possible before you start a numerical solution.
Here's what I get. Check me:
y(x) = e^(-x)*(8e^3x + 3e^4x + 1)/12
Wolfram Alpha says this is correct.
(Note: Trouble for large values of x - this response will grow at e^3x rate.)
You need to express this as a set of coupled first order ODEs.
y' = z
z' = z + 2y + e^(3x)
Boundary conditions become:
y(0) = 1
z(0) = 2
You can set up the equation yourself term by term in Simulink and add the initial conditions to the integrators by double clicking and setting the corresponding field.
So a quick implementation looks like
I assumed that your x is a time-like quantity hence I placed a ramp function. Clock etc. would also do.
Alternatively you can form the state space system or the transfer function with explicitly taking the initial conditions into account.
I want to numerically solve a stochastic differential equation (SDE) in MATLAB, The code I have written just simply does not recognize sde function!
The question is as below:
dz=v*dt +sqrt(2*Ds)*dw_t
where v = 1/(N*delta) * sigma f_i (i=1- N)
N= 100,
delta = e6,
and f_i is calculated form this equation:
for z>=z0 , f_i = -kappa*(z0_i -z) and kappa = .17
for z<z0 , f_i = -kappaT*(z0_i -z) and kappaT = 60
note that the initial values for z0_i is randomly distributed over 60nm range.
Ds = 4e4
and dw_t is an increment in Wiener process.
Firstly I don't know how to set the conditions for z while I don't have the value for it!
Secondly, the Euler algorithm is exactly matching the equation but I don't know why the code with sde function is not working!
In order to numerically solve a SDE, you would need a Initial Condition (IC) for the function you want to code. In your case, I guess it's z. If you want to do so without explicitly declaring the IC, you can write it as a function that takes an IC. Then to test, you would input random ICs in.
Also, it is not clear to me whether your z0 is also stochastic and changes with time, is randomly generated every time step, or a constant that was only randomly generated once. Even simpler, if z0 is just the IC of z, then your f_i just inspects whether z has increased or decreased through the time step to decide how z would change the next time step. Please clarify this and your problem will seem much clearer.
It is not too hard to simulate your SDE without the use of the solver. You can try it out and achieve better result since sometimes you will really need to learn the behavior of the solver in order for it to work. I would suggest Monte Carlo method if you choose to write your own solver to ensure accuracy.
I hope my answer helps. If you still have any questions, feel free to ask.
I want to implement an equation
c= a*w*(sinwt + b*sin(2*w*t))
where w is varying and a,b and c are all constants.
I have done it using Agebraic Constraint block but I am getting an error
Trouble solving algebraic loop containing 'trial1/Algebraic Constraint1/Initial Guess' at time >0. Stopping simulation. There may be a singularity in the solution. If the model is correct, >try reducing the step size (either by reducing the fixed step size or by tightening the error >tolerances)
Pl help as in what might be wrong. Or suggest what are the other ways of solving the equation and finding a graph of w vs t(using scope).
Try implementing equation in this manner.
I have taken a=1,b=1,c=1 & w=1
c= #(t) (a*w*(sin(t) + b*sin(2*w*t)));
t = linspace (-pi,pi,1000);
figure
plot (t,c(t))
Here is the MATLAB/FreeMat code I got to solve an ODE numerically using the backward Euler method. However, the results are inconsistent with my textbook results, and sometimes even ridiculously inconsistent. What is wrong with the code?
function [x,y] = backEuler(f,xinit,yinit,xfinal,h)
%f - this is your y prime
%xinit - initial X
%yinit - initial Y
%xfinal - final X
%h - step size
n = (xfinal-xinit)/h; %Calculate steps
%Inititialize arrays...
%The first elements take xinit and yinit corespondigly, the rest fill with 0s.
x = [xinit zeros(1,n)];
y = [yinit zeros(1,n)];
%Numeric routine
for i = 1:n
x(i+1) = x(i)+h;
ynew = y(i)+h*(f(x(i),y(i)));
y(i+1) = y(i)+h*f(x(i+1),ynew);
end
end
Your method is a method of a new kind. It is neither backward nor forward Euler. :-)
Forward Euler: y1 = y0 + h*f(x0,y0)
Backward Euler solve in y1: y1 - h*f(x1,y1) = y0
Your method: y1 = y0 +h*f(x0,x0+h*f(x0,y0))
Your method is not backward Euler.
You don't solve in y1, you just estimate y1 with the forward Euler method. I don't want to pursue the analysis of your method, but I believe it will behave poorly indeed, even compared with forward Euler, since you evaluate the function f at the wrong point.
Here is the closest method to your method that I can think of, explicit as well, which should give much better results. It's Heun's Method:
y1 = y0 + h/2*(f(x0,y0) + f(x1,x0+h*f(x0,y0)))
The only issue I can spot is that the line:
n=(xfinal-xinit)/h
Should be:
n = abs((xfinal-xinit)/h)
To avoid a negative step count. If you are moving in the negative-x direction, make sure to give the function a negative step size.
Your answers probably deviate because of how coarsely you are approximating your answer. To get a semi-accurate result, deltaX has to be very very small and your step size has to be very very very small.
PS. This isn't the "backward Euler method," it is just regular old Euler's method.
If this is homework please tag it so.
Have a look at numerical recipes, specifically chapter 16, integration of ordinary differential equations. Euler's method is known to have problems:
There are several reasons that Euler’s method is not recommended for practical use, among them, (i) the method is not very accurate when compared to other, fancier, methods run at the equivalent stepsize, and (ii) neither is it very stable
So unless you know your textbook is using Euler's method, I wouldn't expect the results to match. Even if it is, you probably have to use an identical step size to get an identical result.
Unless you really want to solve an ODE via Euler's method that you've written by yourself you should have a look at built-in ODE solvers.
On a sidenote: you don't need to create x(i) inside the loop like this: x(i+1) = x(i)+h;. Instead, you can simply write x = xinit:h:xfinal;. Also, you may want to write n = round(xfinal-xinit)/h); to avoid warnings.
Here are the solvers implemented by MATLAB.
ode45 is based on an explicit
Runge-Kutta (4,5) formula, the
Dormand-Prince pair. It is a one-step
solver – in computing y(tn), it needs
only the solution at the immediately
preceding time point, y(tn-1). In
general, ode45 is the best function to
apply as a first try for most
problems.
ode23 is an implementation of an
explicit Runge-Kutta (2,3) pair of
Bogacki and Shampine. It may be more
efficient than ode45 at crude
tolerances and in the presence of
moderate stiffness. Like ode45, ode23
is a one-step solver.
ode113 is a variable order
Adams-Bashforth-Moulton PECE solver.
It may be more efficient than ode45 at
stringent tolerances and when the ODE
file function is particularly
expensive to evaluate. ode113 is a
multistep solver — it normally needs
the solutions at several preceding
time points to compute the current
solution.
The above algorithms are intended to
solve nonstiff systems. If they appear
to be unduly slow, try using one of
the stiff solvers below.
ode15s is a variable order solver
based on the numerical differentiation
formulas (NDFs). Optionally, it uses
the backward differentiation formulas
(BDFs, also known as Gear's method)
that are usually less efficient. Like
ode113, ode15s is a multistep solver.
Try ode15s when ode45 fails, or is
very inefficient, and you suspect that
the problem is stiff, or when solving
a differential-algebraic problem.
ode23s is based on a modified
Rosenbrock formula of order 2. Because
it is a one-step solver, it may be
more efficient than ode15s at crude
tolerances. It can solve some kinds of
stiff problems for which ode15s is not
effective.
ode23t is an implementation of the
trapezoidal rule using a "free"
interpolant. Use this solver if the
problem is only moderately stiff and
you need a solution without numerical
damping. ode23t can solve DAEs.
ode23tb is an implementation of
TR-BDF2, an implicit Runge-Kutta
formula with a first stage that is a
trapezoidal rule step and a second
stage that is a backward
differentiation formula of order two.
By construction, the same iteration
matrix is used in evaluating both
stages. Like ode23s, this solver may
be more efficient than ode15s at crude
tolerances.
I think this code could work. Try this.
for i =1:n
t(i +1)=t(i )+dt;
y(i+1)=solve('y(i+1)=y(i)+dt*f(t(i+1),y(i+1)');
end
The code is fine. Just you have to add another loop within the for loop. To check the level of consistency.
if abs((y(i+1) - ynew)/ynew) > 0.0000000001
ynew = y(i+1);
y(i+1) = y(i)+h*f(x(i+1),ynew);
end
I checked for a dummy function and the results were promising.