2

I want to run a two C programs called "hello1.c" and "hello2.c" from matlab.

My hello1.c code is as follows:

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <mex.h>
#include <math.h>
#include "matrix.h"


void funcc(double **f, double **x, long n, long b, double lambda, double theta)
{
    long i;
    long j;
    double u,v,y,z,w;
    y = theta*lambda;
    w = lambda*lambda;
    z = 0.5*(theta+1.0)*w;

    u = 0.0;
    for(i=0;i<n;i++)
    {
        for(j=0;j<b;j++)
        v = fabs(x[i][j]);
        if (v <= lambda)
            u += lambda*v;
        else if (v > y)
            u += z;
        else
            u += 0.5*(v*(2*y - v) - w)/(theta-1.0);
        }
    **f = u;
    return;
}


void mexFunction (int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
    /*set up input arguments */
    double **x       =            mxGetPr(prhs[0]);
    long     n      =      (long)mxGetScalar(prhs[1]);
    long     b      =      (long)mxGetScalar(prhs[2]);
    double  lambda  =            mxGetScalar(prhs[3]);
    double  theta   =            mxGetScalar(prhs[4]);
    int     type    =       (int)mxGetScalar(prhs[5]);

    double **f;


    /* set up output arguments */
    plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);

    f=mxGetPr(plhs[0]);

    funcc(f, x, n, b, lambda, theta);
    }

My hello2.c code is as follows:

long mymin(double *x, long n)
{
    long i, ind;
    double temp;
    temp = x[0];
    ind = 0;
    for (i=1;i<n;i++)
    {
        if (x[i] < temp)
        {
            ind = i;
            temp = x[i];
        }

    }
    return ind;
}


        void funnn(double *x, double *d, long n, long b, double lambda, double theta)
        {
            long i;
            long j;
            double u,z,w;
            double xtemp[3],ytemp[3];
            z = theta*lambda;
            w = lambda*lambda;
            for(i=0;i<n;i++)
            {
                for(j=0;j<b;j++)
                u = fabs(d[j*n + i]);
                xtemp[0] = min(lambda,max(0,u - lambda));
                xtemp[1] = min(z,max(lambda,(u*(theta-1.0)-z)/(theta-2.0)));
                xtemp[2] = max(z,u);

                ytemp[0] = 0.5*(xtemp[0] - u)*(xtemp[0] - u) + lambda*xtemp[0];
                ytemp[1] = 0.5*(xtemp[1] - u)*(xtemp[1] - u) + 0.5*(xtemp[1]*(-xtemp[1] + 2*z) - w)/(theta-1.0);
                ytemp[2] = 0.5*(xtemp[2] - u)*(xtemp[2] - u) + 0.5*(theta+1.0)*w;
                x[j*n + i] = xtemp[mymin(ytemp,3)];
                x[j*n + i] = d[j*n + i]>= 0 ? x[j*n + i] : -x[j*n + i];
            }
            //return;
        }



        void mexFunction (int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
        {
            /*set up input arguments */
            double* d       =            mxGetPr(prhs[0]);
            long     n      =      (long)mxGetScalar(prhs[1]);
            long     b      =      (long)mxGetScalar(prhs[2]);
            double  lambda  =            mxGetScalar(prhs[3]);
            double  theta   =            mxGetScalar(prhs[4]);

            double *x;


            /* set up output arguments */
            plhs[0] = mxCreateDoubleMatrix(n,b,mxREAL);

            x=mxGetPr(plhs[0]);

            funnn(x, d, n, b, lambda, theta);
        }

The problem is that when I compile my MATLAB code in which it calls my C functions (of course I have already written mex hello1.c and mex hello2.c), MATLAB returns me the screen which exhibits that MATLAB has encountered an internal problem and needs to close. In fact this error was detected while a MEX-file was running.

Is this because my functions mexFunction are not written correctly? Can anyone who knows how to write MEX functions help me?

Any help will be very appreciated!

1
  • 1
    You could try to write a very easy Hello Word .c file and see if the problem persist when calling it from Matlab Commented Jul 20, 2016 at 15:33

1 Answer 1

2

For hello1.c, mxGetPr in MEX does not give you a double pointer. It gives you a single pointer and for 2D memory, it is in a column-major layout. You have to access the right value in the 2D array by the following syntax, given that i and j are the row and column in the 2D array you want to access:

ind = j*rows + i;

... and thus if you want location (i,j) in your 2D array x, simply do:

double val = x[j*rows + i];

rows is the total number of rows in your 2D array. As such, you will have to correct this in your code to be able to access the 2D array properly. You'll also have to do the same for f as well. In addition, you're missing a pair of curly braces around the second for loop and I'll explain why later.

Therefore, your function becomes:

void funcc(double *f, double *x, long n, long b, double lambda, double theta) // Note change in function declaration
{
    long i;
    long j;
    double u,v,y,z,w;
    y = theta*lambda;
    w = lambda*lambda;
    z = 0.5*(theta+1.0)*w;

    u = 0.0;
    // n is the rows, b is the columns
    for(i=0;i<n;i++)
    {
        for(j=0;j<b;j++) { // Added
        v = fabs(x[j*n + i]); // Change here
        if (v <= lambda)
            u += lambda*v;
        else if (v > y)
            u += z;
        else
            u += 0.5*(v*(2*y - v) - w)/(theta-1.0);
        } // Added
    } 
    *f = u; // Change
    //return; // Superfluous
}

Your mexFunction now becomes:

void mexFunction (int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
    /*set up input arguments */
    double *x       =            mxGetPr(prhs[0]); // Change
    long     n      =      (long)mxGetScalar(prhs[1]);
    long     b      =      (long)mxGetScalar(prhs[2]);
    double  lambda  =            mxGetScalar(prhs[3]);
    double  theta   =            mxGetScalar(prhs[4]);
    int     type    =       (int)mxGetScalar(prhs[5]);

    double *f; // Change

    /* set up output arguments */
    plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);

    f=mxGetPr(plhs[0]);

    funcc(f, x, n, b, lambda, theta);
}

