How can I use unknown variables in Matlab? - matlab

For example, I have an operation from Wolfram Alpha: det({s+1,0},{0,s+1}}). Wolfram solves it and shows me a result: s^2 + 2s + 1. How can I do such things (with unknown variables) in Matlab?

With Symbolic Math Toolbox, this can be done using the following:
syms s;
det([s+1,0 ; 0,s+1])
which gives this:
ans =
(s + 1)^2
and if you want to get the expanded form i.e. s^2 + 2*s + 1, you can use expand function as follows:
syms s;
expand(det([s+1,0 ; 0,s+1]))

Related

Extracting arrays of a symbolic vector in MATLAB

I have a vector of symbolic function of the following form defined in MATLAB R2021a:
O_BF(t) =
[JTP*(diff(theta(t), t)*(w1 + w3 - w4 - w2*(cos(beta)*cos(gamma) +
sin(alpha)*sin(beta)*sin(gamma))) - w2*(cos(gamma)*sin(beta) -
cos(beta)*sin(alpha)*sin(gamma))*diff(say(t), t)), -JTP*(diff(phi(t), t)*(w1 + w3 - w4 - w2*
(cos(beta)*cos(gamma) + sin(alpha)*sin(beta)*sin(gamma))) +
w2*cos(alpha)*sin(gamma)*diff(say(t), t)), JTP*(w2*(cos(gamma)*sin(beta) -
cos(beta)*sin(alpha)*sin(gamma))*diff(phi(t), t) + w2*cos(alpha)*sin(gamma)*diff(theta(t),
t))]
And I want the following results, which obviously is the extracted parts of the above vector:
[JTP*(diff(theta(t), t)*(w1 + w3 - w4 - w2*(cos(beta)*cos(gamma) +
sin(alpha)*sin(beta)*sin(gamma))) - w2*(cos(gamma)*sin(beta) -
cos(beta)*sin(alpha)*sin(gamma))*diff(say(t), t))
-JTP*(diff(phi(t), t)*(w1 + w3 - w4 - w2*
(cos(beta)*cos(gamma) + sin(alpha)*sin(beta)*sin(gamma))) +
w2*cos(alpha)*sin(gamma)*diff(say(t), t))
JTP*(w2*(cos(gamma)*sin(beta) -
cos(beta)*sin(alpha)*sin(gamma))*diff(phi(t), t) +
w2*cos(alpha)*sin(gamma)*diff(theta(t),
t))]
As You can see, this is clearly a vector, but I cannot extract the arrays because MATLAB considers this vector as a function of time. How can I do that?
O_BF(t) in your question is a symbolic function with respect to t that returns a matrix.
This a common issue when working with symbolic functions and Matlab symfun objects. Here's a simpler example that I think reproduces the behavior observed in the question:
syms t a; %define symbolic variables
f(t) = [t a*t 2*t^2]; %define symfun array as function of t
Calling f(1) evaluates the symfun for t = 1 rather than extracting the first element of the 1-by-3 array:
>> f(1)
ans =
[1, a, 2]
To access the elements of the underlying array one must assign the contents to an intermediate symbolic variable:
g = f(t); %or even f=f(t) to redefine f as sym rather than symfun
g(1)
>> g(1)
ans =
t
This is equivalent to using the formula function:
g = formula(f);
g(1)
>> g(1)
ans =
t
I know of no current way to directly access the elements of an array defined as a symfun without going through the above steps.

MATLAB using cosh and sinh

I am trying the find the inverse Laplace voltage of a circuit, but when I compute it MATLAB output contains sinh and cosh. Is there a way to make MATLAB compute it?
Here is my code:
syms s
F=((s^2)+12*s+20)/(s*((s^2)+10*s+4))
f=ilaplace(F)
f=vpa(f,5)
The expression for f contains the t symbol, you have to substitute a value for t before you can compute the output at that time t; the error message directs you precisely to that solution. I chose t = 5, you can change that as you wish.
syms s
F = (s^2 + 12*s + 20) / (s*(s^2 + 10*s + 4));
f = ilaplace(F);
% 5 - 4*exp(-5*t)*(cosh(21^(1/2)*t) + (3*21^(1/2)*sinh(21^(1/2)*t))/14)
f = subs(f, 5);
double(f)
ans =
4.5083

