有一个标准示例说明如何在c ++中创建或更改数组并将其用作matlab中的数组:
/*==========================================================
* arrayProduct.c - example in MATLAB External Interfaces
*
* Multiplies an input scalar (multiplier)
* times a 1xN matrix (inMatrix)
* and outputs a 1xN matrix (outMatrix)
*
* The calling syntax is:
*
* outMatrix = arrayProduct(multiplier, inMatrix)
*
* This is a MEX-file for MATLAB.
* Copyright 2007-2012 The MathWorks, Inc.
*
*========================================================*/
/* $Revision: 1.1.10.4 $ */
#include "mex.h"
/* The computational routine */
void arrayProduct(double x, double *y, double *z, mwSize n)
{
mwSize i;
/* multiply each element y by x */
for (i=0; i<n; i++) {
z[i] = x * y[i];
}
}
/* The gateway function */
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
double multiplier; /* input scalar */
double *inMatrix; /* 1xN input matrix */
size_t ncols; /* size of matrix */
double *outMatrix; /* output matrix */
/* get the value of the scalar input */
multiplier = mxGetScalar(prhs[0]);
/* create a pointer to the real data in the input matrix */
inMatrix = mxGetPr(prhs[1]);
/* get dimensions of the input matrix */
ncols = mxGetN(prhs[1]);
/* create the output matrix */
plhs[0] = mxCreateDoubleMatrix(1,(mwSize)ncols,mxREAL);
/* get a pointer to the real data in the output matrix */
outMatrix = mxGetPr(plhs[0]);
/* call the computational routine */
arrayProduct(multiplier,inMatrix,outMatrix,(mwSize)ncols);
}
这基本上就是我想要的,只是我想要更改一个二维数组而不仅仅是一个简单的数组。我尝试创建一个2D数组(4 * n)并更改第4行,看它是否有效。如果我更改以下行:
/* The computational routine */
void arrayProduct(double x, double *y, double *z, mwSize n)
{
mwSize i;
/* multiply each element y by x */
for (i=0; i<n; i++) {
z[3][i] = x * y[i];
}
}
和
/* create the output matrix */
plhs[0] = mxCreateDoubleMatrix(4,(mwSize)ncols,mxREAL);
它不起作用。我得到错误,z既不是字段也不是指针。任何人都可以告诉我我做错了什么以及我是如何工作的?
答案 0 :(得分:1)
从根本上说,二维数组总是需要定义它的第一个维度。
将指针(z)视为2d数组会破坏该规则。
如果没有定义第一个维度(实际上除最后一个维度之外的所有维度),则无法正确计算指针的实际偏移量。
在您的代码中,如您所知,每个维度的大小相等,您可以自己计算指针偏移量。
答案 1 :(得分:1)
多维数组仍然存储为单个连续数组,而不是2D C数组。数据按列主顺序排列,这意味着z [0]是元素(1,1),z [1]是元素(2,1)等,一直到z [4 * N-1] < / p>
要从所需的2D索引(行,列)(从0开始)计算线性索引,只需编写idx = column*nrows + row;
。这意味着你需要将nrows值传递给你的计算函数。
所以:在名为nrows
的计算函数中添加一个额外的参数,并在调用它时传递该值。并将索引z作为1D数组,如上所述。
答案 2 :(得分:1)
发问者可能已经找到答案。但是,对于像我这样从MATLAB转到C ++并想在C ++中使用某些MATLAB功能的人来说,此答案可能有用。
从C ++向MATLAB发送一维数组非常容易,因为有许多在线示例可以向您展示该过程。但是将2D数组发送到MATLAB有点棘手,因为没有足够的可用信息(尤其是使用动态数组)。下面的代码中显示了一个过程。该过程遵循一些简单的步骤,
engPutVariable_func()
(用户定义函数)将2D数组的每一列发送到MATLAB。engEvalString()
在MATLAB中将每一列一起附加。#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <cmath>
#include <string.h>
#include "engine.h"
#include "mex.h"
#include <armadillo>
/* I'm using armadillo for convenient matrix operations
* The process is applicable for other Linear Algebra libraries as well (including STL)
*/
using namespace std;
using namespace arma;
int Create_2DArray_in_Matlab(Engine &m_pEngine, dmat PlotData);
int engPutVariable_func(Engine &m_pEngine, dvec TheVector, string MatVarName);
int main(void)
{
dmat PlotData(100000, 10, fill::randu);
/* Our Objective is to Put Matrix "PlotData" in MATLAB workspace*/
/* Opening Matlab Engine */
Engine *m_pEngine;
m_pEngine = engOpen(NULL);
if (m_pEngine == NULL)
{
std::cout << "Error" << std::endl;
exit(1);
}
engSetVisible(m_pEngine, 1);
engEvalString(m_pEngine, "clc;");
engEvalString(m_pEngine, "close all;");
engEvalString(m_pEngine, "clear all;");
Create_2DArray_in_Matlab(*m_pEngine, PlotData);
engEvalString(m_pEngine, "open PlotData");
return 0;
}
int Create_2DArray_in_Matlab(Engine &m_pEngine, dmat PlotData)
{
/*Approach is to put one column at a time, of a 2D Matrix
*in Matlab workspace*/
int SIZE_Dmat_rows = PlotData.n_rows;
int SIZE_Dmat_cols = PlotData.n_cols;
for (int i = 0; i < SIZE_Dmat_cols; i++)
{
dvec Temp_Col = PlotData.col(i);
dvec Col_Number(1); Col_Number(0) = i;
engPutVariable_func(m_pEngine, Temp_Col, "Temp_Col");
engPutVariable_func(m_pEngine, Col_Number, "Col_Number");
engEvalString(&m_pEngine, "PlotData(:, Col_Number + 1) = Temp_Col;");
}
return 0;
}
int engPutVariable_func(Engine &m_pEngine, dvec TheVector, string MatVarName)
{
/*This function will put a column vector in MATLAB Workspace*/
int SIZE = TheVector.n_rows;
double *Temp = new double[SIZE];
for (int i = 0; i < SIZE; i++)
{
Temp[i] = TheVector(i);
}
char Char_VariableName[1000];
strcpy(Char_VariableName, MatVarName.c_str());
/* Creating Matlab Variables*/
mxArray *TheMatVec = NULL;
TheMatVec = mxCreateDoubleMatrix(SIZE, 1, mxREAL);
memcpy((void *)mxGetPr(TheMatVec), (void *)Temp, sizeof(Temp)*SIZE);
engPutVariable(&m_pEngine, Char_VariableName, TheMatVec);
delete[] Temp;
return 0;
}
在一个简单的MATLAB程序中,这就是我们在C ++中所做的
clc
clear all
close all
A = rand(10, 20);
for i = 1:length(A)
A_Temp = A(:, i);
B(:, i) = A_Temp
A_Temp = [];
end
希望此信息可能有用...
如果有任何疑问和批评,请发表评论。
感谢和问候