我编写了一个C ++程序,其唯一目的是调用Matlab代码。我有一个主程序,
将文件(高维90000 * 24的矩阵)中的数据读入C ++ 结构
将这些结构传递给Matlab代码
在参数
从Matlab获取输出数据并将它们存储在C ++结构中
在2 /中,矩阵是Matlab结构中的字段。结构,比如MATLAB_STRUCT
有几个矩阵字段,MATLAB_STRUCT.Z1
,MATLAB_STRUCT.Z2
,...和一些浮点字段MATLAB_STRUCT.flt1
,...
将C ++矩阵(double**
)设置为Matlab结构的字段的正确方法是什么?到目前为止,我使用engine.h
mxArray* labcoeffs_array = convertVectorToMxArray(labcoeffs,
coeff_nrows, coeff_ncols);
const std::string lab_coeff_name = "MATLAB_STRUCT.labCoef";
engPutVariable(ep, lab_coeff_name.c_str(), labcoeffs_array);
其中convertVectorToMxArray
是我写的将double**
转换为mxArray
的帮手,
inline mxArray *convertVectorToMxArray(double** mat,
const int nb_rows, const int nb_cols)
{
mxArray *outputMxArray = mxCreateDoubleMatrix(
(int) nb_rows,
(int) nb_cols,
mxREAL);
double *data = (double*) mxGetData(outputMxArray);
for (int r = 0; r < nb_rows; r++)
for (int c = 0; c < nb_cols; c++)
data[r + c*nb_rows] = (double)mat[r][c];
return outputMxArray;
};
但是我已经看到了一些其他技术,用于在Cpp代码中为Matlab结构赋值(尽管不是一个浮点值,而不是矩阵),模仿C ++字符串中的命令行语法:
std::string setStruct = "MATLAB_STRUCT" + "." + "nB" + " = " + str->nB + ";";
matlabExecute(ep, setStruct);
用ep
指向Matlab引擎的指针。
是否可以使用命令行调整此方法,以便为Matlab结构的矩阵类型字段赋值?
将值赋给Matlab结构的矩阵类型字段的最佳方法是什么?
答案 0 :(得分:1)
这是一个类似于你所描述的构成示例:
#include <iostream>
#include <vector>
#include "engine.h"
// create mxArray matrix from an array of data
mxArray* data_to_mxarray(const double *data, int nrows, int ncols)
{
mxArray *arr = mxCreateDoubleMatrix(nrows, ncols, mxREAL);
double *x = mxGetPr(arr);
for (int c=0; c<ncols; c++) {
for (int r=0; r<nrows; r++) {
*x = data[r + c*nrows];
x++;
}
}
return arr;
}
int main()
{
// step 1: some data
const char *fieldnames[2] = {"z1", "z2"};
double z1[] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0};
double z2[] = {7.0, 8.0, 9.0, 0.0, 1.0, 2.0};
// open connection to MATLAB
Engine *ep = engOpen("");
// create structure with desired fields
mxArray *st = mxCreateStructMatrix(1, 1, 2, fieldnames);
mxSetField(st, 0, "z1", data_to_mxarray(z1,2,3));
mxSetField(st, 0, "z2", data_to_mxarray(z2,3,2));
// step 2: pass struct to MATLAB workspace
engPutVariable(ep, "st", st);
// for the sake of this example, lets create a fake function
engEvalString(ep, "my_function = @(x) magic(3);");
// step 3: call some function with the struct as input
engEvalString(ep, "out = my_function(st);");
// step 4: retrieve function output
mxArray *out = engGetVariable(ep, "out");
// extract data out of it. This depends on the type of output.
// Say the result was a numeric array
double *x = mxGetPr(out);
size_t len = mxGetNumberOfElements(out);
std::vector<double> v;
v.resize(len);
v.assign(x, x+len);
for (int i=0; i<v.size(); i++) {
std::cout << v[i] << std::endl;
}
// cleanup
mxDestroyArray(out);
mxDestroyArray(st);
engClose(ep);
return 0;
}
答案 1 :(得分:0)
您已经发现engPutVariable
,这是将变量插入Engine工作区的有效方法。它可以为任何类型的mxArray执行此操作,而不仅仅是双矩阵。
mxCreateDoubleMatrix()
和mxGetData()
都是&#34; C / C ++矩阵库API&#34;中的函数,在此处记录:http://www.mathworks.com/help/matlab/cc-mx-matrix-library.html
从这些函数开始,您可以找到直接从C ++处理MATLAB结构变量的其他函数,包括mxCreateStructMatrix()
和mxSetField()
。 MATLAB结构变量是一个&#34;容器&#34; type,表示每个字段本身都是一个MATLAB变量,因此您需要将相应的字段设置为您已经创建的double mxArray。
如果确实需要设置现有结构的字段,可以像现在一样将变量作为双数组。那么,你提到的matlabExecute()
方法是完美的。它只需要你希望MATLAB执行的字符串,在这种情况下只是&#34; MATLAB_STRUCT.fieldname = existing_variable;&#34;
答案 2 :(得分:0)
要在结构中创建矩阵字段,一个选项是创建临时变量,然后将其值分配给结构的字段:
// Create temp variable
mxArray* array = convertVectorToMxArray(mat, nb_rows, nb_cols);
const std::string temp_name = array_name + "_temp";
int ret = engPutVariable(ep, temp_name.c_str(), array);
// Set variable to struct field
const std::string cmd = std::string(array_name + " = " + temp_name + "; ");
matlabExecute(ep, cmd);
// Delete array
mxDestroyArray(array);