What I Have to do :
Perform the linearization in the vicinity of the operating point. Determine the linearized transfer
This is my non-linear operating point model ('op') with step :
This is my non-linear operating point model ('linmod'), where I have replaced step -> In and to workspace -> Out
Parameter Kn = 948;
For transfer function I did:
[num,den] = linmod('test');
G = tf(num,den);
0.3333 s^2 + 83.33 s + 23.33
--------------------------------------
s^4 + 333.3 s^3 + 2.09e04 s^2 + 5833 s
If I change the value of Kn, and re-run simulation + linmod, I get the exact same transfer function.
Also, I do not quite understand in the mathlab help what is
[A,B,C,D] = linmod['linmod',x,u]
I know that matrixes A,B,C,D are used in
x' = Ax + Bu and
y = Cx + Du
But I do not know what to do from here.
Also a question :
Do I need to use linear or non-linear model for linmod ?
Related
You are given a transfer function G(s)=1.81K(s+20)/(0.03338(s^3+10s^2+32s+32)). This system is connected with unity negative feedback . Determine the smallest positive value of K which makes the closed-loop system unstable. Give the answer to 3 d.p.
Correct Answer:
0.531 ± 0.02
This question is set by my lecturer and I have no idea how to do it.
The closed loop system will become unstable as soon as the rlocus function is no longer in the LHP. Either of the two lines when they intersect with 0 on the x-axis. Assume K=1 at first as we are multiplying by the gain.
>> G=tf([1.81 36.2],[0.03338 0.3338 1.0682 1.0682])
G =
1.81 s + 36.2
------------------------------------------
0.03338 s^3 + 0.3338 s^2 + 1.068 s + 1.068
Continuous-time transfer function.
>> rlocus(G)
you should see that when the real axis is 0 the gain is at 0.531.
if we want greater accuracy we can simply use the rlocfind(G,(point that it is 0)
A smart friend of mine showed me that "Routh Array" is the key for this equation.
Expand the polynomial as you have it, therefore you will have this:
VARS TERM VALUE
A s^3 0.03338
B s^2 0.3338
C s 1.06816 + 1.81Κ
D 1.06816 + 36.2Κ
Equate them as A*D=B*C and you will have the term "s^3" on both sides and then you can cancel it out and solve for K.
(0.03338)(1.06816 + 36.2K) s^3 = (0.3338)(1.06816 + 1.81K) s^3
0.0357 + 1.2084K = 0.3566 + 0.6042K
(1.2084 - 0.6042) K = 0.3566-0.0357
K = 0.5311155247
Otherwise use the rlocus function in MATLAB.
i am trying to solve these 2 equations with 2 unknowns.
i want to find the angle of a1(alpha1), a2(alpha2) in radians.
however when i solve it in maple i get 0.112 for a2 and 0.089 for a1.
but some other guys used matlab and they get something different with plot and 2 angles..
can someone tell me if i am right or he is?
MY equations:
equation 1: 4/(2*pi)*(cos(2*a1)+cos(2*a2))=0
equation 2: 4/(10*pi)*(cos(10*a1)+cos(10*a2))=0
his matlab:
j=0;
for i=0:pi/100:1
j=j+1;
a2(j)=i;
a1_1(j)=acos(-cos(2*i))/2;
a1_2(j)=acos(-cos(10*i))/10;
end
plot(a2,a1_1,'-k',a2,a1_2,'-b','LineWidth',1.4);
I wanna plot like him..but i am not sure his Equations a1_1 is correct?
by the way the main equation it came from:
bn = 4/(npi)(cos(na1)+cos(na2))=0
bn = 0 and n is 2th and 10th harmonics to be eliminated
cos(A)+cos(B) = 0
happens for
A + B = pi + 2*k*pi or A - B = pi + 2*k*pi
Both of the two original equations could resolve the the same of the two variants or to different variants. Resolving to the same equation, say the first, will produce
7*(a1+a2) = pi + 2*k7*pi and 13*(a1+a2) = pi + 2*k13*pi
which can only hold if
0 = 6*pi + 2*(13*k7-7*k13) <=> 3 = 7*k13-13*k7
which implies a1+a2 = pi + 2*m*pi. .
In the case of different to different variant, one obtains (modula sign variations of a1, a2)
7*(a1+a2) = pi + 2*k7*pi and 13*(a1-a2) = pi + 2*k13*pi
and thus
a1 = (pi/7+pi/13)/2 + k7*pi/7 + k13*pi/13
a2 = (pi/7-pi/13)/2 + k7*pi/7 - k13*pi/13
and all possible sign variations, since cosine is an even function. However, simultaneous sign variations are also covered by variations of k7 and k13. Thus you obtain additionally (up to) 2*7*13=182 solutions to your problem.
I have this code in matlab
syms L1 L0 P1 P0 s
L = expand(s*(s^2+L1*s+L0)*(s-75)+1400*(P1*s+P0))
R = expand((s+75)*(s+150)^3)
I want to solve for P1, P0, L1 and L0
L = R
1400*P0 - 75*L0*s + 1400*P1*s + L0*s^2 - 75*L1*s^2 + L1*s^3 - 75*s^3 + s^4 = s^4 + 525*s^3 + 101250*s^2 + 8437500*s + 253125000
by observation:
1400*P0 = 253125000
ETC...
How do i pull simultaneous equations from L=R in Matlab and automatically solve for each variable?
Thanks
You could write the equation as L-R=0, then do something like C=coeffs(L-R,s). Then, something like the following code might solve the equations:
for i=1:length(C)
sol(i)=solve(C(i));
end
but it may be difficult to work out which element of sol refers to which variable. But if you are going to look at the output as the code runs it should be pretty obvious I'd imagine.
I want to determine the linearized transfer function from a non-linear system made in Simulink. I can see that it should be possible to use the linmod function in Matlab but when I try this
[num,den]=linmod('sys')
I'm not getting the numerator and denominator but instead the state space matrix etc. Can anyone help?
Try the function balred instead: documentation
rsys = balred(sys,ORDERS) computes a reduced-order approximation rsys
of the LTI model sys. The desired order (number of states) for rsys is
specified by ORDERS. You can try multiple orders at once by setting
ORDERS to a vector of integers, in which case rsys is a vector of
reduced-order models. balred uses implicit balancing techniques to
compute the reduced- order approximation rsys.
example:
Q = tf([1 2 3 4 5],[5 4 3 2 1])
Q =
s^4 + 2 s^3 + 3 s^2 + 4 s + 5
-------------------------------
5 s^4 + 4 s^3 + 3 s^2 + 2 s + 1
Q_lin = balred(Q,2)
Q_lin =
3.276 s^2 - 2.06 s + 2.394
--------------------------
s^2 - 0.2757 s + 0.4789
balred(Q,1)
is not working for my example, as there are 2 unstable poles, but it may works for your system.
linmod always returns a state-space representation (see documentation). Use tf to convert your stae-space representation to a transfer function:
Conversion to Transfer Function
tfsys = tf(sys) converts the dynamic
system model sys to transfer function form. The output tfsys is a tf
model object representing sys expressed as a transfer function.
BTW, if you have Simulink Control Design, a better alternative to linmod is linearize.
I am currently trying to implement a machine learning algorithm that involves the logistic loss function in MATLAB. Unfortunately, I am having some trouble due to numerical overflow.
In general, for a given an input s, the value of the logistic function is:
log(1 + exp(s))
and the slope of the logistic loss function is:
exp(s)./(1 + exp(s)) = 1./(1 + exp(-s))
In my algorithm, the value of s = X*beta. Here X is a matrix with N data points and P features per data point (i.e. size(X)=[N,P]) and beta is a vector of P coefficients for each feature such that size(beta)=[P 1].
I am specifically interested in calculating the average value and gradient of the Logistic function for given value of beta.
The average value of the Logistic function w.r.t to a value of beta is:
L = 1/N * sum(log(1+exp(X*beta)),1)
The average value of the slope of the Logistic function w.r.t. to a value of b is:
dL = 1/N * sum((exp(X*beta)./(1+exp(X*beta))' X, 1)'
Note that size(dL) = [P 1].
My issue is that these expressions keep producing numerical overflows. The problem effectively comes from the fact that exp(s)=Inf when s>1000 and exp(s)=0 when s<-1000.
I am looking for a solution such that s can take on any value in floating point arithmetic. Ideally, I would also really appreciate a solution that allows me to evaluate the value and gradient in a vectorized / efficient way.
How about the following approximations:
– For computing L, if s is large, then exp(s) will be much larger than 1:
1 + exp(s) ≅ exp(s)
and consequently
log(1 + exp(s)) ≅ log(exp(s)) = s.
If s is small, then using the Taylor series of exp()
exp(s) ≅ 1 + s
and using the Taylor series of log()
log(1 + exp(s)) ≅ log(2 + s) ≅ log(2) + s / 2.
– For computing dL, for large s
exp(s) ./ (1 + exp(s)) ≅ 1
and for small s
exp(s) ./ (1 + exp(s)) ≅ 1/2 + s / 4.
– The code to compute L could look for example like this:
s = X*beta;
l = log(1+exp(s));
ind = isinf(l);
l(ind) = s(ind);
ind = (l == 0);
l(ind) = log(2) + s(ind) / 2;
L = 1/N * sum(l,1)
I found a good article about this problem.
Cutting through a lot of words, we can simplify the argument to stating that the original expression
log(1 + exp(s))
can be rewritten as
log(exp(s)*(exp(-s) + 1))
= log(exp(s)) + log(exp(-s) + 1)
= s + log(exp(-s) + 1)
This stops overflow from occurring - it doesn't prevent underflow, but by the time that occurs, you have your answer (namely, s). You can't just use this instead of the original, since it will still give you problems. However, we now have the basis for a function that can be written that will be accurate and won't produce over/underflow:
function LL = logistic(s)
if s<0
LL = log(1 + exp(s));
else
LL = s + logistic(-s);
I think this maintains reasonably good accuracy.
EDIT now to the meat of your question - making this vectorized, and allowing the calculation of the slope as well. Let's take these one at a time:
function LL = logisticVec(s)
LL = zeros(size(s));
LL(s<0) = log(1 + exp(s(s<0)));
LL(s>=0) = s(s>=0) + log(1 + exp(-s(s>=0)));
To obtain the average you wanted:
L = logisticVec(X*beta) / N;
The slope is a little bit trickier; note I believe you may have a typo in your expression (missing a multiplication sign).
dL/dbeta = sum(X * exp(X*beta) ./ (1 + exp(X*beta))) / N;
If we divide top and bottom by exp(X*beta) we get
dL = sum(X ./ (exp(-X*beta) + 1)) / N;
Once again, the overflow has gone away and we are left with underflow - but since the underflowed value has 1 added to it, the error this creates is insignificant.