How to Loop in mexfunction?

조회 수: 2 (최근 30일)
Chang seok Ma
Chang seok Ma 2021년 2월 13일
댓글: Chang seok Ma 2021년 2월 20일
Hello,
I am working on 2d array in mexfunction. And I have a couple of questions about it.
This is the example that I modify a code that I found on the website.
/*==========================================================
* arrayMultiplier.c
*
* Multiplies a 1xN matrix with a N X N matrix
* and outputs a 1xN matrix
*
* The calling syntax is:
* outMatrix = arrayProduct(vector, array)
*========================================================*/
#include "mex.h"
/* The computational routine */
void arrayMultiplier( double *vec, double *arr, int n, int temp ,double *z){
temp = temp + 1;
for (int i=0; i<n; i++) {
for(int j=0; j<n; j++) {
z[i] += vec[j] * arr[j+i*n];
}
}
}
/* The gateway function */
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]) {
double *vec;
double *arr;
int nr;
double *outMatrix;
int tempr;
vec = mxGetPr(prhs[0]);
arr = mxGetPr(prhs[1]); /* This is where the warning appears */
nr = mxGetScalar(prhs[2]); /*The "n" parameter of the 1 x n output matrix*/
tempr = mxGetScalar(prhs[3]);
/* creating the output matrix */
plhs[0] = mxCreateDoubleMatrix(1,nr,mxREAL);
/* get a pointer to the real data in the output matrix */
outMatrix = mxGetPr(plhs[0]);
/* call the computational routine */
arrayMultiplier(vec,arr,nr,tempr,outMatrix);
}
After this I made .m file
clear all;
clc;
tic
cd 'C:\Users\chang\Desktop\New Folder'
mex testing.c
% ================ 1. Parameters and Constants ============================
numb = 1
A = [1,2,3,4];
B = [1,2,3,4;5,6,7,8;1,2,3,4;5,6,7,8];
AAA = testing(A, B, 4, numb);
I thought by running this code, I should get numb = 2 becasue I added temp = temp +1 in the .c file
Then I got right answer for A*B but numb is still 1 which is quite different from what I expected.
This is quite a simple version of what I am trying to do.
I am trying to use 'while' in the code but everytime I run the code it just run one time and never repeat.
while (it <= itmax) {
it = it ++;
Then I found out that 'temp = temp + 1' doesn't work as what I expected.
Any solutions?
Thanks in advance.
P.S
Is there a way to have matrix multiplication inside mex function?
So that I can just just have A = matrixMultiply(B,C) instead of using for loop to get A.

채택된 답변

James Tursa
James Tursa 2021년 2월 13일
편집: James Tursa 2021년 2월 13일
You have a fundamental misunderstanding of how the C language works with pass-by-value scalar arguments. In this code:
void arrayMultiplier( double *vec, double *arr, int n, int temp ,double *z){ /* (1) */
temp = temp + 1; /* (2) */
:
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]) {
int tempr;
tempr = mxGetScalar(prhs[3]); /* (3) */
arrayMultiplier(vec,arr,nr,tempr,outMatrix); /* (4) */
You pass in numb from MATLAB. In (3) above you get a copy of numb and place it in the tempr variable. From that point on you are working with the copy, not the original. So there is no way to alter the original numb by modifying tempr. Additionally, in (4) you pass tempr by value to the arrayMultiplier function. That means in (1) the temp variable is a copy of the tempr variable. You are not working with tempr directly anymore. So in (2) when you add 1 to temp, you are adding 1 to the copy and this has no effect on the original tempr variable.
There are ways to alter the MATLAB numb variable inplace in a mex routine using data pointers, but this violates the const attribute of prhs[ ] and is not advised because it can have nasty side effects.
You also asked about how to multiply matrices in mex functions without using loops. The short answer is to simply call the same BLAS library function that MATLAB uses in the background for matrix multiplies, which is dgemm for full double precision variables. You can see the interface here:
Some instructions for doing this in MATLAB can be found here:
  댓글 수: 10
James Tursa
James Tursa 2021년 2월 19일
편집: James Tursa 2021년 2월 19일
Yes, same problem. C is an uninitialized pointer in mexFunction. So you pass it down to your functions and write into it and bad things happen. You need to allocate C first. E.g., you could put this in your mexFunction:
C = (double *) mxMalloc(m*n*sizeof(*C));
secondfn(A, m, n, C, P);
mxFree(C):
Chang seok Ma
Chang seok Ma 2021년 2월 20일
Oh I get it.
I followed your comments and finally build my own code.
However I think this only works in Case1. which only have small size matrices.
If I use somewhat bigger size matrices as it is in Case2, I get different results each time I run the code.
Do you think this is just a code error or is there any other thing that I am missing?
Thank you so much for all the comments. I really appreciate it.
#include "mex.h"
void firstfn(double *Af, double *Bf, size_t m, size_t n, size_t p, double *Df){
for(size_t k = 1; k <= n; k++){
for(size_t i = m*(k-1); i < m*k; i++){
size_t temp = i - m*(k-1);
for(size_t j = 0; j < p; j++){
Df[i] += Af[temp+j*m] * Bf[j+p*(k-1)] ;
}
}
}
}
void secondfn(double *As, double *Bs, size_t m, size_t n, size_t p, double *Ds, double *Ps){
firstfn(As, Bs, m, n, p, Ds);
for (size_t i = 0; i < m*n; i++){
Ps[i] = Ds[i];
}
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *A, *B, *D, *P; /* pointers to input & output matrices*/
size_t m,n,p; /* matrix dimensions */
A = mxGetPr(prhs[0]); /* first input matrix */
B = mxGetPr(prhs[1]); /* second input matrix */
m = mxGetM(prhs[0]); /* dimensions of input matrices */
p = mxGetN(prhs[0]);
n = mxGetN(prhs[1]);
plhs[0] = mxCreateDoubleMatrix(m, n, mxREAL);
P = mxGetPr(plhs[0]);
D = (double *) mxMalloc(m*n*sizeof(*D));
//secondfn(A, B, m, n, p, D, P);
secondfn(A, B, m, n, p, D, P);
mxFree(D);
}
Case 1.
mex additionalcodemine2.c
A = [1 2 3 4 ;1 2 3 4 ];
B = [3 4 5 6 ; 7 8 9 10 ; 11 12 13 14 ; 7 8 9 10];
Result = additionalcodemine2(A,B);
Case 2.
mex additionalcodemine2.c
A= 2* ones(320,3);
B = [1/3 1/3 1/3]';
Result = additionalcodemine2(A,B);

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Write C Functions Callable from MATLAB (MEX Files)에 대해 자세히 알아보기

태그

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by