Home > Back-end >  solving for a ratio while eliminating specific variables in a set of linear equations
solving for a ratio while eliminating specific variables in a set of linear equations

Time:04-04

I am still having a problem, a different one than my previous post.

Basically I have [5x5][5x1]=[0] and would like to have the symbolic expression of the solution.

Here is my code.

from sympy import symbols, solve
gm1, gm2, gm4                   = symbols(['gm1', 'gm2', 'gm4'])
gds1, gds2, gds3, gds4, gds5    = symbols(['gds1', 'gds2', 'gds3', 'gds4', 'gds5'])
s                               = symbols('s')
Cd, CF , Cin, Ct                = symbols(['Cd', 'CF', 'Cin', 'Ct'])
K                               = symbols('K')
vb, vc, ve, vout, iin           = symbols(['vb', 'vc', 've', 'vout', 'iin'])

sol = solve([-(gds1 gds3 (s*Cd))*vb   (gm1 gds1)*ve   -gm1*vout, \
              -gm4*vb   (gds4-gds2-(s*Cin)-(s*CF))*vc   (gds2 gm2)*ve   s*CF*vout   iin, \
            gds1*vb   gds2*vc   (-(s*Ct)-gds5-gds1-gm1-gm2-gds2)*ve   gm1*vout, \
            K*vc   vout, 0], [vout])
print(sol)

I am expecting

vout/iin = f(gm1, gm2, gm4, gds1, gds2, gds3, gds4, gds5, s, Cd, CF , Cin, Ct, K)

In other words, vb, vc, ve are eliminated.

Is there any specific command to do that?

CodePudding user response:

The problem is that you have 4 equations and you've only specified one unknown (vout). The system is generically unsolvable for most values of vb, vc, ve so asking to solve only for vout leads to no solution (in the generic case).

Ask to solve for vout, vb, vc, ve as 4 unknowns for the 4 equations and you can get a solution for all 4:

linsolve(eqs, [vout, vb, vc, ve])

(The output is long so I have omitted it)

I'm using linsolve since the equations are linear although solve will also work.

It's not entirely clear what you want but some variation of the above should do it. You said you wanted vout and vin in terms of the other symbols but with vb, vc and ve eliminated. That would require 5 independent equations but since your 5th equation is just 0 you don't have that.

CodePudding user response:

If you suspect that you should be able to solve for the ratio, go ahead and solve for one of the dividends and the others that you don't want in the solution for it:

>>> sol = solve(eqs, iin, vb, vc, ve, check=False, simplify=False)

You suspect that you should be able to form the ratio of vout/iin which means that the solution for iin should be linear in vout:

>>> sol[iin].diff(vout,2)
0

It is. The constant should also be 0:

>>> sol[iin].subs(vout,0)
0

It is. So iin = vout*sol[iin].diff(vout) or

>>> r = 1/sol[iin].diff(vout)  # vout/iin

This is an expression that is in the form K*{quadratic in s}/{cubic in s}. All other solutions for vb,vc,ve are also directly proportional to vout so they can all be expressed as a ratio vout/vi in a similar fashion.

The problems you are having basically boil down to this: your equations are not written in terms of ratios but you are interested in solving for ratios. In your case, the variables of interest should all be normalized by vout. You can get your system into that form and then it will work, too:

>>> V = iin, vb, vc, ve  # variables you have
>>> r = symbols('r:4')  # variables for the ratios
>>> reps = dict([(v, r[i]*vout) for i,v in enumerate(V)])
>>> req = Tuple(*eqs).xreplace(reps)  # e.g. replace iin with r0*vout
>>> rsol = solve(req, r, check=False, simplify=False, dict=True)[0]
>>> explicit_ratio_solutions = Dict(rsol).xreplace({ri: v/vout for ri,v in zip(r, V)})  # restore keys to be iin/vout, vb/vout, etc...

You can confirm that the solutions are free of vout

>>> vout in Dict(rsol).free_symbol
False

When is this going to work? When the additive term independent of the symbols of interest is itself proportional to the normalizing factor and the normalizing factor does not appear in the terms containing the symbol of interest. I'm going to use simpler symbols for your system so it is easy to see explicitly that this is the case:

>>> neq = Tuple(*eqs)
>>> syms = neq.free_symbols - {iin,vout,vb,vc,ve}
>>> neq = neq.xreplace({o:n for o,n in zip(ordered(syms), var('a:z'))})
>>> x = symbols('x:4')
>>> neq = neq.xreplace({i:j for i,j in zip((iin,vb,vc,ve), x)})
>>> neq = neq.xreplace({vout:y})
>>> for i in neq:
...  t = ind, dep = i.as_independent(*x, as_Add=True)
...  t   (dep.has(y),)
(-k*y, x1*(-b*n - f - h)   x3*(f   k), False)
(a*n*y, -m*x1   x0   x2*(-a*n - c*n - g   i)   x3*(g   l), False)
(k*y, f*x1   g*x2   x3*(-d*n - f - g - j - k - l), False)
(y, e*x2, False)

Notice that y (for vout) appears as a factor in all the xi-independent terms and that it does not appear in the xi-dependent terms. That means you can do a change of variables from xi to xi/y.

  • Related