?? cfunc.cpp
字號:
#include <values.h>
#include <math.h>
#include <stdio.h>
#include "cfunc.h"
COMPLEX calgo::cal(DOUBLE x) { // 基類的基本算法
return yfactor*calculate(xfactor*(x-xshift))+addconst;
}
calgo * calgo::clone() // 克隆自己,必須被繼承子類改寫
{
return new calgo(*this);
}
calgo * calgo::mul(COMPLEX a) // 乘a
{
calgo * alg;
alg = this;
if(refnum>1) { refnum--;
alg = clone(); // 如引用數大于1,則產生新的對象
}
alg->yfactor *= a;
alg->addconst *= a;
return alg;
}
calgo * calgo::add(COMPLEX a) // 加a
{
calgo * alg;
alg = this;
if(refnum>1) { refnum--;
alg = clone(); // 如引用數大于1,則產生新的對象
}
alg->addconst += a;
return alg;
}
calgo * calgo::neg() // 取負
{
calgo * alg;
alg = this;
if(refnum>1) { refnum--;
alg = clone(); // 如引用數大于1,則產生新的對象
}
alg->addconst = -alg->addconst;
alg->yfactor = -alg->yfactor;
return alg;
}
calgo * calgo::setxfactor(DOUBLE x) // 設置x軸因子
{
calgo * alg;
alg = this;
if(refnum>1) { refnum--;
alg = clone(); // 如引用數大于1,則產生新的對象
}
alg->xfactor = x;
return alg;
}
calgo * calgo::xroom(DOUBLE x) // 將xfactor擴大x倍
{
calgo * c;
if(x != 0)
c = setxshift(xshift/x);
return c->setxfactor(x*xfactor);
}
calgo * calgo::setxshift(DOUBLE x) // 設置xshift的值
{
calgo * alg;
alg = this;
if(refnum>1) { refnum--;
alg = clone(); // 如引用數大于1,則產生新的對象
}
alg->xshift = x;
return alg;
}
calgo * calgo::xshiftas(DOUBLE x) // 從當前開始平移x
{
return setxshift(xshift+x);
}
calgo * calgojoin::clone() // 克隆自己
{
return new calgojoin(*this);
}
COMPLEX calgojoin::calculate(DOUBLE x) // 實施結合算法
{
if(leftalgo==0 || rightalgo==0)
throw TMESSAGE("empty algo pointor!");
COMPLEX a,b;
a = leftalgo->cal(x);
b = rightalgo->cal(x);
if(met == cadd) // 返回各結合運算值
return a+b;
else if(met == csub)
return a-b;
else if(met == cmul)
return a*b;
else if(met == cdiv)
return a/b;
else if(met == cpow)
return pow(a,b);
return 0.0;
}
calgo * calgofun::clone() // 克隆自己
{
return new calgofun(*this);
}
COMPLEX calgofun::calculate(DOUBLE x) // 實施函數算法
{
if(f)
return f(x);
return 0.0;
}
COMPLEX calgoenter::calculate(DOUBLE x) // 實施函數算法
{
return COMPLEX(er->cal(x),ei->cal(x));
}
calgo * calgoenter::clone() // 克隆自己
{
return new calgoenter(*this);
}
cfunc::cfunc()// 缺省構造函數,產生函數f(x)=x;
{
alg = new calgo();
}
cfunc::cfunc(cfunc & fn) // 拷貝構造函數
{
alg = fn.alg;
alg->refnum++;
}
cfunc::cfunc(COMPLEX (*fun)(DOUBLE)) // 函數指針的構造函數
{
alg = new calgofun(fun);
}
cfunc::cfunc(COMPLEX a) // 常函數構造函數
{
alg = new calgo(a);
}
cfunc& cfunc::operator=(cfunc& fn) // 賦值運算符
{
if(this == &fn) return (*this); // 如果等于自己,干脆啥也別做
if(alg) {
alg->refnum--; // 原算法引用數減1
if(!alg->refnum) // 如結果為0則刪除原算法
delete alg;
}
alg = fn.alg; // 將fn的算法移過來
if(alg) alg->refnum++; // 引用數增加
return (*this);
}
cfunc& cfunc::operator=(COMPLEX (*fn)(DOUBLE)) // 用函數指針的賦值運算符
{
if(alg) {
alg->refnum--; // 原算法引用數減1
if(!alg->refnum) // 如結果為0則刪除原算法
delete alg;
}
alg = new calgofun(fn);
return (*this);
}
cfunc& cfunc::operator=(COMPLEX a) // 常函數的賦值運算符
{
if(alg) {
alg->refnum--; // 原算法引用數減1
if(!alg->refnum) // 如結果為0則刪除原算法
delete alg;
}
alg = new calgo(a);
return (*this);
}
cfunc& cfunc::operator+=(cfunc& fn) // 自身加一個函數
{
calgo * a = new calgojoin(alg, fn.alg, cadd);
alg->refnum--; // 因為聯合算法對兩個算法都加了引用數,因此再減回來
alg = a; // 將新指針賦給alg
return (*this);
}
cfunc& cfunc::operator+=(COMPLEX (*f)(DOUBLE)) // 自身加一個函數指針
{
cfunc fn(f); // 將函數指針包裝為函數類
operator+=(fn); // 實施加操作
return (*this);
}
cfunc cfunc::operator+(cfunc& fn) // 相加產生新函數
{
calgo * a = new calgojoin(alg, fn.alg, cadd);
cfunc f(a);
return f;
}
cfunc cfunc::operator+(COMPLEX a) // 與常數相加產生新函數
{
cfunc f(*this);
f += a;
return f;
}
cfunc cfunc::operator+(COMPLEX (*f)(DOUBLE)) // 加一個函數指針產生新函數
{
cfunc ff(*this);
ff += f;
return ff;
}
cfunc& cfunc::neg() // 自身取負
{
alg=alg->neg();
return (*this);
}
cfunc cfunc::operator-() // 產生負函數
{
cfunc f(*this);
f.neg();
return f;
}
cfunc& cfunc::operator-=(cfunc& fn) // 自身減一個函數
{
calgo * a = new calgojoin(alg, fn.alg, csub);
alg->refnum--; // 因為聯合算法對兩個算法都加了引用數,因此再減回來
alg = a; // 將新指針賦給alg
return (*this);
}
cfunc& cfunc::operator-=(COMPLEX (*f)(DOUBLE)) // 自身減一個函數指針
{
cfunc fn(f); // 將函數指針包裝為函數類
operator-=(fn); // 實施減操作
return (*this);
}
cfunc cfunc::operator-(cfunc& fn) // 相減產生新函數
{
calgo * a = new calgojoin(alg, fn.alg, csub);
cfunc f(a);
return f;
}
cfunc cfunc::operator-(COMPLEX a) // 與常數相減產生新函數
{
cfunc f(*this);
f -= a;
return f;
}
cfunc operator-(COMPLEX a, cfunc& f) // 常數減函數
{
return (-f)+a;
}
cfunc cfunc::operator-(COMPLEX (*f)(DOUBLE)) // 減一個函數指針產生新函數
{
cfunc ff(*this);
ff -= f;
return ff;
}
cfunc operator-(COMPLEX (*f)(DOUBLE),cfunc& fn) // 函數指針減函數
{
cfunc ff(f);
ff -= fn;
return ff;
}
cfunc& cfunc::operator*=(cfunc& fn) // 自身乘一個函數
{
calgo * a = new calgojoin(alg, fn.alg, cmul);
alg->refnum--; // 因為聯合算法對兩個算法都加了引用數,因此再減回來
alg = a; // 將新指針賦給alg
return (*this);
}
cfunc& cfunc::operator*=(COMPLEX (*f)(DOUBLE)) // 自身乘一個函數指針
{
cfunc fn(f); // 將函數指針包裝為函數類
operator*=(fn); // 實施乘操作
return (*this);
}
cfunc cfunc::operator*(cfunc& fn) // 相乘產生新函數
{
calgo * a = new calgojoin(alg, fn.alg, cmul);
cfunc f(a);
return f;
}
cfunc cfunc::operator*(COMPLEX a) // 與常數相乘產生新函數
{
cfunc f(*this);
f *= a;
return f;
}
cfunc cfunc::operator*(COMPLEX (*f)(DOUBLE)) // 乘一個函數指針產生新函數
{
cfunc ff(*this);
ff *= f;
return ff;
}
cfunc& cfunc::operator/=(cfunc& fn) // 自身除以一個函數
{
calgo * a = new calgojoin(alg, fn.alg, cdiv);
alg->refnum--; // 因為聯合算法對兩個算法都加了引用數,因此再減回來
alg = a; // 將新指針賦給alg
return (*this);
}
cfunc& cfunc::operator/=(COMPLEX (*f)(DOUBLE)) // 自身除以一個函數指針
{
cfunc fn(f); // 將函數指針包裝為函數類
operator/=(fn); // 實施除法操作
return (*this);
}
cfunc cfunc::operator/(cfunc& fn) // 相除產生新函數
{
calgo * a = new calgojoin(alg, fn.alg, cdiv);
cfunc f(a);
return f;
}
cfunc cfunc::operator/(COMPLEX a) // 與常數相除產生新函數
{
cfunc f(*this);
f /= a;
return f;
}
cfunc operator/(COMPLEX a, cfunc& f) // 常數除以函數
{
cfunc ff(a);
return ff/f;
}
cfunc cfunc::operator/(COMPLEX (*f)(DOUBLE)) // 除以一個函數指針產生新函數
{
cfunc ff(*this);
ff /= f;
return ff;
}
cfunc operator/(COMPLEX (*f)(DOUBLE),cfunc& fn) // 函數指針除以函數
{
cfunc ff(f);
ff /= fn;
return ff;
}
void cfunc::setxfactor(DOUBLE a) // 設置x因子為a
{
alg = alg->setxfactor(a);
}
void cfunc::xroom(DOUBLE a) // x方向擴大a倍
{
alg = alg->xroom(a);
}
cfunc& cfunc::power(cfunc& f) // 函數的f次乘冪,函數自身改變
{
calgo * a = new calgojoin(alg, f.alg, cpow);
alg->refnum--; // 因為聯合算法對兩個算法都加了引用數,因此再減回來
alg = a; // 將新指針賦給alg
return (*this);
}
cfunc cfunc::operator^(cfunc& fn) // f次乘冪,產生新函數
{
calgo * a = new calgojoin(alg, fn.alg, cpow);
cfunc f(a);
return f;
}
cfunc& cfunc::power(COMPLEX a) // 函數的a次冪,函數自身改變
{
cfunc f(a);
return power(f);
}
cfunc cfunc::operator^( COMPLEX a) // 函數的a次冪,產生新函數,原函數不變
{
cfunc f(a);
cfunc ff(*this);
return ff.power(f);
}
COMPLEX calgopoly::calculate(DOUBLE x) // 實施函數算法
{
size_t i;
COMPLEX u;
size_t n=data.rownum-1;
u=data(n);
for (i=n; i>0; i--)
u=u*x+data(i-1);
return u;
}
calgo * calgopoly::clone() // 克隆自己
{
return new calgopoly(*this);
}
cfunc::cfunc(cmatrix& m) // 構造數值相關函數,
// m為nX1矩陣,是n-1階多項式系數,
// 其中m(0,0)為常數項,m(n-1,0)為n-1次項。
{
alg = new calgopoly(m); // 產生多項式算法
}
void cfunc::setxshift(DOUBLE a) // 設置函數沿x軸平移a
{
alg = alg->setxshift(a);
}
void cfunc::shiftxas(DOUBLE a) // 函數沿x軸右移a
{
alg = alg->xshiftas(a);
}
cfuncenter::cfuncenter(cmatrix& s,DOUBLE t0, DOUBLE dt):
cfunc(new calgoenter(s.real(),s.image(),t0,dt))
{}
cfunc fourier(func& f,DOUBLE tb, DOUBLE te, DOUBLE dt, DOUBLE df)
// 利用fft技術對函數f作傅里葉變換,其中tb為采樣窗口的起始點,te為結束點,
// 必須te>tb,dt為采樣間隔,df為頻率采樣間隔,但返回的cfunc是作了插值的
// 插值函數
{
if(tb>=te) throw TMESSAGE("begin point must less than end point");
DOUBLE tspace;
tspace = te-tb;
size_t n;
if(tspace > 1.0/df) df = 1.0/tspace;
n = ceil(1.0/(df*dt));
cmatrix s(n);
s = 0.0;
n = ceil(tspace/dt);
for(size_t i=0; i<n; i++)
s.set(i,f(tb+i*dt));
s.fft();
n = s.rownum;
cmatrix p(n);
df = 1.0/(dt*n);
for(i=0;i<n/2;i++) {
p.set(i,s(i+n/2));
p.set(i+n/2,s(i));
}
for(i=1; i<n/2; i++) {
COMPLEX c;
DOUBLE phi;
phi = 2.0*M_PI*i*df*(-tb);
c = COMPLEX(cos(phi),sin(phi));
p.set(i+n/2,p(i+n/2)*c);
p.set(-i+n/2,p(-i+n/2)*conj(c));
}
p *= dt;
DOUBLE fbegin = -0.5/dt;
return cfuncenter(p,fbegin,df);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -