codegen error: Conversion to struct from double is not possible - c

I am trying to convert Matlab legacy code into a C program. I went though the usual flows, but am having a build error that I do not understand:
Nfft = 8;
[~,coh] = size(h); // h = array of 168 elements;
display(coh); // displays 168
if mod(coh,Nfft)~=0,
h1 = [h zeros(1,Nfft-mod(coh,Nfft))];
else
h1 = h;
end
This works as expected in Matlab. But when I run it through codegen (after removing the display), I get an error at the line h1 = [h zeros(1,Nfft-mod(coh,Nfft))]; with the error message:
Conversion to struct from double is not possible.
I realize that in the matlab code, it doesn't go through this part of the code. (since 168%8 == 0).
Any ideas how to fix this?
EDIT: After some investigating, I realize that I am reading in h from a .mat file and this may be the reason. Is data read in from a .mat file considered to be a structure? If this is the case, then maybe I need to convert each element to a double first? Seems kind of hacky..

Found the solution!
When using coder.load, the .MAT file is imported as an array structure. So, in my code, I was trying to concatenate a structure with an array of doubles.
The solution to this was the way that I was loading the .MAT file:
old way:
h = coder.load('my_file.mat', 'my_file_var1');
new way:
tmp = coder.load('my_file.mat');
h = tmp.my_file_var1;
Then I was able to use h as an array of doubles.

Related

Getting Data From C Buffer Pointer in Swift

I am attempting to write an app in Swift that uses this library for playing MOD music files: https://github.com/martincameron/micromod/tree/master/ibxm-ac
The library has a method called replay_get_audio that takes in, alongside the actual data to be processed (replay and mute), an int pointer to a buffer where audio data should be written to (mix_buf):
int replay_get_audio( struct replay *replay, int *mix_buf, int mute )
The problem is that no matter what I do, I can't seem to access the data that gets written to this buffer in Swift. It's showing up as an array of zeroes in the variable inspector when I convert the bufferPointer to the data to an array:
let dataSize = Int(calculate_mix_buf_len(44100)) // 14040 is the output for my mod file - this is the necessary memory allocation amount for mix_buf according to the library
let mixBufDataPointer = UnsafeMutablePointer<Int32>.allocate(capacity: dataSize)
let resultingNumSamplesWrittenToMixBuf = replay_get_audio(replay, mixBufDataPointer, 0) // The function outputs the number of samples written to mixBuf - it is returning 882 for my mod file, so I assume it is writing the data successfully
let mixBufBufferPointer = UnsafeMutableBufferPointer(start: mixBufDataPointer, count:dataSize)
let arrayDataForMixBuf = Array(mixBufBufferPointer) // An array of 14040 Int32s - all with the value of 0...as if the data is not being written
If I manually write a value to, say, mixBufDataPointer[1], I can see it shows up in the arrayDataForMixBuf, so I know the reading using mixBufBufferPointer and the associated array conversion are working correctly. The issue appears to be where the library writes into the mixBufDataPointer.
Am I missing something? I'm completely new to pointers in Swift so this is all new to me.

How transfer an array of integers from C to Matlab

Is there a somewhat easy way to transfer an array of integers from a C program to matlab? I have found several guides online on how to do it between C++ and Matlab, but not for C to Matlab.
I have several arrays of 1180 floats that I produce with a program written in C. Now I want to visualize this data in Matlab. I could have the C program export the Matlab code necessary to create the arrays hard-coded, but this seems unnecesarily devious.
I could just use the C++ method and compile my C program with a C++ compiler but at this point I am just curious if it can also be done in C.
Matlab can import .mat files, but these files seem to be encrypted or in binary format.
Please don't give suggestions on how to visualize the data in C, I have to do it in Matlab. I have a piece of code in Matlab that is returning weird results and I wrote the equivalent code in C, now I want to see if there is a difference in results. This way I can debug my Matlab code, since the end result has to be handed in in Matlab code.
My C code so far. Also I made a mistake in my initial upload, I want to transfer an array of integers.
FILE *f = fopen("Ps.bin", "wb");
for(int n = 1; n < N + 1; n++)
{
converter.asInt = Ps[n];
for(int i = 0; i < 4; i++)
{
fwrite(&converter.asBytes[i], sizeof(char), 1, f);
}
}
fclose(f);
This is what I tried in matlab, but none of it gives the proper result. In all cases matlab makes an array of doubles, which I definately don't want. It just generates an array with values that are one of these three: 0, 0.0000 and 4.925.
Ps = fread(fopen('Ps.bin'))
Ps = fread(fopen('Ps.bin'), 1180)
Ps = fread(fopen('Ps.bin'), 1180, 'uint32')
Ps = fread(fopen('Ps.bin'), 1180, '2 * uint16')
Write a binary file in C (using fwrite, look here). From matlab, you can read it using the procedure here (freadfunction)

How to create a 2D matrix with for loop iterating across a struct