For hello2.c, everything is fine except for the second for loop. You simply need to surround the code block with curly braces:

           for(i=0;i<n;i++)
           {
                for(j=0;j<b;j++) { // added
                u = fabs(d[j*n + i]);
                xtemp[0] = min(lambda,max(0,u - lambda));
                xtemp[1] = min(z,max(lambda,(u*(theta-1.0)-z)/(theta-2.0)));
                xtemp[2] = max(z,u);

                ytemp[0] = 0.5*(xtemp[0] - u)*(xtemp[0] - u) + lambda*xtemp[0];
                ytemp[1] = 0.5*(xtemp[1] - u)*(xtemp[1] - u) + 0.5*(xtemp[1]*(-xtemp[1] + 2*z) - w)/(theta-1.0);
                ytemp[2] = 0.5*(xtemp[2] - u)*(xtemp[2] - u) + 0.5*(theta+1.0)*w;
                x[j*n + i] = xtemp[mymin(ytemp,3)];
                x[j*n + i] = d[j*n + i]>= 0 ? x[j*n + i] : -x[j*n + i];
                } //added
            } 

The reason why you need the extra braces for both files is because if you omit them, C only considers the first line after the loop to be the loop body. The rest of the code after the for loop finishes is executed and not part of the loop which is the reason why you're getting segmentation faults.

Sign up to request clarification or add additional context in comments.

10 Comments

Hi there. You should check if your function in hello2.c is correct. For example, I don't see a reason why xtemp and ytemp is declared. You're doing computations and storing them in those variables but they're not being used for the output array. Also check your statement when assigning to x at the end of the loop. To me it's not doing anything meaningful. I'll wait until you verify if this is the code you want before editing my answer.
OK I'll have a look soon.
Figured it out. Look at your second for loop. There are no curly braces that surround that block of code.
Not using curly braces means the for loop will only execute the next statement for the loop. The rest of the code is not in the loop.
Changed. Have a look at the first one now.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.