用C++创建二维数组,并在MATLAB中使用
Create 2D array in C++ and use it in MATLAB
有一个标准示例,说明如何在C++中创建或更改数组,并将其用作WarpControlPoints:中的数组
/*==========================================================
* 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数组,而不仅仅是一个简单的数组。我试图创建一个2D数组(4 x 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
既不是字段也不是指针。有人能告诉我我做错了什么吗?我是如何做到的?
多维数组仍然存储为单个连续数组,而不是2D C数组。数据按列主顺序排列,这意味着z[0]是元素(1,1),z[1]是元素(2,1)等,一直到z[4*N-1]
要从所需的2D索引(行、列)(基于0)计算线性索引,只需写入idx = column*nrows + row;
。这意味着您需要将nrows值传递到计算函数中。
所以:在计算函数nrows
中添加一个额外的参数,并在调用它时传递该值。并将z索引为1D数组,如上所述。
提问者可能已经得到了答案。然而,这个答案可能对像我这样从MATLAB转向C++并希望在C++中使用一些MATLAB功能的人有用。
从C++向MATLAB发送1D数组非常容易,因为有很多在线示例可以向您展示这个过程。但是,将2D数组发送到MATLAB有点棘手,因为没有足够的信息可用(尤其是使用动态数组)。下面的代码中显示了一个过程。这个过程遵循一些简单的步骤,
- 用C++创建一个2D数组
- 使用
engPutVariable_func()
(用户定义函数)将该2D数组的每一列发送到MATLAB - 在MATLAB中使用C++中的
engEvalString()
将每一列附加在一起
#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
希望这些信息可能有用。。。
如果有任何疑问和批评,请发表评论。
感谢并问候
从根本上讲,二维数组总是需要定义其第一个维度。
将指针(z)视为2d数组打破了这一规则。
如果没有定义第一个维度(实际上,除了最后一个维度之外的所有维度),则无法正确计算指针的实际偏移量。
在您的代码中,因为您知道每个维度的大小是相等的,所以您可以自己计算指针偏移量。
- 仅使用绝对值对数组进行排序,并在C++中显示实际值
- 如何创建一个空的全局类并在启动时实例化它
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 在函数内部的声明中初始化数组,并在外部使用它
- C++-我可以创建另一个类的成员并在构造函数中使用它吗
- 缓存std::数组的选定元素,并在c++中自动保持其一致性
- 定义C++新的环境变量并在 bat 文件中使用它
- Visual Studio 2017 停止工作,并在打开后显示许多控制台窗口
- 如何读取单个字符并在输入两个字符序列时输出? 使用 while 循环和C++
- 在 c++ 中模拟输入并在 JAVA 中读取它?
- 是否有必要获取锁并在不需要唤醒线程时通知condition_variable?
- 将通用对象传递给 Rust 并在使用后传递回 C++ 进行销毁
- 动态获取 esp32 的 mac 地址并在以太网库中使用它.
- 从.txt文件中读取浮点型数字并在公式中使用它们
- 如何将成员函数作为参数传递并在派生对象上执行方法列表
- 在C++的头文件中使用常量并在程序中询问其地址的任何潜在危险
- C++ 和 Boost.Python - 如何将变量公开给 python 并在循环中更新它?
- 在C++中拆分32位值,并在MATLAB中连接块
- 用C++创建二维数组,并在MATLAB中使用
- 如何在Matlab中训练一个模型,将其保存到磁盘,并在c++中加载程序