MATLAB Symbolic coeffs issues - matlab

I'm working with MATLAB's symbolic toolbox, and I'm having some issues pulling out the coefficients of derivatives. Maybe MATLAB can't do what I am looking for. Anyway, code that reproduces the issue I'm having is shown below:
clear ; close all; clc;
syms a b t
x = sym('x(t)');
y = sym('y(t)');
syms a b;
ra = a*cos(x);
radot = diff(ra, t);
xdot = diff(x,t);
ydot = diff(y,t);
% This one works as expected
works = coeffs(radot(1), xdot)
% This doesn't work as expected
fails = coeffs(radot(1), ydot)
Comments in the above code sections highlight what works and what does not work as expected. Specifically, the outputs are:
radot =
-a*sin(x(t))*diff(x(t), t)
works =
-a*sin(x(t))
fails =
-a*sin(x(t))*diff(x(t), t)
Does anyone know why this happens or whether I'm doing something wrong?

The result of the last line is constant with respect to ydot, and therefore the whole expression is seen as a single coefficient (a constant).
What is your expected result for coeffs(radot(1), ydot)?

It looks like you may be using coeffs for something that it wasn't meant for. Look at the help. It's designed to give the coefficients of a polynomial, not wether a differential equation is a function of one variable or another.
If you happen to be trying to take the derivative with respect to xdot and ydot, you can do this
syms z; % Subsitution variable for diff(x(t), t) and diff(y(t), t)
diff(subs(radot(1),xdot,z),z)
diff(subs(radot(1),ydot,z),z)
which returns
ans =
-a*sin(x(t))
ans =
0

Related

Matlab syms Function and integration

