优先考虑非线性系统中的方程。

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

Prioritize equations in a nonlinear system

问题

我正在尝试使用最小二乘法解决非线性等式系统(EQS)的问题。我得到了一个结果,但不幸的是它并不非常准确。主要问题是方程29到32必须被满足,但它们并没有被满足。有没有一种方法可以在非线性系统中优先考虑方程?

以下是我的代码:

# 乙醇和1-丙醇与3个塔板

from scipy.optimize import least_squares
import numpy as np


def equations(x):
    # 你的方程式在这里

# 界限
# 特定变量的上界
upper_bounds = np.ones(32) * np.inf
# 你的上界在这里

# 特定变量的下界
bottom_bounds = np.zeros(32)
# 你的下界在这里

# 边界数组
bounds = (bottom_bounds, upper_bounds)

# 初始值
x0 = np.ones(32)
# 你的初始值在这里

# 使用变量边界解决方程组
res = least_squares(equations, x0, bounds=bounds, method='trf', ftol=1e-10, xtol=1e-10, gtol=1e-10)

# 打印结果
print(res.x)
# 你的结果打印在这里

e0_x_Vint_tr1_c1e0_x_Vint_tr1_c2 的结果似乎不正确,因为它们的总和不等于1。您可能需要检查方程29和32以确保它们正确地表示了变量之间的关系。如果这些方程正确,但结果仍然不准确,您可能需要进一步调整初始值或尝试不同的优化方法。

英文:

I am trying to solve a nonlinear EQS using the least squares method. I get a result, but unfortunately it is not very accurate. The main problem is that the equations 29 to 32 must be fullfilled, but they are not. Is there a way to maybe prioritize equations in a nonlinear system?

Here is the my code:

# Ethanol and 1_Propanol with 3 trays

from scipy.optimize import least_squares
import numpy as np


