www.pudn.com > myopenforcal.zip > UseFor.cpp


#include "windows.h" 
#include "math.h" 
 
//定义可由OpenFC调用的实数函数; 
extern "C" __declspec(dllexport) void RegRealFun(char **&,int *&,double (**&)(int ,double *)); 
 
double rfc_a999(int ,double *); 
double rfc_sintegrate(int ,double *); 
 
char *ppchRealNameDll[]={"a999","sintegrate",""}; //外部函数名; 
 
int piRealParaDll[]={-2,-2}; //-2表示有不确定的多个自变量,-1表示有0个自变量,0表示有1个自变量,1表示有2个自变量; 
double (*ppRealFunDll[])(int ,double *)={rfc_a999,rfc_sintegrate}; //外部函数指针数组; 
 
//定义可由OpenFC调用的整数函数; 
extern "C" __declspec(dllexport) void RegIntFun(char **&,int *&,long (**&)(int ,long *)); 
 
long ifc_a999(int ,long *); 
 
char *ppchIntNameDll[]={"a999",""}; //外部函数名; 
int piIntParaDll[]={-2}; //-2表示有不确定的多个自变量,-1表示有0个自变量,0表示有1个自变量,1表示有2个自变量; 
 
long (*ppIntFunDll[])(int ,long *)={ifc_a999}; //外部函数指针数组; 
 
//定义可由OpenFC调用的复数函数; 
extern "C" __declspec(dllexport) void RegComplexFun(char **&,int *&,_complex (**&)(int ,_complex *)); 
 
_complex cfc_a999(int ,_complex *); 
 
char *ppchComplexNameDll[]={"a999",""}; //外部函数名; 
int piComplexParaDll[]={-2}; //-2表示有不确定的多个自变量,-1表示有0个自变量,0表示有1个自变量,1表示有2个自变量; 
_complex (*ppComplexFunDll[])(int ,_complex *)={cfc_a999}; //外部函数指针数组; 
 
//准备使用Forcal表达式; 
typedef double (* pRCALS) (int ); //计算实数表达式的值; 
typedef int (* pFCERRNUM) (void); //获得Forcal中实数表达式运行错误代码,0表示没有错误; 
typedef void (* pSETFCERR) (int ,char *); //设置外部函数运行错误,字符串指针指出出错函数名; 
pRCALS prcals; 
pSETFCERR psetfcerr; 
pFCERRNUM pfcerrnum; 
typedef _complex (* pCCALS) (int ); //计算复数表达式的值; 
typedef void (*pCSETFCERR) (int ,char *); //设置外部函数运行错误,字符串指针指出出错函数名; 
 
typedef int (* pCFCERRNUM) (void); //获得Forcal中复数表达式运行错误代码,0表示没有错误; 
pCCALS pccals; 
pCSETFCERR pcsetfcerr; 
pCFCERRNUM pcfcerrnum; 
typedef long (* pICALS) (int ); //计算整数表达式的值; 
typedef void (*pISETFCERR) (int ,char *); //设置外部函数运行错误,字符串指针指出出错函数名; 
typedef int (* pIFCERRNUM) (void); //获得Forcal中整数表达式运行错误代码,0表示没有错误; 
pICALS picals; 
pISETFCERR pisetfcerr; 
 
pIFCERRNUM pifcerrnum; 
int *forpara; //存放各个实数表达式的自变量个数; 
bool *fortrue; //存放各个实数表达式的编译状态,表达式编译通过时设为true; 
int *cforpara; //存放各个复数表达式的自变量个数; 
bool *cfortrue; //存放各个复数表达式的编译状态,表达式编译通过时设为true; 
int *iforpara; //存放各个整数表达式的自变量个数; 
bool *ifortrue; //存放各个整数表达式的编译状态,表达式编译通过时设为true; 
double **allin; //allin指向存放各实数表达式自变量的指针数组; 
 
_complex **callin; //allin指向存放各复数表达式自变量的指针数组; 
long **iallin; //allin指向存放各整数表达式自变量的指针数组; 
int rfor_max; //最多可用的实数表达式数目; 
int ifor_max; //最多可用的整数表达式数目; 
int cfor_max; //最多可用的复数表达式数目; 
 
extern "C" __declspec(dllexport) void GetRealFor (pRCALS ,pFCERRNUM ,pSETFCERR ,bool * ,double **,int *,int); 
extern "C" __declspec(dllexport) void GetIntFor (pICALS ,pIFCERRNUM ,pISETFCERR ,bool * ,long **,int *,int); 
extern "C" __declspec(dllexport) void GetComplexFor (pCCALS ,pCFCERRNUM ,pCSETFCERR ,bool * ,_complex **,int *,int); 
 
///////////////////////////////////////////////////////////////////////////// 
// 动态库的输出函数; 
 
