#include "VectorCpx.h"
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <limits>
using namespace std;
ostream& operator<<(ostream& ostr, const Complex& cp)
{
ostr << "R:" << cp.real() << ", I:" << cp.imag();
return ostr;
}
// ------------------------------------------------------
// Member function definition of Complex
Complex::Complex(double _real, double _imag): mReal(_real), mImag(_imag)
{
}
const double& Complex::real() const
{
return mReal;
}
const double& Complex::imag() const
{
return mImag;
}
void Complex::real(double value)
{
mReal = value;
}
void Complex::imag(double value)
{
mImag = value;
}
Complex Complex::operator + (const Complex& cpx)const
{
Complex cpOut;
cpOut.real(mReal + cpx.real());
cpOut.imag(mImag + cpx.imag());
return cpOut;
}
Complex Complex::operator - (const Complex& cpx)const
{
Complex cpOut;
cpOut.real(mReal - cpx.real());
cpOut.imag(mImag - cpx.imag());
return cpOut;
}
Complex Complex::operator * (const Complex& cpx)const
{
Complex cpOut;
cpOut.real( mReal * cpx.real() - mImag * cpx.imag() );
cpOut.imag( mReal * cpx.imag() + mImag * cpx.real() );
return cpOut;
}
Complex Complex::operator / (const Complex& cpx)const
{
Complex cpOut;
double rDiv = cpx.real() * cpx.real() + cpx.imag() * cpx.imag();
if( rDiv < numeric_limits<double>::min())
return cpOut;
cpOut.real( (mReal * cpx.real() + mImag * cpx.imag()) / rDiv );
cpOut.imag( (mImag * cpx.real() - mReal * cpx.imag()) / rDiv );
return cpOut;
}
// -----------------------------------------------
// member functio of VectorCpx
VectorCpx::VectorCpx(unsigned _n, const Complex& cpx):pCpx(NULL), mSize(0), mCapacity(0)
{
resize(_n, cpx);
}
VectorCpx::VectorCpx(const VectorCpx& v):pCpx(NULL), mSize(v.mSize), mCapacity(v.mCapacity)
{
if(mCapacity > 0)
{
pCpx = new Complex[mCapacity];
for(unsigned i=0; i<mSize; ++i)
pCpx[i] = v.pCpx[i];
}
}
VectorCpx::~VectorCpx()
{
if(pCpx != NULL)
delete [] pCpx;
}
unsigned VectorCpx::size() const
{
return mSize;
}
unsigned VectorCpx::capacity() const
{
return mCapacity;
}
const Complex& VectorCpx::operator[](int i) const
{
if(i<0)
return pCpx[0];
else if(static_cast<unsigned>(i) >= mSize)
return pCpx[mSize-1];
else return pCpx[i];
}
Complex& VectorCpx::operator[](int i)
{
if(i<0)
return pCpx[0];
else if(static_cast<unsigned>(i) >= mSize)
return pCpx[mSize-1];
else return pCpx[i];
}
VectorCpx& VectorCpx::push_back(const Complex& cpx)
{
resize(mSize+1, cpx);
return *this;
}
VectorCpx& VectorCpx::resize(unsigned _n, const Complex& cpx)
{
if(_n > mCapacity)
{
if(mCapacity < 1)
mCapacity = 1;
while (mCapacity < _n)
mCapacity <<= 1;
Complex *pNew = new Complex[mCapacity];
// Restore original data
if(mSize > 0)
{
for(unsigned i=0; i<mSize; ++i) pNew[i] = pCpx[i];
delete [] pCpx;
}
pCpx = pNew;
}
for(unsigned i=mSize; i<_n; pCpx[i++] = cpx);
mSize = _n;
return *this;
}
VectorCpx& VectorCpx::operator=(const VectorCpx& v)
{
if(this != &v)
{
this->VectorCpx::~VectorCpx();
mSize = v.mSize;
if(mSize>0)
{
mCapacity = 1;
while (mCapacity < mSize)
mCapacity <<= 1;
pCpx = new Complex[mCapacity];
for(unsigned i=0; i<mSize; ++i)
pCpx[i] = v.pCpx[i];
}
}
return *this;
}
VectorCpx VectorCpx::operator*(const Complex& cpx)const
{
VectorCpx vOut = *this;
for(int i=0; i<mSize; ++i)
vOut.pCpx[i] = vOut.pCpx[i] * cpx;
return vOut;
}
Complex VectorCpx::operator*(const VectorCpx& v)
{
Complex cpxDot = 0;
unsigned nLoop = mSize<v.mSize?mSize:v.mSize;
for(int i=0; i<nLoop; ++i)
{
cpxDot = cpxDot + pCpx[i] * v.pCpx[i];
}
return cpxDot;
}
VectorCpx& VectorCpx::operator>>(fstream& file) //= =
{
cout << "^_^" << endl;
return *this;
}
VectorCpx& VectorCpx::operator<<(fstream& file) //......-.-
{
cout << "XD" << endl;
return *this;
}
VectorCpx operator*(const Complex& cpx, const VectorCpx& v)
{
VectorCpx vOut = v;
unsigned n = v.size();
for(int i=0; i<n; ++i)
vOut[i] = vOut[i] * cpx;
return vOut;
}
ostream& operator<<(ostream& ostr, const VectorCpx& v)
{
unsigned n = v.size();
for(int i=0; i<n;)
{
ostr << v[i];
++i;
if(i<n)
ostr << "; ";
}
ostr << endl;
return ostr;
}
//-------------------------------------------------------------
//member function of AdvVectorO
AdvVectorO::AdvVectorO(unsigned number, const Complex& input):VectorCpx(number, input) //constructor
{
}
AdvVectorO::AdvVectorO(const VectorCpx& vec):VectorCpx(vec) //copy constructor
{
}
AdvVectorO& AdvVectorO::operator>>(fstream& file)
{
for(int i = 0; i < mSize; i++)
{
file << (*this)[i].real() << " " << (*this)[i].imag();
file << endl;
}
return *this;
}
//-------------------------------------------------------------
//member function of AdvVectorI
AdvVectorI::AdvVectorI(unsigned number, const Complex& input):VectorCpx(number, input) //constructor
{
}
AdvVectorI::AdvVectorI(const VectorCpx& vec):VectorCpx(vec) //copy constructor
{
}
AdvVectorI& AdvVectorI::operator<<(fstream& file)
{
double regR = 0.0, regI = 0.0;
while(file >> regR >> regI) //如果寫while(!file.eof()){file >> regR >> regI;...}的話,會造成最後一個地方讀兩遍,因為C++的eof()是條件「已發生」才會回傳true
push_back(Complex(regR,regI)); //每從文件讀一組數字進來,就push_back這組數字到原本的VectorCpx後面
return *this;
}
//-------------------------------------------------------------
//member function of AdvVectorIO
//因為這裡要求以binary的形式操作程式,因此不能像前面用Complex的指標做爽爽,得先轉成char型態指標,再用fstream的函式去做
AdvVectorIO::AdvVectorIO(unsigned number, const Complex& input):VectorCpx(number, input) //constructor
{
}
AdvVectorIO::AdvVectorIO(const VectorCpx& vec):VectorCpx(vec) //copy constructor
{
}
AdvVectorIO& AdvVectorIO::operator>>(fstream& file)
{
int size = sizeof(Complex)*mSize;
file.write((char*)(&pCpx[0]), size); //write(const unsigned char buf,int num),從buf指向的暫存區寫入num長度的字元到文件中
//由於pCpx[]是Complex型態,因此需要先在前面加"&"讓它成為指標,再用強制轉換變成char指標
return *this; //到時候執行時,程式就會從pCpx[0]當下指著的VectorCpx上,一口氣把所有的數字都寫到文件中
}
AdvVectorIO& AdvVectorIO::operator<<(fstream& file)
{
Complex reg;
while(file.read((char*)(®), sizeof(Complex))) //read(unsigned char buf,int num),從文件中讀取num長度的字元到buf指向的暫存區
push_back(reg); //每從文件讀一組數字進來,就push_back這組數字到原本的VectorCpx後面
return *this;
}