我正在使用SWIG将C ++代码转换为python代码,但未能成功解决以下导入错误。我不知道问题的根源
ImportError:/.../_RfBm.so:未定义的符号:_ZN5RNormclERSt6vectorIdSaIdEE
RfBm.i文件由
给出%module RfBm
%{
#define SWIG_FILE_WITH_INIT
#include "RfBm.h"
%}
%include "RfBm.h"
.cpp文件由以下代码给出
#include "RfBm.h"
RfBm::RfBm() {
n = 0;
H = 0.0;
gamma = 0.0;
rnorm = 0;
L = std::vector<Vector>(0);
}
double RfBm::A(int i, int j) const {
double ret = 0.0;
if((i < n) && (j < n))
ret = cBm(i,j);
else if((i < n) && (j >= n))
ret = cMixed(i, j-n);
else if((i >= n) && (j < n))
ret = cMixed(j, i-n);
else if((i >= n) && (j >= n))
ret = cfBm(i-n, j-n);
return ret;
}
double RfBm::G(double x) const {
return 2.0 * H
* (pow(x, -gamma) / (1.0 - gamma)
+ gamma * pow(x, -(1.0 + gamma))
* gsl_sf_hyperg_2F1(1.0, 1.0 + gamma, 3.0 - gamma,
1.0 / x) / ((1.0 - gamma) * (2.0 - gamma)));
}
double RfBm::cBm(int i, int j) const {
return (i == j) ? 1.0 : 0.0;
}
double RfBm::cfBm(int i, int j) const {
double t = static_cast<double>(std::min(i,j) + 1) / n;
double s = static_cast<double>(std::max(i,j) + 1) / n;
return pow(t, 2*H) * G(s/t);
}
double RfBm::cMixed(int i, int j) const {
double ret = 0.0;
if(i <= j){
double u = static_cast<double>(i)/n;
double v = static_cast<double>(i+1)/n;
double t = static_cast<double>(j+1)/n;
ret = 2.0 * sqrt(2.0*H*n) * (pow(t - u, 0.5 + H) - pow(t - v, 0.5 + H)) /
(1.0 + 2.0 * H);
}
return ret;
}
RfBm::RfBm(int nI, double HI, RNorm* rnormI) {
n = nI;
H = HI;
gamma = 0.5 - H;
rnorm = rnormI;
L = std::vector<Vector>(2 * n, Vector(2 * n, 0.0)); // fill with 0s first.
// Now fill the matrix L.
for (int k = 0; k < 2 * n; ++k) {
double temp = 0.0;
for (int j = 0; j < k; ++j)
temp += L[k][j] * L[k][j];
L[k][k] = sqrt(A(k, k) - temp);
for (int i = k + 1; i < 2*n; ++i) {
double temp = 0.0;
for (int j = 0; j < k; ++j)
temp += L[i][j] * L[k][j];
L[i][k] = (A(i, k) - temp) / L[k][k];
}
}
}
void RfBm::generate(Vector& W1, Vector& Wtilde) {
Vector x(2 * n);
(*rnorm)(x);
for (int i = 0; i < n; ++i) {
W1[i] = 0.0;
for (int j = 0; j <= i; ++j)
W1[i] += L[i][j] * x[j];
}
for (int i = 0; i < n; ++i) {
Wtilde[i] = 0.0;
for (int j = 0; j <= (i + n); ++j)
Wtilde[i] += L[i + n][j] * x[j];
}
}
void RfBm::operator ()(Vector& W1, Vector& Wtilde) {
this->generate(W1, Wtilde);
}
std::vector<Vector> RfBm::GetA() const {
std::vector<Vector> A_mat(2*n, Vector(2*n, 0.0));
for(int i=0; i<2*n; ++i)
for(int j=0; j<2*n; ++j)
A_mat[i][j] = A(i,j);
return A_mat;
}
我用于编译和链接的命令是:
swig -c++ -python RfBm.i
g++ -O2 -fPIC -c RfBm.cpp -I/home/.../gsl/include
g++ -O2 -fPIC -c RfBm_wrap.cxx -I/home/.../gsl/include
g++ -shared -o _RfBm.so RfBm.o RfBm_wrap.o -L/home/.../gsl/lib -lgsl
-lgslcblas -lm
有帮助吗?谢谢。
答案 0 :(得分:0)
我发现了问题。实际上,首先我查看了_ZN5RNormclERSt6vectorIdSaIdEE的定义位置。它不在RfBM.o中,而在另一个文件RNorm.o
中nm RfBm.o | grep _ZN5RNormclERSt6vectorIdSaIdEE
U _ZN5RNormclERSt6vectorIdSaIdEE
nm RNorm.o | grep _ZN5RNormclERSt6vectorIdSaIdEE
0000000000000280 T _ZN5RNormclERSt6vectorIdSaIdEE
然后我所做的是我在链接命令的末尾添加了该文件
g++ -shared -o _RfBm.so RfBm.o RfBm_wrap.o -L/home/.../gsl/lib -lgsl
-lgslcblas -lm RNorm.o
它解决了这个问题。