c++ - 墨西哥 : error: invalid conversion from ‘void*’ to ‘double*’ [-fpermissive]

标签 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;
}

最佳答案

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

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

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

关于c++ - 墨西哥 : error: invalid conversion from ‘void*’ to ‘double*’ [-fpermissive],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29582732/

相关文章:

c++ - boost 时间戳 UDP 数据包

c++ - 如何在 C++20 中为模板别名创建推导指南?

matlab - 如何用不同的标记绘制多条线

r - 矩阵列中匹配值的计数

r - 将不对称向量列表转换为矩阵

c++ - Web服务器中proactor模式和同步模型的区别

C++ 指针和引用说明

matlab - MATLAB 与 namespace 最接近的东西是什么?

c - 为什么 mex 代码运行得比 matlab 代码慢

r - 如何从R中的矩阵中提取一系列特定值?