Solving optimal control problems, ode45 vs fmincon

Good afternoon!
First things first, I looked for similar questions for a while, but (probably because of my inexperience) I've found nothing similar to what I'm going to ask.
I'm using matlab for the first time to solve this kind of problems, so I'm not sure of what to do. A brief explenation:
I'm doing a project for my Optimal Control course: I have to replicate the results of a paper about employment, and I'm stuck with the plots. I have the following data:
five variable functions (U(t), T(t), R(t), V1(t) and V2(t))
four control functions(u1(t), u2(t), u3(t), u4(t))
constraints on the control variables (each u must be between 0 and 1)
initial values for U, T, R, V1 and V2 (in t=0, in particular V1 and V2 are constant over time)
final values for the λ coefficients in the hamiltonian
(note: for the controls, I've already found the optimal expression, which is in this form: ui = min{1, max{0,"expression"}}. If needed, I can give also the four expressions, neglected to
synthesize a little)
Under professor's suggestions, I've tried to use fmincon, that theoretically should give me directly the information that I need to plot some result using only the cost function of the problem. But in this case I have some issues involving time in the calculations. Below, the code that I used for fmincon:
syms u
%note: u(5) corresponds to U(t), but this is the only way I've found to get
%a result, the other u(i) are in ascending order (u(1) = u1 and so on...)
g = #(u) 30*u(5) + (20/2)*(u(1))^2 + (20/2)*(u(2))^2 + (10/2)*(u(3))^2 + (40/2)*(u(4))^2;
%initial guesses
u0 = [0 0 0 0 100000]; %
A = [];
b = [];
Aeq = [];
beq = [];
lb = 0.0 * ones(1,2,3,4);
ub = 1.0 * ones(1,2,3,4);
[x,fval,output,lambda] = fmincon(g, u0, A, b, Aeq, beq, lb, ub);
Whit this code, i get (obviously) only one value for each variable as result, and since I've not found any method to involve time, as I said before, I start looking for other solving strategies.
I found that ode45 is a differential equation solver that has the "time iteration" already included in the algorithm, so I tried to write the code to get it work with my problem.
I took all the equations from the paper and put them in a vector as shown in the mathworks examples, and this is my matlab file:
syms u1(t) u2(t) u3(t) u4(t)
syms U(t) T(t) R(t) V1(t) V2(t)
syms lambda_u lambda_t lambda_r lambda_v1 lambda_v2
%all the parameters provided by the paper
delta = 500;
alpha1 = 0.004;
alpha2 = 0.005;
alpha3 = 0.006;
gamma1 = 0.001;
gamma2 = 0.002;
phi1 = 0.22;
phi2 = 0.20;
delta1 = 0.09;
delta2 = 0.05;
k1 = 0.000003;
k2 = 0.000002;
k3 = 0.0000045;
%these two variable are set constant
V1 = 200;
V2 = 100;
%weight values for the cost function (only A1 is used in this case, but I left them all since the unused ones are irrelevant)
A1 = 30;
A2 = 20;
A3 = 20;
A4 = 10;
A5 = 40;
%ordering the unknowns in an array
x = [U T R u1 u2 u3 u4];
%initial conditions, ordered as the x vector (for the ui are guesses)
y0 = [100000 2000 1000 0 0 0 0];
%system set up
f = #(t,x) [delta - (1 + x(4))*k1*x(1)*V1 - (1 + x(5))*k2*x(1)*V2 - alpha1*x(1) + gamma1*x(2) + gamma2*x(3);...
(1 + x(4))*k1*x(1)*V1 - k3*x(2)*V2 - alpha2*x(2) - gamma1*x(2);...
(1 + x(5))*k2*x(1)*V2 - alpha3*x(3) - gamma2*x(3) + k3*x(2)*V2;...
alpha2*x(2) + gamma1*x(2) + (1 + x(6))*phi1*x(1) + k3*x(2)*V2 - delta1*V1;...
alpha3*x(3) + gamma2*x(3) + (1 + x(7))*phi2*x(1) - delta2*V2;...
-A1 + (1 + x(4))*k1*V1*(lambda_u - lambda_t) + (1 + x(5))*k2*V2*(lambda_u - lambda_r) + lambda_u*alpha1 - lambda_v1*(1 + x(6))*phi1 - lambda_v2*(1 + x(7))*phi2;...
-lambda_u*gamma1 + (alpha2 + gamma1)*(lambda_t - lambda_v1) + k3*V2*(lambda_t - lambda_r - lambda_v1);...
-lambda_u*gamma2 + (alpha3 + gamma2)*(lambda_r - lambda_v2);...
(1 + x(4))*k1*x(1)*(lambda_u - lambda_t) + lambda_v1*delta1;...
(1 + x(5))*k2*x(1)*(lambda_u -lambda_r) + k3*x(2)*(lambda_t - lambda_r - lambda_v1) + lambda_v2*delta2];
%using ode45 to solve over the chosen time interval
[t,xa] = ode45(f,[0 10],y0);
With this code, I get the following error:
Error using odearguments (line 95)
#(T,X)[DELTA-(1+X(4))*K1*X(1)*V1-(1+X(5))*K2*X(1)*V2-ALPHA1*X(1)+GAMMA1*X(2)+GAMMA2*X(3);(1+X(4))*K1*X(1)*V1-K3*X(2)*V2-ALPHA2*X(2)-GAMMA1*X(2);(1+X(5))*K2*X(1)*V2-ALPHA3*X(3)-GAMMA2*X(3)+K3*X(2)*V2;ALPHA2*X(2)+GAMMA1*X(2)+(1+X(6))*PHI1*X(1)+K3*X(2)*V2-DELTA1*V1;ALPHA3*X(3)+GAMMA2*X(3)+(1+X(7))*PHI2*X(1)-DELTA2*V2;-A1+(1+X(4))*K1*V1*(LAMBDA_U-LAMBDA_T)+(1+X(5))*K2*V2*(LAMBDA_U-LAMBDA_R)+LAMBDA_U*ALPHA1-LAMBDA_V1*(1+X(6))*PHI1-LAMBDA_V2*(1+X(7))*PHI2;-LAMBDA_U*GAMMA1+(ALPHA2+GAMMA1)*(LAMBDA_T-LAMBDA_V1)+K3*V2*(LAMBDA_T-LAMBDA_R-LAMBDA_V1);-LAMBDA_U*GAMMA2+(ALPHA3+GAMMA2)*(LAMBDA_R-LAMBDA_V2);(1+X(4))*K1*X(1)*(LAMBDA_U-LAMBDA_T)+LAMBDA_V1*DELTA1;(1+X(5))*K2*X(1)*(LAMBDA_U-LAMBDA_R)+K3*X(2)*(LAMBDA_T-LAMBDA_R-LAMBDA_V1)+LAMBDA_V2*DELTA2]
returns a vector of length 10, but the length of initial conditions vector is 7. The vector returned by
#(T,X)[DELTA-(1+X(4))*K1*X(1)*V1-(1+X(5))*K2*X(1)*V2-ALPHA1*X(1)+GAMMA1*X(2)+GAMMA2*X(3);(1+X(4))*K1*X(1)*V1-K3*X(2)*V2-ALPHA2*X(2)-GAMMA1*X(2);(1+X(5))*K2*X(1)*V2-ALPHA3*X(3)-GAMMA2*X(3)+K3*X(2)*V2;ALPHA2*X(2)+GAMMA1*X(2)+(1+X(6))*PHI1*X(1)+K3*X(2)*V2-DELTA1*V1;ALPHA3*X(3)+GAMMA2*X(3)+(1+X(7))*PHI2*X(1)-DELTA2*V2;-A1+(1+X(4))*K1*V1*(LAMBDA_U-LAMBDA_T)+(1+X(5))*K2*V2*(LAMBDA_U-LAMBDA_R)+LAMBDA_U*ALPHA1-LAMBDA_V1*(1+X(6))*PHI1-LAMBDA_V2*(1+X(7))*PHI2;-LAMBDA_U*GAMMA1+(ALPHA2+GAMMA1)*(LAMBDA_T-LAMBDA_V1)+K3*V2*(LAMBDA_T-LAMBDA_R-LAMBDA_V1);-LAMBDA_U*GAMMA2+(ALPHA3+GAMMA2)*(LAMBDA_R-LAMBDA_V2);(1+X(4))*K1*X(1)*(LAMBDA_U-LAMBDA_T)+LAMBDA_V1*DELTA1;(1+X(5))*K2*X(1)*(LAMBDA_U-LAMBDA_R)+K3*X(2)*(LAMBDA_T-LAMBDA_R-LAMBDA_V1)+LAMBDA_V2*DELTA2]
and the initial conditions vector must have the same number of elements.
Error in ode45 (line 115)
odearguments(FcnHandlesUsed, solver_name, ode, tspan, y0, options, varargin);
Error in test (line 62)
[t,xa] = ode45(f,[0 10],y0);
For which I can't find a solution, since I have used all the initial values given in the paper. The only values that I have left are the final values for the lambda coefficients, since they are final values, and I am not sure if they can be used.
In this case, I can't also understand where I should put the bounds on the control variable.
For completeness, I will provide also the link to the paper in question:
https://www.ripublication.com/ijss17/ijssv12n3_13.pdf
Can you help me figure out what I can do to solve my problems?
P.S: I know this is a pretty bad code, but I'm basing on the basics tutorials on mathworks; for sure this should need to be refactored and ordered in various file (one for the cost function and one for the constraints for example) but firstly I would like to understand where the problem is and then I will put all in a pretty form.
Thank you so much!
Generally you confused something with Vectors. In initial conditions you declared 7 values:
%initial conditions, ordered as the x vector (for the ui are guesses)
y0 = [100000 2000 1000 0 0 0 0];
But you declared 10 ODE's:
%system set up
f = #(t,x) [delta - (1 + x(4))*k1*x(1)*V1 - (1 + x(5))*k2*x(1)*V2 - alpha1*x(1) + gamma1*x(2) + gamma2*x(3);...
(1 + x(4))*k1*x(1)*V1 - k3*x(2)*V2 - alpha2*x(2) - gamma1*x(2);...
(1 + x(5))*k2*x(1)*V2 - alpha3*x(3) - gamma2*x(3) + k3*x(2)*V2;...
alpha2*x(2) + gamma1*x(2) + (1 + x(6))*phi1*x(1) + k3*x(2)*V2 - delta1*V1;...
alpha3*x(3) + gamma2*x(3) + (1 + x(7))*phi2*x(1) - delta2*V2;...
-A1 + (1 + x(4))*k1*V1*(lambda_u - lambda_t) + (1 + x(5))*k2*V2*(lambda_u - lambda_r) + lambda_u*alpha1 - lambda_v1*(1 + x(6))*phi1 - lambda_v2*(1 + x(7))*phi2;...
-lambda_u*gamma1 + (alpha2 + gamma1)*(lambda_t - lambda_v1) + k3*V2*(lambda_t - lambda_r - lambda_v1);...
-lambda_u*gamma2 + (alpha3 + gamma2)*(lambda_r - lambda_v2);...
(1 + x(4))*k1*x(1)*(lambda_u - lambda_t) + lambda_v1*delta1;...
(1 + x(5))*k2*x(1)*(lambda_u -lambda_r) + k3*x(2)*(lambda_t - lambda_r - lambda_v1) + lambda_v2*delta2];
Every line in above code is recognized as one ODE.
But that's not all. The second problem is with your construction. You mixed symbolic math (lambda declared as syms) with numerical solving, which will be tricky. I'm not familiar with the exact scientific problem you are trying to solve, but if you can't avoid symbolic math, maybe you should try dsolve from Symbolic Math Toolbox?