def equations(x):
    eq1 = x[18] - x[16] * x[19] * x[11] * (x[21] / (x[19] * x[11] * x[13])) ** (2.0 / 3.0)
    eq2 = x[19] - ((732.0 * x[10]) + (747.0 * x[9]))
    eq3 = x[13] - ((1.25E-5 * x[10]) + (1.6E-6 * x[9]))
    eq4 = x[2] - ((((((-6021.54) + (0.055134232180918 * (x[29] - 298.0))) + 2.61275786690816) * x[10])
                   + ((((-6883.827) + (0.058471271259418 * (x[29] - 298.0))) + 2.38446400137128) * x[9])))
    eq5 = x[11] - (((0.055134232180918 * (x[29])) + 2.61275786690816) * x[10] + ((0.058471271259418 * (x[29])) +
                                                                                 2.38446400137128) * x[9])
    eq6 = x[21] - ((((((0.001318 * (x[29])) + 0.16762) * x[10])
                     + (((-0.001075424413 * (x[29])) + 0.155701011727667) * x[9]))))
    eq7 = x[24] - (1.746 * x[22] + 2.76 * x[20])
    eq8 = x[15] - (1.0E-5 * x[22] + 6.5E-6 * x[20])
    eq9 = x[12] - ((((((((-6021.54) + (0.015220202121093 * (x[26] - 298.0))) + 1.60395800121061) + 922.194)
                      * x[22]) + ((((((-6883.827) + (0.01847750929725 * (x[26] - 298.0))) + 1.43843773750579)
                                    + 1067.523)) * x[20]))))
    eq10 = x[6] - ((((((((0.015220202121093 * (x[26])) + 1.60395800121061)
                        * x[22]) + (((0.01847750929725 * (x[26])) + 1.43843773750579)
                                    * x[20]))))))
    eq11 = x[5] - ((((((((5.07392141746E-4 * (x[29])) + 0.015070468544221)
                        * x[22]) + (((4.89248E-4 * (x[29])) + 0.014354384)
                                    * x[20]))))))
    eq12 = x[3] - (1.0 / (10.0 ** (5.24677 - 1598.673 / (x[28] + 46.424))))
    eq13 = x[0] - (1.0 / (10.0 ** (5.31384 - 1690.864 / (x[28] + 51.804))))
    eq14 = x[27] - (x[25] * x[24] * x[6] * ((x[5] / (x[24] * x[6] * x[15])) ** (2.0 / 3.0)))
    eq15 = 0.0 - ((2.0 * 28000.0) - (x[23] * x[2]) + (x[17] * 0.002))
    eq16 = 0.0 - ((0.2 * 30000.0) - (x[14] * x[12]) - (x[17] * 0.002))
    eq17 = 0.0 - ((2.0 * 0.5) - (x[23] * x[10]) + (x[8] * 0.002))
    eq18 = 0.0 - ((2.0 * 0.5) - (x[23] * x[9]) + (x[7] * 0.002))
    eq19 = 0.0 - ((0.2 * 0.6) - (x[14] * x[22]) - (x[8] * 0.002))
    eq20 = 0.0 - ((0.2 * 0.4) - (x[14] * x[20]) - (x[7] * 0.002))
    eq21 = 0.0 - (x[31] - (x[3] * x[4]))
    eq22 = 0.0 - (x[30] - (x[0] * x[1]))
    eq23 = x[17] - (x[18] * (x[28] - x[29]) + (x[8] * (((-6021.54 + (0.055134232180918 * (x[29] - 298.0))) +
                                                        2.61275786690816) + (x[7] * (
            (-6883.827 + (0.058471271259418 * (x[29] - 298.0))) + 2.38446400137128)))))
    eq24 = x[17] - (x[27] * (x[26] - x[28]) + (x[8] * ((((-6021.54 + (0.015220202121093 * (x[26] - 298.0))) +
                                                         1.60395800121061) + 922.194) + (x[7] * (
            ((-6883.827 + (0.01847750929725 * (x[26] - 298.0))) + 1.43843773750579) + 1067.523)))))
    eq25 = x[8] - (x[19] * x[16] * (x[4] - x[10]) + x[10] * (x[8] + x[7]))
    eq26 = x[7] - (x[19] * x[16] * (x[1] - x[9]) + x[9] * (x[8] + x[7]))
    eq27 = x[8] - (x[24] * x[25] * (x[22] - x[31]) + x[22] * (x[8] + x[7]))
    eq28 = x[7] - (x[24] * x[25] * (x[20] - x[30]) + x[20] * (x[8] + x[7]))
    eq29 = 1.0 - (x[10] + x[9])
    eq30 = 1.0 - (x[4] + x[1])
    eq31 = 1.0 - (x[22] + x[20])
    eq32 = 1.0 - (x[31] + x[30])

    return [eq1, eq2, eq3, eq4, eq5, eq6, eq7, eq8, eq9, eq10, eq11, eq12, eq13, eq14, eq15, eq16,
            eq17, eq18, eq19, eq20, eq21, eq22, eq23, eq24, eq25, eq26, eq27, eq28, eq29, eq30,
            eq31, eq32]


# Boundaries
# Upper bounds for specific variables
upper_bounds = np.ones(32) * np.inf
upper_bounds[1] = 1
upper_bounds[4] = 1
upper_bounds[9] = 1
upper_bounds[10] = 1
upper_bounds[20] = 1
upper_bounds[22] = 1
upper_bounds[30] = 1
upper_bounds[31] = 1

# Upper bounds for specific variables
bottom_bounds = np.zeros(32)
bottom_bounds[26] = 340
bottom_bounds[28] = 340
bottom_bounds[29] = 340

# Bounds array
bounds = (bottom_bounds, upper_bounds)
# bounds = (0, np.inf)


# Initial values
x0 = np.ones(32)
x0[1] = 0.5
x0[4] = 0.5
x0[9] = 0.5
x0[10] = 0.5
x0[20] = 0.5
x0[22] = 0.5
x0[30] = 0.5
x0[31] = 0.5

x0[26] = 370
x0[28] = 370
x0[29] = 370


# x0 = np.array([1, 1e-4, 1, 1, 1, 1, 1e-4, 1, 1, 1, 1, 1, 1, 1, 1, 1])


# Lösung des Gleichungssystems mit Variablengrenzen
res = least_squares(equations, x0, bounds=bounds, method='trf', ftol=1e-10, xtol=1e-10, gtol=1e-10)

