我独立完成了Mark Newman的“计算物理”一书,练习6.5具体(可以下载here)。问题是要解决由复指数源电压驱动的RC电路中的节点电压。
我想做的是将我的节点方程转换为 Av = B 的形式。这是我到目前为止所做的。
import numpy as np
import sympy
# Define constants
R1=R3=R5 = 1e3
R2=R4=R6 = 2e3
C1 = 1e-6
C2 = 0.5e-6
x_plus = 3
x_minus = 0
w = 1000
# Define relations
V_plus = sympy.symbols('V_plus')
t = sympy.symbols('t')
V_plus = x_plus*sympy.exp(1j*w*t)
V_minus = 0
V1,V2,V3 = sympy.symbols('V1 V2 V3')
V1_eqn = (V1-V_plus)/R1 + (V1-V2)/(1/(1j*w*C1)) + (V1-V_minus)/R4
V2_eqn = (V2-V_plus)/R2 + (V2-V1)/(1/(1j*w*C1)) + (V2-V_minus)/R5 + (V2-V3)/(1/(1j*w*C2))
V3_eqn = (V3-V_plus)/R3 + (V3-V2)/(1/(1j*w*C2)) + (V3-V_minus)/R6
# Prepare
V = [V1,V2,V3]
V_vec = np.matrix(V)
A = np.matrix([
[V1_eqn.expand().coeff(x) for x in V],
[V2_eqn.expand().coeff(x) for x in V],
[V3_eqn.expand().coeff(x) for x in V]
])
print(A)
现在,我遇到的问题是提取三个方程的常数项,这样我就可以将它们加载到 B 中。除其他事项外,其中一个问题是“常数术语”实际上并不是恒定的。它是't'的复指数函数。由于笔和纸是一个相当简单的问题,我确切地知道常数术语的样子,所以我可以提取它。我的目标是以不需要知道答案的方式解决这个问题;)。
我考虑过的一种方法是采用每个等式并减去我已经放入 Av 的所有术语,但这似乎有点草率而且不是非常pythonic。有没有人知道一种更好的方法来提取技术上不恒定的常数项?感谢。
答案 0 :(得分:1)
除了表示法中的一些快捷方式之外,减去您已经放入A
的条款正是您应该而且必须这样做的。
这是一个稍短的版本:
import sympy
# Define constants
R1=R3=R5 = 1e3
R2=R4=R6 = 2e3
C1 = 1e-6
C2 = 0.5e-6
x_plus = 3
x_minus = 0
w = 1000
# Define relations
V_plus = sympy.symbols('V_plus')
t = sympy.symbols('t')
V_plus = x_plus*sympy.exp(1j*w*t)
V_minus = 0
V1,V2,V3 = sympy.symbols('V1 V2 V3')
# Using a matrix to collect all equations allows you to use a matrix-vector-product below
eqns = sympy.matrices.Matrix([
(V1-V_plus)/R1 + (V1-V2)/(1/(1j*w*C1)) + (V1-V_minus)/R4,
(V2-V_plus)/R2 + (V2-V1)/(1/(1j*w*C1)) + (V2-V_minus)/R5 + (V2-V3)/(1/(1j*w*C2)),
(V3-V_plus)/R3 + (V3-V2)/(1/(1j*w*C2)) + (V3-V_minus)/R6
])
# Prepare
V = [V1,V2,V3]
V_vec = sympy.matrices.Matrix(V)
# The "or 0" does nothing if there are coefficients y in x, but if there aren't, it replaced
# the "None" with "0". This again is required for using A * V_vec below
A = sympy.matrices.Matrix([ [ x.expand().coeff(y) or 0 for y in V ] for x in eqns ])
print(A)
remainder = (eqns - A * V_vec)
remainder.simplify()
print remainder
答案 1 :(得分:1)
您可以直接使用sympy.solve
解决此问题:
import sympy as sp
R1=R3=R5 = 1e3
R2=R4=R6 = 2e3
C1 = 1e-6
C2 = 0.5e-6
w = 1000
V0 = 5
t = sp.Symbol('t')
E = sp.exp(1j*w*t)
V1, V2, V3 = sp.symbols('V1 V2 V3')
V_plus = V0*E
V_minus = 0
V1_eqn = (V1-V_plus)/R1 + (V1-V2)/(1/(1j*w*C1)) + (V1-V_minus)/R4
V2_eqn = (V2-V_plus)/R2 + (V2-V1)/(1/(1j*w*C1)) + (V2-V_minus)/R5 + (V2-V3)/(1/(1j*w*C2))
V3_eqn = (V3-V_plus)/R3 + (V3-V2)/(1/(1j*w*C2)) + (V3-V_minus)/R6
print sp.solve([ sp.Eq(V1_eqn, 0), sp.Eq(V2_eqn, 0), sp.Eq(V3_eqn, 0)], [V1, V2, V3] )
答案 2 :(得分:0)
替换零是获得剩余常量的好方法。此外,jacobian
方法更多的是数学和#34;用coeff
方法做你正在做的事情的方式。
>>> eqs = sympy.Matrix((V1_eqn, V2_eqn, V3_eqn))
>>> eqs.jacobian(V)
Matrix([
[0.0015 + 0.001*I, -0.001*I, 0],
[ -0.001*I, 0.0015 + 0.0015*I, -0.0005*I],
[ 0, -0.0005*I, 0.0015 + 0.0005*I]])