Generated reference › Nelder Mead Search — Control Systems/Optimization
kind: generated#block#control-systems-optimization

Nelder Mead Search — Control Systems/Optimization

min f

Control_Systems/Optimization/Nelder_Mead_Search · 1 input / 3 output port(s) at insert · exports to Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text

Description#

The block's own DESCRIPTION_HTML, rendered verbatim — the same text the config dialog's info panel and the library navigator show. Fix a wrong sentence in the block's .cpp (R-D9), never here.

Nelder-Mead Search

Control Systems / Optimization

Finds the x that minimizes a multivariate polynomial whose coefficients arrive on a port – MATLAB's fminsearch, the Nelder-Mead simplex, solved again on every sample:

f(x) = Σt ct · x1e(t,1) · … · xne(t,n)

The exponents e are configuration – they are the polynomial's shape, and shape fixes the loop bounds every export unrolls. The coefficients c are the signal, one per term, so the surface being minimized can change on every sample while its form does not.

The factory setting is Rosenbrock's function, expanded: 100(x₂−x₁²)² + (1−x₁)² is the six terms [0 2; 2 1; 4 0; 0 0; 1 0; 2 0] against coefficients [100; −200; 100; 1; −2; 1] from [−1.2; 1] – fminsearch's own documented example, so the block out of the library is a worked one.

Ports

  • c – the term coefficients, a column [T,1] with one entry per ROW of Term Exponents, in the same order. A row vector is refused, because the block reads the column entry by entry.
  • x – the minimizer, [n,1], one entry per variable (n = the columns of Term Exponents).
  • f(x) – the value there, a scalar [1,1].
  • exitflag – a scalar [1,1]: 1 when the simplex met both tolerances, 0 when a limit below stopped the search first. fminsearch's own two flags.

Parameters

  • Options – empty (default), or the path of a Solver Options block (Home/Solver Options), MATLAB’s options argument: for the run, every option it sets replaces this block’s parameter of the same name; one it leaves at default, or one this block does not have, changes nothing.
  • Term Exponents – a [T,n] matrix of whole numbers from 0 to 6: row t, column i is the power of xi in term t. T is 1 to 12 terms, n is 1 to 4 variables, and no single term may total more than degree 6. Those three caps are the export's, not the search's – see Code export.
  • Start Point – x0, fminsearch's second argument, a vector of n entries. The search is LOCAL: it descends into the valley it starts in, so on a surface with several minima this parameter chooses which one is reported.
  • X Tolerance – optimset's TolX, positive; default 1e-4. The simplex must be this narrow in every coordinate.
  • Function Tolerance – TolFun, positive; default 1e-4. The values at the vertices must be this close as well: fminsearch requires both, never either.
  • Maximum Iterations – MaxIter, 1 to 2000, default 400 – which is MATLAB's own 200·n at the factory n of 2.
  • Maximum Function Evaluations – MaxFunEvals, same range and default. Whichever limit binds first stops the search and the exit flag is 0.
  • Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.

Code export

All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text, printed from one description of the iteration, so every target does the same arithmetic in the same order as the simulation.

The exponent pattern is unrolled: a power becomes repeated multiplication, because no target can take a loop bound out of a real array. One evaluation is therefore about T·(2 + degree) statements and the body holds seven copies of it, which is why T, n and the degree are capped where they are – Java refuses a method over 64 KB. The main loop is emitted with a fixed trip count (Maximum Iterations) and a flag that stops the arithmetic once the answer is found, because none of the ten has an unbounded loop a hardware target could also carry.

⚠ The three HDL targets run the search in simulation-only real arithmetic, quantizing only at the port boundaries: a simplex step divides and compares across many orders of magnitude, which a Q16.16 datapath does not carry.

Simulink bridge

None (Support::None). The Optimization Toolbox ships no Simulink library at all and fminsearch is a MATLAB function, so there is no block to map onto; the bridge reports this block rather than dropping it silently, and it has no parity testbench. Code export verification still covers it across all ten languages.

Notes

  • Stateless: the search restarts from Start Point on every sample, so the answer depends only on the coefficients present at that step, exactly as its two scalar neighbours do.
  • ⚠ Derivative-free and LOCAL. Nelder-Mead does not use a gradient and does not certify a minimum: it reports the best vertex of a simplex that stopped moving. On a non-convex surface a different Start Point gives a different answer, and that is the method, not a defect.
  • ⚠ The 10·eps(·) floor MATLAB puts under each tolerance is 10·2−53·|z| here, a lower bound on the true spacing of doubles: no target but MATLAB has eps. Measured identical over 600 solves at tolerances from 1e-4 to 1e-12.
  • A search that runs out of iterations still answers: x is the best vertex reached and exitflag is 0. Every port carries a number on every sample, which a block must do and fminsearch need not.

Code facts#

FactValue
registered typeControl_Systems/Optimization/Nelder_Mead_Search
familyControl_Systems/Optimization
solver environment classICoreBlock_0_Control_Systems_1_Optimization_2_Nelder_Mead_Search
sourcesrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Optimization/Nelder_Mead_Search/ICoreBlock_0_Control_Systems_1_Optimization_2_Nelder_Mead_Search.cpp
headersrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Optimization/Nelder_Mead_Search/ICoreBlock_0_Control_Systems_1_Optimization_2_Nelder_Mead_Search.h
default size on canvas170 × 90 px
ports at insert1 in, 3 out
code generators implementedPython, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text

Ports#

#DirectionSignal typeDescription label
1inICoreDoublec
2outICoreDoublex
3outICoreDoublef(x)
4outICoreDoubleexitflag

