在 Julia 中找到多变量函数的不动点
Find fixed point of multivariable function in Julia
我需要在 Julia 中找到多变量函数的不动点。
考虑以下最小示例:
function example(p::Array{Float64,1})
q = -p
return q
end
理想情况下,我会使用像 Roots.jl 这样的包并调用 find_zeros(p -> p - example(p))
,但我找不到用于多变量函数的类似包。我找到了一个名为 IntervalRootFinding
的工具,但奇怪的是它需要 unicode 字符并且文档很少,所以我不知道如何使用它。
有很多选择。最佳选择取决于 example
函数的性质(您必须了解 example
函数的性质并检查特定包的文档是否支持它)。
例如。您可以使用 NLsolve.jl:
中的 fixedpoint
julia> using NLsolve
julia> function example!(q, p::Array{Float64,1})
q .= -p
end
example! (generic function with 1 method)
julia> fixedpoint(example!, ones(1))
Results of Nonlinear Solver Algorithm
* Algorithm: Anderson m=1 beta=1 aa_start=1 droptol=0
* Starting Point: [1.0]
* Zero: [0.0]
* Inf-norm of residuals: 0.000000
* Iterations: 3
* Convergence: true
* |x - x'| < 0.0e+00: true
* |f(x)| < 1.0e-08: true
* Function Calls (f): 3
* Jacobian Calls (df/dx): 0
julia> fixedpoint(example!, ones(3))
Results of Nonlinear Solver Algorithm
* Algorithm: Anderson m=3 beta=1 aa_start=1 droptol=0
* Starting Point: [1.0, 1.0, 1.0]
* Zero: [-2.220446049250313e-16, -2.220446049250313e-16, -2.220446049250313e-16]
* Inf-norm of residuals: 0.000000
* Iterations: 3
* Convergence: true
* |x - x'| < 0.0e+00: false
* |f(x)| < 1.0e-08: true
* Function Calls (f): 3
* Jacobian Calls (df/dx): 0
julia> fixedpoint(example!, ones(5))
Results of Nonlinear Solver Algorithm
* Algorithm: Anderson m=5 beta=1 aa_start=1 droptol=0
* Starting Point: [1.0, 1.0, 1.0, 1.0, 1.0]
* Zero: [0.0, 0.0, 0.0, 0.0, 0.0]
* Inf-norm of residuals: 0.000000
* Iterations: 3
* Convergence: true
* |x - x'| < 0.0e+00: true
* |f(x)| < 1.0e-08: true
* Function Calls (f): 3
* Jacobian Calls (df/dx): 0
如果您的函数需要全局优化工具来找到固定点,那么您可以例如使用 BlackBoxOptim.jl 和 norm(f(x) .-x)
作为 objective:
julia> using LinearAlgebra
julia> using BlackBoxOptim
julia> function example(p::Array{Float64,1})
q = -p
return q
end
example (generic function with 1 method)
julia> f(x) = norm(example(x) .- x)
f (generic function with 1 method)
julia> bboptimize(f; SearchRange = (-5.0, 5.0), NumDimensions = 1)
Starting optimization with optimizer DiffEvoOpt{FitPopulation{Float64},RadiusLimitedSelector,BlackBoxOptim.AdaptiveDiffEvoRandBin{3},RandomBound{ContinuousRectSearchSpace}}
0.00 secs, 0 evals, 0 steps
Optimization stopped after 10001 steps and 0.15 seconds
Termination reason: Max number of steps (10000) reached
Steps per second = 68972.31
Function evals per second = 69717.14
Improvements/step = 0.35090
Total function evaluations = 10109
Best candidate found: [-8.76093e-40]
Fitness: 0.000000000
julia> bboptimize(f; SearchRange = (-5.0, 5.0), NumDimensions = 3);
Starting optimization with optimizer DiffEvoOpt{FitPopulation{Float64},RadiusLimitedSelector,BlackBoxOptim.AdaptiveDiffEvoRandBin{3},RandomBound{ContinuousRectSearchSpace}}
0.00 secs, 0 evals, 0 steps
Optimization stopped after 10001 steps and 0.02 seconds
Termination reason: Max number of steps (10000) reached
Steps per second = 625061.23
Function evals per second = 631498.72
Improvements/step = 0.32330
Total function evaluations = 10104
Best candidate found: [-3.00106e-12, -5.33545e-12, 5.39072e-13]
Fitness: 0.000000000
julia> bboptimize(f; SearchRange = (-5.0, 5.0), NumDimensions = 5);
Starting optimization with optimizer DiffEvoOpt{FitPopulation{Float64},RadiusLimitedSelector,BlackBoxOptim.AdaptiveDiffEvoRandBin{3},RandomBound{ContinuousRectSearchSpace}}
0.00 secs, 0 evals, 0 steps
Optimization stopped after 10001 steps and 0.02 seconds
Termination reason: Max number of steps (10000) reached
Steps per second = 526366.94
Function evals per second = 530945.88
Improvements/step = 0.29900
Total function evaluations = 10088
Best candidate found: [-9.23635e-8, -2.6889e-8, -2.93044e-8, -1.62639e-7, 3.99672e-8]
Fitness: 0.000000391
我是 IntervalRootFinding.jl 的作者。我很高兴地说文档最近有了很大改进,不再需要 unicode 字符。我建议使用 master 分支。
以下是如何使用包解决您的示例。请注意,此包应该能够在一个框内找到 all 个根,并保证它已找到所有根。你的只有 1:
julia> using IntervalArithmetic, IntervalRootFinding
julia> function example(p)
q = -p
return q
end
example (generic function with 2 methods)
julia> X = IntervalBox(-2..2, 2)
[-2, 2] × [-2, 2]
julia> roots(x -> example(x) - x, X, Krawczyk)
1-element Array{Root{IntervalBox{2,Float64}},1}:
Root([0, 0] × [0, 0], :unique)
有关更多信息,我建议查看 https://discourse.julialang.org/t/ann-intervalrootfinding-jl-for-finding-all-roots-of-a-multivariate-function/9515。
我需要在 Julia 中找到多变量函数的不动点。
考虑以下最小示例:
function example(p::Array{Float64,1})
q = -p
return q
end
理想情况下,我会使用像 Roots.jl 这样的包并调用 find_zeros(p -> p - example(p))
,但我找不到用于多变量函数的类似包。我找到了一个名为 IntervalRootFinding
的工具,但奇怪的是它需要 unicode 字符并且文档很少,所以我不知道如何使用它。
有很多选择。最佳选择取决于 example
函数的性质(您必须了解 example
函数的性质并检查特定包的文档是否支持它)。
例如。您可以使用 NLsolve.jl:
中的fixedpoint
julia> using NLsolve
julia> function example!(q, p::Array{Float64,1})
q .= -p
end
example! (generic function with 1 method)
julia> fixedpoint(example!, ones(1))
Results of Nonlinear Solver Algorithm
* Algorithm: Anderson m=1 beta=1 aa_start=1 droptol=0
* Starting Point: [1.0]
* Zero: [0.0]
* Inf-norm of residuals: 0.000000
* Iterations: 3
* Convergence: true
* |x - x'| < 0.0e+00: true
* |f(x)| < 1.0e-08: true
* Function Calls (f): 3
* Jacobian Calls (df/dx): 0
julia> fixedpoint(example!, ones(3))
Results of Nonlinear Solver Algorithm
* Algorithm: Anderson m=3 beta=1 aa_start=1 droptol=0
* Starting Point: [1.0, 1.0, 1.0]
* Zero: [-2.220446049250313e-16, -2.220446049250313e-16, -2.220446049250313e-16]
* Inf-norm of residuals: 0.000000
* Iterations: 3
* Convergence: true
* |x - x'| < 0.0e+00: false
* |f(x)| < 1.0e-08: true
* Function Calls (f): 3
* Jacobian Calls (df/dx): 0
julia> fixedpoint(example!, ones(5))
Results of Nonlinear Solver Algorithm
* Algorithm: Anderson m=5 beta=1 aa_start=1 droptol=0
* Starting Point: [1.0, 1.0, 1.0, 1.0, 1.0]
* Zero: [0.0, 0.0, 0.0, 0.0, 0.0]
* Inf-norm of residuals: 0.000000
* Iterations: 3
* Convergence: true
* |x - x'| < 0.0e+00: true
* |f(x)| < 1.0e-08: true
* Function Calls (f): 3
* Jacobian Calls (df/dx): 0
如果您的函数需要全局优化工具来找到固定点,那么您可以例如使用 BlackBoxOptim.jl 和 norm(f(x) .-x)
作为 objective:
julia> using LinearAlgebra
julia> using BlackBoxOptim
julia> function example(p::Array{Float64,1})
q = -p
return q
end
example (generic function with 1 method)
julia> f(x) = norm(example(x) .- x)
f (generic function with 1 method)
julia> bboptimize(f; SearchRange = (-5.0, 5.0), NumDimensions = 1)
Starting optimization with optimizer DiffEvoOpt{FitPopulation{Float64},RadiusLimitedSelector,BlackBoxOptim.AdaptiveDiffEvoRandBin{3},RandomBound{ContinuousRectSearchSpace}}
0.00 secs, 0 evals, 0 steps
Optimization stopped after 10001 steps and 0.15 seconds
Termination reason: Max number of steps (10000) reached
Steps per second = 68972.31
Function evals per second = 69717.14
Improvements/step = 0.35090
Total function evaluations = 10109
Best candidate found: [-8.76093e-40]
Fitness: 0.000000000
julia> bboptimize(f; SearchRange = (-5.0, 5.0), NumDimensions = 3);
Starting optimization with optimizer DiffEvoOpt{FitPopulation{Float64},RadiusLimitedSelector,BlackBoxOptim.AdaptiveDiffEvoRandBin{3},RandomBound{ContinuousRectSearchSpace}}
0.00 secs, 0 evals, 0 steps
Optimization stopped after 10001 steps and 0.02 seconds
Termination reason: Max number of steps (10000) reached
Steps per second = 625061.23
Function evals per second = 631498.72
Improvements/step = 0.32330
Total function evaluations = 10104
Best candidate found: [-3.00106e-12, -5.33545e-12, 5.39072e-13]
Fitness: 0.000000000
julia> bboptimize(f; SearchRange = (-5.0, 5.0), NumDimensions = 5);
Starting optimization with optimizer DiffEvoOpt{FitPopulation{Float64},RadiusLimitedSelector,BlackBoxOptim.AdaptiveDiffEvoRandBin{3},RandomBound{ContinuousRectSearchSpace}}
0.00 secs, 0 evals, 0 steps
Optimization stopped after 10001 steps and 0.02 seconds
Termination reason: Max number of steps (10000) reached
Steps per second = 526366.94
Function evals per second = 530945.88
Improvements/step = 0.29900
Total function evaluations = 10088
Best candidate found: [-9.23635e-8, -2.6889e-8, -2.93044e-8, -1.62639e-7, 3.99672e-8]
Fitness: 0.000000391
我是 IntervalRootFinding.jl 的作者。我很高兴地说文档最近有了很大改进,不再需要 unicode 字符。我建议使用 master 分支。
以下是如何使用包解决您的示例。请注意,此包应该能够在一个框内找到 all 个根,并保证它已找到所有根。你的只有 1:
julia> using IntervalArithmetic, IntervalRootFinding
julia> function example(p)
q = -p
return q
end
example (generic function with 2 methods)
julia> X = IntervalBox(-2..2, 2)
[-2, 2] × [-2, 2]
julia> roots(x -> example(x) - x, X, Krawczyk)
1-element Array{Root{IntervalBox{2,Float64}},1}:
Root([0, 0] × [0, 0], :unique)
有关更多信息,我建议查看 https://discourse.julialang.org/t/ann-intervalrootfinding-jl-for-finding-all-roots-of-a-multivariate-function/9515。