ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Fri, 22 Oct 2021 17:17:26 +0200solve() fails for 3 simple linear equationshttps://ask.sagemath.org/question/59355/solve-fails-for-3-simple-linear-equations/I am doing basic circuit analysis, which involves solving multiple algebraic equations. solve() fails for a simple linear circuit (image does not work -- see circuit description below).
> Vi, Vo, Vm, Vx, R1, R2, R3, C, A, s = var('Vi,Vo,Vm,Vx,R1,R2,R3,C,A,s')
> # Three Kirchoff equations at nodes Vm, Vx, Vo
> eq_at_Vm = (Vi-Vm)/R1 + (Vx-Vm)/R2 == 0
> eq_at_Vx = (Vm-Vx)/R2 + (Vo-Vx)/R3 + (0-Vx)/(1/(C*s)) == 0
> eq_at_Vo = Vo == -A*Vm
> # solving for Vo FAILS
> solve([eq_at_Vm,eq_at_Vx,eq_at_Vo],Vo)
The output is just [].
Am I doing something wrong, or is this a limitation of solve()?
I did find a workaround, solving each equation individually, which in this case is easy, but in general is not:
> Vi, Vo, Vm, Vx, R1, R2, R3, C, A, s = var('Vi,Vo,Vm,Vx,R1,R2,R3,C,A,s')
> # Three Kirchoff equations at nodes Vm, Vx, Vo
> eq_at_Vm = (Vi-Vm)/R1 + (Vx-Vm)/R2 == 0
> eq_at_Vx = (Vm-Vx)/R2 + (Vo-Vx)/R3 + (0-Vx)/(1/(C*s)) == 0
> eq_at_Vo = Vo == -A*Vm
> # eliminate Vm
> Vm_eq = solve(eq_at_Vo,Vm)[0]
> eq_at_Vm = eq_at_Vm.substitute(Vm_eq)
> eq_at_Vx = eq_at_Vx.substitute(Vm_eq)
> # eliminate Vx
> Vx_eq = solve(eq_at_Vm,Vx)[0]
> eq_at_Vx = eq_at_Vx.substitute(Vx_eq)
> # final transfer function
> print((solve(eq_at_Vx,Vo)[0]/Vi).simplify_full())
The output is: `Vo/Vi == -(A*C*R2*R3*s + A*R2 + A*R3)/((C*R1 + C*R2)*R3*s + (A + 1)*R1 + R2 + R3)`
**Circuit Description:**
This is an inverting OpAmp with a R2-C-R3 Tee network as feedback. The OpAmp has gain=A with in+ grounded, so Vo=-A*in-. Nodes are labeled Vi, Vm, Vx, Vo: Vi is the input, Vo is the OpAmp output, Vm is the OpAmp in-, and Vx is inside the Tee. R1 is Vi to Vm, R2 is Vm to Vx, R3 is Vx to Vo, and C is Vx to ground.Thu, 14 Oct 2021 20:18:17 +0200https://ask.sagemath.org/question/59355/solve-fails-for-3-simple-linear-equations/Comment by tjrob for <p>I am doing basic circuit analysis, which involves solving multiple algebraic equations. solve() fails for a simple linear circuit (image does not work -- see circuit description below).</p>
<blockquote>
<pre><code>Vi, Vo, Vm, Vx, R1, R2, R3, C, A, s = var('Vi,Vo,Vm,Vx,R1,R2,R3,C,A,s')
# Three Kirchoff equations at nodes Vm, Vx, Vo
eq_at_Vm = (Vi-Vm)/R1 + (Vx-Vm)/R2 == 0
eq_at_Vx = (Vm-Vx)/R2 + (Vo-Vx)/R3 + (0-Vx)/(1/(C*s)) == 0
eq_at_Vo = Vo == -A*Vm
# solving for Vo FAILS
solve([eq_at_Vm,eq_at_Vx,eq_at_Vo],Vo)
</code></pre>
<p>The output is just [].</p>
</blockquote>
<p>Am I doing something wrong, or is this a limitation of solve()?</p>
<p>I did find a workaround, solving each equation individually, which in this case is easy, but in general is not:</p>
<blockquote>
<pre><code>Vi, Vo, Vm, Vx, R1, R2, R3, C, A, s = var('Vi,Vo,Vm,Vx,R1,R2,R3,C,A,s')
# Three Kirchoff equations at nodes Vm, Vx, Vo
eq_at_Vm = (Vi-Vm)/R1 + (Vx-Vm)/R2 == 0
eq_at_Vx = (Vm-Vx)/R2 + (Vo-Vx)/R3 + (0-Vx)/(1/(C*s)) == 0
eq_at_Vo = Vo == -A*Vm
# eliminate Vm
Vm_eq = solve(eq_at_Vo,Vm)[0]
eq_at_Vm = eq_at_Vm.substitute(Vm_eq)
eq_at_Vx = eq_at_Vx.substitute(Vm_eq)
# eliminate Vx
Vx_eq = solve(eq_at_Vm,Vx)[0]
eq_at_Vx = eq_at_Vx.substitute(Vx_eq)
# final transfer function
print((solve(eq_at_Vx,Vo)[0]/Vi).simplify_full())
</code></pre>
<p>The output is: <code>Vo/Vi == -(A*C*R2*R3*s + A*R2 + A*R3)/((C*R1 + C*R2)*R3*s + (A + 1)*R1 + R2 + R3)</code></p>
</blockquote>
<p><strong>Circuit Description:</strong>
This is an inverting OpAmp with a R2-C-R3 Tee network as feedback. The OpAmp has gain=A with in+ grounded, so Vo=-A*in-. Nodes are labeled Vi, Vm, Vx, Vo: Vi is the input, Vo is the OpAmp output, Vm is the OpAmp in-, and Vx is inside the Tee. R1 is Vi to Vm, R2 is Vm to Vx, R3 is Vx to Vo, and C is Vx to ground.</p>
https://ask.sagemath.org/question/59355/solve-fails-for-3-simple-linear-equations/?comment=59356#post-id-59356Note that many asterisks got omitted in the output Vo/Vi, even after editing to indicate it is preformatted.Thu, 14 Oct 2021 20:22:50 +0200https://ask.sagemath.org/question/59355/solve-fails-for-3-simple-linear-equations/?comment=59356#post-id-59356Answer by tmonteil for <p>I am doing basic circuit analysis, which involves solving multiple algebraic equations. solve() fails for a simple linear circuit (image does not work -- see circuit description below).</p>
<blockquote>
<pre><code>Vi, Vo, Vm, Vx, R1, R2, R3, C, A, s = var('Vi,Vo,Vm,Vx,R1,R2,R3,C,A,s')
# Three Kirchoff equations at nodes Vm, Vx, Vo
eq_at_Vm = (Vi-Vm)/R1 + (Vx-Vm)/R2 == 0
eq_at_Vx = (Vm-Vx)/R2 + (Vo-Vx)/R3 + (0-Vx)/(1/(C*s)) == 0
eq_at_Vo = Vo == -A*Vm
# solving for Vo FAILS
solve([eq_at_Vm,eq_at_Vx,eq_at_Vo],Vo)
</code></pre>
<p>The output is just [].</p>
</blockquote>
<p>Am I doing something wrong, or is this a limitation of solve()?</p>
<p>I did find a workaround, solving each equation individually, which in this case is easy, but in general is not:</p>
<blockquote>
<pre><code>Vi, Vo, Vm, Vx, R1, R2, R3, C, A, s = var('Vi,Vo,Vm,Vx,R1,R2,R3,C,A,s')
# Three Kirchoff equations at nodes Vm, Vx, Vo
eq_at_Vm = (Vi-Vm)/R1 + (Vx-Vm)/R2 == 0
eq_at_Vx = (Vm-Vx)/R2 + (Vo-Vx)/R3 + (0-Vx)/(1/(C*s)) == 0
eq_at_Vo = Vo == -A*Vm
# eliminate Vm
Vm_eq = solve(eq_at_Vo,Vm)[0]
eq_at_Vm = eq_at_Vm.substitute(Vm_eq)
eq_at_Vx = eq_at_Vx.substitute(Vm_eq)
# eliminate Vx
Vx_eq = solve(eq_at_Vm,Vx)[0]
eq_at_Vx = eq_at_Vx.substitute(Vx_eq)
# final transfer function
print((solve(eq_at_Vx,Vo)[0]/Vi).simplify_full())
</code></pre>
<p>The output is: <code>Vo/Vi == -(A*C*R2*R3*s + A*R2 + A*R3)/((C*R1 + C*R2)*R3*s + (A + 1)*R1 + R2 + R3)</code></p>
</blockquote>
<p><strong>Circuit Description:</strong>
This is an inverting OpAmp with a R2-C-R3 Tee network as feedback. The OpAmp has gain=A with in+ grounded, so Vo=-A*in-. Nodes are labeled Vi, Vm, Vx, Vo: Vi is the input, Vo is the OpAmp output, Vm is the OpAmp in-, and Vx is inside the Tee. R1 is Vi to Vm, R2 is Vm to Vx, R3 is Vx to Vo, and C is Vx to ground.</p>
https://ask.sagemath.org/question/59355/solve-fails-for-3-simple-linear-equations/?answer=59373#post-id-59373By solving against `Vo` only, you do as if every other symbols involved in the equations were constants. However, `Vi, Vm, Vx` are also unknown.
Imagine that the solver would return `[Vo == -A*Vm]` as a solution, i bet you will not be very happy.
So, what you have to do is to put all unknowns, and let only the constants outside:
sage: solve([eq_at_Vm, eq_at_Vx, eq_at_Vo],[Vo, Vi, Vm, Vx])
[[Vo == (A*R3*r1 + (A*C*R3*r1*s + A*r1)*R2)/(A*R2 - R3), Vi == -((C*R3*r1*s + A*r1 + r1)*R1 + (C*R3*r1*s + r1)*R2 + R3*r1)/(A*R2 - R3), Vm == -((C*R3*r1*s + r1)*R2 + R3*r1)/(A*R2 - R3), Vx == r1]]
Now, as you can see, there is one degree of freedom : `Vx` can take any value, so Sage added a free parameter `r1` and gave you all the solutions using the constants and this free parameter `r1`.
Now, i see in your workaround that you want to solve for `Vo/Vi`, so let me assume that you want `Vi` being the free parameter, not `Vx`.
Hence, you can solve as if `Vi` is also a constant:
sage: solve([eq_at_Vm, eq_at_Vx, eq_at_Vo],[Vo, Vm, Vx])
[[Vo == -((A*C*R3*s + A)*R2 + A*R3)*Vi/((C*R3*s + A + 1)*R1 + (C*R3*s + 1)*R2 + R3), Vm == ((C*R3*s + 1)*R2 + R3)*Vi/((C*R3*s + A + 1)*R1 + (C*R3*s + 1)*R2 + R3), Vx == -(A*R2 - R3)*Vi/((C*R3*s + A + 1)*R1 + (C*R3*s + 1)*R2 + R3)]]Fri, 15 Oct 2021 21:48:46 +0200https://ask.sagemath.org/question/59355/solve-fails-for-3-simple-linear-equations/?answer=59373#post-id-59373Comment by tjrob for <p>By solving against <code>Vo</code> only, you do as if every other symbols involved in the equations were constants. However, <code>Vi, Vm, Vx</code> are also unknown.</p>
<p>Imagine that the solver would return <code>[Vo == -A*Vm]</code> as a solution, i bet you will not be very happy.</p>
<p>So, what you have to do is to put all unknowns, and let only the constants outside:</p>
<pre><code>sage: solve([eq_at_Vm, eq_at_Vx, eq_at_Vo],[Vo, Vi, Vm, Vx])
[[Vo == (A*R3*r1 + (A*C*R3*r1*s + A*r1)*R2)/(A*R2 - R3), Vi == -((C*R3*r1*s + A*r1 + r1)*R1 + (C*R3*r1*s + r1)*R2 + R3*r1)/(A*R2 - R3), Vm == -((C*R3*r1*s + r1)*R2 + R3*r1)/(A*R2 - R3), Vx == r1]]
</code></pre>
<p>Now, as you can see, there is one degree of freedom : <code>Vx</code> can take any value, so Sage added a free parameter <code>r1</code> and gave you all the solutions using the constants and this free parameter <code>r1</code>.</p>
<p>Now, i see in your workaround that you want to solve for <code>Vo/Vi</code>, so let me assume that you want <code>Vi</code> being the free parameter, not <code>Vx</code>.</p>
<p>Hence, you can solve as if <code>Vi</code> is also a constant:</p>
<pre><code>sage: solve([eq_at_Vm, eq_at_Vx, eq_at_Vo],[Vo, Vm, Vx])
[[Vo == -((A*C*R3*s + A)*R2 + A*R3)*Vi/((C*R3*s + A + 1)*R1 + (C*R3*s + 1)*R2 + R3), Vm == ((C*R3*s + 1)*R2 + R3)*Vi/((C*R3*s + A + 1)*R1 + (C*R3*s + 1)*R2 + R3), Vx == -(A*R2 - R3)*Vi/((C*R3*s + A + 1)*R1 + (C*R3*s + 1)*R2 + R3)]]
</code></pre>
https://ask.sagemath.org/question/59355/solve-fails-for-3-simple-linear-equations/?comment=59448#post-id-59448Thanks. This makes sense.Fri, 22 Oct 2021 17:17:26 +0200https://ask.sagemath.org/question/59355/solve-fails-for-3-simple-linear-equations/?comment=59448#post-id-59448