Conversion of dlmread() using MatLab Coder - Not supported for code generation to C

조회 수: 9 (최근 30일)
I have a compensation function that reads in a 2-column csv file. When I run this fuction in the MatLab Coder Generator to convert it to a standalone C function, it states that my dlmread() call, which reads in the csv file, is not supported. I saw that dlmread() should be replaced with readmatrix(), but that is not supported either.
How do I go about converting this call, dlmread() or readmatrix(), over to Matlab code that the MatLab Coder app will recognize? Below is my function:
function x = compensation(band, x, fc)
% Algorithm parameters
fs = 4.5e9; % Sample rate
[Nf, K] = size(x); % Number of SHAPE vectors in the file
if strcmp(band, 'lb')
comp_fn = 'low_band_comp.csv';
elseif strcmp(band, 'hb')
comp_fn = 'high_band_comp.csv';
end
% Calculate the average power spectral density
Xf = fftshift(fft(x, [], 1), 1);
f = [0 : Nf-1]' * fs/Nf - fs/2;
% Read the compensation vector data
F = dlmread(comp_fn);
frq = F(:,1)*1e6; % Convert MHz data to Hz
mag = F(:,2);
% Translate compensation data in frequency
if strcmp(band, 'lb')
frq = frq - fc; % Digital LO
elseif strcmp(band, 'hb')
frq = fc - frq; % f_out = f_lo - f_bb
frq = flipud(frq); % Digital LO
end % Put in ascending order for interpolation
% Normalize compensation data in magnitude
mag = (10.^(mag/10));
mag = mag/mean(mag);
mag = 10*log10(mag);
M = length(mag);
% Interpolate the compensation data
mag_m = ones(Nf,1);
k = 1;
for m = 1 : Nf
if f(m) >= frq(1) && f(m) < frq(M)
if f(m) < frq(k+1) && f(m) >= frq(k)
mag_m(m) = (mag(k+1) - mag(k))*(f(m) - frq(k))/(frq(k+1) - frq(k)) + mag(k);
else
mag_m(m) = (mag(k+1) - mag(k))*(f(m) - frq(k))/(frq(k+1) - frq(k)) + mag(k);
k = k + 1;
end
end
end
figure(3);
plot(frq/1e6, mag, 'b.-');
hold on;
plot(f/1e6, mag_m, 'r.-');
hold off;
title('Compensation Spectrum');
xlabel('Frequency - MHz');
ylabel('Magnitude - dB');
grid on;
% Convert to magnitude scaling values
mag_vec = 10.^(+mag_m/20);
% Apply the compensation vector to frequency domain data
Xf = Xf .* (mag_vec * ones(1,K));
% Recalculate the SHAPE vector from frequency scaled input
x = ifft(fftshift(Xf, 1), [], 1);
end

채택된 답변

Yash
Yash 2023년 8월 30일
In MATLAB Coder, the dlmread and readmatrix functions are not supported because they are part of the MATLAB base workspace and are not compatible with code generation. To read CSV files in generated C code, you can use the fscanf function.
Here's how you can modify your compensation function to use fscanf instead of dlmread or readmatrix:
function x = compensation(band, x, fc)
% Algorithm parameters
fs = 4.5e9; % Sample rate
[Nf, K] = size(x); % Number of SHAPE vectors in the file
if strcmp(band, 'lb')
comp_fn = 'low_band_comp.csv';
elseif strcmp(band, 'hb')
comp_fn = 'high_band_comp.csv';
end
% Calculate the average power spectral density
Xf = fftshift(fft(x, [], 1), 1);
f = [0 : Nf-1]' * fs/Nf - fs/2;
% Open the CSV file for reading
fid = fopen(comp_fn, 'r');
if fid == -1
error('Failed to open the compensation file.');
end
% Read the compensation vector data
F = fscanf(fid, '%f,%f', [2, inf]);
F = F';
fclose(fid);
frq = F(:, 1)*1e6; % Convert MHz data to Hz
mag = F(:, 2);
% Translate compensation data in frequency
if strcmp(band, 'lb')
frq = frq - fc; % Digital LO
elseif strcmp(band, 'hb')
frq = fc - frq; % f_out = f_lo - f_bb
frq = flipud(frq); % Digital LO
end
% Put in ascending order for interpolation
[frq, idx] = sort(frq);
mag = mag(idx);
% Normalize compensation data in magnitude
mag = (10.^(mag/10));
mag = mag/mean(mag);
mag = 10*log10(mag);
M = length(mag);
% Interpolate the compensation data
mag_m = interp1(frq, mag, f, 'linear', 'extrap');
% Rest of your code...
figure(3);
plot(frq/1e6, mag, 'b.-');
hold on;
plot(f/1e6, mag_m, 'r.-');
hold off;
title('Compensation Spectrum');
xlabel('Frequency - MHz');
ylabel('Magnitude - dB');
grid on;
% Convert to magnitude scaling values
mag_vec = 10.^(+mag_m/20);
% Apply the compensation vector to frequency domain data
Xf = Xf .* (mag_vec * ones(1,K));
% Recalculate the SHAPE vector from frequency scaled input
x = ifft(fftshift(Xf, 1), [], 1);
end
In the fscanf function, [2, inf] is used to specify the format and size of the data that you want to read from the file.
  • The 2 in [2, inf] indicates that you expect to read two values from each line of the CSV file: one for the frequency and one for the magnitude.
  • The inf in [2, inf] specifies that you want to read as many rows of data as are available in the file. In other words, it tells MATLAB to read until the end of the file is reached.
This code uses fopen to open the CSV file, fscanf to read its contents, and fclose to close the file when you're done. It also sorts the data by frequency to ensure that it's in ascending order for interpolation, as you did in your original code.
I hope this helps.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 MATLAB Coder에 대해 자세히 알아보기

제품


릴리스

R2019a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by