matlab-review-fi-object-code
Reviews MATLAB fixed-point (fi) code for performance, code generation efficiency, and correctness. Identifies antipatterns and suggests idiomatic improvements. Use when reviewing fi, fimath, numerictype, or quantizenumeric code.
git clone --depth 1 https://github.com/matlab/matlab-agentic-toolkit /tmp/matlab-review-fi-object-code && cp -r /tmp/matlab-review-fi-object-code/skills-catalog/code-generation/matlab-review-fi-object-code ~/.claude/skills/matlab-review-fi-object-codeSKILL.md
# fi Best Practices Review
Reviews MATLAB code for fixed-point (`fi`) best practices and suggests improvements for performance, code generation efficiency, and correctness.
## When to Use
- Reviewing MATLAB code that uses `fi`, `fimath`, `numerictype`, or `quantizenumeric`
- Optimizing fixed-point simulation speed
- Preparing fixed-point code for C or hardware code generation
## When Not to Use
- Code using only built-in integer types (`int8`, `uint16`, etc.) without `fi`
- Pure floating-point algorithms with no fixed-point intent
- Simulink-only workflows where fixed-point is configured through block dialogs (use Fixed-Point Tool instead)
## Checklist
When reviewing code, check for ALL of the following:
### 1. Vectorize fi() Calls
**Problem**: Scalar `fi()` in a loop is slow due to per-element object construction overhead.
**Fix**: Pass entire arrays to `fi()` at once.
```matlab
% BAD — slow: per-element fi object construction
for k = 1:N
x_fi(k) = fi(x(k), 1, 18, 16, F);
end
% GOOD — fast: single vectorized call, bit-true identical result
x_fi = fi(x, 1, 18, 16, F);
```
### 2. Separate Data Types from Algorithm
**Problem**: Hardcoding fi types inside algorithm code makes it impossible to switch between float/fixed or compare configurations.
**Fix**: Use a types table with empty prototypes and `cast(...,'like',...)`.
```matlab
% Types table (separate function)
function T = mytypes(dt)
switch dt
case 'double'
T.b = double([]); T.x = double([]); T.y = double([]);
case 'single'
T.b = single([]); T.x = single([]); T.y = single([]);
case 'fixed16'
F = fimath('RoundingMethod','Floor','OverflowAction','Wrap', ...
'ProductMode','KeepLSB','ProductWordLength',32, ...
'SumMode','KeepLSB','SumWordLength',32);
T.b = fi([], 1, 16, 15, F);
T.x = fi([], 1, 16, 15, F);
T.y = fi([], 1, 16, 14, F);
end
end
% Algorithm — no hardcoded types
function [y,z] = myfilter(b, x, z, T)
y = zeros(size(x), 'like', T.y);
for n = 1:length(x)
z(:) = [x(n); z(1:end-1)];
y(n) = b * z;
end
end
% Entrypoint — wraps types + cast + algorithm
function [y,z] = entrypoint(dt, b, x)
T = mytypes(dt);
b = cast(b, 'like', T.b);
x = cast(x, 'like', T.x);
z = zeros(size(b'), 'like', T.x);
[y,z] = myfilter(b, x, z, T);
end
```
**Validation**: Run with `'double'` first, then `'single'` (catches single-precision issues early — important for embedded targets where double is unavailable or slow), then `'fixed16'`.
### 3. Prevent Bit Growth with Subscripted Assignment
**Problem**: `acc = acc + x(n)` overwrites `acc` with a new fi object whose type may change due to FullPrecision word growth.
**Fix**: Use `acc(:) = acc + x(n)` to retain the original data type.
```matlab
% BAD — acc type may grow each iteration
acc = fi(0, 1, 32, 16);
for n = 1:numel(x)
acc = acc + x(n);
end
% GOOD — preserves acc's declared type
acc = fi(0, 1, 32, 16);
for n = 1:numel(x)
acc(:) = acc + x(n);
end
```
### 4. Configure fimath for Your Target
**Problem**: Default fimath (Nearest rounding, Saturate overflow, FullPrecision) generates bloated code. A simple `a + b` can produce many lines of C with sign-extension and overflow checks.
**Fix**: Choose fimath settings based on your code generation target.
```matlab
% For C targets (MATLAB Coder) — models integer truncation behavior
F_c = fimath('RoundingMethod','Floor', 'OverflowAction','Wrap', ...
'ProductMode','KeepLSB', 'ProductWordLength',32, ...
'SumMode','KeepLSB', 'SumWordLength',32);
% For DSP processor targets — models shift-right behavior
F_dsp = fimath('RoundingMethod','Floor', 'OverflowAction','Wrap', ...
'ProductMode','KeepMSB', 'ProductWordLength',32, ...
'SumMode','KeepMSB', 'SumWordLength',32);
% For FPGA/hardware targets — use the built-in helper
% hdlfimath = Floor/Wrap/FullPrecision (hardware coder manages bit widths internally)
F_hw = hdlfimath;
x_fi = fi(x, 1, 18, 16, F_hw);
```
**Product/Sum mode selection**:
| Mode | Behavior | Use when |
|------|----------|----------|
| `KeepLSB` | Keep least significant bits (C integer truncation) | Targeting C/C++ (MATLAB Coder) |
| `KeepMSB` | Keep most significant bits (shift-right) | Targeting DSP processors |
| `FullPrecision` | Retain all bits (word growth) | Hardware coder (manages widths internally), or debugging |
| `SpecifyPrecision` | Manual word/fraction lengths | Custom precision requirements |
**Note**: `hdlfimath` returns Floor/Wrap/FullPrecision. The hardware coder manages bit widths through its own pipeline — do not use `KeepLSB` or `KeepMSB` with it unless explicitly required by your design constraints.
**Rounding efficiency** (most to least efficient for codegen):
1. `Floor` — two's complement truncation, no extra logic
2. `Zero` — truncation toward zero
3. `Nearest` — ties to +inf (default)
4. `Convergent` — ties to nearest even
5. `Round` — ties away from zero (most expensive)
**Overflow**: `Wrap` (no logic) vs `Saturate` (requires comparison).
**Slope-bias scaling**: If your fi objects use slope-bias (non-power-of-two slope or non-zero bias):
- `ProductMode` and `SumMode` must be `'SpecifyPrecision'` with `CastBeforeSum` set to `true`
- Hardware code generation and DSP System Toolbox do not support slope-bias — use binary-point for hardware targets
- Slope-bias maximizes accuracy per bit when values are bunched away from zero (e.g., sensor ranges like 273–283 K)
- Match net scaling so operations resolve to shifts; non-zero bias makes multiplication costlier, but zero-bias with non-power-of-two slope can still produce shift-only code
### 5. Preallocate fi Arrays
**Problem**: Growing fi arrays inside loops causes quadratic memory and time growth.
**Fix**: Preallocate using `zeros(...,'like',...)` with a prototype.
```matlab
T = fi([], 1, 18, 16, F); % empty prototype
Y = zeros(N, 1, 'like', T); % preallocated out>
Import recorded driving sensor data (GPS, camera, lidar, actor tracks, lanes) into scenariobuilder.* objects (GPSData, CameraData, LidarData, ActorTrackData, Trajectory, laneData) and run preprocessing — synchronize, offset correction, crop, normalizeTimestamps, convertTimestamps. Also: compute actor tracks from lidar when no annotations exist, attach camera/lidar mounting + intrinsics, export to MAT/workspace/timetable/script. Use for raw driving dataset files (KITTI, nuScenes, Waymo, Pandaset, ROS/ROS2 bags, .mat, .csv, .mp4) or driving/vehicle/sensor logs that need wrapping. drivingLogAnalyzer (DLA) is OPT-IN ONLY — invoke only on explicit user request ('DLA', 'open in DLA', 'inspect/explore/analyze the recording') or reported sensor problem (sync drift, timestamp mismatch, overlay misalignment). NEVER auto-launch DLA after wrapping (Rule 0). For 'build scenario / export to RoadRunner / drivingScenario / OpenSCENARIO / Unreal / simulate', hand off to matlab-scenario-builder.
Generate driving scenes, scenarios, road surfaces, and 3D content from already-wrapped scenariobuilder.* sensor data (GPS, camera, lidar, actor tracks) using Scenario Builder for Automated Driving Toolbox. Use to BUILD, EXPORT, or AUGMENT a virtual scenario/scene/map: ego or actor trajectories, trajectory smoothing, OpenCRG road-surface extraction, 3D asset generation, static-object placement, point-cloud georeferencing + elevation, lane-based ego localization, sensor-fusion tracking, scenario-event extraction (cut-ins, hard brakes, near-misses, ADAS disengagements), or export to RoadRunner, drivingScenario, OpenDRIVE, OpenCRG, OpenSCENARIO, or Unreal Engine. Also: log-to-scenario, scenario harvesting, accident/near-miss reconstruction, SOTIF (ISO 21448) and ISO 26262 scenario coverage, USGS-aerial-lidar scene augmentation, traffic-sign placement from camera+lidar logs. NOT for raw-data import or multi-sensor sync/crop/offset/timestamp normalization — route those to matlab-driving-data-importer.
>
>
>
>
Build, modify, and diagram SimBiology models — API reference, helper functions, and layout patterns. Use when constructing or editing models programmatically or visually.