Ports the constructor creates. A block whose port list changes with its configuration adds or removes ports at load time; the count above is the one a freshly inserted block has.

Configuration variables#

Config variableDefaultSimulink parameter
Term Exponents[0 2; 2 1; 4 0; 0 0; 1 0; 2 0]—
Start Point[-1.2; 1]—
X Tolerance1e-4—
Function Tolerance1e-4—
Maximum Iterations400—
Maximum Function Evaluations400—
Options——

Every block also carries Sampling Time (s) from ICoreBlockSolverEnvironment: zero or less inherits the solver's rate, a positive value runs the block at that period.

supportSupport::None
Simulink path—
port-count rulePortsParam::None
SampleTime parameteryes

Caveat (shown to the user): the Optimization Toolbox ships no Simulink library at all, so there is no block to map onto and no library path a diagram could name; fminsearch is a MATLAB function. The block is reported rather than dropped when a model crosses

Catalog contract: src/ICoreBlocks/ICoreCoder/ICoreCommandSystem/SimulinkBridge/ICoreSimulinkBlockCatalog.h

Description vs code#

The checker has a blind spot here — it could not resolve something (a grouped port bullet, a computed config name), which is reported and never counted as a pass. A reader has to settle it:

  • B0 every stimulus in the sample errored — cross-checks skipped

The verdict above is tools/docs/check_block_descriptions.py (P7.1), which compares LISTS. It cannot read a sentence: "stateless" on a block with a state, an initial-value semantic the recursion does not implement, a "not synthesizable" caveat the HDL banner contradicts. That is the agent audit (P7.3) on BLOCK_DESCRIPTION_AUDIT.md, and this tool's green is not a substitute for one.

File banner (developer view)#

The top comment of the block's .cpp — the maths, the realization and the export strategy, addressed to whoever changes it. It must not contradict the description above (P7.5).

Nelder-Mead Search -- fminsearch over a multivariate polynomial whose coefficients are a wire f(x) = sum over terms of c(t) * x1^e(t,1) * ... * xn^e(t,n) c is the input signal [x, fval, exitflag] = fminsearch(f, x0)

THE OBJECTIVE SEAM, which is the whole design question this block had to answer. A solver needs a FUNCTION and a wire carries NUMBERS, and this tree has already answered it once: Scalar Root Find and Scalar Bounded Minimization take a polynomial's coefficient column on a port, the shape Polynomial Fit emits. One dimension up, a polynomial needs one thing more than its coefficients -- its EXPONENT PATTERN -- and that is structure, not data, so it is configuration exactly like every loop bound in this tree. The coefficients stay a signal. Nothing else about the objective is free: this block minimizes polynomials, and says so.

⚠ WHAT WAS MEASURED BEFORE ANY OF IT WAS WRITTEN, and why the seam is not an open question:

  • The tree DOES accept a block that publishes a value and reads the answer back a tick later

-- Algebraic Constraint's loop. A probe diagram (Algebraic Constraint, Cos, Subtract) runs clean, one relaxation per sample. So a "call the diagram as the objective" block is buildable. It is also a NEW CONTRACT for solver blocks -- one objective evaluation per sample, 159 of them for Rosenbrock from [-1.2 1], so 159 samples for one answer -- and it would govern fminunc, fmincon, fsolve and lsqnonlin after it. That is an owner's decision.

  • The tree has already MADE the other decision and landed it. Control_Systems/Optimization

exists, with two solvers whose objective is a polynomial on a port. This block is the third and follows it rather than inventing a second seam beside it.

THE ITERATION IS fminsearch.m's, TRANSCRIBED. Initial simplex by L. Pfeffer's rule (5 % of each non-zero start coordinate, 0.00025 for a zero one), rho = 1, chi = 2, psi = 0.5, sigma = 0.5, and the AND-form stopping test -- both the function spread and the vertex spread, never OR.

⚠ MEASURED AGAINST R2026a: over 200 random objectives (1 to 4 variables, 2 to 8 terms, random exponents 0..3, random coefficients and start points, one in five with a zero start coordinate) a prototype written in the loops this block emits reproduces fminsearch's x, fval, exit flag, ITERATION COUNT and EVALUATION COUNT bit for bit -- 200 of 200, worst |dx| exactly 0. Repeated at TolX = TolFun = 1e-4, 1e-9 and 1e-12: 600 of 600.

⚠ eps() HAS NO SPELLING IN TEN TARGETS. MATLAB's test floors each tolerance with 10*eps(z), the spacing of doubles at z. The block uses 10 * 2^-53 * |z|, which is a LOWER bound on it (the spacing lies in (|z|*2^-53, |z|*2^-52]), so the test is never looser than MATLAB's. It is also never different in practice: the floor only binds above |z| ~ 4.5e11 at the default 1e-4, and the 600 solves above -- three tolerances down to 1e-12 -- are bit-identical with it in place.

Sample results#

No stimulus produced a sampled output in this rig — Invalid input size at: ICore Blocks/Home/Nelder Mead Search. That is a fact about the single-block rig, not a verdict on the block: an offline batch fit, a block whose output only appears at onSolverFinish, or one that needs a driven environment cannot be exercised alone.

Category unsampled · sample time 0.1 · 60 steps · commit 351dc4dde · produced by docsSample --out <folder> --blocks Control_Systems/Vibration/Modal_Parameter_Fit,Control_Systems/Optimization/Nelder_Mead_Search --steps 60

Sample data: docs/generated/samples/Control_Systems__Optimization__Nelder_Mead_Search.json