print(res.x)
print('e0_K_tr1_c2 {0}'.format(res.x[0]))
print('e0_x_Lint_tr1_c2 {0}'.format(res.x[1]))
print('e0_h_L_tr1 {0}'.format(res.x[2]))
print('e0_K_tr1_c1 {0}'.format(res.x[3]))
print('e0_x_Lint_tr1_c1 {0}'.format(res.x[4]))
print('e0_greek_lambda_V_tr1 {0}'.format(res.x[5]))
print('e0_cp_V_tr1 {0}'.format(res.x[6]))
print('e0_f_int_tr1_c2 {0}'.format(res.x[7]))
print('e0_f_int_tr1_c1 {0}'.format(res.x[8]))
print('e0_x_L_tr1_c2 {0}'.format(res.x[9]))
print('e0_x_L_tr1_c1 {0}'.format(res.x[10]))
print('e0_cp_L_tr1 {0}'.format(res.x[11]))
print('e0_h_V_tr1 {0}'.format(res.x[12]))
print('e0_D_L_tr1 {0}'.format(res.x[13]))
print('e0_F_V_tr1 {0}'.format(res.x[14]))
print('e0_D_V_tr1 {0}'.format(res.x[15]))
print('e0_greek_beta_L_tr1 {0}'.format(res.x[16]))
print('e0_e_int_tr1 {0}'.format(res.x[17]))
print('e0_greek_alpha_L_tr1 {0}'.format(res.x[18]))
print('e0_greek_rho_L_tr1 {0}'.format(res.x[19]))
print('e0_x_V_tr1_c2 {0}'.format(res.x[20]))
print('e0_greek_lambda_L_tr1 {0}'.format(res.x[21]))
print('e0_x_V_tr1_c1 {0}'.format(res.x[22]))
print('e0_F_L_tr1 {0}'.format(res.x[23]))
print('e0_greek_rho_V_tr1 {0}'.format(res.x[24]))
print('e0_greek_beta_V_tr1 {0}'.format(res.x[25]))
print('e0_T_V_tr1 {0}'.format(res.x[26]))
print('e0_greek_alpha_V_tr1 {0}'.format(res.x[27]))
print('e0_T_int_tr1 {0}'.format(res.x[28]))
print('e0_T_L_tr1 {0}'.format(res.x[29]))
print('e0_x_Vint_tr1_c2 {0}'.format(res.x[30]))
print('e0_x_Vint_tr1_c1 {0}'.format(res.x[31]))

print('Zusammensetztungen:')

print('e0_x_Vint_tr1_c1 {0}'.format(res.x[31]))
print('e0_x_Vint_tr1_c2 {0}'.format(res.x[30]))

print('e0_x_V_tr1_c1 {0}'.format(res.x[22]))
print('e0_x_V_tr1_c2 {0}'.format(res.x[20]))

print('e0_x_Lint_tr1_c1 {0}'.format(res.x[4]))
print('e0_x_Lint_tr1_c2 {0}'.format(res.x[1]))

print('e0_x_L_tr1_c1 {0}'.format(res.x[10]))
print('e0_x_L_tr1_c2 {0}'.format(res.x[9]))

and the results for x[31], x[30], x[22],... are:

Zusammensetztungen:
e0_x_Vint_tr1_c1 0.5189962572539993
e0_x_Vint_tr1_c2 0.24082903753005624
e0_x_V_tr1_c1 2.3066615630447933e-32
e0_x_V_tr1_c2 1.246796204196686e-33
e0_x_Lint_tr1_c1 0.9999999999999999
e0_x_Lint_tr1_c2 0.01258253962013115
e0_x_L_tr1_c1 7.013309435002394e-33
e0_x_L_tr1_c2 3.0913699644636455e-33

but e0_x_Vint_tr1_c1 + e0_x_Vint_tr1_c2 should be 1, but it's not.

答案1

得分: 1

去掉多余的括号并重新格式化你的方程,以便更容易调试。

用命名变量替换你的索引变量。我通过NamedTuple展示了一种快速的方法。

不幸的是,尽管方法lm似乎可以改善你的结果 - 它声称找到的解决方案的成本比trf低约10倍(30.7比399) - 但它不能使用,因为它不遵守你的边界。没有一个神奇的方法可以提高准确性。了解领域问题是必要的。如果某些方程“比其他方程更重要”,你可以简单地按照它们的权重来缩放这些方程。

添加回归测试。我展示的结果中,方程与你的原始方程等效。

始终检查result.success

第一次尝试可以如下所示:

"""乙醇和1-丙醇,3个托盘"""

from pprint import pprint
from typing import NamedTuple

