在C ++ mex函数中使用Eigen的迭代求解器

时间:2018-07-11 15:30:35

标签: c++ matlab c++11 mex eigen3

我想在C ++ mex函数中使用Eigen的迭代求解器 BiCGSTAB 来计算N×n密集的B'* Q ^(-1)* B的对角元素矩阵B和N乘N的稀疏矩阵Q,但是在编译C ++ mex代码时遇到错误。如果使用求解器 SimplicialLLT ,则可以编译我的C ++ mex代码,而不会出现任何错误。顺便说一句,从stackoverflow复制了将MATLAB稀疏矩阵转换为Eigen稀疏矩阵的代码。

另一个小问题是,如何释放C ++代码中分配给稀疏矩阵Q的空间?

我是特征库的新手。任何解决我的问题的建议将不胜感激。

提前谢谢

C ++ mex代码为:

#include "mex.h"
#include "matrix.h"
#include <Eigen>
#include <type_traits>
#include <limits>

typedef Eigen::SparseMatrix<double,Eigen::ColMajor,std::make_signed<mwIndex>::type> MatlabSparse;

Eigen::Map<MatlabSparse > matlab_to_eigen_sparse(const mxArray * mat)
{
    mxAssert(mxGetClassID(mat) == mxDOUBLE_CLASS,
    "Type of the input matrix isn't double");
    mwSize     m = mxGetM(mat);
    mwSize     n = mxGetN(mat);
    mwSize    nz = mxGetNzmax(mat);
    /*Theoretically fails in very very large matrices*/
    mxAssert(nz <= std::numeric_limits< std::make_signed<mwIndex>::type>::max(),
    "Unsupported Data size.");
    double  * pr = mxGetPr(mat);
    MatlabSparse::StorageIndex* ir = reinterpret_cast<MatlabSparse::StorageIndex*>(mxGetIr (mat));
    MatlabSparse::StorageIndex* jc = reinterpret_cast<MatlabSparse::StorageIndex*>(mxGetJc (mat));
    Eigen::Map<MatlabSparse> result(m, n, nz, jc, ir, pr);
    return result;
}

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])

{

if(!(mxIsSparse(prhs[0]))){
    mexErrMsgIdAndTxt("MATLAB: ", "First input matrix is not sparse.\n");
}

if((mxIsSparse(prhs[1]))){
    mexErrMsgIdAndTxt("MATLAB: ", "Second input matrix is not dense.\n");
}




// prhs[0]: Q
Eigen::Map<MatlabSparse> Q = matlab_to_eigen_sparse(prhs[0]);
mwSize N = mxGetM(prhs[0]); // size of BAUs for constructing the GGM

// prhs[1]: B (dense matrix)
mwSize n = mxGetN(prhs[2]);
Eigen::Map<Eigen::MatrixXd> B(mxGetPr(prhs[5]), N, n);



// Eigen::SimplicialLLT<Eigen::SparseMatrix<double> > Qsolver;
// Qsolver.analyzePattern(Q);
// Qsolver.factorize(Q);    

  Eigen::BiCGSTAB<Eigen::SparseMatrix<double> > Qsolver;
  //Eigen::ConjugateGradient<Eigen::SparseMatrix<double>, Lower|Upper> Qsolver;
  Qsolver.analyzePattern(Q);
  Qsolver.factorize(Q);


// intermidiate variables
Eigen::VectorXd Qb(N), xsol(n);
mwIndex i;
//mexPrintf("\n begin for-loop.\n");

// compute diagonal elements of B'*Q^(-1)*B
for(i=0; i<n; i++){
    Qb = Qsolver.solve(B.col(i));
    xsol(i) = B.col(i).dot(Qb);
}

//mexPrintf("\n finish for-loop.\n");

double* x = (double*) mxCalloc(n, sizeof(double));
Eigen::Map<Eigen::MatrixXd>(x, n, 1) = xsol;

// set output
plhs[0] = mxCreateDoubleMatrix(n, 1, mxREAL);
mxSetPr(plhs[0], x);


B.resize(0,0);
Qb.resize(0,0);
xsol.resize(0,0);

}

错误消息是

