Modified Inertial Spectral Three-Term Derivative-Free Projection Method for solving nonlinear equations with convex constraints.
Problem: Find x in C such that F(x) = 0, where C is a closed convex subset of R^n and F: R^n -> R^n is continuous and monotone.
The method combines inertial extrapolation, a spectral three-term conjugate-gradient-type search direction (adapted from Amini-Faramarzi), a unified Armijo-type line search framework (7 variants from Ibrahim, Alshahrani & Al-Homidan, JOTA 2026), and feasible inexact projection via the Frank-Wolfe (conditional gradient) method.
- Julia 1.12+ (developed on 1.12.4)
- All dependencies are declared in
Project.toml/Manifest.toml
cd jcode/
julia --project=. -e 'using Pkg; Pkg.instantiate()'This installs: LazySets, DataFrames, CSV, ProgressMeter, Plots, BenchmarkProfiles, Images, TestImages, Wavelets, XLSX, Colors, BenchmarkTools.
# From jcode/ directory
include("src/includes.jl")
# Define problem
F(x) = exp.(x) .- 1.0
C = Ball2(zeros(5), 1.0) # unit ball in R^5
# Solve with default (tuned) parameters
solver = MISTTDFPM(F, C)
x, k, converged = solve(solver; maxiter=1000, verbose=true)
# Solve with original paper parameters
solver = MISTTDFPM(F, C; preset=:paper)
x, k, converged = solve(solver)
# Reference algorithms (same solve() interface)
x, k, converged = solve(IHZIPM(F, C))
x, k, converged = solve(STTDFPM(F, C))
x, k, converged = solve(ISTTDFPM(F, C))
# Use built-in test problems
for p in safe_all_problems(1000)
s = MISTTDFPM(p.F, p.C; x0=p.x0)
x, k, conv = solve(s)
println("$(p.name): k=$k, converged=$conv")
endAll paper experiments can be reproduced from the jcode/ directory. Scripts use
modular ARGS dispatch: pass subset names to run specific parts, or no args
to run everything.
julia --project=. scripts/01_smoke_test.jlRuns all 4 algorithms on a few problems. Should complete in under a minute with all tests passing.
15 problems x 10 starting points x 9 dimensions (1,350 instances). Compares MISTTDFPM vs IHZIPM, STTDFPM, ISTTDFPM (exact & inexact).
# Full run (all 9 dimensions: 1k, 5k, 10k, 20k, 30k, 50k, 80k, 100k, 120k)
julia --project=. scripts/50_experiment1.jl
# Or run by tier
julia --project=. scripts/50_experiment1.jl small # dims [1k, 5k, 10k]
julia --project=. scripts/50_experiment1.jl mid # dims [20k, 30k, 50k]
julia --project=. scripts/50_experiment1.jl large # dims [80k, 100k, 120k]
# Generate LaTeX tables and summary (after benchmarks complete)
julia --project=. scripts/50_experiment1.jl latex summaryOutput: results/experiment1/
experiment1_raw.csv— per-instance resultsexperiment1_matrix.csv— pivot table for performance profilesexperiment1_tables.tex— LaTeX tables for the paperexp1_*.pdf— performance profile figures
DWT-based scrambled Hadamard compressed sensing with image restoration.
# Full run
julia --project=. scripts/65_compressed_sensing.jl
# Or run by part
julia --project=. scripts/65_compressed_sensing.jl partA # scaling (cameraman 64²/128²/256²)
julia --project=. scripts/65_compressed_sensing.jl partB # generality (4 images, ratio=0.3 & 0.5)
julia --project=. scripts/65_compressed_sensing.jl partC # visual comparison PNGs
julia --project=. scripts/65_compressed_sensing.jl latex summaryOutput: results/compressed_sensing/
partA_scaling_raw.csv,partB_generality_raw.csv— numerical resultscompressed_sensing_tables.tex— LaTeX tablesvisual_*.png— recovered image comparisons
These scripts were used during development to find optimal parameters. The winning
parameters are already baked into the :default preset, so re-running them is
not required for reproduction.
# OAT sensitivity analysis
julia --project=. scripts/10_sensitivity_analysis.jl
# Scale-aware LHS parameter search (3-phase)
julia --project=. scripts/20_parameter_search.jl
# CS-specific parameter search
julia --project=. scripts/25_cs_parameter_search.jl| Step | Operation |
|---|---|
| 0 | Initialize x_0 in C |
| 1 | Stop if ‖F(x_k)‖ < ε |
| 2 | Inertial: w_k = (1 - λ_k) x_k + λ_k w_{k-1} |
| 3 | Direction: d_k = -θ_k F(w_k) + β_k d_{k-1} + ξ_k p_k |
| 4 | Line search: find α_k via Armijo condition |
| 5 | Projection: x_{k+1} = P_C[w_k - ζ_k F(z_k), x_k, θ_k] |
| Algorithm | Description | Projection |
|---|---|---|
IHZIPM |
Improved HZ two-term CG direction | Inexact (Frank-Wolfe) |
STTDFPM |
Spectral three-term, no inertia | Exact (default) or inexact |
ISTTDFPM |
Inertial STTDFPM | Exact (default) or inexact |
All four share the same solve(solver; maxiter, verbose, timeout, ...) interface.
Named parameter sets for MISTTDFPM(F, C; preset=...):
| Preset | Description |
|---|---|
:default |
Best tuned parameters from LHS search (used in paper) |
:paper |
Original conservative paper parameters |
:no_inertia |
Default with inertia disabled (λ=0) |
:tuned |
Alias for :default |
:v2 |
Previous defaults (before scale-aware search) |
:scale_small |
Best for n ∈ {1k, 5k, 10k} |
:scale_large |
Best for n ∈ {75k, 100k, 120k} |
:cs |
CS / image restoration — clipped LS |
:cs_constant |
CS / image restoration — constant LS |
User kwargs always override the preset: MISTTDFPM(F, C; preset=:paper, λ=0.5).
Seven Armijo-type variants from the unified framework (JOTA 2026), selected via ls_type:
ls_type |
γ_k formula |
|---|---|
:constant |
1 |
:residual |
‖F(z_k)‖ |
:normalized |
‖F(z_k)‖ / (1 + ‖F(z_k)‖) |
:blend |
τ + (1-τ)‖F(z_k)‖ |
:capped |
min(1, ‖F(z_k)‖) |
:clipped |
clamp(‖F(z_k)‖, η₁, η₂) (default) |
:adaptive |
clipped + stabilized initial step |
Additionally, EMA history smoothing (β_smooth < 1) can be applied to any variant.
| Parameter | Default | Description |
|---|---|---|
ε |
1e-6 |
Stopping tolerance |
η |
1.419 |
Initial line search step |
ρ |
0.460 |
Line search contraction ∈ (0,1) |
σ |
0.1 |
Armijo parameter |
ls_type |
:clipped |
Line search variant |
η₁_ls |
0.085 |
Clipping lower bound |
η₂_ls |
0.881 |
Clipping upper bound |
β_smooth |
0.712 |
EMA smoothing (1.0 = off) |
λ |
0.200 |
Inertial parameter bound |
α_min |
0.740 |
Spectral parameter lower bound |
α_max |
10.0 |
Spectral parameter upper bound |
κ |
6.967 |
Parameter for μ_k |
ξ̄ |
0.393 |
Adaptive parameter bound ∈ (0,1) |
p_choice |
:F_w |
Direction p_k: :F_w, :F_w_prev, :d_prev, :y |
γ_proj |
1.782 |
Projection step scaling |
θ̄ |
0.04 |
Inexact projection bound |
See CLAUDE.md for the full parameter reference.
15 problems used in paper experiments, available via safe_all_problems(n):
| Problem | Constraint |
|---|---|
| ExponentialI | Ball, Box |
| ExponentialIII | Box |
| SmoothSine | Box |
| NonsmoothSine | Triangle |
| ModifiedNonsmoothSine (2 variants) | Triangle |
| PolynomialI | Box |
| Logarithmic | Box |
| NonsmoothLogarithmic | Box |
| ModifiedTrigI | Box |
| ARWHEAD | Ball |
| ENGVAL1 | Ball |
| PENALTY1 | Ball |
| DIXON3DQ | Ball |
Compressed sensing problems: dwt_cs_problem(...) for DWT-based image recovery.
safe_all_problems(n) # 15 problems at dimension n
all_problems(n) # all 16 (includes ModifiedTridiagonal-Triangle)
ball_problems(n) # ball-constrained subset
general_constraint_problems(n) # BallBox + BoxLinear constraints (no closed-form projection)jcode/
├── Project.toml / Manifest.toml # Julia dependencies (locked)
├── CLAUDE.md # Full development documentation
├── README.md # This file
├── src/
│ ├── includes.jl # Entry point (load order)
│ ├── deps.jl # Package dependencies
│ ├── conditionalGradient.jl # Inexact projection (Frank-Wolfe)
│ ├── direction.jl # Inertial step + spectral direction
│ ├── linesearch.jl # Armijo-type line search (7 variants)
│ ├── MISTTDFPM.jl # Our algorithm (struct, iterator, solve)
│ ├── exact_projection.jl # Exact projection (Ball2, Hyperrectangle, fallback)
│ ├── IHZIPM.jl # Reference: improved HZ CG + inexact projection
│ ├── ISTTDFPM.jl # Reference: STTDFPM + ISTTDFPM
│ ├── problems.jl # Test problems + constraint sets
│ └── benchmark.jl # Multi-solver benchmarking utilities
├── scripts/
│ ├── 01_smoke_test.jl # Quick verification of all algorithms
│ ├── 10_sensitivity_analysis.jl # OAT parameter sensitivity sweeps
│ ├── 15_cs_sensitivity.jl # CS-specific sensitivity analysis
│ ├── 20_parameter_search.jl # Scale-aware LHS parameter search
│ ├── 25_cs_parameter_search.jl # CS-specific parameter search
│ ├── 50_experiment1.jl # Experiment 1: large-scale comparison (paper)
│ ├── 55_experiment2_general.jl # Experiment 2: general constraints
│ ├── 60_traffic_application.jl # Traffic assignment application
│ ├── 65_compressed_sensing.jl # Compressed sensing image recovery (paper)
│ └── 70_convergence_history.jl # Convergence history plots
├── results/ # Script output (CSVs, PDFs, PNGs, LaTeX)
└── oldcode/ # Retired scripts and reference code
All scripts support modular ARGS dispatch. Run with no args for full execution, or pass subset names for partial runs.
| Script | Purpose | ARGS |
|---|---|---|
01_smoke_test.jl |
Verify all algorithms work | — |
10_sensitivity_analysis.jl |
OAT parameter sweeps | oat, joint, summary, plots |
15_cs_sensitivity.jl |
CS sensitivity analysis | — |
20_parameter_search.jl |
3-phase LHS search | small, mid, large, phase2, report |
25_cs_parameter_search.jl |
CS parameter search | search, report |
50_experiment1.jl |
Paper Experiment 1 | small, mid, large, latex, summary |
55_experiment2_general.jl |
General constraints | small, large, latex, summary |
60_traffic_application.jl |
Traffic assignment | — |
65_compressed_sensing.jl |
Paper CS experiment | partA, partB, partC, latex, summary |
70_convergence_history.jl |
Convergence plots | — |