How to retrieve accelerations from ode - matlab

As the title says I'd like to know how to retrieve the 2nd order derivative from a Matlab ode.
The system i'm trying to simulate is described by 12 1st order differential equations.
Let's explain:
...
[T,Y] = ode113(#sixdofsolver,time,Y0,options,settings);
T = 1700x1 vector
Y = 1700x12 matrix
Now if i do:
[dY] = sixdofsolver(T,Y,settings)
dY = 12x1 vector
I'd have expected to have a same-size matrix like Y.
What am I doing wrong?

You're on the right track. Your integration function sixdofsolver is likely designed first for used by Matlab's ODE solvers. These functions evaluate the function at one point in time (and a single state value) rather than across a range of times.
You either need to rewrite your sixdofsolver function so that it can handle more than a single time or your need to create a new function based on it that does that. In other words you need to vectorize the integration function. You probably have variable like y(1), y(2), ..., y(12). Well, now the input state vector is a matrix so you need to use something likey(:,1),y(:,2), ..., y(:,12). You may need to do other things like switch to element-wise operators. I can't help you more from what you've provided.

Related

How do I get the values of y and y' for specific values of t from ode45 in Matlab?

I have to solve a second-degree differential equation and I specifically need the value of the first derivative of y at the final time point. My code is the following:
[T Y]=ode45(#(t y)vdp4(t,y,0.3),[0 1],[0.3/4,((3*0.3)^0.5)/2]);
I know the output will contain the values at which ode45 evaluated the function. To get the y values at specific time value at have it has been advised to give more than two time points in the MATLAB documentation. I did that too.
tspan=[0:0.01:1]
[T Y]=ode45(#(t y)vdp4(t,y,0.3),tspan,[0.3/4,((3*0.3)^0.5)/2]);
The T vector still does not have all the values from 0 to 1 (The last value is 0.39). This happens especially after multiple executions of ode45 function. I found something else in the MATLAB documentation: using "sol" structure to deval the values for specific t values. Is that the right way to go?
For reference, my differential equation is in the following function.
function dy = vdp4(t,y,k)
dy = zeros(2,1); % a column vector
dy(1)=y(2);
dy(2)=(y(2)^2-2*t*y(2)+2*y(1))/k+2;
end
Edit: I provided the parameter value. It should now be executable.
Try to plot your solution, you will find the answer

Minimizing Function with vector valued input in MATLAB

I want to minimize a function like below:
Here, n can be 5,10,50 etc. I want to use Matlab and want to use Gradient Descent and Quasi-Newton Method with BFGS update to solve this problem along with backtracking line search. I am a novice in Matlab. Can anyone help, please? I can find a solution for a similar problem in that link: https://www.mathworks.com/help/optim/ug/unconstrained-nonlinear-optimization-algorithms.html .
But, I really don't know how to create a vector-valued function in Matlab (in my case input x can be an n-dimensional vector).
You will have to make quite a leap to get where you want to be -- may I suggest to go through some basic tutorial first in order to digest basic MATLAB syntax and concepts? Another useful read is the very basic example to unconstrained optimization in the documentation. However, the answer to your question touches only basic syntax, so we can go through it quickly nevertheless.
The absolute minimum to invoke the unconstraint nonlinear optimization algorithms of the Optimization Toolbox is the formulation of an objective function. That function is supposed to return the function value f of your function at any given point x, and in your case it reads
function f = objfun(x)
f = sum(100 * (x(2:end) - x(1:end-1).^2).^2 + (1 - x(1:end-1)).^2);
end
Notice that
we select the indiviual components of the x vector by matrix indexing, and that
the .^ notation effects that the operand is to be squared elementwise.
For simplicity, save this function to a file objfun.m in your current working directory, so that you have it available from the command window.
Now all you have to do is to call the appropriate optimization algorithm, say, the quasi Newton method, from the command window:
n = 10; % Use n variables
options = optimoptions(#fminunc,'Algorithm','quasi-newton'); % Use QM method
x0 = rand(n,1); % Random starting guess
[x,fval,exitflag] = fminunc(#objfun, x0, options); % Solve!
fprintf('Final objval=%.2e, exitflag=%d\n', fval, exitflag);
On my machine I see that the algorithm converges:
Local minimum found.
Optimization completed because the size of the gradient is less than
the default value of the optimality tolerance.
Final objval=5.57e-11, exitflag=1

For loop equation into Octave / Matlab code

I'm using octave 3.8.1 which works like matlab.
I have an array of thousands of values I've only included three groupings as an example below:
(amp1=0.2; freq1=3; phase1=1; is an example of one grouping)
t=0;
amp1=0.2; freq1=3; phase1=1; %1st grouping
amp2=1.4; freq2=2; phase2=1.7; %2nd grouping
amp3=0.8; freq3=5; phase3=1.5; %3rd grouping
The Octave / Matlab code below solves for Y so I can plug it back into the equation to check values along with calculating values not located in the array.
clear all
t=0;
Y=0;
a1=[.2,3,1;1.4,2,1.7;.8,5,1.5]
for kk=1:1:length(a1)
Y=Y+a1(kk,1)*cos ((a1(kk,2))*t+a1(kk,3))
kk
end
Y
PS: I'm not trying to solve for Y since it's already solved for I'm trying to solve for Phase
The formulas located below are used to calculate Phase but I'm not sure how to put it into a for loop that will work in an array of n groupings:
How would I write the equation / for loop for finding the phase if I want to find freq=2.5 and amp=.23 and the phase is unknown I've looked online and it may require writing non linear equations which I'm not sure how to convert what I'm trying to do into such an equation.
phase1_test=acos(Y/amp1-amp3*cos(2*freq3*pi*t+phase3)/amp1-amp2*cos(2*freq2*pi*t+phase2)/amp1)-2*freq1*pi*t
phase2_test=acos(Y/amp2-amp3*cos(2*freq3*pi*t+phase3)/amp2-amp1*cos(2*freq1*pi*t+phase1)/amp2)-2*freq2*pi*t
phase3_test=acos(Y/amp3-amp2*cos(2*freq2*pi*t+phase2)/amp3-amp1*cos(2*freq1*pi*t+phase1)/amp3)-2*freq2*pi*t
Image of formula below:
I would like to do a check / calculate phases if given a freq and amp values.
I know I have to do a for loop but how do I convert the phase equation into a for loop so it will work on n groupings in an array and calculate different values not found in the array?
Basically I would be given an array of n groupings and freq=2.5 and amp=.23 and use the formula to calculate phase. Note: freq will not always be in the array hence why I'm trying to calculate the phase using a formula.
Ok, I think I finally understand your question:
you are trying to find a set of phase1, phase2,..., phaseN, such that equations like the ones you describe are satisfied
You know how to find y, and you supply values for freq and amp.
In Matlab, such a problem would be solved using, for example fsolve, but let's look at your problem step by step.
For simplicity, let me re-write your equations for phase1, phase2, and phase3. For example, your first equation, the one for phase1, would read
amp1*cos(phase1 + 2 freq1 pi t) + amp2*cos(2 freq2 pi t + phase2) + amp3*cos(2 freq3 pi t + phase3) - y = 0
Note that ampX (X is a placeholder for 1, 2, 3) are given, pi is a constant, t is given via Y (I think), freqX are given.
Hence, you are, in fact, dealing with a non-linear vector equation of the form
F(phase) = 0
where F is a multi-dimensional (vector) function taking a multi-dimensional (vector) input variable phase (comprised of phase1, phase2,..., phaseN). And you are looking for the set of phaseX, where all of the components of your vector function F are zero. N.B. F is a shorthand for your functions. Therefore, the first component of F, called f1, for example, is
f1 = amp1*cos(phase1+...) + amp2*cos(phase2+...) + amp3*cos(phase3+...) - y = 0.
Hence, f1 is a one-dimensional function of phase1, phase2, and phase3.
The technical term for what you are trying to do is find a zero of a non-linear vector function, or find a solution of a non-linear vector function. In Matlab, there are different approaches.
For a one-dimensional function, you can use fzero, which is explained at http://www.mathworks.com/help/matlab/ref/fzero.html?refresh=true
For a multi-dimensional (vector) function as yours, I would look into using fsolve, which is part of Matlab's optimization toolbox (which means I don't know how to do this in Octave). The function fsolve is explained at http://www.mathworks.com/help/optim/ug/fsolve.html
If you know an approximate solution for your phases, you may also look into iterative, local methods.
In particular, I would recommend you look into the Newton's Method, which allows you to find a solution to your system of equations F. Wikipedia has a good explanation of Newton's Method at https://en.wikipedia.org/wiki/Newton%27s_method . Newton iterations are very simple to implement and you should find a lot of resources online. You will have to compute the derivative of your function F with respect to each of your variables phaseX, which is very simple to compute since you're only dealing with cos() functions. For starters, have a look at the one-dimensional Newton iteration method in Matlab at http://www.math.colostate.edu/~gerhard/classes/331/lab/newton.html .
Finally, if you want to dig deeper, I found a textbook on this topic from the society for industrial and applied math: https://www.siam.org/books/textbooks/fr16_book.pdf .
As you can see, this is a very large field; Newton's method should be able to help you out, though.
Good luck!

How to have square wave in Matlab symbolic equation

My project require me to use Matlab to create a symbolic equation with square wave inside.
I tried to write it like this but to no avail:
syms t;
a=square(t);
Input arguments must be 'double'.
What can i do to solve this problem? Thanks in advance for the helps offered.
here are a couple of general options using floor and sign functions:
f=#(A,T,x0,x) A*sign(sin((2*pi*(x-x0))/T));
f=#(A,T,x0,x) A*(-1).^(floor(2*(x-x0)/T));
So for example using the floor function:
syms x
sqr=2*floor(x)-floor(2*x)+1;
ezplot(sqr, [-2, 2])
Here is something to get you started. Recall that we can express a square wave as a Fourier Series expansion. I won't bother you with the details, but you can represent any periodic function as a summation of cosines and sines (à la #RTL). Without going into the derivation, this is the closed-form equation for a square wave of frequency f, with a peak-to-peak amplitude of 2 (i.e. it goes from -1 to 1). Recall that the frequency is the amount of cycles per seconds. Therefore, f = 1 means that we repeat our square wave every second.
Basically, what you have to do is code up the first line of the equation... but how in the world would you do that? Welcome to the world of the Symbolic Math Toolbox. What we will need to do before hand is declare what our frequency is. Let's assume f = 1 for now. With the Symbolic Math Toolbox, you can define what are considered as mathematics variables within MATLAB. After, MATLAB has a whole suite of tools that you can use to evaluate functions that rely on these variables. A good example would be if you want to use this to define a closed-form solution of a function f(x). You can then use diff to differentiate and see what the derivative is. Try it yourself:
syms x;
f = x^4;
df = diff(f);
syms denotes that you are declaring anything coming after the statement to be a mathematical variable. In this case, x is just that. df should now give you 4x^3. Cool eh? In any case, let's get back to our problem at hand. We see that there are in fact two variables in the periodic square function that need to be defined: t and k. Once we do this, we need to create our function that is inside the summation first. We can do this by:
syms t k;
f = 1; %//Define frequency here
funcSum = (sin(2*pi*(2*k - 1)*f*t) / (2*k - 1));
That settles that problem... now how do we encapsulate this into an infinite sum!? The sum command in MATLAB assumes that we have a finite array to sum over. If you want to symbolically sum over a function, we must use the symsum function. We usually call it like this:
funcOut = symsum(func, v, start, finish);
func is the function we wish to sum over. v is the summation variable that we wish to use to index in the sum. In our case, that's k. start is the beginning of the sum, which is 1 in our case, and finish is where we wish to finish up our summation. In our case, that's infinity, and so MATLAB has a special keyword called Inf to denote that. Therefore:
xsquare = (4/pi) * symsum(funcSum, k, 1, Inf);
xquare now contains your representation of a square wave defined in terms of the Symbolic Math Toolbox. Now, if you want to plot your square wave and see if we have this right. We can do the following. Let's go between -3 <= t <= 3. As such, you would do something like this:
tVector = -3 : 0.01 : 3; %// Choose a step size of 0.01
yout = subs(xsquare, t, tVector);
You will notice though that there will be some values that are NaN. The reason why is because right at a multiple of the period (T = 1, 2, 3, ...), the behaviour is undefined as the derivative right at these points is undefined. As such, we can fill this in using either 1 or -1. Let's just choose 1 for now. Also, because the Fourier Series is generally a complex-valued function, and the square-wave is purely real, the output of this function will actually give you a complex-valued vector. As such, simply chop off the complex parts to get the real parts only:
yout = real(double(yout)); %// To cast back to double.
yout(isnan(yout)) = 1;
plot(tVector, yout);
You'll get something like:
You could also do this the ezplot way by doing: ezplot(xsquare). However, you'll see that at the points where the wave repeats itself, we get NaN values and so there is a disconnect between the high peak and low peak.
Note:
Natan's solution is much more elegant. I was still writing this post by the time he put something up. Either way, I wanted to give a more signal processing perspective to how to do this. Go Fourier!
A Fourier series for the square wave of unit amplitude is:
alpha + 2/Pi*sum(sin( n * Pi*alpha)/n*cos(n*theta),n=1..infinity)
Here is a handy trick:
cos(n*theta) = Re( exp( I * n * theta))
and
1/n*exp(I*n*theta) = I*anti-derivative(exp(I*n*theta),theta)
Put it all together: pull the anti-derivative ( or integral ) operator out of the sum, and you get a geometric series. Then integrate and finally take the real part.
Result:
squarewave=
alpha+ 1/Pi*Re(I*ln((1-exp(I*(theta+Pi*alpha)))/(1-exp(I*(theta-Pi*alpha)))))
I tried it in MAPLE and it works great! (probably not very practical though)

matlab genetic algorithm solver complex input and output

My Matlab program has multiple inputs as a struct (in.a, in.b, etc.)
and multiple outputs (out.a, out.b, etc.)
I would like to use the genetic algorithm solver from teh optimization toolbox to find the best input in.a, while all the other inputs are constant. The fitness is one of the outputs, e.g. out.b(2,3).
How do I "tell" the solver this?
Thanks
Daniel
It is not uncommon in programming to have a situation where what is most convenient for your function and what some library call expects of it don't agree. The normal resolution to such a problem is to write a small layer in between that allows the two to talk; an interface.
From help ga:
X = GA(FITNESSFCN,NVARS) finds a local unconstrained minimum X to the
FITNESSFCN using GA. [...] FITNESSFCN accepts a vector X of size
1-by-NVARS, and returns a scalar evaluated at X.
So, ga expects vector input, scalar output, whereas you have a structure going in and out. You would have to write the following (sub)function:
function Y = wrapper_Objfun(X, in)
in.a = X; %# variable being optimized
out = YOUR_REAL_FUNCTION(in); %# call to your actual function
Y = out.b(2,3); %# objective value
end
and then the call to ga will look like
X = ga(#(x) wrapper_Objfun(x,in), N);
where N is however large in.a should be.
Also have a read about it in Matlab's own documentation on the subject.