>> mex -v test.cpp -I/usr/local/include/eigen3/Eigen
Verbose mode is on.
... Looking for compiler 'Xcode Clang++' ...
... Looking for environment variable 'DEVELOPER_DIR' ...No.
... Executing command 'xcode-select -print-path' ...Yes ('/Applications/Xcode.app/Contents/Developer').
... Looking for folder '/Applications/Xcode.app/Contents/Developer' ...Yes.
... Executing command 'which xcrun' ...Yes ('/usr/bin/xcrun').
... Looking for folder '/usr/bin' ...Yes.
... Executing command 'defaults read com.apple.dt.Xcode IDEXcodeVersionForAgreedToGMLicense' ...No.
... Executing command 'defaults read /Library/Preferences/com.apple.dt.Xcode IDEXcodeVersionForAgreedToGMLicense' ...Yes ('9.2').
... Executing command '
agreed=9.2 
 if echo $agreed | grep -E '[\.\"]' >/dev/null; then 
 lhs=`expr "$agreed" : '\([0-9]*\)[\.].*'` 
  rhs=`expr "$agreed" : '[0-9]*[\.]\(.*\)$'` 
 if echo $rhs | grep -E '[\."]' >/dev/null; then 
 rhs=`expr "$rhs" : '\([0-9]*\)[\.].*'` 
 fi 
 if [ $lhs -gt 4 ] || ( [ $lhs -eq 4 ] && [ $rhs -ge 3 ] ); then 
 echo $agreed 
 else 
 exit 1
 fi 
 fi' ...Yes ('9.2').
