Generated reference › Evaluate Fit — Control Systems/Curve Fitting
kind: generated#block#control-systems-curve-fitting

Evaluate Fit — Control Systems/Curve Fitting

y(x)

Control_Systems/Curve_Fitting/Evaluate_Fit · 2 input / 1 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.

Evaluate Fit

Control Systems / Curve Fitting

Evaluates a polynomial whose coefficients arrive on a port: y = c₀·xL−1 + c₁·xL−2 + … + cL−1, entry by entry over x, with the coefficients in descending powers. This is MATLAB's polyval with the first argument taken from a signal.

It is the reading half of Curve Fitting: wire Polynomial Fit into c to read a fit that is recomputed every sample, or put Fit Derivative or Fit Integral in between to read the slope or the area instead.

Ports

  • c – the coefficients, descending powers, as a vector of L entries: a column [L,1] or a row [1,L]. A scalar is a constant polynomial, and the output is then that constant everywhere.
  • x – where to read the curve. Any size [m,n], applied entry by entry, so one block can read the same curve at several points at once.
  • y – the value, of the same size as x. The block never reshapes a signal; the coefficient port does not affect the output's size.

Parameters

  • 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. There is nothing to tune, so nothing is exposed as a parameter on the generated core – the coefficients are a signal, not a setting.

Every target evaluates by Horner's rule – the nested form ((c₀x + c₁)x + c₂)x + c₃ – and not by summing powers. The two are not the same computation in floating point, so this is what keeps the ten targets agreeing with each other and with this block's own simulation.

The three HDL targets are simulation-only. Horner needs nothing but multiplies and adds, which the Q16.16 datapath has, but a polynomial multiplies the signal by itself once per order and that format saturates at ±32768 while resolving only 1.5×10⁻⁵ – and here the coefficients are a signal, so their magnitude is not known at export time and no scaling can be folded in to compensate. The generated cores convert at the port boundary and evaluate in real arithmetic: correct in simulation, but not offered as synthesizable. Base Blocks / Polynomial makes the same call for the first of those two reasons.

Simulink bridge

None (Support::None). Simulink's own Polynomial block takes its coefficients as a dialog parameter, so it cannot represent this block – a mapping onto it would silently drop the port that makes this block different. polyval itself is a MATLAB function with no library path a diagram could name, and the Curve Fitting Toolbox ships no Simulink library at all. The bridge reports this block rather than dropping it silently, and it therefore has no parity testbench; code export verification still covers it across all ten languages. For a diagram that must cross with constant coefficients, use Base Blocks / Polynomial, which is bridged.

Notes

  • Algebraic, with no state: the output depends only on the current inputs.
  • Use Base Blocks / Polynomial instead whenever the curve is fixed. That block inlines its coefficients, costs less in every target, and is bridged to Simulink. This one exists for a curve that changes every sample, which is the one thing a dialog parameter cannot hold.
  • Reading outside the window is allowed and is not checked. Polynomial Fit writes its curve on x = −i·h with the newest sample at x = 0, so a negative x reads back into the window and a positive x extrapolates past its end – one-step prediction is exactly x = +h. Extrapolation is a legitimate use and also where a high-degree fit goes wrong fastest: the error grows like xL−1.
  • Horner's rule, in all ten targets. Not an optimization – it is what keeps the ten exports agreeing with each other and with this block.
  • No state space. The relation is linear in the coefficients but polynomial in x, so the block carries none and model reduction correctly reports it as unmergeable. Fabricating a feed-through would let a reduction replace a curve with a straight line.

Code facts#

FactValue
registered typeControl_Systems/Curve_Fitting/Evaluate_Fit
familyControl_Systems/Curve_Fitting
solver environment classICoreBlock_0_Control_Systems_1_Curve_Fitting_2_Evaluate_Fit
sourcesrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Curve_Fitting/Evaluate_Fit/ICoreBlock_0_Control_Systems_1_Curve_Fitting_2_Evaluate_Fit.cpp
headersrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Curve_Fitting/Evaluate_Fit/ICoreBlock_0_Control_Systems_1_Curve_Fitting_2_Evaluate_Fit.h
default size on canvas110 × 76 px
ports at insert2 in, 1 out
code generators implementedPython, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text

Ports#

#DirectionSignal typeDescription label
1inICoreDoublec
2inICoreDoublex
3outICoreDoubley

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#

No config variable beyond the Sampling Time (s) every block carries.

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): Simulink's Polynomial block takes its coefficients as a DIALOG PARAMETER, so it cannot represent a block whose coefficients arrive on a port -- a mapping onto it would silently drop what makes this block different; polyval itself is a MATLAB function with no library path. For constant coefficients use Control_Systems/Base_Blocks/Polynomial, which is bridged

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 no sample under docs/generated/samples/ — nothing to cross-check (P8.1)

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).

Evaluate Fit -- polyval with the coefficients on a WIRE y = c0*x^(L-1) + ... + c(L-1), entry by entry over x, with c DESCENDING and arriving on a port rather than out of a config. See the header for why that is a different block from Base_Blocks/Polynomial rather than a duplicate of it.

Every target nests -- Horner's rule -- and every target reads the SAME coefficient entries in the SAME order, because the two are not the same computation in floating point and the ten exported cores are compared against the C++ relation below.

Verified against R2026a: polyval([0.18018728956228861 0.97582972582972149 0.99028980278979795 -0.12171717171717268], -0.7) reports -0.39856770833333272.

Sample results#

No sample run is committed for this block. Samples come from the headless harness (DOCS_PLAN.md P8.1) into docs/generated/samples/; until one exists this block's behaviour is witnessed by the parity and export-verification suites, not by a plot here.