Skip to main content
ClaudeWave
Skill649 repo starsupdated today

matlab-upgrade-mex-ic

This skill converts MATLAB MEX source files from the older Separate Complex API to the Interleaved Complex API, modernizing legacy C, C++, and Fortran code to eliminate performance overhead on complex arrays. Use it when upgrading pre-R2018a MEX files, building with mex -R2018a, or improving performance for MEX functions that handle large complex data, following MathWorks upgrade workflow with verification steps.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/matlab/matlab-agentic-toolkit /tmp/matlab-upgrade-mex-ic && cp -r /tmp/matlab-upgrade-mex-ic/skills-catalog/matlab-external-language-interfaces/matlab-upgrade-mex-ic ~/.claude/skills/matlab-upgrade-mex-ic
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# Upgrade MEX Files to Interleaved Complex API

Convert C, C++, and Fortran MEX source files from the Separate Complex (SC) API to the Interleaved Complex (IC) API, following the MathWorks upgrade workflow with guardrails for SC/IC guarded builds using `MX_HAS_INTERLEAVED_COMPLEX`, required vs recommended changes, and verification.

## When to Use

- User has a C, C++, or Fortran MEX file using `mxGetPr`/`mxGetPi`, `mxGetData`/`mxGetImagData`, or `mxSetPr`/`mxSetPi`
- User wants to build with `mex -R2018a`
- User asks about interleaved complex, IC MEX, or modernizing MEX code
- User has legacy MEX code from File Exchange, GitHub, or pre-R2018a era
- User has a C++ MEX file (`.cpp`, `.cxx`) using the C Matrix API (`mxGetPr`/`mxGetPi`, etc.)
- User has a Fortran MEX file (`.F`, `.f90`) using `mxGetPr`/`mxGetPi` via `%val()` pointers
- User reports a MEX function is slow on large complex arrays (call overhead, not loop)
- User asks how to improve MEX performance for complex data

## When NOT to Use

- Writing a new MEX function from scratch — no conversion needed, but advise the user to use IC APIs (`mxGetDoubles`, `mxGetComplexDoubles`, etc.) from the start for better performance on complex data and modern, type-safe data access instead of legacy `mxGetPr`/`mxGetPi`
- C++ MEX API (`matlab::mex::Function`) — different API entirely; this skill covers C++ files that use the C Matrix API (`mex.h`), not the MATLAB Data API for C++ and C++ Engine
- MEX file already uses typed accessors (`mxGetDoubles`, `mxGetComplexDoubles`, etc.) — already IC-compatible, no conversion needed

## Workflow

Follow these 7 steps in order. Do NOT skip steps.

### Step 1: Pre-Upgrade Verification

Before changing anything, understand the current state:

1. Read the source file completely
2. Identify all SC API calls (see [Key API Mappings](#key-api-mappings))
3. Note which data types the MEX handles (double, single, int32, etc.)
4. Note whether it handles complex data (`mxGetPi`, `mxIsComplex`, `mxCOMPLEX`)

Report to the user:
- Number of SC API calls found
- Whether file processes complex numbers (complex arrays in SC mode incur deinterleave/re-interleave overhead)
- **Performance impact:** If the file handles complex data, note that SC MEX calls incur O(n) deinterleave/re-interleave copies at the MATLAB boundary. For large arrays, IC conversion eliminates this overhead entirely (see [Performance Benefits](#performance-benefits-of-ic-conversion)).
- Any other issues noticed (missing error checking, etc.)

### Step 2: Output File Decision

**ASK the user before proceeding:**

> "Where should I write the converted code?
> - **New file** — creates a separate file (e.g., `<name>_ic.c` or `<name>_dual.c`), preserving the original untouched
> - **Modify in place** — edits the original file directly. Choose this if the file is under version control and you can revert if needed."

If user chooses **new file**, use these naming defaults (or a user-specified name):
- IC-only: `<name>_ic.c` / `<name>_ic.F`
- SC/IC guarded: `<name>_dual.c` / `<name>_dual.F`

If user chooses **modify in place**, confirm the file is recoverable (e.g., "This file is tracked by git — you can revert with `git checkout <file>` if needed."). Then edit the original directly.

Tell the user which file you're writing to and why.

### Step 3: Decision Point — IC-Only or SC/IC Guarded?

> **What is "SC/IC guarded"?** A single source file that uses `#if MX_HAS_INTERLEAVED_COMPLEX` preprocessor guards to compile under both the Separate Complex API (`mex -R2017b`) and the Interleaved Complex API (`mex -R2018a`). The compiler defines `MX_HAS_INTERLEAVED_COMPLEX=1` in IC mode and `0` in SC mode, so the guards select the correct code path at build time.

**ASK the user before proceeding:**

> "Do you need this MEX file to compile under both the old SC API and the new IC API? 
> - **SC/IC guarded** — wraps code in `#if MX_HAS_INTERLEAVED_COMPLEX` / `#else` guards so the same source builds with both `mex -R2017b file.c` (SC mode) and `mex -R2018a file.c` (IC mode). Choose this if you support multiple MATLAB versions.
> - **IC-only** — converts fully to IC API. Requires `mex -R2018a` to build. Simpler code but only works on R2018a+."

If user chooses **SC/IC guarded**, use the `#if MX_HAS_INTERLEAVED_COMPLEX` preprocessor pattern:

**C/C++ files:**
```c
#if MX_HAS_INTERLEAVED_COMPLEX
    /* IC code path */
    mxComplexDouble *pc = mxGetComplexDoubles(prhs[0]);
#else
    /* SC code path */
    double *pr = mxGetPr(prhs[0]);
    double *pi = mxGetPi(prhs[0]);
#endif
```

**Fortran files** (`.F` preprocessed source):
```fortran
#if MX_HAS_INTERLEAVED_COMPLEX
      mwPointer mxGetComplexDoubles
      complex*16, pointer :: pc(:)
      call mxGetComplexDoubles(prhs(1), pc)
#else
      mwPointer mxGetPr, mxGetPi
      mwPointer pr, pi
      pr = mxGetPr(prhs(1))
      pi = mxGetPi(prhs(1))
#endif
```

> **Fortran note:** SC/IC guarded Fortran files MUST use `.F` extension (uppercase) so the MEX compiler invokes the C preprocessor. The `.f` or `.f90` extension skips preprocessing and `#if` guards will not work. For `.f90` files that cannot use preprocessor guards, use IC-only conversion.

If user chooses **IC-only**, convert directly without guards.

### Step 4: Iterative Refactoring

All legacy data-access APIs are **REQUIRED** to be converted for a complete IC upgrade. Convert every pattern in this table:

| Legacy Pattern | Replacement | Reason |
|----------------|-------------|--------|
| `mxGetPi(arr)` for data access | `mxGetComplexDoubles(arr)` + `.imag` | Does not exist in IC |
| `mxSetPi(arr, ptr)` | `mxSetComplexDoubles(arr, ptr)` | Does not exist in IC |
| `mxGetImagData(arr)` | Type-specific complex accessor | Does not exist in IC |
| `mxSetImagData(arr, ptr)` | Type-specific complex setter | Does not exist in IC |
| `mxGetPi(arr) != NULL` for complexity check | `mxIsComplex(arr)` — works in both SC and IC | Does not exist in IC |
| `mxGetPr(arr)` | `mxGet
matlab-train-networkSkill

>

matlab-driving-data-importerSkill

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.

matlab-scenario-builderSkill

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.

roadrunner-asset-mappingSkill

>

roadrunner-convert-lanelet2-to-rrhdSkill

>

roadrunner-import-sceneSkill

>

roadrunner-rrhd-authoringSkill

>

matlab-build-simbiology-modelSkill

Build, modify, and diagram SimBiology models — API reference, helper functions, and layout patterns. Use when constructing or editing models programmatically or visually.