... Executing command 'xcrun -sdk macosx --show-sdk-path' ...Yes ('/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk').
... Executing command 'xcrun -sdk macosx --show-sdk-version' ...Yes ('10.13').
... Executing command 'clang --version | grep -Eo '[0-9]+\.[0-9]+\.[0-9]'|head -1' ...Yes ('9.1.0').
Found installed compiler 'Xcode Clang++'.
Set INCLUDE = /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1;/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/9.1.0/include;/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include;/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include;/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks;/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1;/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/9.1.0/include;/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include;/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include;/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks;
Options file details
-------------------------------------------------------------------
    Compiler location: /Applications/Xcode.app/Contents/Developer
    Options file: /Users/someone/Library/Application Support/MathWorks/MATLAB/R2018a/mex_C++_maci64.xml
    CMDLINE200 : /usr/bin/xcrun -sdk macosx10.13 clang++ -Wl,-twolevel_namespace -undefined error -arch x86_64 -mmacosx-version-min=10.9 -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -framework Cocoa -bundle  -stdlib=libc++ -O -Wl,-exported_symbols_list,"/Applications/MATLAB_R2018a.app/extern/lib/maci64/mexFunction.map" -Wl,-exported_symbols_list,"/Applications/MATLAB_R2018a.app/extern/lib/maci64/c_exportsmexfileversion.map" -Wl,-U,_mexCreateMexFunction -Wl,-U,_mexDestroyMexFunction -Wl,-U,_mexFunctionAdapter -Wl,-exported_symbols_list,"/Applications/MATLAB_R2018a.app/extern/lib/maci64/cppMexFunction.map" /var/folders/_k/ckfbbmb51nz6bptcpb68qftm0000gn/T/mex_1610382819375744_28449/test.o /var/folders/_k/ckfbbmb51nz6bptcpb68qftm0000gn/T/mex_1610382819375744_28449/cpp_mexapi_version.o   -L"/Applications/MATLAB_R2018a.app/bin/maci64" -lmx -lmex -lmat -L"/Applications/MATLAB_R2018a.app/extern/bin/maci64" -lMatlabDataArray -lMatlabEngine -o test.mexmaci64
    CC : /usr/bin/xcrun -sdk macosx10.13 clang
    CXX : /usr/bin/xcrun -sdk macosx10.13 clang++
    DEFINES : -DMATLAB_DEFAULT_RELEASE=R2017b  -DUSE_MEX_CMD   -DMATLAB_MEX_FILE 
    MATLABMEX : -DMATLAB_MEX_FILE 
    MACOSX_DEPLOYMENT_TARGET : 10.9
    CFLAGS : -fno-common -arch x86_64 -mmacosx-version-min=10.9 -fexceptions -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk
    CXXFLAGS : -fno-common -arch x86_64 -mmacosx-version-min=10.9 -fexceptions -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -fobjc-arc -std=c++11 -stdlib=libc++
    INCLUDE : -I"/usr/local/include/eigen3/Eigen"  -I"/Applications/MATLAB_R2018a.app/extern/include" -I"/Applications/MATLAB_R2018a.app/simulink/include"
    CXXOPTIMFLAGS : -O2 -fwrapv -DNDEBUG
    CXXDEBUGFLAGS : -g
    LD : /usr/bin/xcrun -sdk macosx10.13 clang
    LDXX : /usr/bin/xcrun -sdk macosx10.13 clang++
    LDFLAGS : -Wl,-twolevel_namespace -undefined error -arch x86_64 -mmacosx-version-min=10.9 -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -framework Cocoa -bundle  -stdlib=libc++
    LDBUNDLE : -bundle 
    LINKEXPORT : -Wl,-exported_symbols_list,"/Applications/MATLAB_R2018a.app/extern/lib/maci64/mexFunction.map"
    LINKEXPORTVER : -Wl,-exported_symbols_list,"/Applications/MATLAB_R2018a.app/extern/lib/maci64/c_exportsmexfileversion.map"
    LINKEXPORTCPP : -Wl,-U,_mexCreateMexFunction -Wl,-U,_mexDestroyMexFunction -Wl,-U,_mexFunctionAdapter -Wl,-exported_symbols_list,"/Applications/MATLAB_R2018a.app/extern/lib/maci64/cppMexFunction.map"
    LINKLIBS : -L"/Applications/MATLAB_R2018a.app/bin/maci64" -lmx -lmex -lmat -L"/Applications/MATLAB_R2018a.app/extern/bin/maci64" -lMatlabDataArray -lMatlabEngine
    LDOPTIMFLAGS : -O
    LDDEBUGFLAGS : -g
    OBJEXT : .o
    LDEXT : .mexmaci64
    SETENV : CC="/usr/bin/xcrun -sdk macosx10.13 clang"
                CXX="/usr/bin/xcrun -sdk macosx10.13 clang++"
                CFLAGS="-fno-common -arch x86_64 -mmacosx-version-min=10.9 -fexceptions -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -DMATLAB_DEFAULT_RELEASE=R2017b  -DUSE_MEX_CMD   -DMATLAB_MEX_FILE "
                CXXFLAGS="-fno-common -arch x86_64 -mmacosx-version-min=10.9 -fexceptions -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -fobjc-arc -std=c++11 -stdlib=libc++ -DMATLAB_DEFAULT_RELEASE=R2017b  -DUSE_MEX_CMD   -DMATLAB_MEX_FILE "
                COPTIMFLAGS="-O2 -fwrapv -DNDEBUG"
                CXXOPTIMFLAGS="-O2 -fwrapv -DNDEBUG"
                CDEBUGFLAGS="-g"
                CXXDEBUGFLAGS="-g"
                LD="/usr/bin/xcrun -sdk macosx10.13 clang"
                LDXX="/usr/bin/xcrun -sdk macosx10.13 clang++"
                LDFLAGS="-Wl,-twolevel_namespace -undefined error -arch x86_64 -mmacosx-version-min=10.9 -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -framework Cocoa -bundle  -stdlib=libc++ -L"/Applications/MATLAB_R2018a.app/bin/maci64" -lmx -lmex -lmat -L"/Applications/MATLAB_R2018a.app/extern/bin/maci64" -lMatlabDataArray -lMatlabEngine -Wl,-exported_symbols_list,"/Applications/MATLAB_R2018a.app/extern/lib/maci64/mexFunction.map""
                LDDEBUGFLAGS="-g"
    DEVELOPER_DIR_CHECK : 
    XCODE_DIR : /Applications/Xcode.app/Contents/Developer
    XCRUN_DIR : /usr/bin
    XCODE_AGREED_VERSION : 9.2
    ISYSROOT : /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk
    SDKVER : 10.13
    CLANG_VERSION : 9.1.0
    MATLABROOT : /Applications/MATLAB_R2018a.app
    ARCH : maci64
    SRC : "/Users/someone/code/test.cpp";"/Applications/MATLAB_R2018a.app/extern/version/cpp_mexapi_version.cpp"
    OBJ : /var/folders/_k/ckfbbmb51nz6bptcpb68qftm0000gn/T/mex_1610382819375744_28449/test.o;/var/folders/_k/ckfbbmb51nz6bptcpb68qftm0000gn/T/mex_1610382819375744_28449/cpp_mexapi_version.o
    OBJS : /var/folders/_k/ckfbbmb51nz6bptcpb68qftm0000gn/T/mex_1610382819375744_28449/test.o /var/folders/_k/ckfbbmb51nz6bptcpb68qftm0000gn/T/mex_1610382819375744_28449/cpp_mexapi_version.o 
    SRCROOT : /Users/someone/code/test
    DEF : /var/folders/_k/ckfbbmb51nz6bptcpb68qftm0000gn/T/mex_1610382819375744_28449/test.def
    EXP : "test.exp"
    LIB : "test.lib"
    EXE : test.mexmaci64
    ILK : "test.ilk"
    MANIFEST : "test.mexmaci64.manifest"
    TEMPNAME : test
    EXEDIR : 
    EXENAME : test
    OPTIM : -O2 -fwrapv -DNDEBUG
    LINKOPTIM : -O
    CMDLINE100_0 : /usr/bin/xcrun -sdk macosx10.13 clang++ -c -DMATLAB_DEFAULT_RELEASE=R2017b  -DUSE_MEX_CMD   -DMATLAB_MEX_FILE  -I"/usr/local/include/eigen3/Eigen"  -I"/Applications/MATLAB_R2018a.app/extern/include" -I"/Applications/MATLAB_R2018a.app/simulink/include" -fno-common -arch x86_64 -mmacosx-version-min=10.9 -fexceptions -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -fobjc-arc -std=c++11 -stdlib=libc++ -O2 -fwrapv -DNDEBUG "/Users/mapulong/GoogleDrive/MATLAB/MODIS/code/STFGP/test.cpp" -o /var/folders/_k/ckfbbmb51nz6bptcpb68qftm0000gn/T/mex_1610382819375744_28449/test.o
    CMDLINE100_1 : /usr/bin/xcrun -sdk macosx10.13 clang++ -c -DMATLAB_DEFAULT_RELEASE=R2017b  -DUSE_MEX_CMD   -DMATLAB_MEX_FILE  -I"/usr/local/include/eigen3/Eigen"  -I"/Applications/MATLAB_R2018a.app/extern/include" -I"/Applications/MATLAB_R2018a.app/simulink/include" -fno-common -arch x86_64 -mmacosx-version-min=10.9 -fexceptions -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -fobjc-arc -std=c++11 -stdlib=libc++ -O2 -fwrapv -DNDEBUG "/Applications/MATLAB_R2018a.app/extern/version/cpp_mexapi_version.cpp" -o /var/folders/_k/ckfbbmb51nz6bptcpb68qftm0000gn/T/mex_1610382819375744_28449/cpp_mexapi_version.o
