Boolean Algebra simplification and factoring - boolean

Starting from a circuit I'm able to obtain simplified the boolean expression:
F(A,B,C,D) = A'D' + ABC + BCD'
After observing the k-map I can observe that the expression BCD' (green) is covered by A'D + ABC.
k-map of F(A,B,C,D)
How can I factor out BCD' mathematically?

Use the consensus theorem
XY + X'Z + YZ = XY + X'Z
A'D' + ABC + BCD' = A'D' + ABC
with BCD' being a redundant term

Related

beginconditions should give 0, Lorentz system

I want to plot the Lorentz system (s=10, r=28, b=8/3) for a start condition which should give 0 since it's a start condition in the plane spanned by v1 and v2 and trough the critical point (0,0,0) (equation of the plane : -x + (-9- \sqrt(1201))/56 * y = 0) When I use the Runge-Kutta method to plot the solution with as start conditions ((-9-sqrt(1201))/56,1,10) my graph doesn't converge to 0 and I don't know why.
[X,Y,Z,T] = Runge(T0,(-9-sqrt(1201))/56,1,10,h,1000);
plot(T,X);
plot(T,Y);
plot(T,Z);
I expect a solution in which the lines in the plots go to 0. But I get some random function which goes up and down all the time.
Could this be caused by approximations?
Thanks in advance
This is the function Runge
function [X,Y,Z,T] = Runge(t0,x0,y0,z0,h,n)
X=[x0];
Y=[y0];
Z=[z0];
T=[t0];
k1x = 0;
k1y = 0;
k1z = 0;
k2x=0;
k2y=0;
k2z=0;
k3x=0;
k3y=0;
k3z=0;
k4x=0;
k4y=0;
k4z=0;
for k = 1:n
T(k+1)= T(k) +h;
k1x = F(X(k),Y(k),Z(k));
k1y = G(X(k),Y(k),Z(k));
k1z = H(X(k),Y(k),Z(k));
k2x = F(X(k)+h/2*k1x,Y(k) + h/2*k1y, Z(k) + h/2*k1z);
k2y= G(X(k)+h/2*k1x,Y(k) + h/2*k1y, Z(k) + h/2*k1z);
k2z= H(X(k)+h/2*k1x,Y(k) + h/2*k1y, Z(k) + h/2*k1z);
k3x= F(X(k)+h/2*k2x,Y(k)+h/2*k2y,Z(k) + h/2*k2z);
k3y=G(X(k)+h/2*k2x,Y(k)+h/2*k2y,Z(k) + h/2*k2z);
k3z=H(X(k)+h/2*k2x,Y(k)+h/2*k2y,Z(k) + h/2*k2z);
k4x= F(X(k)+h*k3x,Y(k)+h*k3y,Z(k)+h*k3z);
k4y=G(X(k)+h*k3x,Y(k)+h*k3y,Z(k)+h*k3z);
k4z=H(X(k)+h*k3x,Y(k)+h*k3y,Z(k)+h*k3z);
X(k+1) = X(k) + h/6 * (k1x + 2*k2x + 2*k3x + k4x);
Y(k+1) = Y(k) + h/6 * (k1y + 2*k2y + 2*k3y + k4y);
Z(k+1) = Z(k) + h/6 * (k1z + 2*k2z + 2*k3z + k4z);
end
end
There is no such plane for the non-linear system
Why do you think this plane is invariant?
In the system
F=#(x,y,z) sigma*(y-x);
G=#(x,y,z) x*(rho-z)-y;
H=#(x,y,z) x*y-beta*z;
no non-trivial linear combination of the first two equations is independent of z, which would be required to get an invariant expression in only x and y.
The invariant sub-spaces of the linearization are close to the stable and unstable manifolds, but they are not identical to them. So if you are on some invariant subspace of the linearization, you are in fact some distance away from any curved sub-manifolds related to the non-linear system, and numerical as well as exact solutions will move towards the chaotic attractor.
The Lorentz system is chaotic
Apart from that your observation is correct that floating point errors accumulate to drive the numerical solution away from the exact solution and any properties of it.

Is there a way to prevent MATLAB's simplify()/numden() function from cancelling equal numerator/denominator terms?