from numpy.random import default_rng
from scipy.optimize import least_squares
import numpy as np


class Vars(NamedTuple):
    e0_K_tr1_c2: float            # 0
    e0_x_Lint_tr1_c2: float       # 1
    e0_h_L_tr1: float             # 2
    e0_K_tr1_c1: float            # 3
    e0_x_Lint_tr1_c1: float       # 4
    e0_lambda_V_tr1: float        # 5
    e0_cp_V_tr1: float            # 6
    e0_f_int_tr1_c2: float        # 7
    e0_f_int_tr1_c1: float        # 8
    e0_x_L_tr1_c2: float          # 9
    e0_x_L_tr1_c1: float          # 10
    e0_cp_L_tr1: float            # 11
    e0_h_V_tr1: float             # 12
    e0_D_L_tr1: float             # 13
    e0_F_V_tr1: float             # 14
    e0_D_V_tr1: float             # 15
    e0_beta_L_tr1: float          # 16
    e0_e_int_tr1: float           # 17
    e0_alpha_L_tr1: float         # 18
    e0_rho_L_tr1: float           # 19
    e0_x_V_tr1_c2: float          # 20
    e0_lambda_L_tr1: float        # 21
    e0_x_V_tr1_c1: float          # 22
    e0_F_L_tr1: float             # 23
    e0_rho_V_tr1: float           # 24
    e0_beta_V_tr1: float          # 25
    e0_T_V_tr1: float             # 26
    e0_alpha_V_tr1: float         # 27
    e0_T_int_tr1: float           # 28
    e0_T_L_tr1: float             # 29
    e0_x_Vint_tr1_c2: float       # 30
    e0_x_Vint_tr1_c1: float       # 31


def equations(x: np.ndarray) -> tuple[float, ...]:
    v = Vars(*x)

    eq1 = v.e0_alpha_L_tr1 - v.e0_beta_L_tr1 * v.e0_rho_L_tr1 * v.e0_cp_L_tr1 * (
        v.e0_lambda_L_tr1 / (v.e0_rho_L_tr1 * v.e0_cp_L_tr1 * v.e0_D_L_tr1)
    ) ** (2 / 3)

    eq2 = v.e0_rho_L_tr1 - (732 * v.e0_x_L_tr1_c1 + 747 * v.e0_x_L_tr1_c2)
    eq3 = v.e0_D_L_tr1 - (1.25E-5 * v.e0_x_L_tr1_c1 + 1.6E-6 * v.e0_x_L_tr1_c2)

    eq4 = v.e0_h_L_tr1 - (
        (
            -6021.54
            + 0.055134232180918 * (v.e0_T_L_tr1 - 298)
            + 2.61275786690816
        ) * v.e0_x_L_tr1_c1
        + (
            -6883.827
            + 0.058471271259418 * (v.e0_T_L_tr1 - 298)
            + 2.38446400137128
        ) * v.e0_x_L_tr1_c2
    )

    eq5 = v.e0_cp_L_tr1 - (
        (
            0.055134232180918 * v.e0_T_L_tr1 + 2.61275786690816
        ) * v.e0_x_L_tr1_c1
        + (
            0.058471271259418 * v.e0_T_L_tr1 + 2.38446400137128
        ) * v.e0_x_L_tr1_c2
    )
    eq6 = v.e0_lambda_L_tr1 - (
        (
            0.001318 * v.e0_T_L_tr1 + 0.16762
        ) * v.e0_x_L_tr1_c1
        + (
            -0.001075424413 * v.e0_T_L_tr1 + 0.155701011727667
        ) * v.e0_x_L_tr1_c2
    )

    eq7 = v.e0_rho_V_tr1 - (1.746 * v.e0_x_V_tr1_c1 + 2.76 * v.e0_x_V_tr1_c2)
    eq8 = v.e0_D_V_tr1 - (1E-5 * v.e0_x_V_tr1_c1 + 6.5E-6 * v.e0_x_V_tr1_c2)

    eq9 = v.e0_h_V_tr1 - (
        (
            -6021.54
            + 0.015220202121093 * (v.e0_T_V_tr1 - 298)
            + 1.60395800121061
            + 922.194
        ) * v.e0_x_V_tr1_c1
        + (
            -6883.827
            + 0.01847750929725 * (v.e0_T_V_tr1 - 298)
            + 1.43843773750579
            + 1067.523
        ) * v.e0_x_V_tr1_c2
    )
    eq10 = v.e0_cp