-------------------------------------------------------------------
Building with 'Xcode Clang++'.
/usr/bin/xcrun -sdk macosx10.13 clang++ -c -DMATLAB_DEFAULT_RELEASE=R2017b  -DUSE_MEX_CMD   -DMATLAB_MEX_FILE  -I"/usr/local/include/eigen3/Eigen"  -I"/Applications/MATLAB_R2018a.app/extern/include" -I"/Applications/MATLAB_R2018a.app/simulink/include" -fno-common -arch x86_64 -mmacosx-version-min=10.9 -fexceptions -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -fobjc-arc -std=c++11 -stdlib=libc++ -O2 -fwrapv -DNDEBUG "/Users/mapulong/GoogleDrive/MATLAB/MODIS/code/STFGP/test.cpp" -o /var/folders/_k/ckfbbmb51nz6bptcpb68qftm0000gn/T/mex_1610382819375744_28449/test.o
Error using mex
In file included from /Users/someone/code/test.cpp:8:
In file included from /usr/local/include/eigen3/Eigen/Eigen:2:
In file included from /usr/local/include/eigen3/Eigen/Sparse:26:
In file included from /usr/local/include/eigen3/Eigen/SparseCore:46:
/usr/local/include/eigen3/Eigen/src/SparseCore/SparseRef.h:101:40: error: no matching
constructor for initialization of 'Eigen::internal::SparseRefBase<Eigen::Ref<const
Eigen::SparseMatrix<double, 0, int>, 0, Eigen::OuterStride<-1> > >::Base' (aka
'SparseMapBase<Eigen::Ref<const Eigen::SparseMatrix<double, 0, int>, 0,
Eigen::OuterStride<-1> > >')
      ::new (static_cast<Base*>(this)) Base(expr.size(), expr.nonZeros(),
      expr.innerIndexPtr(), expr.valuePtr());
                                       ^
                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                       /usr/local/include/eigen3/Eigen/src/SparseCore/SparseRef.h:223:15:
                                       note: in instantiation of function template
                                       specialization
                                       'Eigen::internal::SparseRefBase<Eigen::Ref<const
                                       Eigen::SparseMatrix<double, 0, int>, 0,
                                       Eigen::OuterStride<-1> > >::construct<const
                                       Eigen::Map<Eigen::SparseMatrix<double, 0, long>,
                                       0, Eigen::Stride<0, 0> > >' requested here
        Base::construct(expr);
              ^