I am trying to find the denominator of a given fraction G, but I cannot find a way to use MATLAB's built-in functions without oversimplifying the fraction, and losing important information.
I've tried using MATLAB's built-in commands "numden", "simplify", and "simplifyFraction" but they keep cancelling equal terms from the numerator and denominator. This is normally okay, but for my application, I need to know all values in the denominator which might cause a hole/instability in the function, G.
I've tried looking into the additional constraints within those functions like "IgnoreAnalyticConstraints", but they don't seem to fix the issue. I've simplified my code to isolate my problem below with my current attempts:
syms 's'
G = 2/(s - 1) + 1/(s + 1) - 4/((s - 1)*(s + 1));
[n,d]=numden(G)
G_simp=simplify(G)
G_simpC=simplify(G,'IgnoreAnalyticConstraints',false)
G_simpF=simplifyFraction(G)
Output:
n = 3
d = s + 1
G_simp = 3/(s + 1)
G_simpC = 3/(s + 1)
G_simpF = 3/(s + 1)
Here is an example fraction input:
G = 2/(s - 1) + 1/(s + 1) - 4/((s - 1)*(s + 1))
which simplifies to:
G = 3*(s - 1)/((s - 1)*(s + 1)). <-desired result
I am trying to keep the fraction in this simplified form, but the built-in commands will cancel the (s-1) terms resulting in:
G = 3/(s + 1). <-actual result
You can use the Control System Toolbox:
s= tf([1 0],1);
G = 2/(s - 1) + 1/(s + 1) - 4/((s - 1)*(s + 1))
zpk(G)
The code s= tf([1 0],1); creates a variable s. It contains a Transfer Function object that represents the transfer function f(s)=s. The line
G = 2/(s - 1) + 1/(s + 1) - 4/((s - 1)*(s + 1))
creates a Transfer Function object that contains the corresponding transfer function. And zpk(G) converts this function to the zero/pole/gain form.
The result of the code above is
G =
3 s^3 - 3 s^2 - 3 s + 3
-----------------------
s^4 - 2 s^2 + 1
Continuous-time transfer function.
ans =
3 (s+1) (s-1)^2
---------------
(s+1)^2 (s-1)^2
Continuous-time zero/pole/gain model.

Unstable Closed Loop System

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.

What is the least time-consuming way to solve a system of nonlinear equations?

I am developing an equilibrium model where producers weight benefits and costs to choose the optimal time they work. However, the relevant benefit and cost functions are both rational, which results in a complex first-order derivative of the problem. When parameter values are introduced, I get systems of 3 equations in 3 variables just like the following:
eq1 = (10940*((12034*x)/35 + (1094*y)/5 + (2734*z)/25))/(7*(((12034*x)/35 + (1094*y)/5 + (2734*z)/25)^2 + 640000)) - (10940*((12034*x)/35 + (1094*y)/5 + (2734*z)/25)^3)/(7*(((12034*x)/35 + (1094*y)/5 + (2734*z)/25)^2 + 640000)^2) == x^3/5184
eq2 = (10940*((1094*x)/15 + (51418*y)/105 + (2734*z)/25))/(7*(((1094*x)/15 + (51418*y)/105 + (2734*z)/25)^2 + 640000)) - (10940*((1094*x)/15 + (51418*y)/105 + (2734*z)/25)^3)/(7*(((1094*x)/15 + (51418*y)/105 + (2734*z)/25)^2 + 640000)^2) == y^2/576
eq3 = (5468*((1094*x)/15 + (1094*y)/5 + (30074*z)/75))/(5*(((1094*x)/15 + (1094*y)/5 + (30074*z)/75)^2 + 490000)) - (5468*((1094*x)/15 + (1094*y)/5 + (30074*z)/75)^3)/(5*(((1094*x)/15 + (1094*y)/5 + (30074*z)/75)^2 + 490000)^2) == z^2/576
It has usually taken around 48 hs for MATLAB to find solutions for such systems of equations - when it does find them - using the solve command. Is there a more efficient way to complete this task? (I do have a pretty clear guess at what solutions should look like: all three outcome variables are expected to be within the [0,12] interval.)

Avoiding numerical overflow when calculating the value AND gradient of the Logistic loss function

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.