英文:
Use linear algebra methods of SciPy to solve the three simultaneous equations
问题
我有一个问题,如何在数组中编写这些方程并解决?
from scipy import linalg
import numpy as np
import matplotlib.pyplot as plt
x = np.array([[-23, 1100, 2300],
[2300, 1500, 550],
[550, 1600, ???]])
我尝试在上面的数组中编写,但我无法弄清楚如何替换问题中的 'In' 和 'Vs2'。你可以帮我解决这个问题吗?
英文:
My question is that how to write theese equations in array and solve?
from scipy import linalg
import numpy as np
import matplotlib.pyplot as plt
x = np.array[-23,1100,2300],[2300,1500,550],[550,1600,]
I tried to write in the array above, but I couldn't figure out how to replace 'In' and 'Vs2' in the question. Can you help me solve the question?
答案1
得分: 1
以下是您要翻译的部分:
您想要解这些方程以获得几个电压的解,这表明需要使用for
循环。为了清晰起见,通常最好使用标识符来表示值,例如,使用R1
而不是1100。将R1
放入公式中,让计算机为您执行简单的算术运算。
您可能考虑使用linalg solve
函数,因为您需要解一个三阶方阵。未知数是电流。因此,进行代数运算,使您得到矩阵系数的表达式以及方程的右侧,用电阻和电压表示。
对于矩阵(如文档中所示https://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.solve.html#scipy.linalg.solve):
a = np.array([[f1(Rs, Vs), f2(Rs, Vs), f3(Rs, Vs)], [...], [...]])
对于右侧的向量:
b = np.array([f4(Rs, Vs), f5(Rs,Vs), f6(Rs, Vs)])
然后 currents = solve(a, b)
请注意,f1、f2等是您需要代数计算的函数。
现在将此代码放入循环中,类似于以下方式:
for vs2 in [10,15,20,25]:
currents = solve(a, b)
因为您已经在代数表达式中得到了电阻和vs2的值,您将获得相应的电流。您需要收集与绘图所需的电压对应的电流。
附加信息:代数运算的部分结果:
更多:如何使用sympy库避免大部分繁琐的代数运算:
>>> R1, R2, R3, R4, R5, Vs1 = 1100, 2300, 1500, 550, 1600, 23
>>> from sympy import *
>>> var('I1,I2,I3,Vs2')
(I1, I2, I3, Vs2)
>>> eq1 = -Vs1 + R1*I1 + R2 * (I1-I2)
>>> eq1
3400*I1 - 2300*I2 - 23
>>> eq2 = R2*(I2-I1)+R3*I2+R4*(I2-I3)
>>> eq2
-2300*I1 + 4350*I2 - 550*I3
>>> eq3 = R4*(I3-I2)+R5*I3 + Vs2
>>> eq3
-550*I2 + 2150*I3 + Vs2
>>> from scipy import linalg
>>> import numpy as np
>>> for Vs2 in [10,15,20,25]:
... ls = np.array([[3400,-2300,0],[-2300,4350,-550],[0,-550,2150]])
... rs = np.array([23, 0, -Vs2])
... I = linalg.solve(ls, rs)
... Vs2, I
...
(10, array([ 0.01007914, 0.0048996 , -0.00339778]))
(15, array([ 0.00975305, 0.00441755, -0.00584667]))
(20, array([ 0.00942696, 0.0039355 , -0.00829557]))
(25, array([ 0.00910087, 0.00345346, -0.01074446]))
英文:
You want to solve these equations for several voltages, which suggests the use of a for
-loop. For clarity, it's usually better to use identifiers for values, thus for instance, R1
rather than 1100. Put the R1
in formulae and let the computer do the simple arithmetic for you.
You may be thinking of using the linalg solve
function since you need to solve a square matrix of order three. The unknowns are the currents. Therefore, do the algebra so that you have expressions for the coefficients of the matrix, and for the right side of the equation, in terms of resistances and voltages.
For the matrix (as indicated in the documentation at https://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.solve.html#scipy.linalg.solve),
a = np.array([[f1(Rs, Vs), f2(Rs, Vs), f3(Rs, Vs)], [...], [...]])
For the vector on the right side,
b = np.array([f4(Rs, Vs), f5(Rs,Vs), f6(Rs, Vs)])
Then currents = solve(a, b)
Notice that f1, f2, etc are those functions that you have to calculate algebraically.
Now put this code in a loop, more or less like this:
for vs2 in [10,15,20,25]:
currents = solve(a, b)
Because you've got the resistances and vs2's in your algebraic expressions you'll get the corresponding currents. You'll need to collect the currents corresponding to voltages for plotting.
Addition: Partial result of algebraic manipulation:
More: How I would avoid most of the pesky algebra using the sympy library:
>>> R1, R2, R3, R4, R5, Vs1 = 1100, 2300, 1500, 550, 1600, 23
>>> from sympy import *
>>> var('I1,I2,I3,Vs2')
(I1, I2, I3, Vs2)
>>> eq1 = -Vs1 + R1*I1 + R2 * (I1-I2)
>>> eq1
3400*I1 - 2300*I2 - 23
>>> eq2 = R2*(I2-I1)+R3*I2+R4*(I2-I3)
>>> eq2
-2300*I1 + 4350*I2 - 550*I3
>>> eq3 = R4*(I3-I2)+R5*I3 + Vs2
>>> eq3
-550*I2 + 2150*I3 + Vs2
>>> from scipy import linalg
>>> import numpy as np
>>> for Vs2 in [10,15,20,25]:
... ls = np.array([[3400,-2300,0],[-2300,4350,-550],[0,-550,2150]])
... rs = np.array([23, 0, -Vs2])
... I = linalg.solve(ls, rs)
... Vs2, I
...
(10, array([ 0.01007914, 0.0048996 , -0.00339778]))
(15, array([ 0.00975305, 0.00441755, -0.00584667]))
(20, array([ 0.00942696, 0.0039355 , -0.00829557]))
(25, array([ 0.00910087, 0.00345346, -0.01074446]))
答案2
得分: 0
以下是您提供的代码的中文翻译部分:
为了解一个未知向量x=In
的线性方程组,经典写作Ax=b
,您需要为linalg.solve
函数指定一个系数矩阵A
和右手边的向量b
。根据您的问题,您只需要将您的三个方程以未知电流的矩阵形式重新编写,以获得A
和b
,这可以使用sympy
完成,但在这里我认为这样做有点过度。以下是使用解析的A
更易于阅读的解决方案:
from scipy.linalg import lu_factor, lu_solve
import numpy as np
import matplotlib.pyplot as plt
# 您的数据
R1 = 1100
R2 = 2300
R3 = 1500
R4 = 550
R5 = 1600
Vs1 = 23
# Vs2 的兴趣范围,以列表形式
Vs2_range = [10, 15, 20, 25]
# 构建 A:左侧的系数矩阵,以未知电流 In = [I1, I2, I3] 为条件
A = np.array([[R1+R2, -R2, 0],
[-R2, R2+R3+R4, -R4],
[0, -R4, R4+R5]])
# 预先计算 A 的分解 LU 分解,以解 Ax=b(因为只有 b 在这里改变)
A_LU = lu_factor(A)
# 初始化结果
res = np.empty((len(Vs2_range), 3))
# 遍历 Vs2 值
for i, Vs2 in enumerate(Vs2_range):
# 构建 b:每个 Vs2 的右侧向量
b = np.array([Vs1, 0, -Vs2])
# 然后解决线性系统 Ax=b
In = lu_solve(A_LU, b)
# 将结果作为 res 数组的行存储
res[i, :] = In
# 绘制每个电流 In(res 的列)与 Vs2_range
for i in range(3):
plt.plot(Vs2_range, res[:, i], '-+', label='I' + str(i+1))
plt.xlabel('Vs2 [V]')
plt.ylabel('I [A]')
plt.legend()
希望这有所帮助。
英文:
In order to solve a linear system of equations for unknown vector x=In
which is classically written as Ax=b
, you need to specify a coefficient matrix A
and right hand side vector b
to linalg.solve
function. Based on your question, you just have to re-write in matrix form your three equations in terms of unknown currents to get A
and b
which was done with sympy
but it is pretty overkill here imo. Here follows an easier to read solution with analytic A
:
from scipy.linalg import lu_factor, lu_solve
import numpy as np
import matplotlib.pyplot as plt
# your data
R1 = 1100
R2 = 2300
R3 = 1500
R4 = 550
R5 = 1600
Vs1 = 23
# Vs2 range of interest as a list
Vs2_range = [10,15,20,25]
# construct A: the coefficient matrix of the left-hand side in terms of In = [I1, I2, I3]
A = np.array([[ R1+R2, -R2, 0],
[ -R2, R2+R3+R4, -R4],
[ 0, -R4, R4+R5]])
# pre-compute pivoted LU decomposition of A to solve Ax=b (because only b is changing here)
A_LU = lu_factor(A)
# initialize results
res = np.empty((len(Vs2_range),3))
# loop over Vs2 values
for i,Vs2 in enumerate(Vs2_range):
# construct b: the right hand side vector for each Vs2
b = np.array([Vs1,0,-Vs2])
# then solve the linear system Ax=b
In = lu_solve(A_LU,b)
# stock results as rows of the res array
res[i,:] = In
# plot each current In (column of res) vs Vs2_range
for i in range(3):
plt.plot(Vs2_range,res[:,i],'-+',label='I'+str(i+1))
plt.xlabel('Vs2 [V]')
plt.ylabel('I [A]')
plt.legend()
Hope this helps.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论