我想在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.