pass data between C++ Eigen Matrix and MATLAB mxArray with a cell array Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!Pass C++ Eigen matrix to Matlab mex outputWhat are the differences between a pointer variable and a reference variable in C++?matlab mex files and C++ dll (windows)error in unravel function for linking and decoding in huffman using matlabMapping existing memory to Matlab mxArray without waste of memoryHow to form a C++ 2D array with a Matlab matrix input?Creating and Passing of mxArray Data from other functions to Mex gateway functionHow to combine matrix of different size in a cell array into a matrix in MATLABHow MATLAB mex files access MATLAB instances?return value of mxGetPr() — equivalent loopingHow to convert varibles correctely between matlab (matrix, cell) and c++ (vectors or self-defining class) in Mexfile
Is it accepted to use working hours to read general interest books?
Processing ADC conversion result: DMA vs Processor Registers
All ASCII characters with a given bit count
Putting Ant-Man on house arrest
What's called a person who work as someone who puts products on shelves in stores?
Preserving file and folder permissions with rsync
France's Public Holidays' Puzzle
Eigenvalues of the Laplacian of the directed De Bruijn graph
Was there ever a LEGO store in Miami International Airport?
Raising a bilingual kid. When should we introduce the majority language?
What's the difference between using dependency injection with a container and using a service locator?
What *exactly* is electrical current, voltage, and resistance?
How to translate "red flag" into Spanish?
Has a Nobel Peace laureate ever been accused of war crimes?
Feather, the Redeemed and Dire Fleet Daredevil
Is there an efficient way for synchronising audio events real-time with LEDs using an MCU?
What does こした mean?
My admission is revoked after accepting the admission offer
Could a cockatrice have parasitic embryos?
Will I have to go through TSA security when I return to the US after preclearance in Atlanta?
What do you call an IPA symbol that lacks a name (e.g. ɲ)?
Suing a Police Officer Instead of the Police Department
In search of the origins of term censor, I hit a dead end stuck with the greek term, to censor, λογοκρίνω
Why aren't road bicycle wheels tiny?
pass data between C++ Eigen Matrix and MATLAB mxArray with a cell array
Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!Pass C++ Eigen matrix to Matlab mex outputWhat are the differences between a pointer variable and a reference variable in C++?matlab mex files and C++ dll (windows)error in unravel function for linking and decoding in huffman using matlabMapping existing memory to Matlab mxArray without waste of memoryHow to form a C++ 2D array with a Matlab matrix input?Creating and Passing of mxArray Data from other functions to Mex gateway functionHow to combine matrix of different size in a cell array into a matrix in MATLABHow MATLAB mex files access MATLAB instances?return value of mxGetPr() — equivalent loopingHow to convert varibles correctely between matlab (matrix, cell) and c++ (vectors or self-defining class) in Mexfile
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I would like to pass data between Eigen Matrix/Vector and mex arrays. In the following code, I defined a mex array called y_output, which contains a cell array. The variable y_output will be passed to MATLAB. Each element in y_output is a vector but with different lengths. I would like to pass a pointer that points to Eigen vectors to the mex array y_output.
Notice that the data stored in y will be modified with a user-defined function. After calling the function, I would assume that the data stored in y_output will be modified corresponding. However, I cannot directly pass the pointer from y_output to y. Is there any way to make it possible? Thanks!
This question is similar but different from the one at Pass C++ Eigen matrix to Matlab mex output. This question is asking how to pass an array of matrices, while the question in that link is asking how to pass a matrix.
#include "mex.h"
#include "matrix.h"
#include <Eigen>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
// prhs[0]: a cell array of length T, each element is a vector with different lengths
mwSize T = mxGetNumberOfElements(prhs[0]);
mwSize* n = new mwSize[T];
Eigen::VectorXd* z = new Eigen::VectorXd[T];
for(int t=0; t<T; t++)
n[t] = mxGetNumberOfElements(mxGetCell(prhs[0], t));
z[t] = Eigen::Map<Eigen::VectorXd>(mxGetPr(mxGetCell(prhs[0], t)), n[t]);
// create a cell matrix with T rows and one columns
mxArray* y_output = mxCreateCellMatrix(T,1);
// create corresponding Eigen objects
Eigen::VectorXd* y = new Eigen::VectorXd[T]();
Eigen::VectorXd y_temp(n[0]); y_temp.setZero();
for(int t=0; t<T; t++)
mxSetCell(y_output, t, mxCreateDoubleMatrix(n[t], 1, mxREAL));
y[t] = Eigen::VectorXd::Zero(n[t]);
y_temp.resize(n[t]);
Eigen::Map<Eigen::VectorXd> y[t](mxGetPr(mxGetCell(y_output, t)), n[t]); // This is not correct!
// Myfun(y, z);
// set output
plhs[0] = y_output;
c++ matlab mex eigen3
|
show 1 more comment
I would like to pass data between Eigen Matrix/Vector and mex arrays. In the following code, I defined a mex array called y_output, which contains a cell array. The variable y_output will be passed to MATLAB. Each element in y_output is a vector but with different lengths. I would like to pass a pointer that points to Eigen vectors to the mex array y_output.
Notice that the data stored in y will be modified with a user-defined function. After calling the function, I would assume that the data stored in y_output will be modified corresponding. However, I cannot directly pass the pointer from y_output to y. Is there any way to make it possible? Thanks!
This question is similar but different from the one at Pass C++ Eigen matrix to Matlab mex output. This question is asking how to pass an array of matrices, while the question in that link is asking how to pass a matrix.
#include "mex.h"
#include "matrix.h"
#include <Eigen>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
// prhs[0]: a cell array of length T, each element is a vector with different lengths
mwSize T = mxGetNumberOfElements(prhs[0]);
mwSize* n = new mwSize[T];
Eigen::VectorXd* z = new Eigen::VectorXd[T];
for(int t=0; t<T; t++)
n[t] = mxGetNumberOfElements(mxGetCell(prhs[0], t));
z[t] = Eigen::Map<Eigen::VectorXd>(mxGetPr(mxGetCell(prhs[0], t)), n[t]);
// create a cell matrix with T rows and one columns
mxArray* y_output = mxCreateCellMatrix(T,1);
// create corresponding Eigen objects
Eigen::VectorXd* y = new Eigen::VectorXd[T]();
Eigen::VectorXd y_temp(n[0]); y_temp.setZero();
for(int t=0; t<T; t++)
mxSetCell(y_output, t, mxCreateDoubleMatrix(n[t], 1, mxREAL));
y[t] = Eigen::VectorXd::Zero(n[t]);
y_temp.resize(n[t]);
Eigen::Map<Eigen::VectorXd> y[t](mxGetPr(mxGetCell(y_output, t)), n[t]); // This is not correct!
// Myfun(y, z);
// set output
plhs[0] = y_output;
c++ matlab mex eigen3
I think you misunderstood whatEigen::Mapdoes. It can interpret memory allocated by others as Eigen objects, but not the other way around.
– chtz
Mar 9 at 14:54
Thanks for the comment. Did you mean that I cannot pass the pointer to the content iny_outputthat is a vector of doubles to Eigen Vectory[t]? With the following code, I can copy the data, but I do not want just to copy the data but also to modify the content iny[t]so that the content iny_outputis also modified.y[t] = Eigen::Map<Eigen::VectorXd>(mxGetPr(mxGetCell(y_output, t)), n[t]);
– Bayes
Mar 9 at 15:21
Possible duplicate of Pass C++ Eigen matrix to Matlab mex output
– Cris Luengo
Mar 9 at 17:10
In the linked duplicate I explain how to avoid a copy by first allocating a MATLAB array of the right size, usingEigen::Mapto create an Eigen matrix or vector over that, and using that in your Eigen code to put the answer in. This question adds the complication of the cell array, but it seems you know how to create such an array already.
– Cris Luengo
Mar 9 at 17:13
@CrisLuengo It is almost a duplicate, though as you said yourself, this question wants not to only pass a single matrix, but an array of matrices ...
– chtz
Mar 9 at 20:32
|
show 1 more comment
I would like to pass data between Eigen Matrix/Vector and mex arrays. In the following code, I defined a mex array called y_output, which contains a cell array. The variable y_output will be passed to MATLAB. Each element in y_output is a vector but with different lengths. I would like to pass a pointer that points to Eigen vectors to the mex array y_output.
Notice that the data stored in y will be modified with a user-defined function. After calling the function, I would assume that the data stored in y_output will be modified corresponding. However, I cannot directly pass the pointer from y_output to y. Is there any way to make it possible? Thanks!
This question is similar but different from the one at Pass C++ Eigen matrix to Matlab mex output. This question is asking how to pass an array of matrices, while the question in that link is asking how to pass a matrix.
#include "mex.h"
#include "matrix.h"
#include <Eigen>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
// prhs[0]: a cell array of length T, each element is a vector with different lengths
mwSize T = mxGetNumberOfElements(prhs[0]);
mwSize* n = new mwSize[T];
Eigen::VectorXd* z = new Eigen::VectorXd[T];
for(int t=0; t<T; t++)
n[t] = mxGetNumberOfElements(mxGetCell(prhs[0], t));
z[t] = Eigen::Map<Eigen::VectorXd>(mxGetPr(mxGetCell(prhs[0], t)), n[t]);
// create a cell matrix with T rows and one columns
mxArray* y_output = mxCreateCellMatrix(T,1);
// create corresponding Eigen objects
Eigen::VectorXd* y = new Eigen::VectorXd[T]();
Eigen::VectorXd y_temp(n[0]); y_temp.setZero();
for(int t=0; t<T; t++)
mxSetCell(y_output, t, mxCreateDoubleMatrix(n[t], 1, mxREAL));
y[t] = Eigen::VectorXd::Zero(n[t]);
y_temp.resize(n[t]);
Eigen::Map<Eigen::VectorXd> y[t](mxGetPr(mxGetCell(y_output, t)), n[t]); // This is not correct!
// Myfun(y, z);
// set output
plhs[0] = y_output;
c++ matlab mex eigen3
I would like to pass data between Eigen Matrix/Vector and mex arrays. In the following code, I defined a mex array called y_output, which contains a cell array. The variable y_output will be passed to MATLAB. Each element in y_output is a vector but with different lengths. I would like to pass a pointer that points to Eigen vectors to the mex array y_output.
Notice that the data stored in y will be modified with a user-defined function. After calling the function, I would assume that the data stored in y_output will be modified corresponding. However, I cannot directly pass the pointer from y_output to y. Is there any way to make it possible? Thanks!
This question is similar but different from the one at Pass C++ Eigen matrix to Matlab mex output. This question is asking how to pass an array of matrices, while the question in that link is asking how to pass a matrix.
#include "mex.h"
#include "matrix.h"
#include <Eigen>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
// prhs[0]: a cell array of length T, each element is a vector with different lengths
mwSize T = mxGetNumberOfElements(prhs[0]);
mwSize* n = new mwSize[T];
Eigen::VectorXd* z = new Eigen::VectorXd[T];
for(int t=0; t<T; t++)
n[t] = mxGetNumberOfElements(mxGetCell(prhs[0], t));
z[t] = Eigen::Map<Eigen::VectorXd>(mxGetPr(mxGetCell(prhs[0], t)), n[t]);
// create a cell matrix with T rows and one columns
mxArray* y_output = mxCreateCellMatrix(T,1);
// create corresponding Eigen objects
Eigen::VectorXd* y = new Eigen::VectorXd[T]();
Eigen::VectorXd y_temp(n[0]); y_temp.setZero();
for(int t=0; t<T; t++)
mxSetCell(y_output, t, mxCreateDoubleMatrix(n[t], 1, mxREAL));
y[t] = Eigen::VectorXd::Zero(n[t]);
y_temp.resize(n[t]);
Eigen::Map<Eigen::VectorXd> y[t](mxGetPr(mxGetCell(y_output, t)), n[t]); // This is not correct!
// Myfun(y, z);
// set output
plhs[0] = y_output;
c++ matlab mex eigen3
c++ matlab mex eigen3
edited Mar 9 at 22:27
Bayes
asked Mar 9 at 4:20
BayesBayes
209
209
I think you misunderstood whatEigen::Mapdoes. It can interpret memory allocated by others as Eigen objects, but not the other way around.
– chtz
Mar 9 at 14:54
Thanks for the comment. Did you mean that I cannot pass the pointer to the content iny_outputthat is a vector of doubles to Eigen Vectory[t]? With the following code, I can copy the data, but I do not want just to copy the data but also to modify the content iny[t]so that the content iny_outputis also modified.y[t] = Eigen::Map<Eigen::VectorXd>(mxGetPr(mxGetCell(y_output, t)), n[t]);
– Bayes
Mar 9 at 15:21
Possible duplicate of Pass C++ Eigen matrix to Matlab mex output
– Cris Luengo
Mar 9 at 17:10
In the linked duplicate I explain how to avoid a copy by first allocating a MATLAB array of the right size, usingEigen::Mapto create an Eigen matrix or vector over that, and using that in your Eigen code to put the answer in. This question adds the complication of the cell array, but it seems you know how to create such an array already.
– Cris Luengo
Mar 9 at 17:13
@CrisLuengo It is almost a duplicate, though as you said yourself, this question wants not to only pass a single matrix, but an array of matrices ...
– chtz
Mar 9 at 20:32
|
show 1 more comment
I think you misunderstood whatEigen::Mapdoes. It can interpret memory allocated by others as Eigen objects, but not the other way around.
– chtz
Mar 9 at 14:54
Thanks for the comment. Did you mean that I cannot pass the pointer to the content iny_outputthat is a vector of doubles to Eigen Vectory[t]? With the following code, I can copy the data, but I do not want just to copy the data but also to modify the content iny[t]so that the content iny_outputis also modified.y[t] = Eigen::Map<Eigen::VectorXd>(mxGetPr(mxGetCell(y_output, t)), n[t]);
– Bayes
Mar 9 at 15:21
Possible duplicate of Pass C++ Eigen matrix to Matlab mex output
– Cris Luengo
Mar 9 at 17:10
In the linked duplicate I explain how to avoid a copy by first allocating a MATLAB array of the right size, usingEigen::Mapto create an Eigen matrix or vector over that, and using that in your Eigen code to put the answer in. This question adds the complication of the cell array, but it seems you know how to create such an array already.
– Cris Luengo
Mar 9 at 17:13
@CrisLuengo It is almost a duplicate, though as you said yourself, this question wants not to only pass a single matrix, but an array of matrices ...
– chtz
Mar 9 at 20:32
I think you misunderstood what
Eigen::Map does. It can interpret memory allocated by others as Eigen objects, but not the other way around.– chtz
Mar 9 at 14:54
I think you misunderstood what
Eigen::Map does. It can interpret memory allocated by others as Eigen objects, but not the other way around.– chtz
Mar 9 at 14:54
Thanks for the comment. Did you mean that I cannot pass the pointer to the content in
y_output that is a vector of doubles to Eigen Vector y[t]? With the following code, I can copy the data, but I do not want just to copy the data but also to modify the content in y[t] so that the content in y_output is also modified. y[t] = Eigen::Map<Eigen::VectorXd>(mxGetPr(mxGetCell(y_output, t)), n[t]);– Bayes
Mar 9 at 15:21
Thanks for the comment. Did you mean that I cannot pass the pointer to the content in
y_output that is a vector of doubles to Eigen Vector y[t]? With the following code, I can copy the data, but I do not want just to copy the data but also to modify the content in y[t] so that the content in y_output is also modified. y[t] = Eigen::Map<Eigen::VectorXd>(mxGetPr(mxGetCell(y_output, t)), n[t]);– Bayes
Mar 9 at 15:21
Possible duplicate of Pass C++ Eigen matrix to Matlab mex output
– Cris Luengo
Mar 9 at 17:10
Possible duplicate of Pass C++ Eigen matrix to Matlab mex output
– Cris Luengo
Mar 9 at 17:10
In the linked duplicate I explain how to avoid a copy by first allocating a MATLAB array of the right size, using
Eigen::Map to create an Eigen matrix or vector over that, and using that in your Eigen code to put the answer in. This question adds the complication of the cell array, but it seems you know how to create such an array already.– Cris Luengo
Mar 9 at 17:13
In the linked duplicate I explain how to avoid a copy by first allocating a MATLAB array of the right size, using
Eigen::Map to create an Eigen matrix or vector over that, and using that in your Eigen code to put the answer in. This question adds the complication of the cell array, but it seems you know how to create such an array already.– Cris Luengo
Mar 9 at 17:13
@CrisLuengo It is almost a duplicate, though as you said yourself, this question wants not to only pass a single matrix, but an array of matrices ...
– chtz
Mar 9 at 20:32
@CrisLuengo It is almost a duplicate, though as you said yourself, this question wants not to only pass a single matrix, but an array of matrices ...
– chtz
Mar 9 at 20:32
|
show 1 more comment
2 Answers
2
active
oldest
votes
Your solution copies data around both for the input and the output of MyFunc. It is possible to pass both arguments using a std::vector of Eigen::Map objects. The following code is based on your answer. Lines starting with //-- were removed from your code and replaced by the line which follow.
As a sidenote: Avoid allocating arrays with new (in 99.99% of all cases), but use a std::vector instead. This takes care of deallocating all resources when the object gets out of scope.
Also, in MyFunc you don't have to guess the size of y and z.
#include "mex.h"
#include "matrix.h"
//-- #include <Eigen> <-- this should be <Eigen/Eigen>, but likely Eigen/Core suffices
// Perhaps you also need to change your include-path
#include <Eigen/Core>
#include <vector>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
// prhs[0]: a cell array of length T, each element is a vector with different lengths
mwSize T = mxGetNumberOfElements(prhs[0]);
//-- mwSize* n = new mwSize[T];
std::vector<mwSize> n(T);
//-- Eigen::VectorXd* z = new Eigen::VectorXd[T];
std::vector<Eigen::Map<const Eigen::VectorXd> > z; // input vector of Maps
z.reserve(T);
for(int t=0; t<T; t++)
// Note: You don't actually seem to need n[t], except for creating y_output
n[t] = mxGetNumberOfElements(mxGetCell(prhs[0], t));
//-- z[t] = Eigen::Map<Eigen::VectorXd>(mxGetPr(mxGetCell(prhs[0], t)), n[t]);
z.emplace_back(mxGetPr(mxGetCell(prhs[0], t)), n[t]);
// create a cell matrix with T rows and one columns
mxArray* y_output = mxCreateCellMatrix(T,1);
// create corresponding Eigen objects
//-- Eigen::VectorXd* y = new Eigen::VectorXd[T]();
std::vector<Eigen::Map<Eigen::VectorXd> > y; // output vector of Maps
y.reserve(T);
// This must be called after setting up y:
//-- Myfun(y, z);
//-- double* ptemp;
for(int t=0; t<T; t++)
mxSetCell(y_output, t, mxCreateDoubleMatrix(n[t], 1, mxREAL));
//-- ptemp = mxGetPr(mxGetCell(y_output, t));
//-- // assign the data stored in y[t] to the contents in y_output.
//-- for(int i=0; i<n[t]; i++)
//-- //mxGetPr(mxGetCell(y_output, t))[i] = y[t](i);
//-- ptemp[i] = y[t](i);
//--
y.emplace_back(mxGetPr(mxGetCell(y_output, t)), n[t]);
// Now call Myfun, but the function now needs to accept vectors of Eigen::Map, instead of pointers to VectorXd
// It should be possible to keep the Code inside Myfun unchanged
// Myfun(y, z);
//-- ptemp = NULL;
// set output
plhs[0] = y_output;
Thank you so much for helping me out on this. This is exactly what I was looking for. The point of usingstd::vectoris taken. I need to learn more about C++.
– Bayes
Mar 9 at 22:20
add a comment |
I have figured a way to achieve what I wanted to. The crucial step is to call my own function first, and in the end, assign the data stored in y to y_output. I included the modified code below so that it can be helpful to anyone who is interested in.
#include "mex.h"
#include "matrix.h"
#include <Eigen>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
// prhs[0]: a cell array of length T, each element is a vector with different lengths
mwSize T = mxGetNumberOfElements(prhs[0]);
mwSize* n = new mwSize[T];
Eigen::VectorXd* z = new Eigen::VectorXd[T];
for(int t=0; t<T; t++)
n[t] = mxGetNumberOfElements(mxGetCell(prhs[0], t));
z[t] = Eigen::Map<Eigen::VectorXd>(mxGetPr(mxGetCell(prhs[0], t)), n[t]);
// create a cell matrix with T rows and one columns
mxArray* y_output = mxCreateCellMatrix(T,1);
// create corresponding Eigen objects
Eigen::VectorXd* y = new Eigen::VectorXd[T]();
// Myfun(y, z);
double* ptemp;
for(int t=0; t<T; t++)
mxSetCell(y_output, t, mxCreateDoubleMatrix(n[t], 1, mxREAL));
ptemp = mxGetPr(mxGetCell(y_output, t));
// assign the data stored in y[t] to the contents in y_output.
for(int i=0; i<n[t]; i++)
//mxGetPr(mxGetCell(y_output, t))[i] = y[t](i);
ptemp[i] = y[t](i);
ptemp = NULL;
// set output
plhs[0] = y_output;
1
You don’t need to copy, though this certainly works.
– Cris Luengo
Mar 9 at 17:09
Thanks for the suggestion!@CrisLuengo. I have updated my code to avoid repeated call to themxGetCell. I was trying to avoid copying the data between cell arrayy_outputandy, but I was failed to do so in my original question. That's why I came up with this compromise.
– Bayes
Mar 9 at 17:59
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55073946%2fpass-data-between-c-eigen-matrix-and-matlab-mxarray-with-a-cell-array%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Your solution copies data around both for the input and the output of MyFunc. It is possible to pass both arguments using a std::vector of Eigen::Map objects. The following code is based on your answer. Lines starting with //-- were removed from your code and replaced by the line which follow.
As a sidenote: Avoid allocating arrays with new (in 99.99% of all cases), but use a std::vector instead. This takes care of deallocating all resources when the object gets out of scope.
Also, in MyFunc you don't have to guess the size of y and z.
#include "mex.h"
#include "matrix.h"
//-- #include <Eigen> <-- this should be <Eigen/Eigen>, but likely Eigen/Core suffices
// Perhaps you also need to change your include-path
#include <Eigen/Core>
#include <vector>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
// prhs[0]: a cell array of length T, each element is a vector with different lengths
mwSize T = mxGetNumberOfElements(prhs[0]);
//-- mwSize* n = new mwSize[T];
std::vector<mwSize> n(T);
//-- Eigen::VectorXd* z = new Eigen::VectorXd[T];
std::vector<Eigen::Map<const Eigen::VectorXd> > z; // input vector of Maps
z.reserve(T);
for(int t=0; t<T; t++)
// Note: You don't actually seem to need n[t], except for creating y_output
n[t] = mxGetNumberOfElements(mxGetCell(prhs[0], t));
//-- z[t] = Eigen::Map<Eigen::VectorXd>(mxGetPr(mxGetCell(prhs[0], t)), n[t]);
z.emplace_back(mxGetPr(mxGetCell(prhs[0], t)), n[t]);
// create a cell matrix with T rows and one columns
mxArray* y_output = mxCreateCellMatrix(T,1);
// create corresponding Eigen objects
//-- Eigen::VectorXd* y = new Eigen::VectorXd[T]();
std::vector<Eigen::Map<Eigen::VectorXd> > y; // output vector of Maps
y.reserve(T);
// This must be called after setting up y:
//-- Myfun(y, z);
//-- double* ptemp;
for(int t=0; t<T; t++)
mxSetCell(y_output, t, mxCreateDoubleMatrix(n[t], 1, mxREAL));
//-- ptemp = mxGetPr(mxGetCell(y_output, t));
//-- // assign the data stored in y[t] to the contents in y_output.
//-- for(int i=0; i<n[t]; i++)
//-- //mxGetPr(mxGetCell(y_output, t))[i] = y[t](i);
//-- ptemp[i] = y[t](i);
//--
y.emplace_back(mxGetPr(mxGetCell(y_output, t)), n[t]);
// Now call Myfun, but the function now needs to accept vectors of Eigen::Map, instead of pointers to VectorXd
// It should be possible to keep the Code inside Myfun unchanged
// Myfun(y, z);
//-- ptemp = NULL;
// set output
plhs[0] = y_output;
Thank you so much for helping me out on this. This is exactly what I was looking for. The point of usingstd::vectoris taken. I need to learn more about C++.
– Bayes
Mar 9 at 22:20
add a comment |
Your solution copies data around both for the input and the output of MyFunc. It is possible to pass both arguments using a std::vector of Eigen::Map objects. The following code is based on your answer. Lines starting with //-- were removed from your code and replaced by the line which follow.
As a sidenote: Avoid allocating arrays with new (in 99.99% of all cases), but use a std::vector instead. This takes care of deallocating all resources when the object gets out of scope.
Also, in MyFunc you don't have to guess the size of y and z.
#include "mex.h"
#include "matrix.h"
//-- #include <Eigen> <-- this should be <Eigen/Eigen>, but likely Eigen/Core suffices
// Perhaps you also need to change your include-path
#include <Eigen/Core>
#include <vector>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
// prhs[0]: a cell array of length T, each element is a vector with different lengths
mwSize T = mxGetNumberOfElements(prhs[0]);
//-- mwSize* n = new mwSize[T];
std::vector<mwSize> n(T);
//-- Eigen::VectorXd* z = new Eigen::VectorXd[T];
std::vector<Eigen::Map<const Eigen::VectorXd> > z; // input vector of Maps
z.reserve(T);
for(int t=0; t<T; t++)
// Note: You don't actually seem to need n[t], except for creating y_output
n[t] = mxGetNumberOfElements(mxGetCell(prhs[0], t));
//-- z[t] = Eigen::Map<Eigen::VectorXd>(mxGetPr(mxGetCell(prhs[0], t)), n[t]);
z.emplace_back(mxGetPr(mxGetCell(prhs[0], t)), n[t]);
// create a cell matrix with T rows and one columns
mxArray* y_output = mxCreateCellMatrix(T,1);
// create corresponding Eigen objects
//-- Eigen::VectorXd* y = new Eigen::VectorXd[T]();
std::vector<Eigen::Map<Eigen::VectorXd> > y; // output vector of Maps
y.reserve(T);
// This must be called after setting up y:
//-- Myfun(y, z);
//-- double* ptemp;
for(int t=0; t<T; t++)
mxSetCell(y_output, t, mxCreateDoubleMatrix(n[t], 1, mxREAL));
//-- ptemp = mxGetPr(mxGetCell(y_output, t));
//-- // assign the data stored in y[t] to the contents in y_output.
//-- for(int i=0; i<n[t]; i++)
//-- //mxGetPr(mxGetCell(y_output, t))[i] = y[t](i);
//-- ptemp[i] = y[t](i);
//--
y.emplace_back(mxGetPr(mxGetCell(y_output, t)), n[t]);
// Now call Myfun, but the function now needs to accept vectors of Eigen::Map, instead of pointers to VectorXd
// It should be possible to keep the Code inside Myfun unchanged
// Myfun(y, z);
//-- ptemp = NULL;
// set output
plhs[0] = y_output;
Thank you so much for helping me out on this. This is exactly what I was looking for. The point of usingstd::vectoris taken. I need to learn more about C++.
– Bayes
Mar 9 at 22:20
add a comment |
Your solution copies data around both for the input and the output of MyFunc. It is possible to pass both arguments using a std::vector of Eigen::Map objects. The following code is based on your answer. Lines starting with //-- were removed from your code and replaced by the line which follow.
As a sidenote: Avoid allocating arrays with new (in 99.99% of all cases), but use a std::vector instead. This takes care of deallocating all resources when the object gets out of scope.
Also, in MyFunc you don't have to guess the size of y and z.
#include "mex.h"
#include "matrix.h"
//-- #include <Eigen> <-- this should be <Eigen/Eigen>, but likely Eigen/Core suffices
// Perhaps you also need to change your include-path
#include <Eigen/Core>
#include <vector>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
// prhs[0]: a cell array of length T, each element is a vector with different lengths
mwSize T = mxGetNumberOfElements(prhs[0]);
//-- mwSize* n = new mwSize[T];
std::vector<mwSize> n(T);
//-- Eigen::VectorXd* z = new Eigen::VectorXd[T];
std::vector<Eigen::Map<const Eigen::VectorXd> > z; // input vector of Maps
z.reserve(T);
for(int t=0; t<T; t++)
// Note: You don't actually seem to need n[t], except for creating y_output
n[t] = mxGetNumberOfElements(mxGetCell(prhs[0], t));
//-- z[t] = Eigen::Map<Eigen::VectorXd>(mxGetPr(mxGetCell(prhs[0], t)), n[t]);
z.emplace_back(mxGetPr(mxGetCell(prhs[0], t)), n[t]);
// create a cell matrix with T rows and one columns
mxArray* y_output = mxCreateCellMatrix(T,1);
// create corresponding Eigen objects
//-- Eigen::VectorXd* y = new Eigen::VectorXd[T]();
std::vector<Eigen::Map<Eigen::VectorXd> > y; // output vector of Maps
y.reserve(T);
// This must be called after setting up y:
//-- Myfun(y, z);
//-- double* ptemp;
for(int t=0; t<T; t++)
mxSetCell(y_output, t, mxCreateDoubleMatrix(n[t], 1, mxREAL));
//-- ptemp = mxGetPr(mxGetCell(y_output, t));
//-- // assign the data stored in y[t] to the contents in y_output.
//-- for(int i=0; i<n[t]; i++)
//-- //mxGetPr(mxGetCell(y_output, t))[i] = y[t](i);
//-- ptemp[i] = y[t](i);
//--
y.emplace_back(mxGetPr(mxGetCell(y_output, t)), n[t]);
// Now call Myfun, but the function now needs to accept vectors of Eigen::Map, instead of pointers to VectorXd
// It should be possible to keep the Code inside Myfun unchanged
// Myfun(y, z);
//-- ptemp = NULL;
// set output
plhs[0] = y_output;
Your solution copies data around both for the input and the output of MyFunc. It is possible to pass both arguments using a std::vector of Eigen::Map objects. The following code is based on your answer. Lines starting with //-- were removed from your code and replaced by the line which follow.
As a sidenote: Avoid allocating arrays with new (in 99.99% of all cases), but use a std::vector instead. This takes care of deallocating all resources when the object gets out of scope.
Also, in MyFunc you don't have to guess the size of y and z.
#include "mex.h"
#include "matrix.h"
//-- #include <Eigen> <-- this should be <Eigen/Eigen>, but likely Eigen/Core suffices
// Perhaps you also need to change your include-path
#include <Eigen/Core>
#include <vector>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
// prhs[0]: a cell array of length T, each element is a vector with different lengths
mwSize T = mxGetNumberOfElements(prhs[0]);
//-- mwSize* n = new mwSize[T];
std::vector<mwSize> n(T);
//-- Eigen::VectorXd* z = new Eigen::VectorXd[T];
std::vector<Eigen::Map<const Eigen::VectorXd> > z; // input vector of Maps
z.reserve(T);
for(int t=0; t<T; t++)
// Note: You don't actually seem to need n[t], except for creating y_output
n[t] = mxGetNumberOfElements(mxGetCell(prhs[0], t));
//-- z[t] = Eigen::Map<Eigen::VectorXd>(mxGetPr(mxGetCell(prhs[0], t)), n[t]);
z.emplace_back(mxGetPr(mxGetCell(prhs[0], t)), n[t]);
// create a cell matrix with T rows and one columns
mxArray* y_output = mxCreateCellMatrix(T,1);
// create corresponding Eigen objects
//-- Eigen::VectorXd* y = new Eigen::VectorXd[T]();
std::vector<Eigen::Map<Eigen::VectorXd> > y; // output vector of Maps
y.reserve(T);
// This must be called after setting up y:
//-- Myfun(y, z);
//-- double* ptemp;
for(int t=0; t<T; t++)
mxSetCell(y_output, t, mxCreateDoubleMatrix(n[t], 1, mxREAL));
//-- ptemp = mxGetPr(mxGetCell(y_output, t));
//-- // assign the data stored in y[t] to the contents in y_output.
//-- for(int i=0; i<n[t]; i++)
//-- //mxGetPr(mxGetCell(y_output, t))[i] = y[t](i);
//-- ptemp[i] = y[t](i);
//--
y.emplace_back(mxGetPr(mxGetCell(y_output, t)), n[t]);
// Now call Myfun, but the function now needs to accept vectors of Eigen::Map, instead of pointers to VectorXd
// It should be possible to keep the Code inside Myfun unchanged
// Myfun(y, z);
//-- ptemp = NULL;
// set output
plhs[0] = y_output;
answered Mar 9 at 20:29
chtzchtz
8,16421335
8,16421335
Thank you so much for helping me out on this. This is exactly what I was looking for. The point of usingstd::vectoris taken. I need to learn more about C++.
– Bayes
Mar 9 at 22:20
add a comment |
Thank you so much for helping me out on this. This is exactly what I was looking for. The point of usingstd::vectoris taken. I need to learn more about C++.
– Bayes
Mar 9 at 22:20
Thank you so much for helping me out on this. This is exactly what I was looking for. The point of using
std::vector is taken. I need to learn more about C++.– Bayes
Mar 9 at 22:20
Thank you so much for helping me out on this. This is exactly what I was looking for. The point of using
std::vector is taken. I need to learn more about C++.– Bayes
Mar 9 at 22:20
add a comment |
I have figured a way to achieve what I wanted to. The crucial step is to call my own function first, and in the end, assign the data stored in y to y_output. I included the modified code below so that it can be helpful to anyone who is interested in.
#include "mex.h"
#include "matrix.h"
#include <Eigen>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
// prhs[0]: a cell array of length T, each element is a vector with different lengths
mwSize T = mxGetNumberOfElements(prhs[0]);
mwSize* n = new mwSize[T];
Eigen::VectorXd* z = new Eigen::VectorXd[T];
for(int t=0; t<T; t++)
n[t] = mxGetNumberOfElements(mxGetCell(prhs[0], t));
z[t] = Eigen::Map<Eigen::VectorXd>(mxGetPr(mxGetCell(prhs[0], t)), n[t]);
// create a cell matrix with T rows and one columns
mxArray* y_output = mxCreateCellMatrix(T,1);
// create corresponding Eigen objects
Eigen::VectorXd* y = new Eigen::VectorXd[T]();
// Myfun(y, z);
double* ptemp;
for(int t=0; t<T; t++)
mxSetCell(y_output, t, mxCreateDoubleMatrix(n[t], 1, mxREAL));
ptemp = mxGetPr(mxGetCell(y_output, t));
// assign the data stored in y[t] to the contents in y_output.
for(int i=0; i<n[t]; i++)
//mxGetPr(mxGetCell(y_output, t))[i] = y[t](i);
ptemp[i] = y[t](i);
ptemp = NULL;
// set output
plhs[0] = y_output;
1
You don’t need to copy, though this certainly works.
– Cris Luengo
Mar 9 at 17:09
Thanks for the suggestion!@CrisLuengo. I have updated my code to avoid repeated call to themxGetCell. I was trying to avoid copying the data between cell arrayy_outputandy, but I was failed to do so in my original question. That's why I came up with this compromise.
– Bayes
Mar 9 at 17:59
add a comment |
I have figured a way to achieve what I wanted to. The crucial step is to call my own function first, and in the end, assign the data stored in y to y_output. I included the modified code below so that it can be helpful to anyone who is interested in.
#include "mex.h"
#include "matrix.h"
#include <Eigen>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
// prhs[0]: a cell array of length T, each element is a vector with different lengths
mwSize T = mxGetNumberOfElements(prhs[0]);
mwSize* n = new mwSize[T];
Eigen::VectorXd* z = new Eigen::VectorXd[T];
for(int t=0; t<T; t++)
n[t] = mxGetNumberOfElements(mxGetCell(prhs[0], t));
z[t] = Eigen::Map<Eigen::VectorXd>(mxGetPr(mxGetCell(prhs[0], t)), n[t]);
// create a cell matrix with T rows and one columns
mxArray* y_output = mxCreateCellMatrix(T,1);
// create corresponding Eigen objects
Eigen::VectorXd* y = new Eigen::VectorXd[T]();
// Myfun(y, z);
double* ptemp;
for(int t=0; t<T; t++)
mxSetCell(y_output, t, mxCreateDoubleMatrix(n[t], 1, mxREAL));
ptemp = mxGetPr(mxGetCell(y_output, t));
// assign the data stored in y[t] to the contents in y_output.
for(int i=0; i<n[t]; i++)
//mxGetPr(mxGetCell(y_output, t))[i] = y[t](i);
ptemp[i] = y[t](i);
ptemp = NULL;
// set output
plhs[0] = y_output;
1
You don’t need to copy, though this certainly works.
– Cris Luengo
Mar 9 at 17:09
Thanks for the suggestion!@CrisLuengo. I have updated my code to avoid repeated call to themxGetCell. I was trying to avoid copying the data between cell arrayy_outputandy, but I was failed to do so in my original question. That's why I came up with this compromise.
– Bayes
Mar 9 at 17:59
add a comment |
I have figured a way to achieve what I wanted to. The crucial step is to call my own function first, and in the end, assign the data stored in y to y_output. I included the modified code below so that it can be helpful to anyone who is interested in.
#include "mex.h"
#include "matrix.h"
#include <Eigen>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
// prhs[0]: a cell array of length T, each element is a vector with different lengths
mwSize T = mxGetNumberOfElements(prhs[0]);
mwSize* n = new mwSize[T];
Eigen::VectorXd* z = new Eigen::VectorXd[T];
for(int t=0; t<T; t++)
n[t] = mxGetNumberOfElements(mxGetCell(prhs[0], t));
z[t] = Eigen::Map<Eigen::VectorXd>(mxGetPr(mxGetCell(prhs[0], t)), n[t]);
// create a cell matrix with T rows and one columns
mxArray* y_output = mxCreateCellMatrix(T,1);
// create corresponding Eigen objects
Eigen::VectorXd* y = new Eigen::VectorXd[T]();
// Myfun(y, z);
double* ptemp;
for(int t=0; t<T; t++)
mxSetCell(y_output, t, mxCreateDoubleMatrix(n[t], 1, mxREAL));
ptemp = mxGetPr(mxGetCell(y_output, t));
// assign the data stored in y[t] to the contents in y_output.
for(int i=0; i<n[t]; i++)
//mxGetPr(mxGetCell(y_output, t))[i] = y[t](i);
ptemp[i] = y[t](i);
ptemp = NULL;
// set output
plhs[0] = y_output;
I have figured a way to achieve what I wanted to. The crucial step is to call my own function first, and in the end, assign the data stored in y to y_output. I included the modified code below so that it can be helpful to anyone who is interested in.
#include "mex.h"
#include "matrix.h"
#include <Eigen>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
// prhs[0]: a cell array of length T, each element is a vector with different lengths
mwSize T = mxGetNumberOfElements(prhs[0]);
mwSize* n = new mwSize[T];
Eigen::VectorXd* z = new Eigen::VectorXd[T];
for(int t=0; t<T; t++)
n[t] = mxGetNumberOfElements(mxGetCell(prhs[0], t));
z[t] = Eigen::Map<Eigen::VectorXd>(mxGetPr(mxGetCell(prhs[0], t)), n[t]);
// create a cell matrix with T rows and one columns
mxArray* y_output = mxCreateCellMatrix(T,1);
// create corresponding Eigen objects
Eigen::VectorXd* y = new Eigen::VectorXd[T]();
// Myfun(y, z);
double* ptemp;
for(int t=0; t<T; t++)
mxSetCell(y_output, t, mxCreateDoubleMatrix(n[t], 1, mxREAL));
ptemp = mxGetPr(mxGetCell(y_output, t));
// assign the data stored in y[t] to the contents in y_output.
for(int i=0; i<n[t]; i++)
//mxGetPr(mxGetCell(y_output, t))[i] = y[t](i);
ptemp[i] = y[t](i);
ptemp = NULL;
// set output
plhs[0] = y_output;
edited Mar 9 at 17:57
answered Mar 9 at 15:47
BayesBayes
209
209
1
You don’t need to copy, though this certainly works.
– Cris Luengo
Mar 9 at 17:09
Thanks for the suggestion!@CrisLuengo. I have updated my code to avoid repeated call to themxGetCell. I was trying to avoid copying the data between cell arrayy_outputandy, but I was failed to do so in my original question. That's why I came up with this compromise.
– Bayes
Mar 9 at 17:59
add a comment |
1
You don’t need to copy, though this certainly works.
– Cris Luengo
Mar 9 at 17:09
Thanks for the suggestion!@CrisLuengo. I have updated my code to avoid repeated call to themxGetCell. I was trying to avoid copying the data between cell arrayy_outputandy, but I was failed to do so in my original question. That's why I came up with this compromise.
– Bayes
Mar 9 at 17:59
1
1
You don’t need to copy, though this certainly works.
– Cris Luengo
Mar 9 at 17:09
You don’t need to copy, though this certainly works.
– Cris Luengo
Mar 9 at 17:09
Thanks for the suggestion!@CrisLuengo. I have updated my code to avoid repeated call to the
mxGetCell. I was trying to avoid copying the data between cell array y_output and y, but I was failed to do so in my original question. That's why I came up with this compromise.– Bayes
Mar 9 at 17:59
Thanks for the suggestion!@CrisLuengo. I have updated my code to avoid repeated call to the
mxGetCell. I was trying to avoid copying the data between cell array y_output and y, but I was failed to do so in my original question. That's why I came up with this compromise.– Bayes
Mar 9 at 17:59
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55073946%2fpass-data-between-c-eigen-matrix-and-matlab-mxarray-with-a-cell-array%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I think you misunderstood what
Eigen::Mapdoes. It can interpret memory allocated by others as Eigen objects, but not the other way around.– chtz
Mar 9 at 14:54
Thanks for the comment. Did you mean that I cannot pass the pointer to the content in
y_outputthat is a vector of doubles to Eigen Vectory[t]? With the following code, I can copy the data, but I do not want just to copy the data but also to modify the content iny[t]so that the content iny_outputis also modified.y[t] = Eigen::Map<Eigen::VectorXd>(mxGetPr(mxGetCell(y_output, t)), n[t]);– Bayes
Mar 9 at 15:21
Possible duplicate of Pass C++ Eigen matrix to Matlab mex output
– Cris Luengo
Mar 9 at 17:10
In the linked duplicate I explain how to avoid a copy by first allocating a MATLAB array of the right size, using
Eigen::Mapto create an Eigen matrix or vector over that, and using that in your Eigen code to put the answer in. This question adds the complication of the cell array, but it seems you know how to create such an array already.– Cris Luengo
Mar 9 at 17:13
@CrisLuengo It is almost a duplicate, though as you said yourself, this question wants not to only pass a single matrix, but an array of matrices ...
– chtz
Mar 9 at 20:32