/usr/local/include/eigen3/Eigen/src/SparseCore/SparseRef.h:190:7: note: in
instantiation of function template specialization 'Eigen::Ref<const
Eigen::SparseMatrix<double, 0, int>, 0, Eigen::OuterStride<-1>
>::construct<Eigen::Map<Eigen::SparseMatrix<double, 0, long>, 0, Eigen::Stride<0, 0> >
>' requested here
      construct(expr.derived(), typename Traits::template match<Derived>::type());
      ^
/usr/local/include/eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h:81:23:
note: in instantiation of function template specialization 'Eigen::Ref<const
Eigen::SparseMatrix<double, 0, int>, 0, Eigen::OuterStride<-1>
>::Ref<Eigen::Map<Eigen::SparseMatrix<double, 0, long>, 0, Eigen::Stride<0, 0> > >'
requested here
    ::new (&m_matrix) Ref<const MatrixType>(mat.derived());
                      ^
/usr/local/include/eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h:377:21:
note: in instantiation of function template specialization
'Eigen::internal::generic_matrix_wrapper<Eigen::SparseMatrix<double, 0, int>,
false>::grab<Eigen::Map<Eigen::SparseMatrix<double, 0, long>, 0, Eigen::Stride<0, 0> >
>' requested here
    m_matrixWrapper.grab(A);
                    ^
/usr/local/include/eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h:199:5:
note: in instantiation of function template specialization
'Eigen::IterativeSolverBase<Eigen::BiCGSTAB<Eigen::SparseMatrix<double, 0, int>,
Eigen::DiagonalPreconditioner<double> > >::grab<Eigen::Map<Eigen::SparseMatrix<double,
0, long>, 0, Eigen::Stride<0, 0> > >' requested here
    grab(A.derived());
    ^
/Users/someone/code/test.cpp:64:15: note: in
instantiation of function template specialization
'Eigen::IterativeSolverBase<Eigen::BiCGSTAB<Eigen::SparseMatrix<double, 0, int>,
Eigen::DiagonalPreconditioner<double> >
>::analyzePattern<Eigen::Map<Eigen::SparseMatrix<double, 0, long>, 0, Eigen::Stride<0,
0> > >' requested here
      Qsolver.analyzePattern(Q);
              ^
/usr/local/include/eigen3/Eigen/src/SparseCore/SparseMap.h:131:12: note: candidate
constructor not viable: no known conversion from 'const
Eigen::SparseMapBase<Eigen::Map<Eigen::SparseMatrix<double, 0, long>, 0,
Eigen::Stride<0, 0> >, 0>::StorageIndex *' (aka 'const long *') to
'Eigen::SparseMapBase<Eigen::Ref<const Eigen::SparseMatrix<double, 0, int>, 0,
Eigen::OuterStride<-1> >, 0>::IndexPointer' (aka 'const int *') for 3rd argument
    inline SparseMapBase(Index size, Index nnz, IndexPointer innerIndexPtr,
    ScalarPointer valuePtr)
           ^
/usr/local/include/eigen3/Eigen/src/SparseCore/SparseMap.h:50:7: note: candidate
constructor (the implicit copy constructor) not viable: requires 1 argument, but 4 were
provided
class SparseMapBase<Derived,ReadOnlyAccessors>
      ^
/usr/local/include/eigen3/Eigen/src/SparseCore/SparseMap.h:124:12: note: candidate
constructor not viable: requires at least 6 arguments, but 4 were provided
    inline SparseMapBase(Index rows, Index cols, Index nnz, IndexPointer outerIndexPtr,
    IndexPointer innerIndexPtr,
           ^
/usr/local/include/eigen3/Eigen/src/SparseCore/SparseMap.h:140:12: note: candidate
constructor not viable: requires 0 arguments, but 4 were provided
    inline SparseMapBase() {}
           ^
1 error generated.

0 个答案:

没有答案