How to add a row of coefficients to a matrix and compute differences between rows using sympy and fractions in Python?

huangapple go评论76阅读模式
英文:

How to add a row of coefficients to a matrix and compute differences between rows using sympy and fractions in Python?

问题

# Add coefficient row to the output matrix
output.append([None] + [sp.sympify(term) if term != 'B' else None for term in output[0][1:]])

# Calculate the differences between the penultimate and last row
difference_row = [None] + [output[-2][i] - output[-1][i] if output[-2][i] is not None and output[-1][i] is not None else None for i in range(1, len(output[0]))]

# Add the difference row to the output matrix
output.append(difference_row)

# Display the updated output matrix
for row in output:
    print(row)

Note: The code you provided appears to be mostly correct. It adds the coefficient row to the output matrix and calculates the differences between rows correctly. However, the output formatting in your code may not match exactly with the desired output format you mentioned in your request. Make sure you adjust the formatting as needed based on your specific requirements.

英文:
import sympy as sp
from fractions import Fraction

M = sympy.symbols('M')

#It is called output, but in reality it is because the matrix is obtained 
# from a previous process, although it would be the input of this process.
output = [['B', 'X1', 'X2', 'X3', 'X4', 'X5', 'U1', 'U2'], 
          [5*M + 3, 3, 5*M/2 - 3/2, 3/2 - 3*M/2, -M, M/2 - 3/2, M, 3/2 - M/2]]

z_function = "Z = 3 * X1 + 2 * X2 + 1 * X3 + 0 * X4 + 0 * X5 + M * U1 + M * U2"

I must add a row of the coefficients in the expression of z_function. Keep in mind that with coefficients I mean the numerical values that multiply the variables in a mathematical expression

Note that the coefficient of the expression corresponding to the column variable is placed inside the matrix, and if there is no associated coefficient (as is the case of B) then it will simply place None

output = [['B', 'X1', 'X2', 'X3', 'X4', 'X5', 'U1', 'U2'], 
          [5*M + 3, 3, 5*M/2 - 3/2, 3/2 - 3*M/2, -M, M/2 - 3/2, M, 3/2 - M/2], 
          [None, 3, 2, 1, 0, 0, M, M]]

Then using sympy with sp.sympify() or/and using fractions with Fraction().limit_denominator() compute the difference between row index 1 and row index 2, and add the results in a new row with index 3, this as long as none of the cells to be subtracted is None

(5*M + 3) - (None) = None
(3) - (3) = 0
(5*M/2 - 3/2) - (2) = 5*M/2 - 5/2
(3/2 - 3*M/2) - (1) = 1/2 - 3*M/2
(-M) - (0) = -M
(M/2 - 3/2) - (0) = M/2 - 3/2
(M) - (M) = 0
(3/2 - M/2) - (M) = 3/2 - 3*M/2

The array should look like this:

output = [[    'B', 'X1',        'X2',        'X3', 'X4',      'X5', 'U1',        'U2'], 
          [5*M + 3,    3, 5*M/2 - 3/2, 3/2 - 3*M/2,   -M, M/2 - 3/2,    M,   3/2 - M/2], 
          [   None,    3,           2,           1,    0,         0,    M,           M], 
          [   None,    0, 5*M/2 - 5/2, 1/2 - 3*M/2,   -M, M/2 - 3/2,    0, 3/2 - 3*M/2]]

Here my code, although it does not work correctly since it subtracts the coefficients of the columns, in addition to the fact that it does not perform the calculations between the boxes correctly

# Add coefficient row to the output matrix
output.append([None] + [sp.sympify(term) if term != 'B' else None for term in output[0][1:]])

# Calculate the differences between the penultimate and last row
difference_row = [None] + [output[-2][i] - output[-1][i] if output[-2][i] is not None and output[-1][i] is not None else None for i in range(1, len(output[0]))]

# Add the difference row to the output matrix
output.append(difference_row)

print(output)
for row in output: print(row)

答案1

得分: 2

以下是翻译好的代码部分:

这是一个简单的方法来实现这个
```python
import sympy as sym

M = sym.symbols('M')

output = [['B', 'X1', 'X2', 'X3', 'X4', 'X5', 'U1', 'U2'],
          [5*M + 3, 3, 5*M/2 - sym.S(3)/2, sym.S(3)/2 - 3*M/2, -M, M/2 - sym.S(3)/2, M, sym.S(3)/2 - M/2]]

z_function = "Z = 3 * X1 + 2 * X2 + 1 * X3 + 0 * X4 + 0 * X5 + M * U1 + M * U2"

z = sym.parse_expr(z_function[3:])

coeffs = [z.coeff(s) if s in z_function else None for s in output[0]]

diffs = [r1 - r2 if None not in (r1, r2) else None for r1, r2 in zip(output[1], coeffs)]

测试s in z_function仅仅是检查一个字符串是否是另一个字符串的子串。这是因为您需要区分B,它不在字符串中,以及X4,它在字符串中但系数为零,这只是一种方便处理这种情况的方式。不过,如果您的变量名重叠,像这样测试子串可能会失败。

英文:

Here is a simple way to do this:

In [34]: import sympy as sym
    ...:
    ...: M = sympy.symbols('M')
    ...:
    ...: output = [['B', 'X1', 'X2', 'X3', 'X4', 'X5', 'U1', 'U2'],
    ...:           [5*M + 3, 3, 5*M/2 - sym.S(3)/2, sym.S(3)/2 - 3*M/2, -M, M/2 - sym.S(3)/2, M, sym.S(3)/2 - M/2]]
    ...:
    ...: z_function = "Z = 3 * X1 + 2 * X2 + 1 * X3 + 0 * X4 + 0 * X5 + M * U1 + M * U2"

In [35]: z = sym.parse_expr(z_function[3:])

In [36]: z
Out[36]: M⋅U₁ + M⋅U₂ + 3⋅X₁ + 2⋅X₂ + X₃

In [37]: coeffs = [z.coeff(s) if s in z_function else None for s in output[0]]

In [38]: coeffs
Out[38]: [None, 3, 2, 1, 0, 0, M, M]

In [39]: diffs = [r1 - r2 if None not in (r1, r2) else None for r1, r2 in zip(output[1], coeffs)]

In [40]: diffs
Out[40]: [None, 0, 5*M/2 - 7/2, 1/2 - 3*M/2, -M, M/2 - 3/2, 0, 3/2 - 3*M/2]

The test s in z_function is just checking if a string is a substring of another. This is because you require to distinguish between B which is not in the string and X4 which is in the string but has a coefficient of zero and that is just a convenient way to handle that case. Testing for a substring like that could fail if your variable names were overlapping though.

huangapple
  • 本文由 发表于 2023年6月26日 23:06:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76557947.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定