<details>
<summary>英文:</summary>

Remove your redundant parentheses and reformat your equations so that they can be more easily debugged.

Replace your indexed variables with named variables. I show a quick way to do this via `NamedTuple`.

Unfortunately, whereas method `lm` may seem to improve your results - it claims to find a solution with ~ 10 times less cost (30.7) than that from `trf` (399) - it&#39;s not usable because it doesn&#39;t respect your bounds. There is no magic bullet to improve the accuracy. Knowledge of the domain problem is necessary. If some equations &quot;matter more&quot; to the solution than others, you can simply scale those equations by their weights.

Add regression tests. For the results that I show, the equations are equivalent to your original equations.

Always check `result.success`.

A first pass can look like

```python
&quot;&quot;&quot;Ethanol and 1_Propanol with 3 trays&quot;&quot;&quot;

from pprint import pprint
from typing import NamedTuple

from numpy.random import default_rng
from scipy.optimize import least_squares
import numpy as np


class Vars(NamedTuple):
    e0_K_tr1_c2: float            # 0
    e0_x_Lint_tr1_c2: float       # 1
    e0_h_L_tr1: float             # 2
    e0_K_tr1_c1: float            # 3
    e0_x_Lint_tr1_c1: float       # 4
    e0_lambda_V_tr1: float        # 5
    e0_cp_V_tr1: float            # 6
    e0_f_int_tr1_c2: float        # 7
    e0_f_int_tr1_c1: float        # 8
    e0_x_L_tr1_c2: float          # 9
    e0_x_L_tr1_c1: float          # 10
    e0_cp_L_tr1: float            # 11
    e0_h_V_tr1: float             # 12
    e0_D_L_tr1: float             # 13
    e0_F_V_tr1: float             # 14
    e0_D_V_tr1: float             # 15
    e0_beta_L_tr1: float          # 16
    e0_e_int_tr1: float           # 17
    e0_alpha_L_tr1: float         # 18
    e0_rho_L_tr1: float           # 19
    e0_x_V_tr1_c2: float          # 20
    e0_lambda_L_tr1: float        # 21
    e0_x_V_tr1_c1: float          # 22
    e0_F_L_tr1: float             # 23
    e0_rho_V_tr1: float           # 24
    e0_beta_V_tr1: float          # 25
    e0_T_V_tr1: float             # 26
    e0_alpha_V_tr1: float         # 27
    e0_T_int_tr1: float           # 28
    e0_T_L_tr1: float             # 29
    e0_x_Vint_tr1_c2: float       # 30
    e0_x_Vint_tr1_c1: float       # 31


def equations(x: np.ndarray) -&gt; tuple[float, ...]:
    v = Vars(*x)

    eq1 = v.e0_alpha_L_tr1 - v.e0_beta_L_tr1 * v.e0_rho_L_tr1 * v.e0_cp_L_tr1 * (
        v.e0_lambda_L_tr1 / (v.e0_rho_L_tr1 * v.e0_cp_L_tr1 * v.e0_D_L_tr1)
    ) ** (2 / 3)

    eq2 = v.e0_rho_L_tr1 - (732 * v.e0_x_L_tr1_c1 + 747 * v.e0_x_L_tr1_c2)
    eq3 = v.e0_D_L_tr1 - (1.25E-5 * v.e0_x_L_tr1_c1 + 1.6E-6 * v.e0_x_L_tr1_c2)

    eq4 = v.e0_h_L_tr1 - (
        (
            -6021.54
            + 0.055134232180918 * (v.e0_T_L_tr1 - 298)
            + 2.61275786690816
        ) * v.e0_x_L_tr1_c1
        + (
            -6883.827
            + 0.058471271259418 * (v.e0_T_L_tr1 - 298)
            + 2.38446400137128
        ) * v.e0_x_L_tr1_c2
    )

    eq5 = v.e0_cp_L_tr1 - (
        (
            0.055134232180918 * v.e0_T_L_tr1 + 2.61275786690816
        ) * v.e0_x_L_tr1_c1
        + (
            0.058471271259418 * v.e0_T_L_tr1 + 2.38446400137128
        ) * v.e0_x_L_tr1_c2
    )
    eq6 = v.e0_lambda_L_tr1 - (
        (
            0.001318 * v.e0_T_L_tr1 + 0.16762
        ) * v.e0_x_L_tr1_c1
        + (
            -0.001075424413 * v.e0_T_L_tr1 + 0.155701011727667
        ) * v.e0_x_L_tr1_c2
    )

    eq7 = v.e0_rho_V_tr1 - (1.746 * v.e0_x_V_tr1_c1 + 2.76 * v.e0_x_V_tr1_c2)
    eq8 = v.e0_D_V_tr1 - (1E-5 * v.e0_x_V_tr1_c1 + 6.5E-6 * v.e0_x_V_tr1_c2)

    eq9 = v.e0_h_V_tr1 - (
        (
            -6021.54
            + 0.015220202121093 * (v.e0_T_V_tr1 - 298)
            + 1.60395800121061
            + 922.194
        ) * v.e0_x_V_tr1_c1
        + (
            -6883.827
            + 0.01847750929725 * (v.e0_T_V_tr1 - 298)
            + 1.43843773750579
            + 1067.523
        ) * v.e0_x_V_tr1_c2
    )
    eq10 = v.e0_cp_V_tr1 - (
        (
            0.015220202121093 * v.e0_T_V_tr1 + 1.60395800121061
        ) * v.e0_x_V_tr1_c1
        + (
            0.01847750929725 * v.e0_T_V_tr1 + 1.43843773750579
        ) * v.e0_x_V_tr1_c2
    )
    eq11 = v.e0_lambda_V_tr1 - (
        (
            5.07392141746E-4 * v.e0_T_L_tr1 + 0.015070468544221
        ) * v.e0_x_V_tr1_c1
        + (
            4.89248E-4 * v.e0_T_L_tr1 + 0.014354384
        ) * v.e0_x_V_tr1_c2
    )

    eq12 = v.e0_K_tr1_c1 - 1 / 10**(5.24677 - 1598.673 / (v.e0_T_int_tr1 + 46.424))
    eq13 = v.e0_K_tr1_c2 - 1 / 10**(5.31384 - 1690.864 / (v.e0_T_int_tr1 + 51.804))

    eq14 = v.e0_alpha_V_tr1 - (
        v.e0_beta_V_tr1 * v.e0_rho_V_tr1 * v.e0_cp_V_tr1 * (
            v.e0_lambda_V_tr1 / (
                v.e0_rho_V_tr1 * v.e0_cp_V_tr1 * v.e0_D_V_tr1
            )
        ) ** (2 / 3)
    )

    eq15 = -(2 * 28000 - v.e0_F_L_tr1 * v.e0_h_L_tr1 + v.e0_e_int_tr1 * 0.002)
    eq16 = -(0.2 * 30000 - v.e0_F_V_tr1 * v.e0_h_V_tr1 - v.e0_e_int_tr1 * 0.002)
    eq17 = -(2 * 0.5 - v.e0_F_L_tr1 * v.e0_x_L_tr1_c1 + v.e0_f_int_tr1_c1 * 0.002)
    eq18 = -(2 * 0.5 - v.e0_F_L_tr1 * v.e0_x_L_tr1_c2 + v.e0_f_int_tr1_c2 * 0.002)
    eq19 = -(0.2 * 0.6 - v.e0_F_V_tr1 * v.e0_x_V_tr1_c1 - v.e0_f_int_tr1_c1 * 0.002)
    eq20 = -(0.2 * 0.4 - v.e0_F_V_tr1 * v.e0_x_V_tr1_c2 - v.e0_f_int_tr1_c2 * 0.002)

    eq21 = -(v.e0_x_Vint_tr1_c1 - v.e0_K_tr1_c1 * v.e0_x_Lint_tr1_c1)
    eq22 = -(v.e0_x_Vint_tr1_c2 - v.e0_K_tr1_c2 * v.e0_x_Lint_tr1_c2)

    eq23 = v.e0_e_int_tr1 - (
        v.e0_alpha_L_tr1 * (v.e0_T_int_tr1 - v.e0_T_L_tr1)
        + v.e0_f_int_tr1_c1 * (
            -6021.54
            + 0.055134232180918 * (v.e0_T_L_tr1 - 298)
            + 2.61275786690816
            # really?
        # )
            + v.e0_f_int_tr1_c2 * (
                -6883.827 +
                0.058471271259418 * (v.e0_T_L_tr1 - 298)
                + 2.38446400137128
            )
        )
    )

    eq24 = v.e0_e_int_tr1 - (
        v.e0_alpha_V_tr1 * (v.e0_T_V_tr1 - v.e0_T_int_tr1)
        + v.e0_f_int_tr1_c1 * (
            -6021.54
            + 0.015220202121093 * (v.e0_T_V_tr1 - 298)
            + 1.60395800121061
            + 922.194
            # really?
        # )
            + v.e0_f_int_tr1_c2 * (
                -6883.827
                + 0.01847750929725 * (v.e0_T_V_tr1 - 298)
                + 1.43843773750579
                + 1067.523
            )
        )
    )

    eq25 = v.e0_f_int_tr1_c1 - (
        v.e0_rho_L_tr1 * v.e0_beta_L_tr1 * (
            v.e0_x_Lint_tr1_c1 - v.e0_x_L_tr1_c1
        )
        + v.e0_x_L_tr1_c1 * (v.e0_f_int_tr1_c1 + v.e0_f_int_tr1_c2)
    )
    eq26 = v.e0_f_int_tr1_c2 - (
        v.e0_rho_L_tr1 * v.e0_beta_L_tr1 * (
            v.e0_x_Lint_tr1_c2 - v.e0_x_L_tr1_c2
        )
        + v.e0_x_L_tr1_c2 * (v.e0_f_int_tr1_c1 + v.e0_f_int_tr1_c2)
    )
    eq27 = v.e0_f_int_tr1_c1 - (
        v.e0_rho_V_tr1 * v.e0_beta_V_tr1 * (
            v.e0_x_V_tr1_c1 - v.e0_x_Vint_tr1_c1
        )
        + v.e0_x_V_tr1_c1 * (v.e0_f_int_tr1_c1 + v.e0_f_int_tr1_c2)
    )
    eq28 = v.e0_f_int_tr1_c2 - (
        v.e0_rho_V_tr1 * v.e0_beta_V_tr1 * (
            v.e0_x_V_tr1_c2 - v.e0_x_Vint_tr1_c2
        )
        + v.e0_x_V_tr1_c2 * (v.e0_f_int_tr1_c1 + v.e0_f_int_tr1_c2)
    )

    eq29 = 1 - (v.e0_x_L_tr1_c1 + v.e0_x_L_tr1_c2)
    eq30 = 1 - (v.e0_x_Lint_tr1_c1 + v.e0_x_Lint_tr1_c2)
    eq31 = 1 - (v.e0_x_V_tr1_c1 + v.e0_x_V_tr1_c2)
    eq32 = 1 - (v.e0_x_Vint_tr1_c1 + v.e0_x_Vint_tr1_c2)

    return (eq1, eq2, eq3, eq4, eq5, eq6, eq7, eq8, eq9, eq10,
            eq11, eq12, eq13, eq14, eq15, eq16, eq17, eq18, eq19, eq20,
            eq21, eq22, eq23, eq24, eq25, eq26, eq27, eq28, eq29, eq30,
            eq31, eq32)


def regression_test(x0: np.ndarray) -&gt; None:
    y = equations(x0)
    assert np.allclose(
        y,
        [ 0.00000000e+00, -7.38500000e+02,  9.99992950e-01,  6.44709509e+03,
         -2.25156291e+01,  7.93463011e-01, -1.25300000e+00,  9.99991750e-01,
          5.45609068e+03, -6.75527448e+00,  8.00909148e-01,  9.60890608e-01,
          9.50476815e-01,  0.00000000e+00, -5.59990020e+04, -5.99899800e+03,
         -5.02000000e-01, -5.02000000e-01,  3.82000000e-01,  4.22000000e-01,
          0.00000000e+00,  0.00000000e+00,  1.28931902e+04,  1.09111814e+04,
          0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,
          0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,
          ],
        rtol=0, atol=1e-4,
    )

    rand = default_rng(seed=0)
    x = rand.uniform(low=0, high=2, size=32)
    y = equations(x)
    assert np.allclose(
        y,
        [-8.89664807e-02, -2.59056243e+03,  6.71477620e-02,  2.27496385e+04,
         -8.97636119e+00, -3.16304973e-01, -1.26737482e+00,  3.51297461e-01,
          7.17475798e+03, -1.06230892e+00,  1.80356351e+00, -1.59115277e+28,
         -3.04937193e+26, -6.69625188e-01, -5.59998961e+04, -5.99749540e+03,
          1.10987295e+00,  1.41775827e+00,  1.83947353e+00,  5.57239541e-03,
         -7.24077112e-01, -6.89518259e-01,  1.75063897e+04,  1.47800191e+04,
         -3.05993271e+00, -1.36098936e+00, -2.85999752e+00,  2.56167351e+00,
         -2.50185196e+00, -1.16611391e+00, -3.97888172e-01, -1.15473631e+00,
         ],
        rtol=1e-8, atol=0,
    )


def make_x0() -&gt; np.ndarray:
    x0 = np.ones(32)
    x0[[1,4,9,10,20,22,30,31]] = 0.5
    x0[[26,28,29]] = 370
    return x0


def solve(x0: np.ndarray) -&gt; Vars:
    upper_bounds = np.full(shape=32, fill_value=np.inf)
    upper_bounds[[1,4,9,10,20,22,30,31]] = 1

    bottom_bounds = np.zeros(32)
    bottom_bounds[[26,28,29]] = 340

    res = least_squares(
        fun=equations, x0=x0,
        bounds=(bottom_bounds, upper_bounds),  # not supported in lm
        method=&#39;trf&#39;,
        ftol=1e-10, xtol=1e-10, gtol=1e-10,
    )
    assert res.success
    return Vars(*res.x)


def dump(x: Vars) -&gt; None:
    pprint(x._asdict())


def main() -&gt; None:
    x0 = make_x0()
    regression_test(x0)
    x = solve(x0)
    dump(x)


if __name__ == &#39;__main__&#39;:
    main()
{&#39;e0_D_L_tr1&#39;: 0.9984442691049119,
&#39;e0_D_V_tr1&#39;: 0.9986041251126907,
&#39;e0_F_L_tr1&#39;: 128.59184097299763,
&#39;e0_F_V_tr1&#39;: 194.05957359631154,
&#39;e0_K_tr1_c1&#39;: 0.9994676910341592,
&#39;e0_K_tr1_c2&#39;: 0.999729237718534,
&#39;e0_T_L_tr1&#39;: 340.0,
&#39;e0_T_V_tr1&#39;: 559.936902192616,
&#39;e0_T_int_tr1&#39;: 369.2496832286959,
&#39;e0_alpha_L_tr1&#39;: 7.5810026415896,
&#39;e0_alpha_V_tr1&#39;: 30.124493018891847,
&#39;e0_beta_L_tr1&#39;: 0.0,
&#39;e0_beta_V_tr1&#39;: 1.2479650000565898,
&#39;e0_cp_L_tr1&#39;: 5.468269302698259,
&#39;e0_cp_V_tr1&#39;: 1.0196495285046383,
&#39;e0_e_int_tr1&#39;: 1856.5186325404206,
&#39;e0_f_int_tr1_c1&#39;: 0.11670635205679133,
&#39;e0_f_int_tr1_c2&#39;: 0.39727951871442857,
&#39;e0_h_L_tr1&#39;: 190.08447743399068,
&#39;e0_h_V_tr1&#39;: 22.650731758245296,
&#39;e0_lambda_L_tr1&#39;: 1.0083185179925418,
&#39;e0_lambda_V_tr1&#39;: 1.0368032854477796,
&#39;e0_rho_L_tr1&#39;: 1.0430730156966466,
&#39;e0_rho_V_tr1&#39;: 0.9986707757704435,
&#39;e0_x_L_tr1_c1&#39;: 0.0,
&#39;e0_x_L_tr1_c2&#39;: 0.0,
&#39;e0_x_Lint_tr1_c1&#39;: 0.5001045740608061,
&#39;e0_x_Lint_tr1_c2&#39;: 0.49992448934879186,
&#39;e0_x_V_tr1_c1&#39;: 1.4663484981775705e-16,
&#39;e0_x_V_tr1_c2&#39;: 0.00041819098423356144,
&#39;e0_x_Vint_tr1_c1&#39;: 0.4998465855173379,
&#39;e0_x_Vint_tr1_c2&#39;: 0.4995202978525341}

huangapple
  • 本文由 发表于 2023年7月27日 21:44:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76780385.html
匿名

发表评论

匿名网友

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

确定