I have a sort of obscure question. I am wanting to do something with two separate set of syms and manipulate the syms. This is a little difficult for me to explain without including my code firsts so:
syms x Wg Iyy b
S = syms;
Pz1 = (Wg*n)/(2*b);
Vzx1 = int(Pz1,x,x,b)
Myx1 = -int(Vzx1,x,x,b)
dw_dx = (-1/(E*Iyy))*int(Myx1,x,0,x);
wx1 = int(dw_dx,x,0,x)
% Get the numerical output of the value using b as wing
clear S;
% assume(S,'clear');
% cellfun(#clear, S);
L = 6;
b = (1490+10*L)/2;
Vzx1_num = Vzx1
Myx1_num = Myx1
wx1_num = wx1
% need to sub b for b=b_prime*cos(40)
% Not really sure how to do this, I know I have to redclare the syms
syms x Wg Iyy
So to expand on more what is going on and what I am looking to do. The first syms (syms = x Wg Iyy b), I would like to keep as is because based on my needs I want to output the value of Vzx1 in terms of those variables. This part works perfectly for what I am intending to do. The error lies in how I would like to manipulate the value I have generated. So secondly, I would like to ouput the numerical value of these generated expression by using the value of b. I am trying to clear the value of syms.
When using
S= syms
clear S
The value of S gets clear. So b would no longer be a symbol and I can set the value of b, allowing Vzx1_num to ouput the value of Vzx1 with b replaced with a number. This is not the case as b remains a sym
Then thirdly I want to substitute the variable value of b for the value of b_prime*cos(40). I have tried to mess with this but based on how I have previously declared b as a syms I am having a hard time manipulating this variable. So when I use syms x Wg Iyy. That is not the value of syms the value of syms outputs
syms
Your symbolic variables are:
Iyy Myx1_num Vzx1 Wg wx1 x
Myx1 Pz1 Vzx1_num dw_dx wx1_num
I am extremely confused why syms gets built using the values I have manipulated previously.
Any and all help would be greatly appreciated.

MatLab ode45 explanation

For a project I need to understand a matlab code, but as I am quite new I dont really understand what is happening. I have a function file and a script file.
Function:
function dxdt = sniffer_ode(t,x,par,tu)
X = x(1);
R = x(2);
k1 = par(1);
k2 = par(2);
k3 = par(3);
k4 = par(4);
S = interp1(tu(:,1),tu(:,2),t);
dxdt(1) = k3*S-k4*X;
dxdt(2) = k1*S-k2*X*R;
dxdt = dxdt(:); %dxdt should be column
and the script file:
%sniffer
close all
%initial conditions:
X0=0; R0=0;
x0=[X0 R0];
%parameters:
k1=1; k2=1; k3=1; k4=1;
par=[k1 k2 k3 k4];
%input:
tu=[ 0 , 0
1 , 0
1.01, 1
20 , 1];
[t,x] = ode45(#sniffer_ode,[0 20],x0, [],par,tu);
plot(t,x);
So the question is: What is happening? I also need to plot S in the same figure as X and R. How do I do this?
I appreciate your help!
This is a really basic Matlab question. There is tons of information about your requested topic. I think these slides will help you on the right path.
However, a quick explanation; the first code you provide is the function which describes your ordinary differential equation. This function always has to be of the form x' = f(t,x,...). Herein t is the time and x is the state. After the state (on the place of the dots ...) you can define other input parameters, such as is being done in your ode function. Furthermore, the interp1 function interpolates the data provided.
The second code you provide is the code you start within Matlab. Parameters are defined, after which the ordinary differential equation is solved and plotted.
If you have any further questions I would recommend that you first try to find your answer using a search engine.

Finding unknown limit of integration in MATLAB

I have an equation of the form c = integral of f(t)dt limiting from a constant to a variable (I don't want to show the full equation because it is very long and complex). Is there any way to calculate in MATLAB what the value of that variable is (there are no other variables and the equation is too difficult to solve by hand)?
Assume your limit is from cons to t and g(t) as your function with variable t. Now,
syms t
f(t) = int(g(t),t);
This will give you the indefinite integral. Now f(t) will be
f(t) = f(t)+f(cons);
You have the value of f(t)=c. So just solve the equation
S = solve(f(t)==c,t,'Real',true);
eval(S) will give the answer i think
This is an extremely unclear question - if you do not want to post the full equation, post an example instead
I am assuming this is what you intend: you have an integrand f(x), which you know, and has been integrated to give some constant c which you know, over the limits of x = 0, to x = y, for example, where y may change, and you desire to find y
My advice would be to integrate f(x) manually, fill in the first limit, and subtract that portion from c. Next you could employ some technique such as the Newton-Ralphson method to iteratively search for the root to your equation, which should be in x only
You could use a function handle and the quad function for the integral
myFunc = #(t) exp(t*3); % or whatever
t0 = 0;
t1 = 3;
L = 50;
f = #(b) quad(#(t) myFunc(t,b),t0,t1);
bsolve = fzero(f,2);
Hope it help !

Implementing iterative solution of integral equation in Matlab

We have an equation similar to the Fredholm integral equation of second kind.
To solve this equation we have been given an iterative solution that is guaranteed to converge for our specific equation. Now our only problem consists in implementing this iterative prodedure in MATLAB.
For now, the problematic part of our code looks like this:
function delta = delta(x,a,P,H,E,c,c0,w)
delt = #(x)delta_a(x,a,P,H,E,c0,w);
for i=1:500
delt = #(x)delt(x) - 1/E.*integral(#(xi)((c(1)-c(2)*delt(xi))*ms(xi,x,a,P,H,w)),0,a-0.001);
end
delta=delt;
end
delta_a is a function of x, and represent the initial value of the iteration. ms is a function of x and xi.
As you might see we want delt to depend on both x (before the integral) and xi (inside of the integral) in the iteration. Unfortunately this way of writing the code (with the function handle) does not give us a numerical value, as we wish. We can't either write delt as two different functions, one of x and one of xi, since xi is not defined (until integral defines it). So, how can we make sure that delt depends on xi inside of the integral, and still get a numerical value out of the iteration?
Do any of you have any suggestions to how we might solve this?
Using numerical integration
Explanation of the input parameters: x is a vector of numerical values, all the rest are constants. A problem with my code is that the input parameter x is not being used (I guess this means that x is being treated as a symbol).
It looks like you can do a nesting of anonymous functions in MATLAB:
f =
#(x)2*x
>> ff = #(x) f(f(x))
ff =
#(x)f(f(x))
>> ff(2)
ans =
8
>> f = ff;
>> f(2)
ans =
8
Also it is possible to rebind the pointers to the functions.
Thus, you can set up your iteration like
delta_old = #(x) delta_a(x)
for i=1:500
delta_new = #(x) delta_old(x) - integral(#(xi),delta_old(xi))
delta_old = delta_new
end
plus the inclusion of your parameters...
You may want to consider to solve a discretized version of your problem.
Let K be the matrix which discretizes your Fredholm kernel k(t,s), e.g.
K(i,j) = int_a^b K(x_i, s) l_j(s) ds
where l_j(s) is, for instance, the j-th lagrange interpolant associated to the interpolation nodes (x_i) = x_1,x_2,...,x_n.
Then, solving your Picard iterations is as simple as doing
phi_n+1 = f + K*phi_n
i.e.
for i = 1:N
phi = f + K*phi
end
where phi_n and f are the nodal values of phi and f on the (x_i).

How do I symbolically integrate functions in matlab where I know the output must contain bessel functions?

I am working with the following function:
f(x) = a*(1+cos(3*x)) where a is constant/parameter.
y(x) = exp(-b*f(x)) where b is another constant.
I need to compute the definite integral integral(0,2pi)y(x)dx.
I am trying to implement another research paper for our research group. I know the output must contain modified bessel functions of the first kind which are functions of 'a'. Matlab simply refuses to evaluate this integral.
The following is my code(Matlab):
syms x;
syms a;
syms b;
f_x = a*(1+cos(3*x));
y_x = exp(-b*f_x);
z_x = int(y_x, x, 0, 2*pi)
Output:
Warning: Explicit integral could not be found.
z_x =
int(1/exp(a*b*(cos(3*x) + 1)), x = 0..2*pi)
Request your assistance in solving this! I am sure that the integral contains bessel functions like I(a), etc. at many places. Is there any pre-processing I need to do here? I kind of need this solution urgently. I appreciate quick responses which can atleast point in the right direction.
Solved!. It worked in mathematica, failed in Matlab.
Starting R2017b, this works. Use int.
>> syms x;
syms a;
syms b;
f_x = a*(1+cos(3*x));
y_x = exp(-b*f_x);
z_x = int(y_x, x, 0, 2*pi)
z_x =
2*pi*exp(-a*b)*besselj(0, a*b*1i)