2017-08-10 3 views
-1

C++でFFTプログラムをコーディングし、Pythonのライブラリとして実装したいと思います。Boost/Pythonを使用した未定義シンボル - 複合語

だから、私はBoost.Python 1.64使用して、私はC++とのFFTについては、以下をコード化されてきた:

1.fft.hpp(ヘッダ)

#ifndef _FFT_HPP_ 
#define _FFT_HPP_ 

#define BOOST_PYTHON_STATIC_LIB 

#include <iostream> 
#include <string> 
#include <algorithm> 
#include <boost/python.hpp> 
#include <boost/python/numpy.hpp> 
#ifdef _OPENMP 
    #include <omp.h> 
#endif 
#include "blas.h" 
#include <complex> 
#include <fftw3.h> 

/* define namespace */ 

namespace py = boost::python; 
namespace npy = boost::python::numpy; 

typedef std::complex<double> dcomplex; 

/* data format */ 

typedef struct DATA { 

    /* define variable of struct */ 

} data; 
extern data uvdata; 

/* image format */ 

typedef struct IMAGE { 

    /* define variable of struct */ 

} image; 

/* result format */ 

typedef struct RESULT { 

    /* define variable of struct */ 

} result; 

/* memmory allocation of matrix and vectors */ 

template <typename T> T *alloc_vector(int length); 
template <typename T> T *alloc_matrix(int width, int height); 

/* subroutines for input data */ 

extern void input_pos(npy::ndarray u, npy::ndarray v, npy::ndarray uidx, npy::ndarray vidx); 
extern void input_fcv(npy::ndarray uvidxfcv, npy::ndarray Vfcvr, npy::ndarray Vfcvi, npy::ndarray Varfcv); 
extern void input_amp(npy::ndarray uvidxamp, npy::ndarray Vamp, npy::ndarray Varamp); 
extern void input_cp(npy::ndarray uvidxcp, npy::ndarray Vcp, npy::ndarray Varcp); 
extern void input_ca(npy::ndarray uvidxca, npy::ndarray Vca, npy::ndarray Varca); 

/* subroutine for calculating cost */ 

extern void fft_test(npy::ndarray Iin, npy::ndarray x, npy::ndarray y, 
          npy::ndarray xidx, npy::ndarray yidx, int NX, int NY); 

#endif // _FFT_HPP_ 

2.ftt.cpp( FFT用FFTW)

#include "fft.hpp" 


/* redefine struct of data */ 

data uvdata; 

template <typename T> T *transform_c_matrix(npy::ndarray matrix) { 
    return reinterpret_cast<T *>(matrix.get_data()); 
} 

void fftw_test(image *fitsimage, data *tmpdata); 

void input_pos(npy::ndarray u, npy::ndarray v, npy::ndarray uidx, npy::ndarray vidx) 
{ 
    /* input position and index of u and v to uvdata */ 
    uvdata.u = transform_c_matrix<double>(u); 
    uvdata.v = transform_c_matrix<double>(v); 
    uvdata.uidx = transform_c_matrix<int>(uidx); 
    uvdata.vidx = transform_c_matrix<int>(vidx); 
} 

void input_fcv(npy::ndarray uvidxfcv, npy::ndarray Vfcvr, npy::ndarray Vfcvi, npy::ndarray Varfcv) 
{ 
    /* input full-comp. visiblity to uvdata */ 
    /* index */ 
    uvdata.Nfcv = int(uvidxfcv.shape(0)); 
    uvdata.uvidxfcv = transform_c_matrix<int>(uvidxfcv); 
    /* data and variance */ 
    uvdata.Vfcvr = transform_c_matrix<double>(Vfcvr); 
    uvdata.Vfcvi = transform_c_matrix<double>(Vfcvi); 
    uvdata.Varfcv = transform_c_matrix<double>(Varfcv); 

    /* inverse flag */ 
    uvdata.isfcv = true; 
} 

void input_amp(npy::ndarray uvidxamp, npy::ndarray Vamp, npy::ndarray Varamp) 
{ 
    /* input visibility amplitude to uvdata */ 
    /* index */ 
    uvdata.Namp = int(uvidxamp.shape(0)); 
    uvdata.uvidxamp = transform_c_matrix<int>(uvidxamp); 
    /* data and variance */ 
    uvdata.Vamp = transform_c_matrix<double>(Vamp); 
    uvdata.Varamp = transform_c_matrix<double>(Varamp); 

    /* inverse flag */ 
    uvdata.isamp = true; 
} 

void input_cp(npy::ndarray uvidxcp, npy::ndarray Vcp, npy::ndarray Varcp) 
{ 
    /* input closure phase to uvdata */ 
    /* index */ 
    uvdata.Ncp = int(uvidxcp.shape(0)); 
    uvdata.uvidxcp = transform_c_matrix<int>(uvidxcp); 
    /* data and variance */ 
    uvdata.Vcp = transform_c_matrix<double>(Vcp); 
    uvdata.Varcp = transform_c_matrix<double>(Varcp); 

    /* inverse flag */ 
    uvdata.iscp = true; 
} 

