Finding the roots of a polynomial with symbolic coefficients - matlab

As part of an assignment, I had to derive the equations of motion for a car's suspension system. Essentially it is a spring mass damper problem. The values for the car mass, M1, wheel mass, M2, the spring constant, k1 & k2 and the damping constant, c have not been given. I have derived the equations of motion and derived a transfer function relating the road surface (input) to the resulting car body displacement (output).
I must determine the poles of this transfer function, hence I need to find the roots of the characteristic equation (denominator). The problem is that I do not have any values for the aforementioned variables and I am trying to either factorise my 4th order polynomial in MATLAB symbolically or calculate the roots straight away.
I cannot assume any values, and it must be solved symbolically, however I do not know if this is possible in MATLAB.
I do not have a lot of experience with MATLAB so I am not aware of all its capabilities.
The characteristic equation I am trying to solve is :
(M1*M2)*s^4 + c*(M1+M2)*s^3 + ((M1*k1)+(M1*k2)+c^2+(M2*k2)-c)*s^2 + k1*c*s + ((k1*k2)-(k2^2))
Thank You in advance.

You have some errors in your equation;
c(M1+M2)*s^3 -> c*(M1+M2)*s^3
+ +k1*c*s -> + k1*c*s
But if you want to solve multivariate equations you can do it like this;
syms M1 M2 c k1 k2 s
eqn = (your equation) == 0;
roots = solve(eqn, s);
More information here: solve

Now you only need to follow this steps in case you only want to calculate the roots of the equation , which are similar to the previous comment:
1. syms c s
2. roots=solve((M1*M2)*s^4 + c*(M1+M2)*s^3 + ((M1*k1)+(M1*k2)+c^2+(M2*k2)-c)*s^2 + k1*c*s + ((k1*k2)-(k2^2)),s)
or
roots=solve((M1*M2)*s^4 + c*(M1+M2)*s^3 + ((M1*k1)+(M1*k2)+c^2+(M2*k2)-c)*s^2 + k1*c*s +((k1*k2)-(k2^2)),c)
or
roots=solve((M1*M2)*s^4 + c*(M1+M2)*s^3 + ((M1*k1)+(M1*k2)+c^2+(M2*k2)-c)*s^2 + k1*c*s + ((k1*k2)-(k2^2)),s,c)
depending on the solution you want

Related

Online polynomial curve fitting in Simulink

How to fit curves in Simulink and still generate the code?
I have a model of a sensor in Simulink, that returns vectors Pos_x and Pos_y. Each vector has size of 20x1, and their values change every one step time (1ms).
I am trying to calculate the coeffecients of the 3rd degree Polynomial y(x) = p1*x^3 + p2*x^2 + p3*x + p4 in Simulink, that fits the data.
I did not find any block in simulink that calculates the coeffecients, so I used a simple Matlab function
function [p1, p2, p3, p4] = fcn(x,y)
% f(x) = p1*x^3 + p2*x^2 + p3*x + p4
f = fit(x', y', 'Poly3'); % I have also tried "polyfit"
p1 = f.p1;
p2 = f.p2;
p3 = f.p3;
p4 = f.p4;
end
but I get the error:
Function 'fit' not supported for code generation.
1- so back to my qustion, How to fit curves in Simulink and still generate the code?
2- I am also open to any other suggestion
If possible, you can use directly the LSQCURVEFIT function using Levenberg-Marquardt - method, which is Coder-compatible, with some limitations - see it's documentation that describes the limitations in detail.
Under the hood FIT uses LSQCURVEFIT, but in a non-Coder-compatible way.

Find arc length of implicit function

