2

我正在寻找一种在 Python 3.2 中转换方程的通用方法。我最近才开始玩弄它,偶然发现了一些我的旧 MATLAB 作业。我可以在 MATLAB 中计算这个,但 pylab 对我来说仍然有点神秘。

因此,我有一个方程文本文件,我试图将其转换为相同形式的 A x = b,然后在 PYLAB 中解决一些与它们相关的线性代数问题。

文本文件“equations.txt”包含以下格式的线性方程组:

-38 y1  +  35 y2  +  31 y3  = -3047

11 y1  + -13 y2  + -34 y3  = 784

34 y1  + -21 y2  +  19 y3  = 2949

等等

该文件包含四组方程的方程,每组具有不同数量的变量。每组方程都具有所示的精确形式(上面的 3 个示例),每组之间有一个空行。

我想编写一个程序来读取文件中的所有方程组,将方程组转换为矩阵方程 A x = b,并求解向量的方程组x

我的方法非常“MATLABy”,这是一个问题,因为我希望能够编写一个可以解决所有变量的程序。

我尝试将单个方程式读取为文本行,去掉末尾的回车符,并在=符号处分割线,因为我们知道分割中的第二个元素是等式的右侧,进入向量b

拆分中的第一个元素是您必须获取A矩阵中的系数的部分。如果你在空白处分割它' ',你会得到一个类似的列表

['-38', 'y1', '+', '35', 'y2', '+', '31', 'y3']

现在请注意,您可以提取每个第三个元素并获取进入矩阵的系数A
部分答案是:

y1 = 90; c2 = 28; x4 = 41; z100 = 59

我试图操纵它们给我y1, ..., y3第一个方程组的解的条目总和,c1, ..., c6第二个方程组的解的条目总和,解的条目x1, ..., x13总和第三个方程组,以及z1, ..., z100第四个方程组解的条目总和。

就像,我说过 - 我可以在 MATLAB 中做到这一点,但不能在 Python 中做到这一点,所以我可能以错误的方式处理这个问题,但这是我目前所拥有的:

import pylab
f = open('equations.txt', 'r')

L=f.readlines()

list_final = []

for line in L:
line_l = line.rstrip()
list_l = line_l.split(";")
list_l = filter(None, list_l)

for expression in list_l:

并以

f.close()

这只是我尝试将方程格式化为所有看起来相同的尝试。我意识到这不是很多,但我真的希望有人可以开始我的工作,因为即使我知道一些 python,我通常不会将它用于数学,因为我有 MATLAB。

我认为这对我们中的许多有 MATLAB 经验但没有 pylab 的人来说可能很有用。你会如何解决这个问题?谢谢!

4

2 回答 2

2

对于您的示例格式,很容易通过以下方式处理它numpy.loadtxt()

import numpy as np
data = np.loadtxt("equations.txt", dtype=str)[:, ::3].astype(np.float)
a = data[:, :-1]
b = data[:, -1]
x = np.linalg.solve(a, b)

步骤是:

于 2013-04-13T11:23:20.457 回答
0

另一种可能对非结构化输入更健壮的方法是使用 Python 符号数学包 ( sympy ) 和一些解析技巧的组合。这可以缩放到以任意顺序编写的方程中的变量。

尽管 sympy 有一些解析工具(您的输入在外观上与 Mathematica 非常接近),但该sympy.parsing.mathematica模块似乎无法处理某些输入(尤其是前导减号)。

import sympy
from sympy.parsing.sympy_parser import parse_expr
import re

def text_to_equations(text):
    lines = text.split('\n')
    lines = [line.split('=') for line in lines]
    eqns = []
    for lhs, rhs in lines:
        # clobber all the spaces
        lhs = lhs.replace(' ','')
        # *assume* that a number followed by a letter is an
        # implicit multiplication
        lhs = re.sub(r'(\d)([a-z])', r'\g<1>*\g<2>', lhs)
        eqns.append( (parse_expr(lhs), parse_expr(rhs)) )
    return eqns

def get_all_symbols(eqns):
    symbs = set()
    for lhs, rhs in eqns:
        for sym in lhs.atoms(sympy.Symbol):
            symbs.add(sym)
    return symbs

def text_to_eqn_matrix(text):
    eqns = text_to_equations(text)
    symbs = get_all_symbols(eqns)
    n = len(eqns)
    m = len(symbs)
    A = numpy.zeros((m, n))
    b = numpy.zeros((m, 1))
    for i, (lhs, rhs) in enumerate(eqns):
        d = lhs.as_coefficients_dict()
        b[i] = int(rhs)
        for j, s in enumerate(symbs):
            A[i, j] = d[s]
    x = sympy.Matrix([list(symbs)]).T
    return sympy.Matrix(A), x, sympy.Matrix(b)

s = '''-38 y1  +  35 y2  +  31 y3  = -3047
11 y1  + -13 y2  + -34 y3  = 784
34 y1  + -21 y2  +  19 y3  = 2949'''
A, x, b = text_to_eqn_matrix(s)
print A
print x
print b
于 2013-04-13T13:17:55.747 回答