Mex - 传递3维数组作为输出

时间:2016-11-08 15:58:35

标签: c arrays matlab mex

我的问题是我想将一个3维数组作为输出传递给matlab并在单独的C void函数中使用它。但是当我尝试我的Matlab Crashes时。我几乎刚刚开始使用mex函数并创建了其他没有问题的函数,但它们只输出了数组和单个值。

这是我的代码。:

第一个文件是我的输入文件pm_motion_entry.c。:

#include <mex.h>
#include <matrix.h>

/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
/* Variable declarations here */    
    double sigma;   
    double L;
    double radius;
    int N;
    int M;

    double *outMatrixOne;
    mwSignedIndex *outMatrixTwo;
    mxArray *Array;

/* Dimensions for cell array */
    mwSize dim[2] = {M,N};

/* checks for right type*/
    if(nrhs != 5) {
        mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs","Inputs: sigma, L, radius,  N, NumberOfParticles");
    }

    if(nlhs != 2) {
        mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs","Too Few output argumetns, Output is I and Particle");
    }
    sigma = mxGetScalar(prhs[0]);   
    L = mxGetScalar(prhs[1]);
    radius = mxGetScalar(prhs[2]);
    N = mxGetScalar(prhs[3]);
    M = mxGetScalar(prhs[4]);

    if( !mxIsDouble(prhs[0]) || !mxIsDouble(prhs[1]) || !mxIsDouble(prhs[2]) || !mxIsDouble(prhs[3]) || !mxIsDouble(prhs[4])) {
        mexErrMsgIdAndTxt("MyToolBox:arrayProduct:notScalar","Input 1,2 and 3 should be of type double, and 4 and 5 should be of type Integer.");
    }

/* create output matrix */
    plhs[0] = mxCreateDoubleMatrix(N,1,mxREAL);
    Array = mxCreateNumericArray(2,dim,mxDOUBLE_CLASS,mxREAL); /* Two cell arrays one for x positions and one for y positions*/

/* assign pointer to output*/
    outMatrixOne = mxGetPr(plhs[0]);
    outMatrixTwo = (mwSignedIndex*)mxGetData(Array);

/* run function */
    pBm_motion(sigma,L,radius,N,M,outMatrixOne,outMatrixTwo);
}

我的主要计算函数名为pm_motion.c。:

#define _USE_MATH_DEFINES
#include <math.h>
#define UNIFORM ((rand()+0.5)/(RAND_MAX+1.0)) /* uniform inside [0,1] */
#include "mex.h"
/* Function for the calculation of the Intensity spectra of pure Brownian motion in FSC data */
void pBm_motion(double sigma, double L, double radius, int N, int M, double *In, double ***Particle)
{   
    /* Inputs/Outputs: D is the diffusion coefficient, tau is the size of timesteps, L is the length of on side of the system, radius is the radius of the focal volume, N is the number of time steps and M is the number of particles */
    /* Initialization of Parameters */
    int n = 1;
    int i;
    double pos_x,pos_y;

    /* The random walk and advancement in time */
    /* First place all particles randomly, this is t=0 */
    for(i = 0; i <= M; i++){
        Particle[i][0][0] = (-1.0)*UNIFORM + 0.5;
        Particle[i][0][1] = (-1.0)*UNIFORM + 0.5;
        In[0] += exp(-((Particle[i][0][0]*Particle[i][0][0])+(Particle[i][0][1]*Particle[i][0][1]))/(2.0*radius*radius));
    }

    /* Then we let time flow in the system */
    while(N >= n){
        for(i = 0; i <= M; i++){
            /* Using the Box-Muller Method to generate random normal distrubuted number to find the new position */
            pos_x = Particle[i][n][0] + sigma*sqrt(-2.0*log(UNIFORM))*sin(2.0*M_PI*UNIFORM);
            pos_y = Particle[i][n][1] + sigma*sqrt(-2.0*log(UNIFORM))*sin(2.0*M_PI*UNIFORM);

            /* Double Periodic violation */
            if(pos_x > (L/2.0) && pos_y > (L/2.0)){
                pos_x = -(L/2.0)+(pos_x - (L/2.0));
                pos_y = -(L/2.0)+(pos_y - (L/2.0));
            }
            if(pos_x < -(L/2.0) && pos_y > (L/2.0)){
                pos_y = -(L/2.0)+(pos_y - (L/2.0));
                pos_x = (L/2.0)+((L/2.0) + pos_x);
            }
            if(pos_x < (L/2.0) && pos_y < -(L/2.0)){
                pos_x = -(L/2.0)+(pos_x - (L/2.0));
                pos_y = (L/2.0)+((L/2.0) + pos_y);
            }
            if(pos_x < -(L/2.0) && pos_y < -(L/2.0)){
                pos_y = (L/2.0)+((L/2.0) + pos_y);
                pos_x = (L/2.0)+((L/2.0) + pos_x);
            }

            /* Periodic Boundary condition invoked, maybe.. */
            if(pos_x > (L/2.0)){
                pos_x = -(L/2.0)+(pos_x - (L/2.0));
            }
            if(pos_y > (L/2.0)){
                pos_y = -(L/2.0)+(pos_y - (L/2.0));
            }
            if(pos_x < -(L/2.0)){
                pos_x = (L/2.0)+((L/2.0) + pos_x);
            }
            if(pos_y < -(L/2.0)){
                pos_y = (L/2.0)+((L/2.0) + pos_y);
            }
            /* Update position. */
            Particle[i][n][0] = pos_x;
            Particle[i][n][1] = pos_y;
            /* Calculate Intensity */
            In[n] += exp(-((Particle[i][n][0]*Particle[i][n][0])+(Particle[i][n][1]*Particle[i][n][1]))/(2.0*radius*radius));   
        }       
        n++;    
    }
}

我觉得这是我在条目文件中访问3D矩阵的方式,但我对mex了解不够,但还不太确定。

0 个答案:

没有答案