【问题标题】:Ax=b with b dependent on xAx=b 其中 b 取决于 x
【发布时间】:2017-02-09 20:13:59
【问题描述】:

我知道如何解决 Ax=b,但是如果 b 依赖于 x 怎么办?参见图片 E3 = 函数(E4)。我想这是迭代完成的..这样的问题叫什么?我用什么方法来解决?

我正在尝试解决以下系统:

给出以下方程组:

导致以下矩阵:

更新: 根据要求提供更多信息:

A = ([
[-1, 0, 0, 0, 0],
[1, -1, -1, 0, 0],
[0, 1, 0, -1, 0],
[0, 0, 1, 1, -1],
[0, 0, 1, 0, 0]
])

b = [-10, 0, 1, 1, 3]

print(np.linalg.solve(A, b))

-> [ 10.   7.   3.   6.   8.]

这可行,但如果:

b = [-10, 0, 1, 1, some_function(x[3])]

所以 E3 = some_function(E4),因此 E3 依赖于 E4,由 'some_function' 定义(非线性)

【问题讨论】:

  • 您的问题缺少很多信息(流程图中的箭头是什么意思?什么是f?)。你能以 numpy 数组的形式给出一些示例输入吗?在我看来,它不像线性系统 (Ax = b)。
  • @ali_m 我更新了问题,希望它说清楚
  • 我猜它不是一个线性系统,所以它叫什么。我不是想得到解决方案,我想了解它是什么样的问题
  • some_function 是一个控制器,将 E3 设置为 0 或设置为取决于 E4 的值的设定值
  • 您应该通过提供some_function 的定义将您的代码转换为complete, verifiable example。另外,为什么您的问题同时标记为matlabnumpy

标签: matlab numpy linear-algebra solver


【解决方案1】:

是的,您可以通过非线性优化来解决这个问题。 scipy.optimize 包含所有有趣的细节,但这里有一个示例可以解决您的系统问题,假设 some_function(x)x ** 2

import numpy as np
import scipy.optimize as opt

A = np.array([
    [-1, 0, 0, 0, 0],
    [1, -1, -1, 0, 0],
    [0, 1, 0, -1, 0],
    [0, 0, 1, 1, -1],
    [0, 0, 1, 0, 0.0]
    ])
b = np.array([-10, 0, 1, 1, 3.0]) # last value is fake

def objectiveFunction(x):
    bNew = b.copy()
    bNew[-1] = x[3] ** 2 # "some_function = lambda x: x**2"
    error = np.dot(A, x) - bNew
    return np.dot(error, error)

solution = opt.minimize(objectiveFunction, np.zeros((5)))

print(solution)

所有优化技术基本上都是函数最小化。你优化器

  1. 一个最小化函数(它接受一个向量输入参数并返回一个标量数)和
  2. 关于哪个输入向量产生最小标量的初始猜测。

优化器将输入返回到产生最小输出的那个函数。

上面的objectiveFunction 函数正在被最小化,它返回A . x - b 之间的错误,其中x 是一个候选解决方案,而b 具有依赖于x 的形式。

您可能会陷入局部最小值,因此使用优化方法有点像魔法。但是这个例子看起来很简单:上面的代码打印出以下内容:

      fun: 1.3591186209050682e-11
 hess_inv: array([[ 0.49698215,  0.08279412,  0.40828859,  0.08067816,  0.47743665],
       [ 0.08279412,  0.39205925, -0.22445874, -0.02791535, -0.26595691],
       [ 0.40828859, -0.22445874,  1.01438679,  0.18492456,  1.19990433],
       [ 0.08067816, -0.02791535,  0.18492456,  0.05283296,  0.23785942],
       [ 0.47743665, -0.26595691,  1.19990433,  0.23785942,  1.94819504]])
      jac: array([ -5.37158676e-06,   4.82585577e-06,   7.97108114e-06,
        -6.31780565e-06,   4.76041890e-07])
  message: 'Optimization terminated successfully.'
     nfev: 105
      nit: 13
     njev: 15
   status: 0
  success: True
        x: array([ 10.00000068,   3.54138098,   6.45862309,   2.54138196,   8.00000528])

这是很多信息,但重要的是xfun 值:注意x 是一个向量,fun 是一个标量。这意味着objectiveFunction(solution.x) == solution.fun。这反过来意味着您正在寻找的答案b(假设我假设some_function)是solution.x,您可以确信这是正确的,因为solution.funA . x 和@987654342 之间的错误@) 接近于零。

我跳过了一堆解释,但如果您需要,我可以详细说明。

【讨论】:

  • 感谢 Ahmed Fasih,所以这基本上是线性系统的迭代器?
  • @Gilbert 对不起,我说错了:是的,它在软件术语和数学术语中都是“迭代器”,但将其视为“朝向”某个线性化系统的迭代是不正确的。它迭代到均方误差函数的(局部)最小值。这有意义吗?
【解决方案2】:

如果您的b(x)x 的某个非线性函数,那么在左侧有A*x 并不重要。方程的最简单表达方式是A*x - b(x)=0,换句话说F(x) = 0,一般非线性方程。在尝试解决这个问题之前,请注意一些令人讨厌的后果:

  • 一般来说,你不能说任何关于解决方案的分布。有吗?没有更详细的分析是不可能的。也许有几个,或者无限多?对于线性方程组 (A*x = b),所有信息都在矩阵中,但对于非线性方程组则不然。

  • 由于非线性求解器无法对解的结构做出假设,因此无法保证求解器收敛。事实上,所有非深奥的求解器都只是局部的,即,您提供一个“接近”解决方案的初始猜测,求解器会将这个猜测收敛到它。为了保证收敛,您必须在开始之前对解决方案有一个很好的了解。在实践中,很多人只是随机猜测,然后让本地求解器执行一些步骤,保持手指交叉。

  • 可以说,最流行的局部求解器是牛顿法;它是唯一实现二次收敛的求解器(如果您已经接近解决方案)。在每一步中,都需要求解一个雅可比线性方程组,即J*d = -F(x)。如果您不小心操作,仅此一项就会非常昂贵。

现在您已经了解了所有这些,您可以使用scipy optimize

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-15
    • 2017-12-19
    • 2022-04-11
    • 1970-01-01
    • 2014-04-05
    • 2015-07-18
    相关资源
    最近更新 更多