extern "C" __declspec(dllexport) void RegRealFun(char **&ppchRealName,int *&piRealPara,double (**&ppRealFun)(int ,double *)) 
{ppchRealName=ppchRealNameDll; piRealPara=piRealParaDll; ppRealFun=ppRealFunDll; 
} 
extern "C" __declspec(dllexport) void RegIntFun(char **&ppchIntName,int *&piIntPara,long (**&ppIntFun)(int ,long *)) 
{ppchIntName=ppchIntNameDll; piIntPara=piIntParaDll; ppIntFun=ppIntFunDll; 
 
} 
extern "C" __declspec(dllexport) void RegComplexFun(char **&ppchComplexName,int *&piComplexPara,_complex (**&ppComplexFun)(int ,_complex *)) 
{ppchComplexName=ppchComplexNameDll; piComplexPara=piComplexParaDll; ppComplexFun=ppComplexFunDll; 
} 
extern "C" __declspec(dllexport) void GetRealFor (pRCALS cal,pFCERRNUM num,pSETFCERR err,bool * b,double **d,int *i,int ir) 
{prcals=cal; pfcerrnum=num; psetfcerr=err; fortrue=b; allin=d; forpara=i; rfor_max=ir;} 
extern "C" __declspec(dllexport) void GetIntFor (pICALS cal,pIFCERRNUM num,pISETFCERR err,bool * b,long **l,int *i,int ii) 
 
{picals=cal; pifcerrnum=num; pisetfcerr=err; ifortrue=b; iallin=l; iforpara=i; ifor_max=ii;} 
extern "C" __declspec(dllexport) void GetComplexFor (pCCALS cal,pCFCERRNUM num,pCSETFCERR err,bool * b,_complex **c,int *i,int ic) 
{pccals=cal; pcfcerrnum=num; pcsetfcerr=err; cfortrue=b; callin=c; cforpara=i; cfor_max=ic;} 
 
// 定义一些简单的实数函数; 
 
double rfc_a999(int m,double *x) //返回常数999; 
{return 999.0;} 
 
double rfc_sintegrate(int m,double *xx) //一元积分函数; 
 
{double a,b,eps,*pIn; //a为积分下限,b为积分上限,eps为积分精度要求; 
 int n,k,nfor; //nfor指出对第nfor个表达式进行积分; 
 double h,t1,t2,s1,s2,ep,p,x; 
 static int sintegratenum=0,sintegratemax=10; //sintegratemax为递归调用的最大次数,sintegratenum记录递归调用的实际次数; 
 
 if(pfcerrnum()!=0) goto end; //pfcerrnum()函数获取Forcal的运行错误,若出现过任何运行错误,不再进行计算; 
 if(++sintegratenum>sintegratemax) {if(pfcerrnum()==0) psetfcerr(-2,"sintegrate"); goto end;} //递归次数超出限制,用psetfcerr()函数设定运行错误; 
 
 if(rfor_max<1) {if(pfcerrnum()==0) psetfcerr(-1,"sintegrate"); goto end;} //未设置可接受外部函数功能; 
 if(m<3) {if(pfcerrnum()==0) psetfcerr(3,"sintegrate"); goto end;} //函数的参数个数不匹配; 
 nfor=(int)xx[3]; //nfor指出对第nfor个表达式进行积分; 
 if(nfor<0||nfor>=rfor_max) {if(pfcerrnum()==0) psetfcerr(1,"sintegrate"); goto end;} //指定的表达式不存在; 
 if(!fortrue[nfor]) {if(pfcerrnum()==0) psetfcerr(2,"sintegrate"); goto end;} //指定的表达式编译未通过,fortrue数组存放表达式的编译状态; 
 
 n=forpara[nfor]; //获取该表达式的自变量个数; 
 if(m!=3+n) {if(pfcerrnum()==0) psetfcerr(3,"sintegrate"); goto end;} //函数的参数个数不匹配; 
 pIn=allin[nfor]; //pgetin(nfor)获取第nfor个表达式的自变量指针; 
 for(k=1;k<=n;k++) pIn[k]=xx[3+k]; //当n>0时,进行两个表达式之间的参数传递; 
 a=xx[0]; b=xx[1]; eps=xx[2]; 
 ////////////////////////////////////以下进行积分! 
 n=1; h=b-a; 
 pIn[0]=a; x=prcals(nfor); //prcals(nfor)计算第nfor个表达式的值; 
 
 pIn[0]=b; 
 t1=h*(x+prcals(nfor))/2.0; 
 s1=t1; 
 ep=eps+1.0; 
 while (ep>=eps) 
   { p=0.0; 
     for (k=0;k<=n-1;k++) 
       { pIn[0]=a+(k+0.5)*h; 
         p=p+prcals(nfor); 
       } 
     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; 
   } 
 ////////////////////////////////以上进行积分! 
 if(pfcerrnum()==0) {sintegratenum--; return(s2);} //未发生任何错误退出时,递归次数减1; 
end: //出错时,递归次数设为0; 
 
 sintegratenum=0; return 0.0; 
} 
 
// 定义一些简单的整数函数; 
 
long ifc_a999(int m,long *x) 
{return 999;} 
 
// 定义一些简单的复数函数; 
 
_complex cfc_a999(int m,_complex *x) 
{x[0].x=999.0; x[0].y=999.0; return x[0];}