g++ -std=c++0x -Wall -O3 -lm m_source.cpp Math.o FT.o -o m_source
FT.o: In function `FFTmix::bfy(Complex*, Complex*, int, int, int)':
FT.cpp:(.text+0x5ca): undefined reference to `Complex& operator/=<int>(Complex&, int)'
FT.o: In function `FFTof2::bfy(std::vector<std::vector<Complex, std::allocator<Complex> >, std::allocator<std::vector<Complex, std::allocator<Complex> > > >&, std::vector<std::vector<Complex, std::allocator<Complex> >, std::allocator<std::vector<Complex, std::allocator<Complex> > > >&)':
FT.cpp:(.text+0x8b5): undefined reference to `Complex operator*<double>(double, Complex)'
FT.cpp:(.text+0xa45): undefined reference to `Complex operator*<double>(double, Complex)'
FT.o: In function `DFTof2::bfy(std::vector<std::vector<Complex, std::allocator<Complex> >, std::allocator<std::vector<Complex, std::allocator<Complex> > > >&, std::vector<std::vector<Complex, std::allocator<Complex> >, std::allocator<std::vector<Complex, std::allocator<Complex> > > >&)':
FT.cpp:(.text+0xec2): undefined reference to `Complex& operator/=<int>(Complex&, int)'
collect2: エラー: ld はステータス 1 で終了しました
make: *** [m_source] エラー 1
の様なエラーが発生しました。
Math.h内にある"Complexクラス"のoperatorはこのエラー以外全て機能しています。どうすればよろしいのでしょうか?
以下がコードになります。
~Math.h~
#ifndef _MATH_H_
#define _MATH_H_
#include <iostream>
#include <cmath>
class Complex {
friend Complex operator+(const Complex,const Complex);
friend Complex operator-(const Complex,const Complex);
template <typename T>
friend Complex operator*(const T,const Complex);
friend Complex operator*(const Complex,const Complex);
template <typename T>
friend Complex operator/(const T,const Complex);
friend Complex operator/(const Complex,const Complex);
friend Complex& operator+=(Complex&,const Complex);
friend Complex& operator-=(Complex&,const Complex);
template <typename T>
friend Complex& operator*=(Complex&,const T);
friend Complex& operator*=(Complex&,const Complex);
template <typename T>
friend Complex& operator/=(Complex&,const T);
friend Complex& operator/=(Complex&,const Complex);
friend bool operator==(const Complex,const Complex);
friend bool operator!=(const Complex,const Complex);
friend std::ostream& operator<<(std::ostream&,const Complex&);
public:
double Re,Im;
template <typename T,typename U>
Complex(const T t_Re,const U t_Im):Re(static_cast<double>(t_Re)),Im(static_cast<double>(t_Im)) { };
template <typename T>
explicit Complex(const T t_Re):Re(static_cast<double>(t_Re)),Im(0.0) { };
Complex(void):Re(0.0),Im(0.0) { };
template <typename T,typename U>
void set(const T,const U);
/*
* calculate r and theta
* r=sqrt(Re^2+Im^2), theta=atan(Im/Re)
*/
double abs();
double arg();
};
#include "../header/Math.h"
Complex operator+(const Complex a,const Complex b) {
return Complex(a.Re+b.Re,a.Im+b.Im);
};
Complex operator-(const Complex a,const Complex b) {
return Complex(a.Re-b.Re,a.Im-b.Im);
};
template <typename T>
Complex operator*(const T N,const Complex a) {
return Complex(a.Re*N,a.Im*N);
};
Complex operator*(const Complex a,const Complex b) {
return Complex(a.Re*b.Re-a.Im*b.Im,a.Re*b.Im+b.Re*a.Im);
};
template <typename T>
Complex operator/(const T N,const Complex a) {
return (1/N)*a;
};
Complex operator/(const Complex a,const Complex b) {
double r=pow(const_cast<Complex&>(b).abs(),2);
return Complex((a.Re*b.Re+a.Im*b.Im)/r,(a.Re*(-b.Im)+b.Re*a.Im)/r);
};
Complex& operator+=(Complex& a,const Complex b) {
a=a+b;
return a;
};
Complex& operator-=(Complex& a,const Complex b) {
a=a-b;
return a;
};
template <typename T>
Complex& operator*=(Complex& a,const T N) {
a=a*N;
return a;
};
Complex& operator*=(Complex& a,const Complex b) {
a=a*b;
return a;
};
template <typename T>
Complex& operator/=(Complex& a,const T N) {
a=a/N;
return a;
};
Complex& operator/=(Complex& a,const Complex b) {
a=a/b;
return a;
};
bool operator==(const Complex a,const Complex b) {
return ((a.Re==b.Re&&a.Im==b.Im)? true:false);
};
bool operator!=(const Complex a,const Complex b) {
return !(a==b);
};
std::ostream& operator<<(std::ostream& os,const Complex& a) {
os<< a.Re <<" "<< a.Im;
return os;
};
template <typename T,typename U>
void Complex::set(const T t_Re,const U t_Im) {
Re=static_cast<double>(t_Re),Im=static_cast<double>(t_Im);
};
/*
* calculate r and theta
* r=sqrt(Re^2+Im^2), theta=atan(Im/Re)
*/
double Complex::abs(void) {
return sqrt(pow(Re,2)+pow(Im,2));
};
double Complex::arg(void) {
return atan2(Im,Re);
};
#include <vector>
#include "./Math.h"
//Fourier Transformation on 1D
class DFT {
public:
void bfy(Complex*,Complex*,int);
};
class FFTmix {
private:
std::vector<Complex> tmp;
public:
FFTmix(void) {
tmp.clear();
};
void bfy(Complex*,Complex*,int,int,int);
};
//Fourier Transformation on 2D
class DFTof2 {
private:
std::vector<Complex> tmp,in,out;
public:
DFTof2(void) {
tmp.clear(),in.clear(),out.clear();
};
void bfy(std::vector<std::vector<Complex> >&,std::vector<std::vector<Complex> >&);
};
class FFTof2 {
private:
std::vector<Complex> ttmp,tmp,dat;
public:
FFTof2(void) {
ttmp.clear(),tmp.clear(),dat.clear();
};
void bfy(std::vector<std::vector<Complex> >&,std::vector<std::vector<Complex> >&);
};
//calculate W using Fourier Transformation
Complex W(const int,const int);
#include <cstring>
#include "../header/FT.h"
//Fourier Transformation on 1D
void DFT::bfy(Complex in[],Complex out[],int ALL) {
for(int i=0;i<ALL;++i) {
for(int j=0;j<ALL;++j) out[i]+=W(-i*j,ALL)*in[j];
}
};
void FFTmix::bfy(Complex in[],Complex out[],int N,int n,int ALL) {
if(N<=1) return;
else if(N==ALL) tmp.resize(N,Complex());
int width=2,height;
while(N>=pow(width,2)) {
if(N%width==0) break;
++width;
}
if(N%width!=0) width=N;
height=N/width;
for(int h=0;h<height;++h) {
for(int w=0;w<width;++w) {
Complex buf=Complex();
for(int r=0;r<N;r+=height) buf+=in[h+r]*W(-w*r,n);
out[height*w+h]=buf*W(-h*w,n);
}
}
for(int r=0;r<N;r+=height) bfy(&out[r],in,height,n/width,ALL);
if(N==ALL) {
for(int h=0;h<height;++h) {
for(int w=0;w<width;++w) {
out[height*w+h]/=N;
}
}
} else {
for(int h=0;h<height;++h) {
for(int w=0;w<width;++w) {
in[width*h+w]=out[height*w+h];
}
}
}
};
//Fourier transformation on 2D
void DFTof2::bfy(std::vector<std::vector<Complex> >& t_in,std::vector<std::vector<Complex> >& t_out) {
int ALL_x=t_in.size(),ALL_y=t_in[0].size();
tmp.resize(ALL_x*ALL_y,Complex()),in.resize(ALL_x*ALL_y,Complex()),out.resize(ALL_x*ALL_y,Complex());
for(int i=0;i<ALL_x;++i) {
for(int j=0;j<ALL_y;++j) in[j+i*ALL_y]=t_in[i][j];
}
int x,y,u=0,v=0;
for(Complex& val1:out) {
x=y=0;
for(Complex val2:in) {
tmp[v+x*ALL_y]+=W(-v*y,ALL_y)*val2,++y;
if(y==ALL_y) y=0,++x;
}
for(x=0;x<ALL_x;++x) val1+=W(-u*x,ALL_x)*tmp[v+x*ALL_y];
val1/=ALL_x*ALL_y;
}
};
void FFTof2::bfy(std::vector<std::vector<Complex> >& in,std::vector<std::vector<Complex> >& out) {
int ALL_x=in.size(),ALL_y=in[0].size();
FFTmix FFT;
tmp.resize(ALL_x*ALL_y,Complex()),dat.resize(ALL_x,Complex());
for(int y=0;y<ALL_y;++y) {
ttmp.resize(ALL_x,Complex());
for(int x=0;x<ALL_x;++x) dat[x]=in[x][y];
FFT.bfy(&dat[0],&ttmp[0],ALL_x,ALL_x,ALL_x);
for(int u=0;u<ALL_x;++u) tmp[y+u*ALL_y]=1.0/ALL_x*ttmp[u];
}
dat.resize(ALL_y,Complex());
for(int u=0;u<ALL_x;++u) {
ttmp.resize(ALL_y,Complex());
for(int y=0;y<ALL_y;++y) dat[y]=tmp[y+u*ALL_y];
FFT.bfy(&dat[0],&ttmp[0],ALL_y,ALL_y,ALL_y);
for(int v=0;v<ALL_y;++v) out[u][v]=1.0/ALL_y*ttmp[v];
}
};
//calculate W using Fourier Transformation
Complex W(const int n,const int N) {
double Re=cos((n%N)*2*M_PI/N),Im=sin((n%N)*2*M_PI/N);
Re=((fabs(static_cast<double>(Re))<pow(10.0,-15))? 0.0:Re),
Im=((fabs(static_cast<double>(Im))<pow(10.0,-15))? 0.0:Im);
return Complex(Re,Im);
};