1

I need to port a MATLAB script, which uses .csvs to read and write configs and data with csvread(), to C++.

Obvious choice was to use the Coder app in MATLAB but csvread() is not supported by Coder.

What would be the best course of action to get the conversion going?

I tried reading the file via fileread() or fread() to parse the file in MATLAB but functions like textscan() aren't supported by Coder either.

Also it seems like coder.ceval() cannot return arrays - at least the manual says so - how would a parser have to look like in C++? I was planning on returning a nested vector.

Ryan Livingston
  • 1,898
  • 12
  • 18
  • 1
    *I was planning on returning a nested vector* FWIW, don't do that. ND vectors should no be used as they lack data locality. If you need a ND vector, wrap a 1D vector in a class and use math to pretend it has multiple dimensions (or just get a library that already does this) – NathanOliver Jan 21 '20 at 21:27
  • Here is a really simple 2D example of what Nathan's talking about][(https://stackoverflow.com/a/2076668/4581301) – user4581301 Jan 21 '20 at 21:36
  • 1
    Did you consider using the MATLAB Compiler instead? No code generation required but you can still share your Software with users who don't have a MATLAB license. – Daniel Jan 21 '20 at 22:07
  • @Daniel i did, but it would be my last option since i will need the output / results of some of the scripts in my cpp code going forward (e.g. one of the scripts does image comparison on per-pixel basis and returns the likeliness percentage - i will need to use this likeliness value in further calculations) – kamikatze13 Jan 22 '20 at 07:13
  • 1
    You can use MATLAB Compiler to produce a C++ shared library so you can use the results in your other code: https://www.mathworks.com/help/compiler_sdk/gs/create-a-cc-mwarray-application.html – Ryan Livingston Jan 22 '20 at 09:08
  • @Daniel and Ryan: i was successful in using the shared library approach in my limited testing, but it turns out the target environment doesn't allow for an mcr installation (it's a linux compute cluster, i'm developing on windows, so here's another hurdle lol), which would be required by both the mxarray as well as the new data api - please correct me if i'm wrong on this one. – kamikatze13 Feb 17 '20 at 13:40

1 Answers1

1

If you're set on using Coder, once you read the file, you can use a combination of the MATLAB function strtok and a coder.ceval call to the C sscanf to do the parsing. My answer here shows an example of doing this for parsing CSV data.

Data

1, 221.34
2, 125.36
3, 98.27

Code

function [idx, temp, outStr] = readCsv(fname)
% Example of reading in 8-bit ASCII data in a CSV file with FREAD and
% parsing it to extract the contained fields.
NULL = char(0);
f = fopen(fname, 'r');
N = 3;
fileString = fread(f, [1, Inf], '*char'); % or fileread
outStr = fileString;
% Allocate storage for the outputs
idx = coder.nullcopy(zeros(1,N,'int32'));
temp = coder.nullcopy(zeros(1,N));
k = 1;
while ~isempty(fileString)
    % Tokenize the string on comma and newline reading an
    % index value followed by a temperature value
    dlm = [',', char(10)];
    [idxStr,fileString] = strtok(fileString, dlm);
    fprintf('Parsed index: %s\n', idxStr);
    [tempStr,fileString] = strtok(fileString, dlm);
    fprintf('Parsed temp: %s\n', tempStr);
    % Convert the numeric strings to numbers
    if coder.target('MATLAB')
        % Parse the numbers using sscanf
        idx(k) = sscanf(idxStr, '%d');
        temp(k) = sscanf(tempStr, '%f');
    else
        % Call C sscanf instead.  Note the '%lf' to read a double.
        coder.ceval('sscanf', [idxStr, NULL], ['%d', NULL], coder.wref(idx(k)));
        coder.ceval('sscanf', [tempStr, NULL], ['%lf', NULL], coder.wref(temp(k)));
    end
    k = k + 1;
end
fclose(f);
Ryan Livingston
  • 1,898
  • 12
  • 18
  • thanks a lot, I actually have seen the topic you linked to but skipped it for some reason. i managed to adapt it to my needs, however, `coder.wref(temp(k))` throws `Dimensions of arrays being concatenated are not consistent.` I'll open a new topic on this one. – kamikatze13 Feb 17 '20 at 13:19
  • also just a heads-up for anyone stumbling upon this: linear indexing (e.g. `temp(k)`) results in the csv being written row-major, so the result might need to be transposed, as was in my case. – kamikatze13 Feb 17 '20 at 13:29