In a directory I have a collection of 20 files. I want to:
iterate a loop across those 20 files,
extract x and y data from them and
place those data in a 2D matrix that is created within the loop
Note below that files' is a 20x1 struct and file is a 1x1 struct.
I'm unsure how to build the 2-dimenstional matrix A inside such a loop.
I've tried something like
files = dir('./cases/*.dcm');
for file = files'
[data extraction here, creating vars x and y]
for k = 1:length(files')
A(k,:) = (x:y);
end
end
but I get
Subscripted assignment dimension mismatch.
Any idea what I'm doing wrong?
This should work:
files = dir('./cases/*.dcm');
for k = 1:numel(files)
file = files(k);
%[data extraction here, creating vars x and y];
A(k,:) = [x,y];
end
You might also want to add an initialization before the loop like:
A = zeros(numel(files),2);

Need suggestion on Code conversion to Matlab_extension 2

This is an extension of the previously asked question: link. In a short, I am trying to convert a C program into Matlab and looking for your suggestion to improve the code as the code is not giving the correct output. Did I convert xor the best way possible?
C Code:
void rc4(char *key, char *data){
://Other parts of the program
:
:
i = j = 0;
int k;
for (k=0;k<strlen(data);k++){
:
:
has[k] = data[k]^S[(S[i]+S[j]) %256];
}
int main()
{
char key[] = "Key";
char sdata[] = "Data";
rc4(key,sdata);
}
Matlab code:
function has = rc4(key, data)
://Other parts of the program
:
:
i=0; j=0;
for k=0:length(data)-1
:
:
out(k+1) = S(mod(S(i+1)+S(j+1), 256)+1);
v(k+1)=double(data(k+1))-48;
C = bitxor(v,out);
data_show =dec2hex(C);
has = data_show;
end
It looks like you're doing bitwise XOR on 64-bit doubles. [Edit: or not, seems I forgot bitxor() will do an implicit conversion to integer - still, an implicit conversion may not always do what you expect, so my point remains, plus it's far more efficient to store 8-bit integer data in the appropriate type rather than double]
To replicate the C code, if key, data, out and S are not already the correct type you can either convert them explicitly - with e.g. key = int8(key) - or if they're being read from a file even better to use the precision argument to fread() to create them as the correct type in the first place. If this is in fact already happening in the not-shown code then you simply need to remove the conversion to double and let v be int8 as well.
Second, k is being used incorrectly - Matlab arrays are 1-indexed so either k needs to loop over 1:length(data) or (if the zero-based value of k is used as i and j are) then you need to index data by k+1.
(side note: who is x and where did he come from?)
Third, you appear to be constructing v as an array the same size of data - if this is correct then you should take the bitxor() and following lines outside the loop. Since they work on entire arrays you're needlessly repeating this every iteration instead of doing it just once at the end when the arrays are full.
As a general aside, since converting C code to Matlab code can sometimes be tricky (and converting C code to efficient Matlab code very much more so), if it's purely a case of wanting to use some existing non-trivial C code from within Matlab then it's often far easier to just wrap it in a MEX function. Of course if it's more of a programming exercise or way to explore the algorithm, then the pain of converting it, trying to vectorise it well, etc. is worthwhile and, dare I say it, (eventually) fun.

Referencing Structs inside a Cell Array in Matlab

I'm dealing with a Matlab data structure which is analagous to "MyCellArray" in the following example:
% Create a Struct of string values inside a Cell Array
myCellArray = cell(3,1)
myStruct1 = struct('valA','aaa111','valB','bbb111','valC','ccc111')
myStruct2 = struct('valA','aaa222','valB','bbb222','valC','ccc222')
myStruct3 = struct('valA','aaa333','valB','bbb333','valC','ccc333')
myCellArray{1} = myStruct1
myCellArray{2} = myStruct2
myCellArray{3} = myStruct3
I'd like to be able to efficiently extract some of the data into a new array:
% Extract all valA values from myCellArray
% ArrayOfValA = myCellArray(< somehow get all the valA values >)
DesiredResult = cellstr(['aaa111';'aaa222';'aaa333']) % Or something similar
I'm new to Matlab and I just can't get my head around the notation. I've tried things like:
ArrayOfValA = myCellArray{(:,1).valA} % This is incorrect notation!
The real data is over 500K lines long so I'd like to avoid for loops or other iterative functions if possible. Unfortunately I can't change the original data structure but I suppose I could take a copy and manipulate that (I tried using struct2cell but I just got into another mess!). Is it possible to do this in a fast and efficient way?
Many thanks.
The following appears to work in Octave. I assume it also works in MATLAB:
>> temp = {[myCellArray{:}].valA}
temp =
{
[1,1] = aaa111
[1,2] = aaa222
[1,3] = aaa333
}
Does
myCellAsMat = cell2mat(myCellArray);
ArrayOfValA = vertcat(myCellAsMat(:).valA);
work?
edit: or horzcat, depending on the dimension and desired output of your valA field.

Resources