如何使用NLsolve解决“仅一维方程”

时间:2018-08-22 04:18:10

标签: julia

以下没事,

function f!(F,x)
    F[1]=x[1]^3+8
    F[2]=x[2]^2 -8
end

nlsolve(f!, [1.,2])

但是,以下是不好的:

function f!(F,x)
    F[1]=x[1]^3+8
end

nlsolve(f!, [1.])

2 个答案:

答案 0 :(得分:1)

It's fine, but Roots.jl is probably better suited for this kind of equation. Its methods are directly for 1-dimensional rootfinding problems and can be more robust.

答案 1 :(得分:1)

这不是1D问题。问题出在您的函数的Jacobian问题上。

以下是2D中的示例:

    julia> function f!(F,x)
               F[1]=x[1]^3+8
               F[2]=x[2]^3-2
           end
    f! (generic function with 1 method)

    julia> nlsolve(f!, [0.,0.])
    Results of Nonlinear Solver Algorithm
     * Algorithm: Trust-region with dogleg and autoscaling
     * Starting Point: [0.0, 0.0]
     * Zero: [NaN, NaN]
     * Inf-norm of residuals: 8.000000
     * Iterations: 1000
     * Convergence: false
       * |x - x'| < 0.0e+00: false
       * |f(x)| < 1.0e-08: false
     * Function Calls (f): 1001
     * Jacobian Calls (df/dx): 2

现在,让我们回到您的功能上。如果您是从[1.0]开始的,那么您会很不幸,并且nlsolve的根查找过程正好以其默认参数命中[0.0],那么您会遇到一个问题,那就是Jacobian是[0.0]。 / p>

您可以通过运行以下内容来查看它:

julia> function f!(F,x)
           F[1]=x[1]^3+8
       end
f! (generic function with 1 method)

julia> nlsolve(f!, [1.], show_trace=true, extended_trace=true, iterations=3);
Iter     f(x) inf-norm    Step 2-norm
------   --------------   --------------
     0     9.000000e+00              NaN
 * f(x): [9.0]
 * g(x): [3.0]
 * x: [1.0]
 * delta: NaN
 * rho: NaN
     1     8.000000e+00     1.000000e+00
 * f(x): [8.0]
 * g(x): [0.0]
 * x: [0.0]
 * delta: 2.9999999999239875
 * rho: 0.3777777777854353
     2              NaN              NaN
 * f(x): [NaN]
 * g(x): [0.0]
 * x: [NaN]
 * delta: 2.9999999999239875
 * rho: NaN
     3              NaN              NaN
 * f(x): [NaN]
 * g(x): [0.0]
 * x: [NaN]
 * delta: 2.9999999999239875
 * rho: NaN

您可以通过更改起点或更改factor来解决此问题:

julia> nlsolve(f!, [10.])
Results of Nonlinear Solver Algorithm
 * Algorithm: Trust-region with dogleg and autoscaling
 * Starting Point: [10.0]
 * Zero: [-2.0]
 * Inf-norm of residuals: 0.000000
 * Iterations: 18
 * Convergence: true
   * |x - x'| < 0.0e+00: false
   * |f(x)| < 1.0e-08: true
 * Function Calls (f): 17
 * Jacobian Calls (df/dx): 11

julia> nlsolve(f!, [1.], factor=0.5)
Results of Nonlinear Solver Algorithm
 * Algorithm: Trust-region with dogleg and autoscaling
 * Starting Point: [1.0]
 * Zero: [-2.0]
 * Inf-norm of residuals: 0.000000
 * Iterations: 7
 * Convergence: true
   * |x - x'| < 0.0e+00: false
   * |f(x)| < 1.0e-08: true
 * Function Calls (f): 8
 * Jacobian Calls (df/dx): 8

而且-正如克里斯建议的那样-Roots.jl的方法更健壮,因为其中包含无导数的方法。