From e6729fefff0a55bcfd23488128a673582f8b05d9 Mon Sep 17 00:00:00 2001 From: franckgaga Date: Sat, 15 Nov 2025 16:12:15 -0500 Subject: [PATCH 1/4] added: `RandomOrder` and `StableRNGs` dep. This significantly improve the efficiency of `hessian!` for the economic MPC on the pendulum. --- Project.toml | 2 ++ src/ModelPredictiveControl.jl | 5 ++++- src/controller/nonlinmpc.jl | 2 ++ src/general.jl | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 53bc22750..9141af90e 100644 --- a/Project.toml +++ b/Project.toml @@ -20,6 +20,7 @@ RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" SparseConnectivityTracer = "9f842d2f-2579-4b1d-911e-f412cf18a3f5" SparseMatrixColorings = "0a514795-09f3-496d-8182-132a7b665d35" +StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3" [compat] ControlSystemsBase = "1.18.2" @@ -42,6 +43,7 @@ RecipesBase = "1" SparseArrays = "1.10" SparseConnectivityTracer = "0.6.13, 1" SparseMatrixColorings = "0.4.14" +StableRNGs = "1.0.4" TestItemRunner = "1" TestItems = "1" julia = "1.10" diff --git a/src/ModelPredictiveControl.jl b/src/ModelPredictiveControl.jl index 8bb73005f..85e8a83f4 100644 --- a/src/ModelPredictiveControl.jl +++ b/src/ModelPredictiveControl.jl @@ -3,6 +3,7 @@ module ModelPredictiveControl using PrecompileTools using LinearAlgebra, SparseArrays using Random: randn +using StableRNGs: StableRNG using RecipesBase @@ -15,7 +16,9 @@ using DifferentiationInterface: Constant, Cache using SparseConnectivityTracer: TracerSparsityDetector using SparseMatrixColorings: GreedyColoringAlgorithm, sparsity_pattern using SparseMatrixColorings: NaturalOrder, LargestFirst, SmallestLast -using SparseMatrixColorings: IncidenceDegree, DynamicLargestFirst +using SparseMatrixColorings: IncidenceDegree, DynamicLargestFirst, RandomOrder + +using SparseMatrixColorings: ncolors import ProgressLogging diff --git a/src/controller/nonlinmpc.jl b/src/controller/nonlinmpc.jl index 31660bcb4..20df9f41b 100644 --- a/src/controller/nonlinmpc.jl +++ b/src/controller/nonlinmpc.jl @@ -662,6 +662,8 @@ function get_nonlinobj_op(mpc::NonLinMPC, optim::JuMP.GenericModel{JNT}) where J ∇²J_prep = prepare_hessian(J!, hess, Z̃_J, J_cache...; strict) ∇²J = init_diffmat(JNT, hess, ∇²J_prep, nZ̃, nZ̃) ∇²J_structure = lowertriangle_indices(init_diffstructure(∇²J)) + @show ncolors(∇²J_prep) + display(sparsity_pattern(∇²J_prep)) end update_objective! = if !isnothing(hess) function (J, ∇J, ∇²J, Z̃_J, Z̃_arg) diff --git a/src/general.jl b/src/general.jl index 4ce717392..ea814bcd6 100644 --- a/src/general.jl +++ b/src/general.jl @@ -13,6 +13,7 @@ const ALL_COLORING_ORDERS = ( SmallestLast(), IncidenceDegree(), DynamicLargestFirst(), + RandomOrder(StableRNG(0), 0) ) "Termination status that means 'no solution available'." From a93b51b0496bfa3a630459e703d21b4bd976fd88 Mon Sep 17 00:00:00 2001 From: franckgaga Date: Sat, 15 Nov 2025 16:12:51 -0500 Subject: [PATCH 2/4] bump --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 9141af90e..f7bd0ddd5 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "ModelPredictiveControl" uuid = "61f9bdb8-6ae4-484a-811f-bbf86720c31c" -version = "1.13.2" +version = "1.13.3" authors = ["Francis Gagnon"] [deps] From b7c6039ada26950473c580fc4072d1782f2e6f69 Mon Sep 17 00:00:00 2001 From: franckgaga Date: Sat, 15 Nov 2025 16:36:11 -0500 Subject: [PATCH 3/4] doc: `RandomOrder` in `NonLinMPC` and `MovingHorizonEstimator` extended help --- src/controller/nonlinmpc.jl | 11 ++++++----- src/estimator/mhe/construct.jl | 11 ++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/controller/nonlinmpc.jl b/src/controller/nonlinmpc.jl index 20df9f41b..a80b3f31e 100644 --- a/src/controller/nonlinmpc.jl +++ b/src/controller/nonlinmpc.jl @@ -293,11 +293,12 @@ NonLinMPC controller with a sample time Ts = 10.0 s: sparsity_detector = TracerSparsityDetector(), coloring_algorithm = GreedyColoringAlgorithm( ( - NaturalOrder(), - LargestFirst(), - SmallestLast(), - IncidenceDegree(), - DynamicLargestFirst() + NaturalOrder(), + LargestFirst(), + SmallestLast(), + IncidenceDegree(), + DynamicLargestFirst(), + RandomOrder(StableRNG(0), 0) ), postprocessing = true ) diff --git a/src/estimator/mhe/construct.jl b/src/estimator/mhe/construct.jl index 3f43aab6f..316529c3e 100644 --- a/src/estimator/mhe/construct.jl +++ b/src/estimator/mhe/construct.jl @@ -384,11 +384,12 @@ MovingHorizonEstimator estimator with a sample time Ts = 10.0 s: sparsity_detector = TracerSparsityDetector(), coloring_algorithm = GreedyColoringAlgorithm( ( - NaturalOrder(), - LargestFirst(), - SmallestLast(), - IncidenceDegree(), - DynamicLargestFirst() + NaturalOrder(), + LargestFirst(), + SmallestLast(), + IncidenceDegree(), + DynamicLargestFirst(), + RandomOrder(StableRNG(0), 0) ), postprocessing = true ) From 991107dfecf5566a661e1ffcef3fa984f13831d7 Mon Sep 17 00:00:00 2001 From: franckgaga Date: Sat, 15 Nov 2025 17:32:13 -0500 Subject: [PATCH 4/4] removed: useless prints --- src/ModelPredictiveControl.jl | 2 -- src/controller/nonlinmpc.jl | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/ModelPredictiveControl.jl b/src/ModelPredictiveControl.jl index 85e8a83f4..efa05e3d9 100644 --- a/src/ModelPredictiveControl.jl +++ b/src/ModelPredictiveControl.jl @@ -18,8 +18,6 @@ using SparseMatrixColorings: GreedyColoringAlgorithm, sparsity_pattern using SparseMatrixColorings: NaturalOrder, LargestFirst, SmallestLast using SparseMatrixColorings: IncidenceDegree, DynamicLargestFirst, RandomOrder -using SparseMatrixColorings: ncolors - import ProgressLogging import ForwardDiff diff --git a/src/controller/nonlinmpc.jl b/src/controller/nonlinmpc.jl index a80b3f31e..3a42e8b15 100644 --- a/src/controller/nonlinmpc.jl +++ b/src/controller/nonlinmpc.jl @@ -663,8 +663,6 @@ function get_nonlinobj_op(mpc::NonLinMPC, optim::JuMP.GenericModel{JNT}) where J ∇²J_prep = prepare_hessian(J!, hess, Z̃_J, J_cache...; strict) ∇²J = init_diffmat(JNT, hess, ∇²J_prep, nZ̃, nZ̃) ∇²J_structure = lowertriangle_indices(init_diffstructure(∇²J)) - @show ncolors(∇²J_prep) - display(sparsity_pattern(∇²J_prep)) end update_objective! = if !isnothing(hess) function (J, ∇J, ∇²J, Z̃_J, Z̃_arg)