$npx -y skills add matlab/matlab-agentic-toolkit --skill matlab-upgrade-mex-icUpgrade C, C++, and Fortran MEX source files from the Separate Complex (SC) API to the Interleaved Complex (IC) API. Use when converting mxGetPr/mxGetPi to mxGetComplexDoubles, migrating MEX files to -R2018a, adding MX_HAS_INTERLEAVED_COMPLEX guards for SC/IC guarded builds, or m
| 1 | # Upgrade MEX Files to Interleaved Complex API |
| 2 | |
| 3 | 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. |
| 4 | |
| 5 | ## When to Use |
| 6 | |
| 7 | - User has a C, C++, or Fortran MEX file using `mxGetPr`/`mxGetPi`, `mxGetData`/`mxGetImagData`, or `mxSetPr`/`mxSetPi` |
| 8 | - User wants to build with `mex -R2018a` |
| 9 | - User asks about interleaved complex, IC MEX, or modernizing MEX code |
| 10 | - User has legacy MEX code from File Exchange, GitHub, or pre-R2018a era |
| 11 | - User has a C++ MEX file (`.cpp`, `.cxx`) using the C Matrix API (`mxGetPr`/`mxGetPi`, etc.) |
| 12 | - User has a Fortran MEX file (`.F`, `.f90`) using `mxGetPr`/`mxGetPi` via `%val()` pointers |
| 13 | - User reports a MEX function is slow on large complex arrays (call overhead, not loop) |
| 14 | - User asks how to improve MEX performance for complex data |
| 15 | |
| 16 | ## When NOT to Use |
| 17 | |
| 18 | - 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` |
| 19 | - 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 |
| 20 | - MEX file already uses typed accessors (`mxGetDoubles`, `mxGetComplexDoubles`, etc.) — already IC-compatible, no conversion needed |
| 21 | |
| 22 | ## Workflow |
| 23 | |
| 24 | Follow these 7 steps in order. Do NOT skip steps. |
| 25 | |
| 26 | ### Step 1: Pre-Upgrade Verification |
| 27 | |
| 28 | Before changing anything, understand the current state: |
| 29 | |
| 30 | 1. Read the source file completely |
| 31 | 2. Identify all SC API calls (see [Key API Mappings](#key-api-mappings)) |
| 32 | 3. Note which data types the MEX handles (double, single, int32, etc.) |
| 33 | 4. Note whether it handles complex data (`mxGetPi`, `mxIsComplex`, `mxCOMPLEX`) |
| 34 | |
| 35 | Report to the user: |
| 36 | - Number of SC API calls found |
| 37 | - Whether file processes complex numbers (complex arrays in SC mode incur deinterleave/re-interleave overhead) |
| 38 | - **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)). |
| 39 | - Any other issues noticed (missing error checking, etc.) |
| 40 | |
| 41 | ### Step 2: Output File Decision |
| 42 | |
| 43 | **ASK the user before proceeding:** |
| 44 | |
| 45 | > "Where should I write the converted code? |
| 46 | > - **New file** — creates a separate file (e.g., `<name>_ic.c` or `<name>_dual.c`), preserving the original untouched |
| 47 | > - **Modify in place** — edits the original file directly. Choose this if the file is under version control and you can revert if needed." |
| 48 | |
| 49 | If user chooses **new file**, use these naming defaults (or a user-specified name): |
| 50 | - IC-only: `<name>_ic.c` / `<name>_ic.F` |
| 51 | - SC/IC guarded: `<name>_dual.c` / `<name>_dual.F` |
| 52 | |
| 53 | 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. |
| 54 | |
| 55 | Tell the user which file you're writing to and why. |
| 56 | |
| 57 | ### Step 3: Decision Point — IC-Only or SC/IC Guarded? |
| 58 | |
| 59 | > **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. |
| 60 | |
| 61 | **ASK the user before proceeding:** |
| 62 | |
| 63 | > "Do you need this MEX file to compile under both the old SC API and the new IC API? |
| 64 | > - **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. |
| 65 | > - **IC-only** |