root@iZ14rcmneyrcltZ:~/cpptest# g++ -o fromb fromb.cpp
root@iZ14rcmneyrcltZ:~/cpptest# ./fromb
被积函数:x*x+sin(x),积分区间:[2.500000,8.400000]:
矩形求积法定积分值:192.077812,梯形求积法定积分值:192.077812,抛物线求积法定积分值:192.077390,变步长辛普生求积法定积分值:192.077812,切比雪夫求积法定积分值:192.077808,龙贝格求积法定积分值:192.077812,
被积函数:y=x/(4.0+x*x),积分区间:[2.500000,8.400000]:
矩形求积法定积分值:0.992163,梯形求积法定积分值:0.992163,抛物线求积法定积分值:0.992163,变步长辛普生求积法定积分值:0.992163,切比雪夫求积法定积分值:0.992163,龙贝格求积法定积分值:0.992163,
被积函数:y=exp(x*x),积分区间:[2.500000,8.400000]:
矩形求积法定积分值:264023978821239618505904488448.000000,梯形求积法定积分值:264023980084158764445880811520.000000,抛物线求积法定积分值:263997998331346174975301124096.000000,变步长辛普生求积法定积分值:264023979869547922162236522496.000000,切比雪夫求积法定积分值:264021982876615073323382996992.000000,龙贝格求积法定积分值:264023980021669454844394471424.000000,
#include <math.h>
#include <stdio.h>
// 矩形求积法
double integalrect(double a,double b,double eps,double(*fun)(double x))
{
double sum=0,h,x1,x2;
int n=static_cast<int>(1.f/eps);
h=(b-a)/n; /*积分步长*/
x1=a;
x2=x1+h;
for(int i=1;i<=n;i++)
{
sum+=(*fun)((x2+x1)/2);
x1+=h;
x2+=h;
}
sum*=h;
return sum;
}
// 梯形求积法:a是积分下限,b是积分上限,精度eps定义为等分区间数n的倒数,fun是被积函数
double integaltrap(double a,double b,double eps,double(*fun)(double x))
{
#if 1
double s,h,y;
s=(fun(a)+fun(b))/2;
int n=static_cast<int>(1.f/eps);
h=(b-a)/n; /*积分步长*/
for(int i=1;i<n;i++)
s=s+fun(a+i*h);
y=s*h;
return y;/*返回积分值*/
#else
double s=0,h,x1,x2;
h=(b-a)/n;
x1=a;
x2=x1+h;
for(int i=1;i<=n-1;i++)
{
x1+=h;
s+=(*fun)(x1);
}
s=h*(s*2+(*fun)(a)+(*fun)(b))/2;
return s;
#endif
}
// 抛物线求积法
double integalpara(double a,double b,double eps,double(*fun)(double x))
{
double sum=0,h,x1,x2;
int n=static_cast<int>(1.f/eps);
h=(b-a)/n; /*积分步长*/
x1=a;
x2=x1+h;
for(int i=1;i<=n-1;i++)
{
sum+=(*fun)(x1)+4*(*fun)((x1+x2)/2)+(*fun)(x2);
x1+=h;
x2+=h;
}
sum*=h/6;
return sum;
}
double fsimp(double a,double b,double eps,double(*fsimpf)(double)) /*辛普森求积法*/
/*a为积分下限,b为积分上限,eps是希望达到的精度*/
{
int n,k;
double h,t1,t2,s1,s2,ep,p,x;
n=1; h=b-a;
t1=h*(fsimpf(a)+fsimpf(b))/2.0; /*用梯形公式求出一个大概的估值*/
s1=t1;
ep=eps+1.0;
while (ep>=eps)
{
/*用梯形法则计算*/
p=0.0;
for (k=0;k<=n-1;k++)
{
x=a+(k+0.5)*h;
p=p+fsimpf(x);
}
t2=(t1+h*p)/2.0;
/*用辛普森公式求精*/
s2=(4.0*t2-t1)/3.0;
ep=fabs(s2-s1);
t1=t2; s1=s2; n=n+n; h=h/2.0;
}
return(s2);
}
/**********************变步长辛普生法*************/
/***a为积分下限;b为积分上限;eps为精度要求.********/
double bcsimp(double a,double b,double eps,double(*bcsimpf)(double x))
{
int n,k;
double h,t1,t2,s1,s2,ep,p,x;
n=1;h=b-a;
t1=h*(bcsimpf(a)+bcsimpf(b))/2.0;
s1=t1;
ep=eps+1.0;
while(ep>=eps)
{
p=0.0;
for(k=0;k<=n-1;k++)
{x=a+(k+0.5)*h;
p=p+bcsimpf(x);
}
t2=(t1+h*p)/2.0;
s2=(4.0*t2-t1)/3.0;
ep=fabs(s2-s1);
t1=t2;s1=s2;n=n+n;h=h/2.0;
}
return(s2);
}
double fcbsv(double a,double b,double eps,double(*fcbsvf)(double))//切比雪夫求积法
{
int m,i,j;
double h,d,p,ep,g,aa,bb,s,x;
static double t[5]={-0.8324975,-0.3745414,0.0,
0.3745414,0.8324975};
m=1;
h=b-a; d=fabs(0.001*h);
p=1.0e+35; ep=1.0+eps;
while ((ep>=eps)&&(fabs(h)>d))
{ g=0.0;
for (i=1;i<=m;i++)
{ aa=a+(i-1.0)*h; bb=a+i*h;
s=0.0;
for (j=0;j<=4;j++)
{ x=((bb-aa)*t[j]+(bb+aa))/2.0;
s=s+fcbsvf(x);
}
g=g+s;
}
g=g*h/5.0;
ep=fabs(g-p)/(1.0+fabs(g));
p=g; m=m+1; h=(b-a)/m;
}
return(g);
}
double fromb(double a,double b,double eps,double(*frombf)(double))//龙贝格求积法
/*a为积分下限,b为积分上限,eps是希望达到的精度*/
{
int m,n,i,k;
double y[10],h,ep,p,x,s,q;
h=b-a;
y[0]=h*(frombf(a)+frombf(b))/2.0;
m=1; n=1; ep=eps+1.0;
while ((ep>=eps)&&(m<=9))
{ p=0.0;
for (i=0;i<=n-1;i++)
{ x=a+(i+0.5)*h;
p=p+frombf(x);
}
p=(y[0]+h*p)/2.0;
s=1.0;
for (k=1;k<=m;k++)
{ s=4.0*s;
q=(s*p-y[k-1])/(s-1.0);
y[k-1]=p; p=q;
}
ep=fabs(q-y[m-1]);
m=m+1; y[m-1]=q; n=n+n; h=h/2.0;
}
return(q);
}
int main(int argc, char* argv[])
{
typedef double(*pR)(double a,double b,double eps,double(*frombf)(double));
pR R[]={integalrect,integaltrap,integalpara,bcsimp,fcbsv,fromb};
const char *szNameR[]={"矩形求积法","梯形求积法","抛物线求积法","变步长辛普生求积法","切比雪夫求积法","龙贝格求积法"};
int nR=sizeof(szNameR)/sizeof(szNameR[0]);
double a,b,eps,t;
a=2.5; b=8.4; eps=0.000001;
typedef double(*pF)(double);
pF F[]={[](double x)->double{return x*x+sin(x);},[](double x)->double{return x/(4.0+x*x);},[](double x)->double{return exp(x*x);}};
const char *szNameF[]={"x*x+sin(x)","y=x/(4.0+x*x)","y=exp(x*x)"};
int nF=sizeof(szNameF)/sizeof(szNameF[0]);
for(int i=0;i<nF;i++)
{
printf("被积函数:%s,积分区间:[%f,%f]:\n",szNameF[i],a,b);
for (int j=0;j<nR;j++)
{
t=R[j](a,b,eps,F[i]);
printf("%s定积分值:%f,",szNameR[j],t);
}
printf("\n");
}
return 0;
}
root@iZ14rcmneyrcltZ:~/cpptest# g++ -o polyInF2 polyInF2.cpp
root@iZ14rcmneyrcltZ:~/cpptest# ./polyInF2
int g_F4Add[]={
1,2,3,4,
2,1,4,3,
3,4,1,2,
4,3,2,1,
};
int g_F4Mul[]={
1,1,1,1,
1,2,3,4,
1,3,4,2,
1,4,2,3,
};
int g_R4Add[]={
1,2,3,4,
2,1,4,3,
3,4,1,2,
4,3,2,1,
};
int g_R4Mul[]={
1,1,1,1,
1,2,3,4,
1,3,2,4,
1,4,4,1,
};
#include<stdio.h>
#include<string.h>
#include<vector>
#include<iostream>
#include<iterator>
#include<algorithm>
#include<functional>
using namespace std;
/*
GF(2)上的多项式f(x)=x^2+1的剩余类全体为:
~0,~1,~x,~(x+1)
GF(2)上的多项式f(x)=x^2+x+1的剩余类全体为:
~0,~1,~x,~(x+1)
对所定义的加法和乘法运算,前者构成剩余类环,后者构成域。
结论:若n次首一多项式f(x)在域F_p上既约,则f(x)的剩余类环构成一个有p^n个元素的有限域。
多项式环F_p[x]的一切理想均是主理想。
多项式剩余类环F_p[x]/f(x)中的每一个理想都是主理想。
多项式(1+x+x^4+x^6)mod(1+x+x^3+x^4+x^8)的乘法逆元是(x+x^3+x^6+x^7)
*/
// 欧几里得算法
template<class T>
T gcd(T a, T b)
{
int temp;
if(b == 0) return a;
if(a == 0) return b;
if(a%b == 0) return b;
else return gcd(b, a%b);
}
// 多项式a乘以多项式b得到多项式c,deg(a)=m-1,deg(b)=n-1,deg(c)=m+n-2=k
int polymul(int* a,int m,int* b,int n,int* c,int* k)
{
int i,j;
if(k)*k=m+n-2;
for(i=0;i<m+n-2;i++)
c[i]=0;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
c[i+j]=a[i]*b[j]+c[i+j];
return 0;
}
int Mod(int ret,unsigned int n)
{
//assert(n>0);
if(ret<0)
{
int ret1=ret+(-ret+1)*n;
return ret1%n;
}
return ret%n;
}
auto Mod2=std::bind(Mod,std::placeholders::_1,2);
auto AddInF2=[](int a,int b)->bool{
int ret=Mod2(a+b);
return ret;
};
auto MulInF2=[](int a,int b)->bool{
int ret=Mod2(a*b);
return ret;
};
int AddInvInF2(int a)
{
static int F_2[5]={0,1};
for(int i=0;i<2;i++)
{
if(AddInF2(F_2[i],Mod2(a))==0)
return F_2[i];
}
return -1;//错误值
}
int MulInvInF2(int a)
{
static int F_2[2]={0,1};
for(int i=0;i<2;i++)
{
if(MulInF2(F_2[i],Mod2(a))==1)
return F_2[i];
}
return -1;//错误值
}
/*取余函数(被除数a,除数b)*/
vector<int> polymodInF2( vector<int>& a, vector<int>& b)
{
vector<int> m=a,n=b;
int coe;/*商系数*/
if( m.size() < n.size() )
return m;
else for( unsigned int i = 0 ; i < m.size() - n.size() + 1 ; i++ )
{
for( int ma = m[m.size()-1-i] ; ; )
{
if( !( ma % n[n.size()-1] ))
{
coe = ma / n[n.size()-1];
break;
}
ma += 2;
}
for( unsigned int j=0;j<n.size();j++)
m[m.size()-1-i-j] = ( m[m.size()-1-i-j] - coe*n[n.size()-1-j] % 2 + 2 ) % 2;
}
/* while( !m.empty() && !m.back() )
m.pop_back();*/
while (m.size() && *(m.rbegin()) == 0) { // 清除高位无效零
m.pop_back();
}
if (m.empty()) { // 补零
m.push_back(0);
}
return m;
}
/*乘法函数*/
vector<int> polymulInF2(vector<int>& a,vector<int>& b)
{
#if 1
int m=a.size();
int n=b.size();
vector<int> c(m+n-1);
int k=0;
int ret=polymul(&a[0],m,&b[0],n,&c[0],&k);
for_each(c.begin(),c.end(),[](int& i)->void{i=Mod2(i);});//Mod2(a[i]*b[j]+c[i+j])=Mod2(Mod2(a[i]*b[j])+c[i+j])
while (c.size() && *(c.rbegin()) == 0) { // 清除高位无效零
c.pop_back();
}
if (c.empty()) { // 补零
c.push_back(0);
}
return c;
#else
vector<int> c;
c.assign( a.size() + b.size() - 1 , 0 );
for(unsigned int i=0 ; i < a.size() ; i++ )
for( unsigned int j=0 ; j < b.size() ; j++ )
c[i+j] =(( c[i+j] + a[i] * b[j] ) % 2 +2 ) % 2 ;
while (c.size() && *(c.rbegin()) == 0) { // 清除高位无效零
c.pop_back();
}
if (c.empty()) { // 补零
c.push_back(0);
}
return c;
#endif
}
/*加法函数*/
vector<int> polyaddInF2(vector<int>& a,vector<int>& b)
{
int m=a.size();
int n=b.size();
int k=(m>n?m:n);
int ki=(m>n?n:m);
vector<int> c(k);
for(int i=0;i<ki;i++)
{
c[i]=Mod2(a[i]+b[i]);
}
if(m>n)
{
memcpy(&c[n],&a[n],(m-n)*sizeof(int));
}
else if(m<n)
{
memcpy(&c[m],&b[m],(n-m)*sizeof(int));
}
while (c.size() && *(c.rbegin()) == 0) { // 清除高位无效零
c.pop_back();
}
if (c.empty()) { // 补零
c.push_back(0);
}
return c;
}
#if 1
int fa[]={1,1,1};
int ga[]={1,0,1};
int f0a[]={0};
int f1a[]={1};
int f2a[]={0,1};
int f3a[]={1,1};
vector<int> f(fa,fa+sizeof(fa)/sizeof(int));
vector<int> g(ga,ga+sizeof(ga)/sizeof(int));;
vector<int> f0(f0a,f0a+sizeof(f0a)/sizeof(int));
vector<int> f1(f1a,f1a+sizeof(f1a)/sizeof(int));
vector<int> f2(f2a,f2a+sizeof(f2a)/sizeof(int));
vector<int> f3(f3a,f3a+sizeof(f3a)/sizeof(int));
vector<int> g_F4[]={f,f0,f1,f2,f3};
vector<int> g_R4[]={g,f0,f1,f2,f3};
#else
vector<int> f={1,1,1};
vector<int> g={1,0,1};
vector<int> f0={0};
vector<int> f1={1};
vector<int> f2={0,1};
vector<int> f3={1,1};
vector<int> g_F4[]={f,f0,f1,f2,f3};
vector<int> g_R4[]={g,f0,f1,f2,f3};
#endif
int R4ElemToInt(vector<int>& a,vector<int> R4[])
{
for(int i=1;i<=4;i++)
{
if(R4[i].size()==a.size() && memcmp(&R4[i][0],&a[0],sizeof(int)*a.size())==0)
return i;
}
return -1;
}
int R4mul(int a,int b,vector<int> R4[])
{
vector<int> fa=R4[a];
vector<int> fb=R4[b];
vector<int> fafb=polymulInF2(fa,fb);
vector<int> fc=polymodInF2(fafb,R4[0]);
int c=R4ElemToInt(fc,R4);
return c;
}
int R4add(int a,int b,vector<int> R4[])
{
vector<int> fa=R4[a];
vector<int> fb=R4[b];
vector<int> fafb=polyaddInF2(fa,fb);
//vector<int> fc=polymodInF2(fafb,R4[0]);
int c=R4ElemToInt(fafb,R4);
return c;
}
int main()
{
vector<int> *R4[2]={g_F4,g_R4};
const char *szName[2]={"F4","R4"};
for(int i=0;i<2;i++)
{
auto add=std::bind(R4add,std::placeholders::_1,std::placeholders::_2,R4[i]);
printf("int g_%sAdd[]={\n",szName[i]);
for(int i=1;i<=4;i++)
{
printf("%d,%d,%d,%d,\n",add(i,1),add(i,2),add(i,3),add(i,4));
}
printf("};\n");
auto mul=std::bind(R4mul,std::placeholders::_1,std::placeholders::_2,R4[i]);
printf("int g_%sMul[]={\n",szName[i]);
for(int i=1;i<=4;i++)
{
printf("%d,%d,%d,%d,\n",mul(i,1),mul(i,2),mul(i,3),mul(i,4));
}
printf("};\n");
}
return 0;
}
root@iZ14rcmneyrcltZ:~/cpptest# g++ -o Solver1D Solver1D.cpp
root@iZ14rcmneyrcltZ:~/cpptest# ./Solver1D
输出一阶常微分方程y'=-0.05的特解y(x)的采样值:
x=0,y=1,y的理论值=1
x=0.1,y=0.995,y的理论值=0.995
x=0.2,y=0.99,y的理论值=0.99
x=0.3,y=0.985,y的理论值=0.985
x=0.4,y=0.98,y的理论值=0.98
x=0.5,y=0.975,y的理论值=0.975
x=0.6,y=0.97,y的理论值=0.97
x=0.7,y=0.965,y的理论值=0.965
x=0.8,y=0.96,y的理论值=0.96
x=0.9,y=0.955,y的理论值=0.955
x=1,y=0.95,y的理论值=0.95
x=1.1,y=0.945,y的理论值=0.945
x=1.2,y=0.94,y的理论值=0.94
x=1.3,y=0.935,y的理论值=0.935
x=1.4,y=0.93,y的理论值=0.93
x=1.5,y=0.925,y的理论值=0.925
x=1.6,y=0.92,y的理论值=0.92
x=1.7,y=0.915,y的理论值=0.915
x=1.8,y=0.91,y的理论值=0.91
x=1.9,y=0.905,y的理论值=0.905
x=2,y=0.9,y的理论值=0.9
x=2.1,y=0.895,y的理论值=0.895
x=2.2,y=0.89,y的理论值=0.89
x=2.3,y=0.885,y的理论值=0.885
x=2.4,y=0.88,y的理论值=0.88
x=2.5,y=0.875,y的理论值=0.875
x=2.6,y=0.87,y的理论值=0.87
x=2.7,y=0.865,y的理论值=0.865
x=2.8,y=0.86,y的理论值=0.86
x=2.9,y=0.855,y的理论值=0.855
x=3,y=0.85,y的理论值=0.85
x=3.1,y=0.845,y的理论值=0.845
x=3.2,y=0.84,y的理论值=0.84
x=3.3,y=0.835,y的理论值=0.835
x=3.4,y=0.83,y的理论值=0.83
x=3.5,y=0.825,y的理论值=0.825
x=3.6,y=0.82,y的理论值=0.82
x=3.7,y=0.815,y的理论值=0.815
x=3.8,y=0.81,y的理论值=0.81
x=3.9,y=0.805,y的理论值=0.805
x=4,y=0.8,y的理论值=0.8
x=4.1,y=0.795,y的理论值=0.795
x=4.2,y=0.79,y的理论值=0.79
x=4.3,y=0.785,y的理论值=0.785
x=4.4,y=0.78,y的理论值=0.78
x=4.5,y=0.775,y的理论值=0.775
x=4.6,y=0.77,y的理论值=0.77
x=4.7,y=0.765,y的理论值=0.765
x=4.8,y=0.76,y的理论值=0.76
x=4.9,y=0.755,y的理论值=0.755
x=5,y=0.75,y的理论值=0.75
输出一阶常微分方程y'=-0.05y的特解y(x)的采样值:
x=0,y=1,y的理论值=1
x=0.1,y=0.995012,y的理论值=0.995012
x=0.2,y=0.99005,y的理论值=0.99005
x=0.3,y=0.985112,y的理论值=0.985112
x=0.4,y=0.980199,y的理论值=0.980199
x=0.5,y=0.97531,y的理论值=0.97531
x=0.6,y=0.970446,y的理论值=0.970446
x=0.7,y=0.965606,y的理论值=0.965605
x=0.8,y=0.96079,y的理论值=0.960789
x=0.9,y=0.955998,y的理论值=0.955997
x=1,y=0.95123,y的理论值=0.951229
x=1.1,y=0.946485,y的理论值=0.946485
x=1.2,y=0.941765,y的理论值=0.941765
x=1.3,y=0.937068,y的理论值=0.937067
x=1.4,y=0.932394,y的理论值=0.932394
x=1.5,y=0.927744,y的理论值=0.927743
x=1.6,y=0.923117,y的理论值=0.923116
x=1.7,y=0.918513,y的理论值=0.918512
x=1.8,y=0.913932,y的理论值=0.913931
x=1.9,y=0.909373,y的理论值=0.909373
x=2,y=0.904838,y的理论值=0.904837
x=2.1,y=0.900325,y的理论值=0.900325
x=2.2,y=0.895835,y的理论值=0.895834
x=2.3,y=0.891367,y的理论值=0.891366
x=2.4,y=0.886921,y的理论值=0.88692
x=2.5,y=0.882497,y的理论值=0.882497
x=2.6,y=0.878096,y的理论值=0.878095
x=2.7,y=0.873716,y的理论值=0.873716
x=2.8,y=0.869359,y的理论值=0.869358
x=2.9,y=0.865023,y的理论值=0.865022
x=3,y=0.860709,y的理论值=0.860708
x=3.1,y=0.856416,y的理论值=0.856415
x=3.2,y=0.852144,y的理论值=0.852144
x=3.3,y=0.847894,y的理论值=0.847894
x=3.4,y=0.843665,y的理论值=0.843665
x=3.5,y=0.839458,y的理论值=0.839457
x=3.6,y=0.835271,y的理论值=0.83527
x=3.7,y=0.831105,y的理论值=0.831104
x=3.8,y=0.82696,y的理论值=0.826959
x=3.9,y=0.822835,y的理论值=0.822835
x=4,y=0.818731,y的理论值=0.818731
x=4.1,y=0.814648,y的理论值=0.814647
x=4.2,y=0.810585,y的理论值=0.810584
x=4.3,y=0.806542,y的理论值=0.806541
x=4.4,y=0.80252,y的理论值=0.802519
x=4.5,y=0.798517,y的理论值=0.798516
x=4.6,y=0.794534,y的理论值=0.794534
x=4.7,y=0.790572,y的理论值=0.790571
x=4.8,y=0.786629,y的理论值=0.786628
x=4.9,y=0.782705,y的理论值=0.782705
x=5,y=0.778802,y的理论值=0.778801
#include <math.h>
#include <stdio.h>
/*
A 1st order 1D DE solver.
Assumes the function is not time dependent.
Parameters
h - step size
y0 - last value
method - algorithm to use [0,5]
#define EULER 0
#define MIDPOINT 3
fcn - evaluate the derivative of the field
*/
double Solver1D(double h,double y0,int method,double (*fcn)(double))
{
double ynew;
double k1,k2,k3,k4,k5,k6;
switch (method) {
case 0: /* Euler method */
k1 = h * (*fcn)(y0);
ynew = y0 + k1;
break;
case 1: /* Modified Euler */
k1 = h * (*fcn)(y0);
k2 = h * (*fcn)(y0 + k1);
ynew = y0 + (k1 + k2) / 2;
break;
case 2: /* Heuns method */
k1 = h * (*fcn)(y0);
k2 = h * (*fcn)(y0 + 2 * k1 / 3);
ynew = y0 + k1 / 4 + 3 * k2 / 4;
break;
case 3: /* Midpoint */
k1 = h * (*fcn)(y0);
k2 = h * (*fcn)(y0 + k1 / 2);
ynew = y0 + k2;
break;
case 4: /* 4'th order Runge-kutta */
k1 = h * (*fcn)(y0);
k2 = h * (*fcn)(y0 + k1/2);
k3 = h * (*fcn)(y0 + k2/2);
k4 = h * (*fcn)(y0 + k3);
ynew = y0 + k1 / 6 + k2 / 3 + k3 / 3 + k4 / 6;
break;
case 5: /* England 4'th order, six stage */
k1 = h * (*fcn)(y0);
k2 = h * (*fcn)(y0 + k1 / 2);
k3 = h * (*fcn)(y0 + (k1 + k2) / 4);
k4 = h * (*fcn)(y0 - k2 + 2 * k3);
k5 = h * (*fcn)(y0 + (7 * k1 + 10 * k2 + k4) / 27);
k6 = h * (*fcn)(y0 + (28*k1 - 125*k2 + 546*k3 + 54*k4 - 378*k5) / 625);
ynew = y0 + k1 / 6 + 4 * k3 / 6 + k4 / 6;
break;
}
return(ynew);
}
int main(int argc, char* argv[])
{
typedef double(*pR)(double,double,int,double(*)(double));
pR R=Solver1D;
double t;
double dt=0.1; /* Step size */
double T=100; /* Simulation duration */
double y = 1; /* Initial value */
typedef double(*pF)(double);
pF func[]={[](double y)->double{return -0.05;},[](double y)->double{return -0.05 * y;}};
pF func1[]={[](double x)->double{return -0.05*x+1;},[](double x)->double{return exp(-0.05*x);}};
const char *szName[]={"y'=-0.05","y'=-0.05y"};
for(int i=0;i<2;i++)
{
y=1;
printf("输出一阶常微分方程%s的特解y(x)的采样值:\n",szName[i]);
for (t=0;t<5;t+=dt)
{
printf("x=%g,y=%g,y的理论值=%g\n",t,y,func1[i](t));
y=R(dt,y,3,func[i]);
}
}
return 0;
}
/*
root@iZ14rcmneyrcltZ:~/cpptest# g++ -o FindrootInF5 FindrootInF5.cpp
root@iZ14rcmneyrcltZ:~/cpptest# ./FindrootInF5
x^2+x=0在F_5中的根:0,4,
root@iZ14rcmneyrcltZ:~/cpptest# g++ -std=c++11 -o FindrootInF5 FindrootInF5.cpp
root@iZ14rcmneyrcltZ:~/cpptest# ./FindrootInF5
x^2+x=0在F_5中的根:0,4,
*/
#include <iostream>
#include <vector>
#include <cassert>
#include <functional>//std::placeholders
using namespace std;
int F_5[5]={0,1,2,3,4};
int Mod(int ret,unsigned int n)
{
assert(n>0);
if(ret<0)
{
int ret1=ret+(-ret+1)*n;
return ret1%n;
}
return ret%n;
}
/*
int Mod5(int ret)
{
return Mod(ret,5);
}
*/
auto Mod5=std::bind(Mod,std::placeholders::_1,5);
/*
int AddInF5(int a,int b)
{
int ret=Mod5(a+b);
return ret;
}
int MulInF5(int a,int b)
{
int ret=Mod5(a*b);
return ret;
}
*/
auto AddInF5=[](int a,int b)->bool{
int ret=Mod5(a+b);
return ret;
};
auto MulInF5=[](int a,int b)->bool{
int ret=Mod5(a*b);
return ret;
};
int AddInvInF5(int a)
{
static int F_5[5]={0,1,2,3,4};
for(int i=0;i<5;i++)
{
if(AddInF5(F_5[i],Mod5(a))==0)
return F_5[i];
}
return -1;//错误值
}
int MulInvInF5(int a)
{
static int F_5[5]={0,1,2,3,4};
for(int i=0;i<5;i++)
{
if(MulInF5(F_5[i],Mod5(a))==1)
return F_5[i];
}
return -1;//错误值
}
typedef void(*pFuncVoid)(void);
typedef int(*pFuncInt0)(int x);
/*
int Polygon(int x)
{
return x*x+1;
}
*/
vector<int> FindrootInF5(pFuncInt0 fun)
{
vector<int> ret;
if(fun!=NULL)
{
static int F_5[5]={0,1,2,3,4};
for(int i=0;i<5;i++)
{
if(Mod5(fun(F_5[i]))==0)
ret.push_back(F_5[i]);
}
}
return ret;
}
void Print(const char *szName,vector<int>& tlVect)
{
printf("%s",szName);
for (int i = 0; i < tlVect.size(); i++) {
printf("%d,",tlVect[i]);
}
printf("\n");
}
int main()
{
//vector<int> retVec=FindrootInF5(Polygon);//2,3,即x^2+1=0在F_5中有两根:x_1=2,x_2=3
auto Polygon=[](int x)->int{
return x*x+1;
};
vector<int> retVec=FindrootInF5([](int x)->int{return x*x+x;});
Print("x^2+x=0在F_5中的根:",retVec);//x^2+x=0在F_5中的根:0,4,
return 0;
}
20190820添加:
C++11 新特性
统一的初始化方法(VC2012不支持,VC2013支持)
成员变量默认初始值
auto关键字,用于定义变量,编译器可以自动判断变量的类型
decltype关键字求表达式的类型
智能指针share_ptr,托管一个new运算符返回的指针
new出来的指针只能被delete一次,delete两次会崩溃
空指针nullptr
基于范围的for循环
右值引用和move语义
左值引用一个&,右值引用两个&
减少深拷贝的次数
try{}catch(...){t1.join();throw;}
std::ref(s)
std::move(s)
线程对象只能被移动不能被复制
std::thread t2=std::move(t1);
std::this_thread::get_id()
t2.get_id()
根据cpu的核心数,告诉我们最多可以使用多少个线程进行并发编程
std::thread::hardware_concurrency()
std::lock_guard<std::mutex> guard(mu);代替mu.lock()、mu.unlock()避免抛出异常死锁
std::lock(mu1,mu2)确保多个lock的顺序是相同的,避免死锁
std::uniquelock不能被复制,可以被移动
std::lock_guard不能被复制和移动
std::uniquelock所提供的弹性操作会消耗更多的性能
不用mutex,确保文件打开操作只被一个线程执行一次
std::once_flag m_flag;
std::call_once(m_flag,[&](){f.open("log.txt");});
20161118添加:
http://www.cnblogs.com/haippy/p/3237213.html
https://my.oschina.net/shou1156226/blog/802859
深入应用C++ 11:代码优化与工程级应用
祁宇 著
2015.5出版
技术博客http://www.cnblogs.com/qicosmos/
本书示例代码需要支持C++ 11的编译器:
Windows:Visual Studio 2013。
Linux:GCC 4.8+或者Clang 3.4。
由于少数代码用到了boost库,还需要编译boost 1.53或更新的boost库。
chap1 使用C++ 11让程序更简洁、更现代
1.1类型推导
C++ 11引入了auto和decltype关键字实现类型推导。
1.1.1 auto类型推导
auto并不能代表一个实际的类型声明,只是一个类型声明的占位符。
使用auto声明的变量必须马上初始化,以让编译器推断出它的实际类型,并在编译时将auto占位符替换为真正的类型。
非static的局部变量默认就是具有自动存储期的。
3.auto的限制
auto是不能用于函数参数的。
4.什么时候用auto
auto简化STL迭代器(iterator)变量的定义
注意:auto是一个很强大的工具,但不加选择地随意使用auto,会带来代码可读性和可维护性的严重下降。因此,在使用auto的时候,一定要权衡好它带来的价值和相应的损失。
1.1.2 decltype关键字
若仅希望得到类型,而不需要(或不能)定义变量的时候应该怎么办呢?
C++ 11新增了decltype关键字,用来在编译时推导出一个表达式的类型。
1.1.3 返回类型后置语法——auto和decltype的综合使用
20170331添加:
5.7右值引用
右值引用的目的是为了实现“移动语义”和“完美转发”。
将普通的引用定义为Type&,那么右值引用的写法则是Type&&,通过std::move函数,可以将左值转换为右值引用,move可理解为static_cast<T&&><obj>。
C++ 11有一个定义:“基于安全的原因,具名参数将不被认定为右值,即便是右值引用,必须使用move来获取右值”。
5.7.2移动语义
移动是为了消除不必要的对象复制,为提高效率而存在的。
VS的DEBUG模式默认没有开启RVO。
在C++ 11之前,使用const A&也可以将函数内的变量取出,但由于是const引用,所以并不能对变量进行操作,而非const的右值引用则没有该限制。
3种构造方法:
默认复制构造(浅拷贝)、复制构造(深拷贝)、移动构造
5.7.3完美转发
完美转发是为了能更简洁明确地定义泛型函数——将一组参数原封不动地传给另一个函数。原封不动指的是参数数值和类型不变,参数的const属性不变。
C++ 11定义的T&&推导规则是,右值实参为右值引用,左值实参为左值引用,参数属性不变。
5.8显示虚函数重写
override和final并不是关键字,只有在特定的位置才有特殊含义,在其他地方仍可当变量来使用。为了保存向后兼容,override是选择性的。
20170409添加:
// 20170409.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
// VS2012编译
#include <set>
#include <iostream>
template <typename ObType, typename BinaryFunction>
bool isGroup12(const std::set<ObType> & S, BinaryFunction & op)
{
/*
isGroup returns true or false depending on whether the set S
along with the operator op is a group in the Algebraic sense.
That is, S is a group if and only if all the 4 following
conditions are true:
(1) If a, b in S, then a op b in S
(2) If a, b, c in S, then (a + b) + c = a + (b + c)
(3) There is an element 0 in S such that a + 0 = 0 + a for all a in S
(4) If a in S, then there is a b in S such that a + b = b + a = 0
*/
typename std::set<ObType>::const_iterator beg(S.cbegin()), offend(S.cend());
bool noProblems = true;
for (std::set<ObType>::const_iterator ia = beg; ia != offend && noProblems; ++ia)
{
for (std::set<ObType>::const_iterator ib = beg; ib != offend && noProblems; ++ib)
{
// ---------- (1) --------------
if (S.count(op(*ia, *ib)) == 0)
noProblems = false;
// -----------------------------
for (std::set<ObType>::const_iterator ic = beg; ic != offend && noProblems; ++ic)
{
// ---------- (2) -------------
//is wrong
//if (((*ia + *ib) + *ic) != (*ia + (*ib + *ic)))
// noProblems = false;
if ( op( op(*ia,*ib), *ic) != op( *ia, op( *ib, *ic)))
noProblems = false;
// ----------------------------
}
}
}
return noProblems;
}
template <typename ObType, typename BinaryFunction>
bool isGroup3( const std::set<ObType> & S, BinaryFunction & op)
{
// ... important define BinaryFunction as taking const args !
typename std::set<ObType>::const_iterator beg(S.cbegin()), offend(S.cend());
for (std::set<ObType>::const_iterator ia = beg; ia != offend; ++ia)
{
// ---------- (3) -------------
/* let e be an *ia */
ObType e = *ia;
bool isGroup = true;
for ( auto ia2 : S) {
if( op(ia2, e) != ia2 || op( e, ia2) != ia2) {
isGroup = false;
break;
}
// identity found, set e_ in class to e and return
if( isGroup) {
// e_ = e;
return true;
}
}
}
/* identity not found, this is not a group */
return false;
}
template <typename T>
class Plus
{
public:
T operator() (const T & x, const T & y) { return x + y; };
};
int main()
{
#if 1
int a1[]={0, 1, -1};
int n1=sizeof(a1)/sizeof(int);
std::set<int> S1(a1,a1+n1);
int a2[]={0};
int n2=sizeof(a2)/sizeof(int);
std::set<int> S2(a2,a2+n2);
#else
std::set<int> S1 = { 0, 1, -1 };//这种写法在VS2013以后支持
std::set<int> S2 = { 0 };//这种写法在VS2013以后支持
#endif
class Plus<int> p;
std::cout << isGroup12(S1, p)<<std::endl;
std::cout << isGroup3(S1, p)<<std::endl;
system("pause");
return 0;
}
20170413添加:
使用STL通用算法find_if()在list中搜索对象
这是find()的一个更强大的版本。这个例子演示了find_if(),它接收一个函数对象的参数作为参数,并使用它来做更复杂的评价对象是否和给出的查找条件相符。
// VS2012编译
#include <iostream>
#include <string>
#include <list>
#include <vector>
#include <algorithm>
#include <functional>//greater
using namespace std;
// 类比较,重载了()操作符
class personIsIn1492
{
public:
bool operator()(string& personRecord)
{
return personRecord.substr(0,4)=="1492";//第二个参数是要截的长度,不是截取结束的位置
}
};
void Test1()
{
list<string> persons;
persons.push_back("1487迪亚士");
persons.push_back("1492.10.12哥伦布 国庆日");
persons.push_back("1519麦哲伦");
persons.push_back("1649.1查理二世");
persons.push_back("1774中原王伦起义");
#if 1
/*
捕获列表捕获的是调用该表达式函数内的局部非静态变量,对于那些函数内的静态变量和定义在函数外的变量,Lambda表达式可以直接使用。
下面Lambda表达式中捕获了变量str,返回类型是bool。
编译器在解释Lambda表达式时,会解释成一个未命名类的未命名对象,该类包含了一个重载函数调用操作符的函数,如果捕获列表中包含有值捕获参数时,那么该类中会有一个相对应的成员参数
*/
string str="1492";
list<string>::iterator personIterator = find_if (persons.begin(), persons.end(),[str](string& personRecord)->bool{
if(personRecord.substr(0,4)==str)return true;
return false;
});
#else
// 使用重载了()操作符类对象比较
list<string>::iterator personIterator = find_if (persons.begin(), persons.end(),personIsIn1492());
#endif
if (personIterator==persons.end()) {
cout << "person not found in list" << endl;
}
else {
cout << *personIterator << endl;
}
}
class Grade
{
public:
Grade(int id,string name,int score)
{
ID=id;
Name=name;
Score=score;
}
int ID;
string Name;
int Score;
};
//针对Grade的vector对象进行排序
//定义函数对象用来排序
class sort_Grade
{
//函数对象的最大好处是可以内联,效率极高
public:
sort_Grade(){}
bool operator()(Grade X,Grade Y)const
{
//return X.Score<Y.Score;//按成绩的升序排
return X.Score>Y.Score;//按成绩的降序排
}
};
void Test2()
{
vector<Grade> finalGrade;
finalGrade.push_back(Grade(1,"A",56));
finalGrade.push_back(Grade(2,"B",57));
finalGrade.push_back(Grade(3,"C",58));
//当定义了用于排序的函数对象后就可以直接调用sort算法进行排序了
#if 1
//sort中使用Lambda表达式:
sort(finalGrade.begin(),finalGrade.end(),[](Grade X,Grade Y)->bool{
//return X.Score<Y.Score;//按成绩的升序排
return X.Score>Y.Score;//按成绩的降序排
});
#else
//排序,根据函数对象,函数对象的最大好处是可以内联,效率极高
sort(finalGrade.begin(),finalGrade.end(),sort_Grade());
#endif
int a=0;
}
void Test3()
{
int a[10]={0};
int N=5;
vector<int> b;
for(int i=0;i<N;i++)
{
cin>>a[i];
b.push_back(a[i]);
}
#if 1
//sort中使用Lambda表达式:
sort(a,a+N,[](int i,int j)->bool{
return (i>j);//降序排
});
sort(b.begin(),b.end(),[](int i,int j)->bool{
return (i<j);//升序排
});
#else
sort(a,a+N,greater<int>());//降序排列
sort(b.begin(),b.end());//升序排列
#endif
for(int i=0;i<N;i++)
cout<<a[i]<<" ";
cout<<endl;
for(int i=0;i<N;i++)
cout<<b[i]<<" ";
}
// 函数比较,例如带金牌的麻将牌排序
bool func(int i,int j,bool less,int a)
{
//a放在最左边
if(i==a)
return true;
if(j==a)
return false;
return less?(i<j):(i>j);//升序:降序
}
void Test4()
{
vector<int>::iterator Iter;
vector<int> the_vector;
int temp;
for( int i = 0; i < 5; i++ )
{
cin>>temp;
the_vector.push_back(temp);//vector无push_front方法
}
#if 1
// bind函数,用于函数绑定的模版,它可以指定函数中的部分参数,也可以是全部参数
sort(the_vector.begin(),the_vector.end(),bind(func,placeholders::_1,placeholders::_2,true,4));//升序排列,4放在最左边
//sort(the_vector.begin(),the_vector.end(),bind(func,placeholders::_1,placeholders::_2,false,4));//降序排列,4放在最左边
#else
sort(the_vector.begin(),the_vector.end(),less<int>());//升序排列
//sort(the_vector.begin(),the_vector.end(),greater<int>());//降序排列
#endif
cout<<"the_vector=";
for(Iter=the_vector.begin();Iter!=the_vector.end();Iter++)
cout<< " "<<*Iter;
cout<<endl;
}
void Test5()
{
//string str="abcdadcdefdde!@234";
string str="ABCDADCDEFDDE!@234";
#if 0
transform(str.begin(),str.end(),str.begin(),[](char ch)->char{return ch+1;});
#else
// 将字符串变成大写
//transform(str.begin(),str.end(),str.begin(),toupper);
// 将所有的字符变成小写
transform(str.begin(),str.end(),str.begin(),tolower);
#endif
cout<<str;
}
int main(int argc, char* argv[])
{
Test1();
Test2();
//Test3();
Test4();
Test5();
system("pause");
return 0;
}
20170417添加:
//VS2012编译
#include<cstdlib>
#include<functional>
#include<iostream>
#include<string>
using namespace std;
//ToInt成员函数的返回值与WinGDI.h的RGB宏或VB6的RGB函数值是不一致的,请不要混淆
//typedef unsigned long D3DCOLOR;
class Color
{
public:
int mRed;
int mGreen;
int mBlue;
int mAlpha;//255表示完全不透明
static Color Black;
static Color White;
static Color Empty;
public:
//缺省构造函数
Color():mRed(0),mGreen(0),mBlue(0),mAlpha(255){}
Color(int theRed,int theGreen,int theBlue,int theAlpha=0xFF):mRed(theRed),mGreen(theGreen),mBlue(theBlue),mAlpha(theAlpha){}
//拷贝构造函数
Color(const Color& c):mRed(c.mRed),mGreen(c.mGreen),mBlue(c.mBlue),mAlpha(c.mAlpha){}
//操作符重载
int& operator[](int theIdx);
int operator[](int theIdx)const;
Color& operator=(const Color& c){mRed=c.mRed;mGreen=c.mGreen;mBlue=c.mBlue;mAlpha=c.mAlpha;return *this;}
//inline函数
int GetRed()const{return mRed;}
int GetGreen()const{return mGreen;}
int GetBlue()const{return mBlue;}
int GetAlpha()const{return mAlpha;}
unsigned long ToInt()const{return (mAlpha<<24)|(mRed<<16)|(mGreen<<8)|(mBlue);}//返回值与D3DCOLOR_ARGB宏是一致的
unsigned long ToWinRGBInt()const{return (0<<24)|(mBlue<<16)|(mGreen<<8)|(mRed);}
static Color& WinRGBToColor(unsigned long lng);
static unsigned char GetRedValue(unsigned long lng);
static unsigned char GetGreenValue(unsigned long lng);
static unsigned char GetBlueValue(unsigned long lng);
friend ostream& operator<<(ostream& os,const Color& c);//put-to操作符<<
};
Color& Color::WinRGBToColor(unsigned long lng)
{
unsigned char b[10]={0};
//unsigned char b[4]={0};
memcpy(&b[0],&lng,4);
return Color(b[0],b[1],b[2],b[3]);
//int i[4]={0};
//i[0]=b[0];
//i[1]=b[1];
//i[2]=b[2];
//i[3]=b[3];
//return Color(i[0],i[1],i[2],i[3]);
//return Color((int)b[0],(int)b[1],(int)b[2],(int)b[3]);
}
unsigned char Color::GetRedValue(unsigned long lng)
{
return (unsigned char)(lng);
}
unsigned char Color::GetGreenValue(unsigned long lng)
{
return (unsigned char)(unsigned short((lng)>>8));
}
unsigned char Color::GetBlueValue(unsigned long lng)
{
return (unsigned char)((lng)>>16);
}
ostream& operator<<(ostream& os,const Color& c)
{
os<<"ARGB:"<<c.mAlpha<<","<<c.mRed<<","<<c.mGreen<<","<<c.mBlue;
return os;
}
int& Color::operator[](int theIdx)
{
static int aJunk=0;
switch(theIdx)
{
case 0:return mRed;
case 1:return mGreen;
case 2:return mBlue;
case 3:return mAlpha;
default:return aJunk;
}
}
int Color::operator[](int theIdx)const
{
switch(theIdx)
{
case 0:return mRed;
case 1:return mGreen;
case 2:return mBlue;
case 3:return mAlpha;
default:return 0;
}
}
//ARGB:255,255,0,0
//4294901760
//ARGB:0,255,0,0
//16711680
//ARGB:0,0,0,255
//255
//ARGB:255,0,0,255
//4278190335
//16711680
void Test7()
{
//const Color &theColor=Color(255,0,0);
//const Color &theColor=Color(255,0,0,255);
//const Color &theColor=Color(255,0,0,0);
//const Color &theColor=Color(0,0,255,0);//blue
const Color &theColor=Color(0,0,255,255);//blue
cout<<theColor<<endl;
#if 1
// function存放类的公有成员函数,使用bind绑定成员函数和对象指针,使用placeholders::_1~placeholders::_20占位符来表示函数的参数数量
function<unsigned long()> mf1=bind(&Color::ToInt,theColor);
function<unsigned long()> mf2=bind(&Color::ToWinRGBInt,theColor);
cout<<mf1()<<endl;
cout<<mf2()<<endl;
// function存放静态函数
function<Color(unsigned long)> smf1=Color::WinRGBToColor;
Color c=smf1(16761798);
cout<<c<<endl;
#else
cout<</*(unsigned int)*/theColor.ToInt()<<endl;
cout<<theColor.ToWinRGBInt()<<endl;
//Color ret=Color::WinRGBToColor(16711680);
Color c=Color::WinRGBToColor(16761798);
cout<<c<<endl;
#endif
cout<<"RGB:"<<(int)Color::GetRedValue(16761798)<<","<<(int)Color::GetGreenValue(16761798)<<","<<(int)Color::GetBlueValue(16761798)<<endl;
}
int main()
{
Test7();
system("pause");
return 0;
}
//VS2012编译
//计算雅可比符号(d/n)
#include <functional>
#include <iostream>
using namespace std;
int neg_one(int m);
int two(int m);
int Jacobi(int d,int n);
int Jacobi1(int d,int n);
function<int(int)> f1=neg_one;
function<int(int)> f2=two;
// function存放普通函数
#if 1
function<int(int,int)> JacobiSymbol=Jacobi;
#else
function<int(int,int)> JacobiSymbol=Jacobi1;//有问题
#endif
int neg_one(int m)
{
if( m%4 == 1 )
return 1;
if( m%4 == 3 )
return -1;
}
int two(int m)
{
if( m%8 == 1 || m%8 == 7 )
return 1;
if( m%8 == 3 || m%8 == 5 )
return -1;
}
int Jacobi1(int m,int n)
{
if(n%m==0)
return 0;
int q, s, t, d, mul=1;
s=m;
t=n;
loon:
if( m>n )
{
m%=n;
}
while( m%2 == 0 )
{
m/=2;
#if 1
mul*=f2(n);
#else
mul*=two(n);
#endif
}
if( m == -1 )
{
#if 0
auto fun0=[=](int m)->int{
if( m%4 == 1 )
return 1;
if( m%4 == 3 )
return -1;
};
mul*=fun0(n);
#else
//mul*=neg_one(n);
mul*=f1(n);
#endif
goto mark;
}
if( m == 1 )
{
goto mark;
}
q=n;
n=m;
m=q;
if( (n-1)*(m-1)%8 != 0 )
{
mul*=-1;
}
goto loon;
mark:
return mul;
}
/*
计算雅可比符号(d/n),n>2且为奇整数
Jacobi符号的值:
0表示d可以整除n
1表示d是模n的平方剩余(?NOSURE)
-1表示d是模n的非平方剩余(?NOSURE)
*/
int Jacobi(int d,int n)
{
int x=d;
int y=n;
int j=1;
int t;
while(y>1){
x=x%y;
if(x>y/2){
x=y-x;
if(y%4==3) j=-1*j;
}
if(x==0) {x=1;y=0;j=0;}
while(x%4==0){
x=x/4;
}
if(x%2==0){
x=x/2;
if((y%8==3)||(y%8==5)) j=-1*j;
}
if((x%4==3)&&(y%4==3)){
j=-1*j;
t=x;
x=y;
y=t;
}
else{
t=x;
x=y;
y=t;
}
}
return j;
}
void Test6()
{
int n=45;
for(int x=1;x<180;x++)
{
//cout<<JacobiSymbol(x,n)<< endl;
cout<<"Jacobi(x="<<x<<"/n="<<n<<")="<<JacobiSymbol(x,n)<<endl;
}
}
int main()
{
Test6();
system("pause");
return 0;
}
http://www.cnblogs.com/huoyao/p/4248925.html
白板放在代替金牌的位置
#include <algorithm>
// 带金牌a,替金b的麻将牌排序
bool MJSortFunc(BYTE i,BYTE j,BYTE a,BYTE b)
{
//a放在最左边
#if 1
if(i==a && j==a)
return false;
if(i==a && j!=a)
return true;
#else
if(i==a)
return true;
#endif
if(j==a)
return false;
if(i==b)
i=a;
if(j==b)
j=a;
return (i<j);//升序
}
//排序,根据牌值排序
bool CGameLogic::SortCardList( BYTE cbCardData[MAX_COUNT], BYTE cbCardCount )
{
//数目过虑
if (cbCardCount==0||cbCardCount>MAX_COUNT) return false;
BYTE MagicData = SwitchToCardData(GetMagicIndex());
std::sort(cbCardData,cbCardData+cbCardCount,std::bind(MJSortFunc,std::placeholders::_1,std::placeholders::_2,MagicData,0x37));
return true;
}