I want to convert the function
f(x) = x^2 + y^2 -4.5*sin(x*y)-1.
into polar form by x=rcos(t) and y=rsin(t). The code for substituting into polar coordinates is
t=linspace(0,2*pi);
x=r*cos(t)
y=r*sin(t)
My function then becomes
f(t)=(r.*cos(t)).^2 + (r.*sin(t)).^2 - 4.5.*sin((r.*cos(t)).*(r.*sin(t))) - 1
But now im tasked to solve the radius r in terms of the angle t and then using fzero to compute different radiuses for different angles. I can't solve r out of the equation f(t)=0 in terms of elementary equations. How s this done?
First define related syms, then solve using solve function:
syms r t;
solutions = solve((r*cos(t))^2 + (r*sin(t))^2 - 4.5*sin((r*cos(t))*(r*sin(t))) - 1, r);
For this case you do not need dot before operators.
Also, you can simplify it by replacing (r*cos(t))^2 + (r*sin(t))^2 with r^2:
solutions = solve(r^2 - 4.5*sin((r*cos(t))*(r*sin(t)), r);

Exponential curve fitting without the Curve Fitting toolbox?

I have some data points to which I need to fit an exponential curve of the form
y = B * exp(A/x)
(without the help of Curve Fitting Toolbox).
What I have tried so far to linearize the model by applying log, which results in
log(y/B) = A/x
log(y) = A/x + log(B)
I can then write it in the form
Y = AX + B
Now, if I neglect B, then I am able to solve it with
A = pseudoinverse (X) * Y
but I am stuck with values of B...
Fitting a curve of the form
y = b * exp(a / x)
to some data points (xi, yi) in the least-squares sense is difficult. You cannot use linear least-squares for that, because the model parameters (a and b) do not appear in an affine manner in the equation. Unless you're ready to use some nonlinear-least-squares method, an alternative approach is to modify the optimization problem so that the modified problem can be solved using linear least squares (this process is sometimes called "data linearization"). Let's do that.
Under the assumption that b and the yi's be positive, you can apply the natural logarithm to both sides of the equations:
log(y) = log(b) + a / x
or
a / x + log(b) = log(y)
By introducing a new parameter b2, defined as log(b), it becomes evident that parameters a and b2 appear in a linear (affine, really) manner in the new equation:
a / x + b2 = log(y)
Therefore, you can compute the optimal values of those parameters using least squares; all you have left to do is construct the right linear system and then solve it using MATLAB's backslash operator:
A = [1 ./ x, ones(size(x))];
B = log(y);
params_ls = A \ B;
(I'm assuming x and y are column vectors, here.)
Then, the optimal values (in the least-squares sense) for the modified problem are given by:
a_ls = params_ls(1);
b_ls = exp(params_ls(2));
Although those values are not, in general, optimal for the original problem, they are often "good enough" in practice. If needed, you can always use them as initial guesses for some iterative nonlinear-least-squares method.
Doing the log transform then using linear regression should do it. Wikipedia has a nice section on how to do this:
http://en.wikipedia.org/wiki/Linear_least_squares_%28mathematics%29#The_general_problem
%MATLAB code for finding the best fit line using least squares method
x=input('enter a') %input in the form of matrix, rows contain points
a=[1,x(1,1);1,x(2,1);1,x(3,1)] %forming A of Ax=b
b=[x(1,2);x(2,2);x(3,2)] %forming b of Ax=b
yy=inv(transpose(a)*a)*transpose(a)*b %computing projection of matrix A on b, giving x
%plotting the best fit line
xx=linspace(1,10,50);
y=yy(1)+yy(2)*xx;
plot(xx,y)
%plotting the points(data) for which we found the best fit line
hold on
plot(x(2,1),x(2,2),'x')
hold on
plot(x(1,1),x(1,2),'x')
hold on
plot(x(3,1),x(3,2),'x')
hold off
I'm sure the code can be cleaned up, but that's the gist of it.

ODE solver of a system with adaptive law

I have an unknown non-linear system and I want to model it using another system with some adaptable parameters (for instance, a neural network). So, I want to fix an online learning structure of the unknown system without knowing its dynamics, I can only interact with it through inputs-outputs. My problem is that I can not make it work in MATLAB using ode solvers. Lets say that we have this real system (my actual system is more complicated, but I will give a simple example in order to be understood):
function dx = realsystem(t, x)
u = 2;
dx = -3*x+6*u;
end
and we solve the equations like this:
[t,x_real] = ode15s(#(t,x)realsystem(t,x), [0 1], 0)
We suppose that is an unknown system and we do not know the coefficients 3 and 6 so we take an adaptive system with the 2 adaptive laws:
dx(t) = -p1(t)*x(t) + p2(t)*u(t)
dp1(t) = -e(t)*x(t)
dp2(t) = e(t)*u(t)
with e(t) the error e(t) = x(t) - x_real(t).
The thing is that I cannot find a way to feed the real values for each t to the ode solver in order to have online learning.
I tried with something like this but it didn't work:
function dx = adaptivesystem(t, x, x_real)
dx = zeros(3,1);
e = x_real - x;
u = 2;
dx(1) = -x(2)*x(1)+x(3)*u;
dx(2) = -e*x(1); %dx(2) = dp1(t)
dx(3) = e*u; %dx(3) = dp2(t)
end
You should be aware that your problem is ill-posed as it is. Given any trajectory x(t) obtained via sampling and smoothing/interpolating, you can choose p1(t) at will and set
p2(t) = ( x'(t) - p1(t)*x(t) ) / u.
So you have to formulate restrictions. One obvious is that the functions p1 and p2 should be valid for all trajectories of the black-box system. Do you have different trajectories available?
Another variant is to demand that p1 and p2 are constants. Actually, in this case and if you have equally spaced samples available, it would be easier to first find a good difference equation for the data. With the samples x[n] for time t[n]=t0+n*dt form a matrix X with rows
[ -u, x[n], x[n+1], ... ,x[n+k] ] for n=0, ... , N-k
and apply QR decomposition or SVD to X to determine the right hand kernel vectors. QR may fail to show a usable rank deficiency, so use the SVD on the top square part of R = USV^T, S diagonal, ordered as usual, U,V square and orthogonal, and use the last row of V, with coefficients
[b, a[0], ..., a[k] ],
corresponding to the smallest eigenvalue, to form the difference equation
a[0]*x[n]+a[1]*x[n-1]+...+a[k]*x[n-k]=b*u.
If the effective rank of R resp. S is not (k-1), then reduce k to be the effective rank plus one and start again.
If in the end k=1 is found, then you can make a differential equation out of it. Reformulate the difference equation as
a[0]*(x[n]-x[n-1])/dt = -(a[0]+a[1])/dt * x[n-1] + b/dt * u
and read off the differential equation
x'(t) = -(a[0]+a[1])/(a[0]*dt) * x(t) + b/(a[0]*dt) * u
One may reject this equation if the coefficients become uncomfortably large.

MATLAB matrix coefficients how to get them

Hi i have to resolve AX=0 in matlab. The problem is that I don't have the A coefficients I need to extract them from q(x)f(x) - q(x) = 0, a complex expression. In this system the variables are a0 a1 a2 b0 b1 b2, since I going to evaluate the expression for a given set of points x, p(x) = a0 + a1*x + a2*x^2 and q(x) = b0 + b1*x + b2*x^2 and f(x) is some function. So i got a system of 6 variables and the number of equation is the quantity of points. My question is how i extract the coefficients of the A matrix including the 0 for any variable? I have been trying several ways but nothing. Do I have to manually copy the variables coefficients for all the given points (x, f(x))? Please i like the thing well done help me in case there is a solution even if it is big. just guide me.
So, I guess you want to solve q(x)f(x) - p(x) = 0 (where q,p is quadric and f arbitary function, respect to x), not AX=0. Note: AX=0 is linear equation while q(x)f(x) - p(x) = 0 not necessarily. If so, it may be impossible to "extract coefficients" and what you need is nonlinear equation solver, check out: fsolve function.