void input_ca(npy::ndarray uvidxca, npy::ndarray Vca, npy::ndarray Varca) 
{ 
    /* input closure amplitude to uvdata */ 
    /* index */ 
    uvdata.Nca = int(uvidxca.shape(0)); 
    uvdata.uvidxca = transform_c_matrix<int>(uvidxca); 
    /* data and variance */ 
    uvdata.Vca = transform_c_matrix<double>(Vca); 
    uvdata.Varca = transform_c_matrix<double>(Varca); 

    /* inverse flag */ 
    uvdata.isca = true; 
} 

void fft_test(npy::ndarray Iin, npy::ndarray x, npy::ndarray y, 
    npy::ndarray xidx, npy::ndarray yidx, int NX, int NY) 
{ 
    data tmpdata; 
    image fitsimage; 

    /* input initial image */ 
    fitsimage.Iin = transform_c_matrix<double>(Iin); 
    fitsimage.x = transform_c_matrix<double>(x); 
    fitsimage.y = transform_c_matrix<double>(y); 
    fitsimage.xidx = transform_c_matrix<int>(xidx); 
    fitsimage.yidx = transform_c_matrix<int>(yidx); 
    fitsimage.NX = NX; 
    fitsimage.NY = NY; 
    fitsimage.Npix = NX*NY; 

    uvdata.NU = NX/2+1; 
    uvdata.NV = NY; 
    uvdata.Nuv = uvdata.NU*uvdata.NV; 

    tmpdata = uvdata; 
    fftw(&fitsimage, &tmpdata); 
} 

void fftw(image *fitsimage, data *tmpdata) 
{ 
    int iuv,inc=1; 
    double *in,*Vreal,*Vimag; 
    dcomplex *out; 
    fftw_plan fftplan; 

    in = alloc_matrix<double>(fitsimage->NX,fitsimage->NY); 
    out = alloc_matrix<dcomplex>(tmpdata->NU,tmpdata->NV); 
    Vreal = alloc_matrix<double>(tmpdata->NU,tmpdata->NV); 
    Vimag = alloc_matrix<double>(tmpdata->NU,tmpdata->NV); 

    fftplan = fftw_plan_dft_r2c_2d(fitsimage->NX, fitsimage->NY, 
          in, reinterpret_cast<fftw_complex*>(out), FFTW_MEASURE); 

    dcopy_(&(fitsimage->Npix), fitsimage->Iin, &inc, in, &inc); 
    fftw_execute(fftplan); 

    for (iuv=0; iuv<tmpdata->Nuv; ++iuv) { 
    Vreal[iuv] = std::real(out[iuv]); 
    Vimag[iuv] = std::imag(out[iuv]); 
    printf("%d %f\n",iuv,Vreal[iuv]); 
    } 

    delete[] in; 
    delete[] out; 
    fftw_destroy_plan(fftplan); 
} 

3.fft_tools.cpp(ツール)

#include "fft.hpp" 


template <typename T> T *alloc_vector(int length) { 
    return new T[length]; 
} 

template <typename T> T *alloc_matrix(int width, int height) { 
    return new T[width*height]; 
} 

4.libfftw.cpp私はこの使用して遵守してきました

#include "fft.hpp" 


BOOST_PYTHON_MODULE(libfft) 
{ 
    Py_Initialize(); 
    npy::initialize(); 

    py::def("input_pos", &input_pos); 
    py::def("input_fcv", &input_fcv); 
    py::def("input_amp", &input_amp); 
    py::def("input_cp", &input_cp); 
    py::def("input_ca", &input_ca); 
    py::def("fft_test", &fft_test); 
} 

(のpythonの実装):

g++ -fPIC -Wall -O2 -lopenblas -fftw3 -lboost_python -lboost_numpy -I/usr/include/python2.7 -shared -o libfft.so fft.cpp fft_tools.cpp libfftw.cpp 

そして、私はインポート時に次のエラーを取得:

import libfft 
ImportError: ./libfft.sp: undefined symbol: _Z12alloc_matrixISt7complexIdEEPT_ii 

を何これはどういう意味ですか、どうすれば修正できますか?

答えて

0

コードをリンクするとき、リンカはシンボルalloc_matrix<complex>を見つけることができません。これは、.hppファイルではなく、.cppファイルにその実装を配置したためです。あなたがいる場合:

    fft_tools.cppのあなたの実装を移動し、今 fft.hpp
  • に入れ
  • 完全に、その空fft_tools.cppファイルを取り除きます。

次に、この特定のリンクエラーが消えることがわかります。

+0

ありがとうございます!私はこの問題を解決しました。 –

関連する問題