How can I get MATLAB to numerically solve a particularly nasty system of equations?

I have four parameters, t1,t2, theta1, and theta2. I want to find a solution (there can potentially be infinitely many) to the following system of equations:
t1*cos(theta1) + t2*cos(theta2) + 2*t1*t2*sin(theta1 + theta2) = t1*sin(theta1) + t2*sin(theta2) + 2*t1*t2*cos(theta1 + theta2) + 1
t1*cos(theta1) + t2*cos(theta2) + t1*sin(theta1) + t2*sin(theta2) = 2*t1*t2*sin(theta1 + theta2) + 2*t1*t2*cos(theta1 + theta2) + 1
2*t1^2*t2^2 + sin(theta1)*t1*t2^2 + sin(theta1 + theta2)*t1*t2 + 1 = sin(theta2)*t1^2*t2 + t1^2 + sin(theta1)*t1 + t2^2
Since there are more parameters than equations, we have to impose further restrictions to identify a specific solution to this system. Right now I don't really care which solution is picked, as long as it isn't trivial (like all the variables equaling zero).
My current method is to set the third equation to 0.5, solving for t1 and t2 in terms of theta1 and theta2, and substituting these expressions into the first two equations to solve for theta1 and theta2. However, MATLAB is trying to do this symbolically, which is extremely time-consuming. Is there a way I can get some approximate solutions to this system? I can't exactly plot the surfaces represented by these equations and look at their intersection, because each side of the equations involves more than two parameters, which means it can't be visualized in three dimensions.
You can use fsolve to do this.
First, you need to create anonymous functions for the residuals of the three equations. I'm going to create a vector x where x = [t1; t2; theta1; theta2]. That makes the residuals:
r1 = #(x) x(1)*cos(x(3)) + x(2)*cos(x(4)) + 2*x(1)*x(2)*sin(x(3) + x(4)) - (x(1)*sin(x(3)) + x(2)*sin(x(4)) + 2*x(1)*x(2)*cos(x(3) + x(4)) + 1);
r2 = #(x) x(1)*cos(x(3)) + x(2)*cos(x(4)) + x(1)*sin(x(3)) + x(2)*sin(x(4)) - (2*x(1)*x(2)*sin(x(3) + x(4)) + 2*x(1)*x(2)*cos(x(3) + x(4)) + 1);
r3 = #(x) 2*x(1)^2*x(2)^2 + sin(x(3))*x(1)*x(2)^2 + sin(x(3) + x(4))*x(1)*x(2) + 1 - (sin(x(4))*x(1)^2*x(2) + x(1)^2 + sin(x(3))*x(1) + x(2)^2);
Then, we need to make a single function that is a vector of those three residuals, since fsolve tries to get this vector to be zero:
r = #(x) [r1(x); r2(x); r3(x)]
Now, we call fsolve. I picked an arbitrary starting point:
>> [x, fval, exitflag] = fsolve(r, [0.5,0.5,pi/4,pi/4])
Warning: Trust-region-dogleg algorithm of FSOLVE cannot handle non-square systems; using Levenberg-Marquardt algorithm instead.
> In fsolve at 287
Equation solved.
fsolve completed because the vector of function values is near zero
as measured by the default value of the function tolerance, and
the problem appears regular as measured by the gradient.
<stopping criteria details>
x =
0.9654 0.5182 0.7363 0.7344
fval =
1.0e-10 *
-0.0090
0.2743
-0.0181
exitflag =
1
You can ignore the warning. x is the four values you were looking for. fval is the value of the residuals. exitFlag == 1 means we found a root.

How do I differentiate and evaluate in Matlab?

I need to differentiate exp((s^2*sigma^2)/2 + mu*s) and evaluate it to s=0.
Anyone can provide advice on the syntax or how I should go about performing this differentiation?
If it helps, the above function is the mgf of a standard normal.
I want to differentiate and evaluate s=0 so I can get the mean,variance,skew and kurtosis.
Thanks!
Try this :
>> syms s sigma mu
>> f=diff(exp((s^2*sigma^2)/2 + mu*s),s)
f =
exp((s^2*sigma^2)/2 + mu*s)*(s*sigma^2 + mu)
>> subs(f, 's', 0)
ans =
mu
>> subs(f, 's', 1)
ans =
exp(sigma^2/2 + mu)*(sigma^2 + mu)
Ref - diff, subs