mex:错误:从'void *'到'double *'的无效转换[-fpermissive]

时间:2015-04-11 20:29:28

标签: c++ matlab matrix armadillo

我很感激将全矩阵转换为稀疏矩阵的一些帮助/指导。

内部mex功能:     执行一些计算==>得到满矩阵==> 将完整矩阵转换为稀疏矩阵 ==>执行更多计算==>将结果返回给Matlab

1)我不确定我是否正确地将全矩阵转换为稀疏矩阵?例如,我使用单个线性索引访问矩阵,我认为它不会改变任何方式存储矩阵。我对吗?

2)在将完整矩阵转换为稀疏矩阵(我的代码基于Matlab示例代码:fulltosparse.c)时,我收到了这些错误:

normpdfDKU.cpp: In function ‘int Convert_Full_2_Sparse(mxArray*)’:
normpdfDKU.cpp:216:69: error: invalid conversion from ‘void*’ to ‘double*’ [-fpermissive]
                     mxSetPr(pOUT, mxRealloc(sr, nzmax*sizeof(double)));
                                                                     ^
In file included from /usr/local/MATLAB/R2011b/extern/include/mex.h:58:0,
                 from normpdfDKU.cpp:4:
/usr/local/MATLAB/R2011b/extern/include/matrix.h:606:15: error:   initializing argument 2 of ‘void mxSetPr(mxArray*, double*)’ [-fpermissive]
 EXTERN_C void mxSetPr(
               ^
normpdfDKU.cpp:218:73: error: invalid conversion from ‘void*’ to ‘double*’ [-fpermissive]
                         mxSetPi(pOUT, mxRealloc(si, nzmax*sizeof(double)));
                                                                         ^
In file included from /usr/local/MATLAB/R2011b/extern/include/mex.h:58:0,
                 from normpdfDKU.cpp:4:
/usr/local/MATLAB/R2011b/extern/include/matrix.h:623:15: error:   initializing argument 2 of ‘void mxSetPi(mxArray*, double*)’ [-fpermissive]
 EXTERN_C void mxSetPi(
               ^
normpdfDKU.cpp:219:71: error: invalid conversion from ‘void*’ to ‘int*’ [-fpermissive]
                     mxSetIr(pOUT, mxRealloc(irs, nzmax*sizeof(mwIndex)));
                                                                       ^
In file included from /usr/local/MATLAB/R2011b/extern/include/mex.h:58:0,
                 from normpdfDKU.cpp:4:
/usr/local/MATLAB/R2011b/extern/include/matrix.h:1275:6: error:   initializing argument 2 of ‘void mxSetIr_700(mxArray*, int*)’ [-fpermissive]
 void mxSetIr_700(mxArray *, int *);
      ^
make: *** [normpdfDKU.o] Error 1

mex文件中的代码是:

#include "mex.h"
#include <math.h>

#include "/home/dkumar/libtsnnls-2.3.3/tsnnls/taucs_basic/taucs.h"
#include "/home/dkumar/armadillo-4.600.3/include/armadillo"
using namespace arma;
using namespace std;

#define PI (3.141592653589793)

#if defined(NAN_EQUALS_ZERO)
#define IsNonZero(d) ((d)!=0.0 || mxIsNaN(d))
#else
#define IsNonZero(d) ((d)!=0.0)
#endif

extern void _main();

const int numInputArgs  = 3;
const int numOutputArgs = 2;

// Function declarations.
// -----------------------------------------------------------------
double  getMatlabScalar    (const mxArray* ptr);
double& createMatlabScalar (mxArray*& ptr);

int TestingLibraries() ;   // declared and defined in In Include_4_TSNNLS.c and Include_4_TSNNLS.h

struct stColMajorMAt_EXT{
   double* pColMajMat;
   int nrows, ncols;
};

stColMajorMAt_EXT Convert_ARMA_RowMajorMAt_2_ColMajorMat(mat);

// Function definitions.
// -----------------------------------------------------------------
void mexFunction (int nlhs, mxArray *plhs[],
          int nrhs, const mxArray *prhs[]) {

  // Check to see if we have the correct number of input and output
  // arguments.
  if (nrhs != numInputArgs)
    mexErrMsgTxt(" DKU-1: Incorrect number of input arguments");
  if (nlhs != numOutputArgs)
    mexErrMsgTxt("DKU-2: Incorrect number of output arguments");

  // Get the inputs.
  double x  = getMatlabScalar(prhs[0]);
  double mu = getMatlabScalar(prhs[1]);
  double v  = getMatlabScalar(prhs[2]);

  // Create the output. It is also a double-precision scalar.
  double& p = createMatlabScalar(plhs[0]);

  // Compute the value of the univariate Normal at x.
  p = exp(-(x-mu)*(x-mu)/(2*v)) / sqrt(2*PI*v);

  // CREATE ARMA::mat and print 
  mat B = eye<mat>(20,30);

  //Print B
  B.print();

   mwSize sz[2];
   sz[0] = B.n_rows  ; // Matlab is row first
   sz[1] = B.n_cols  ;
   //mxArray* pOUT = mxCreateNumericArray(2, sz, mxDOUBLE_CLASS, mxREAL);
   plhs[1] = mxCreateNumericArray(2, sz, mxDOUBLE_CLASS, mxREAL);

   //Get a pointer to pOUT
   double* p2 = (double*)mxGetData(plhs[1]);

   for (int i = 0; i<B.n_rows*B.n_cols; i++)
   {
       p2[i] = B[i];
   }


   // Convert B to a sparse column major matrix
   /*p is already column major; but, not sparse*/
   mxArray* M1 = (mxArray*)p2;

   // I will convert full matrix to sparse matrix now  

}

double getMatlabScalar (const mxArray* ptr) {

  // Make sure the input argument is a scalar in double-precision.
  if (!mxIsDouble(ptr) || mxGetNumberOfElements(ptr) != 1)
    mexErrMsgTxt("The input argument must be a double-precision scalar");

  return *mxGetPr(ptr);
}

double& createMatlabScalar (mxArray*& ptr) { 
  ptr = mxCreateDoubleMatrix(1,1,mxREAL);
  return *mxGetPr(ptr);
}

mxArray*  Convert_Full_2_Sparse(double* pColMajMat)
// MLoc is already a pointer to column major matrix
{
    mxArray* M_Loc = (mxArray*)pColMajMat;

    /* Declare variable */
    mwSize m,n;
    mwSize nzmax;
    mwIndex *irs,*jcs,j,k;
    int cmplx,isfull;
    double *pr,*pi,*si,*sr;
    double percent_sparse;

    /* Get the size and pointers to input data */
    m  = mxGetM(M_Loc);
    n  = mxGetN(M_Loc);
    pr = mxGetPr(M_Loc);
    pi = mxGetPi(M_Loc);
    cmplx = (pi==NULL ? 0 : 1);

    /* Allocate space for sparse matrix
     * NOTE:  Assume at most 20% of the data is sparse.  Use ceil
     * to cause it to round up.
     */

    percent_sparse = 0.2;
    nzmax=(mwSize)ceil((double)m*(double)n*percent_sparse);

    mxArray* pOUT = mxCreateSparse(m,n,nzmax,mxREAL);
    sr  = mxGetPr(pOUT);
    si  = mxGetPi(pOUT);
    irs = mxGetIr(pOUT);
    jcs = mxGetJc(pOUT);

    /* Copy nonzeros */
    k = 0;
    isfull=0;
    for (j=0; (j<n); j++) {
        mwSize i;
        jcs[j] = k;
        for (i=0; (i<m ); i++) {
            if (IsNonZero(pr[i])) {

                /* Check to see if non-zero element will fit in
                 * allocated output array.  If not, increase percent_sparse
                 * by 10%, recalculate nzmax, and augment the sparse array
                 */
                if (k>=nzmax){
                    mwSize oldnzmax = nzmax;
                    percent_sparse += 0.1;
                    nzmax = (mwSize)ceil((double)m*(double)n*percent_sparse);

                    /* make sure nzmax increases atleast by 1 */
                    if (oldnzmax == nzmax)  nzmax++;

                    mxSetNzmax(pOUT, nzmax);
                    mxSetPr(pOUT, mxRealloc(sr, nzmax*sizeof(double)));

                    if(si != NULL)  mxSetPi(pOUT, mxRealloc(si, nzmax*sizeof(double)));

                    mxSetIr(pOUT, mxRealloc(irs, nzmax*sizeof(mwIndex)));

                    sr  = mxGetPr(pOUT);
                    si  = mxGetPi(pOUT);
                    irs = mxGetIr(pOUT);
                }
                sr[k] = pr[i];
                if (cmplx){
                    si[k]=pi[i];
                }
                irs[k] = i;
                k++;
            }
        }
        pr += m;
        pi += m;
    }
    jcs[n] = k;

return pOUT;
}

1 个答案:

答案 0 :(得分:3)

此错误表明您正在使用C ++编译器来编译C代码。

要解决此问题,请使用C编译器编译代码。错误消息还具有文件名normpdfDKU.cpp,因此有人将C代码放入.cpp文件中,欺骗了编译器。如果整个文件是C,你可以重命名它,否则你可能需要解开C部分。

如果项目包含一些C代码和一些C ++代码,那很好,所有主要的C ++编译器都支持带有一些.c文件和一些.cpp文件的项目。 See here以及有关该主题的其他信息的类似问题。