I've generated C code from MATLAB by using the codegen tool. The function can be described as follows:
function [result] = calculate_data(my_matrix)
for idx = 1:length(my_matrix)
result = result + sum(my_matrix(idx,1:3));
end
end
When using the codegen tool, I explicitly stated that my_matrix is a type of double(:inf, 3). In other words, the number of rows is unbounded, but it will have 3 columns. When the code is generated, this is the function that is generated that I am to execute:
calculate_data(my_matrix : UnsafePointer<emxArray_real_T>!, result : UnsafeMutablePointer<emxArray_real_T>!)
emxArray_real_T is defined as follows in a different c file:
struct emxArray_real_T
{
double *data;
int *size;
int allocatedSize;
int numDimensions;
boolean_T canFreeData;
};
When I see my initialization options for the above class, this one in particular makes sense:
emxArray_real_T.init(data: UnsafeMutablePointer<Double>!, size: UnsafeMutablePointer<Int32>!, allocatedSize: Int32, numDimensions: Int32, canFreeData: boolean_T)
I've tried to follow this document as a means to wrap my head around how to call the generated C code, but I think I might be missing a basic step. Here is what I am doing:
// create an 2d array with some fake data
var mySampleData = [[Double]]();
for i in 0 ..< 3 {
mySampleData.append([1.1, 2.2, 3.3]);
}
// begin fulfilling requirements for emxArray_real_T
var data_pointer = UnsafeMutablePointer<Double>.allocate(capacity: 3);
data_pointer.initialize(from: mySampleData)
However, the above code throws an error stating that:
Generic parameter 'C' could not be inferred
I take it that I am then doing something completely wrong, and am probably on an incorrect path. There is a similar post that relates to my question, How to convert float[][] type array to "emxArray_real_T *x" , however the provided solution seems to be for C, as opposed to for Swift 4. How can I effectively call a C function using Swift 4, and meet the requirements of the emxArray_real_T.init method? Using fake data is ok to demonstrate the basic principle.
In a simple Xcode project with mocked C constructs for the struct emxArray_real_T
and the function calculate_data
I can run the following code successfully. To create an object of type emxArray_real_T
I do
var data: [Double] = (0 ..< 12).map(Double.init)
var size: [Int32] = [4, 3]
var array = emxArray_real_T(
data: &data,
size: &size,
allocatedSize: 12,
numDimensions: 2,
canFreeData: false
)
This object can be passed to the function calculate_data
like calculate_data(&array, nil)
. In a real application nil
would be another array object. For the sake of simplicity it is just used as a placeholder here.
Your second issue can be solved by using the right types ([Double]
instead of Double
in line 6):
var mySampleData = [[Double]]();
for i in 0 ..< 3 {
mySampleData.append([i*1, i*2, i*3].map(Double.init));
}
let pointer = UnsafeMutablePointer<[Double]>.allocate(capacity: 3)
pointer.initialize(from: mySampleData, count: 3)
print((pointer + 0).pointee)
print((pointer + 1).pointee)
print((pointer + 2).pointee)
pointer.deallocate()
The output will be
[0.0, 0.0, 0.0]
[1.0, 2.0, 3.0]
[2.0, 4.0, 6.0]
as expected.
I have to admit that I used Swift 5.0.1. This should not make significant differences, though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With