Product Of Elements — Control Systems/Base Blocks
Control_Systems/Base_Blocks/Product_Of_Elements · 1 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.
Product of Elements
Control Systems / Base Blocks
Multiplies every entry of its input together and outputs the result: y = ∏ u(i,j). For a vector that is the product of its components; for a matrix it is the product over all entries. The result is always a single number.
Ports
- Input – the signal u, of any size [m,n].
- Output – the product y, always a scalar [1,1], whatever the input size. This block reduces rather than reshapes.
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.
Every target multiplies the entries in the same order – row by row, left to right – because floating-point multiplication is not associative, so a built-in reduction free to regroup the product would land a rounding step away from the reference.
The three HDL targets carry the product in Q16.16 fixed point and are fully synthesizable. Note that a product compounds dynamic range: each entry is rescaled after multiplying, and an input whose entries are large will reach the ±32768 the format holds far sooner than a sum would.
Simulink bridge
Import and export, mapped to
simulink/Math Operations/Product of Elements. The block has no parameters
of its own; Simulink's counterpart is its Product block in collapsing form, so
Inputs is always written as 1,
CollapseMode as All dimensions and
Multiplication as Element-wise(.*) – which is
what this block computes. Collapsing along one specified dimension has no
counterpart here. "Sampling Time (s)" goes to SampleTime, as on
every block.
Notes
- Algebraic, with no state.
- Not linear: an m-entry input makes this a degree-m function of the signal, so the block deliberately carries no state space and model reduction reports it as unmergeable. Sum of Elements is the same reduction with constant coefficients, and that one IS linear.
- A single zero entry takes the whole output to zero, which is what makes this block useful as a gate and worth watching in a feedback path.
Code facts#
| Fact | Value |
|---|---|
| registered type | Control_Systems/Base_Blocks/Product_Of_Elements |
| family | Control_Systems/Base_Blocks |
| solver environment class | ICoreBlock_0_Control_Systems_1_Base_Blocks_2_Product_Of_Elements |
| source | src/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Base_Blocks/Product_Of_Elements/ICoreBlock_0_Control_Systems_1_Base_Blocks_2_Product_Of_Elements.cpp |
| header | src/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Base_Blocks/Product_Of_Elements/ICoreBlock_0_Control_Systems_1_Base_Blocks_2_Product_Of_Elements.h |
| default size on canvas | 70 × 70 px |
| ports at insert | 1 in, 1 out |
| code generators implemented | Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text |
Ports#
| # | Direction | Signal type | Description label |
|---|---|---|---|
| 1 | in | ICoreDouble | — |
| 2 | out | ICoreDouble | — |
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.
Simulink bridge#
| support | Support::Both |
| Simulink path | simulink/Math Operations/Product of Elements |
| port-count rule | PortsParam::None |
SampleTime parameter | yes |
| always set | Inputs = 1, CollapseMode = All dimensions, Multiplication = Element-wise(.*) |
Catalog contract: src/ICoreSDK/ICoreCoder/ICoreCommandSystem/SimulinkBridge/ICoreSimulinkBlockCatalog.h
Description vs code#
The lists agree. check_block_descriptions.py finds no disagreement between the description's Ports, Parameters, Code export and Simulink bridge lists and the code's.
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).
Product of Elements block -- collapse a signal to the product of its entries y = product over every element of u. One input in, one SCALAR out, whatever the input shape. Algebraic and stateless, no state space (see header).
The output is 1x1 regardless of the input, so the size is forced in initializePortSignalSize() rather than left to the base class's "outputs take the input's size" default.
Every target multiplies in the SAME order -- row-major over the elements -- because floating-point multiplication is not associative either, and a reduction free to regroup would land a rounding step from the reference.
Sample results#
| t | in ICoreDouble-Out-0 | out ICoreDouble-Out-0 |
|---|---|---|
| 0 | -2 | -2 |
| 0.4 | 0.5 | 0.5 |
| 0.8 | -2 | -2 |
| 1.2 | 0.5 | 0.5 |
| 1.6 | -2 | -2 |
| 2 | 0.5 | 0.5 |
| 2.4 | -2 | -2 |
| 2.8 | 0.5 | 0.5 |
| 3.2 | -2 | -2 |
| 3.6 | 0.5 | 0.5 |
| 4 | -2 | -2 |
| 4.4 | 0.5 | 0.5 |
| 4.8 | -2 | -2 |
| 5.2 | 0.5 | 0.5 |
Every 4th of 60 samples, from the table stimulus.
The same rig also ran:
| Stimulus | What it is | Output range |
|---|---|---|
impulse | Impulse: one sample of 1 at k = 5, 0 elsewhere (Repeating Sequence Stair) | 0 … 1 |
ramp | Ramp: slope 1 from t = 0 | 0 … 5.8 |
sine | Sine Wave: amplitude 1, 2 rad/s, no phase, no bias | -1 … 0.9996 |
step | Step: 0 -> 1 at t = 1 s | 0 … 1 |
Plotted: table — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample
Category static · sample time 0.1 · 60 steps · commit ccf005c8 · produced by docsSample --out <folder> --steps 60 · data docs/generated/samples/Control_Systems__Base_Blocks__Product_Of_Elements.json · the SVG is generated from those numbers by tools/docs/plot_svg.py, so it is a run and not a drawing (R-D10).