00001
00002
00003
00004
00005 #ifndef _FUNCTION_
00006 # define _FUNCTION_
00007
00008 #include <math.h>
00009 #include "Math.hpp"
00010 #include <iostream>
00011 using namespace std;
00012
00014 struct Function {
00016 virtual double Eval (double *x)=0 ;
00018 virtual void SetParameters(double *p)=0 ;
00019
00020
00024 double GaussQuadrature(double *XA, double *XE, int D, int order=4) ;
00025
00026 private:
00027 double GQ(double *x, int i, double *XA, double *XE, int D , int order) ;
00028
00029
00030
00031 } ;
00032
00033
00035 struct ConstFunction : public Function {
00036 double par ;
00037 void SetParameters(double *p) {par=*p ;}
00038 double Eval(double *) {return par ;}
00039 } ;
00040
00041
00044 template<int N>
00045 struct SparseGridFunction : public Function {
00046 int MaxLevel[N] ;
00047 SparseGridFunction() ;
00048 void SetParameters(double *p) ;
00049 double Eval(double *x) ;
00050 } ;
00051
00054 template<int N>
00055 struct FullGridFunction : public SparseGridFunction<N> {
00056 double Eval(double *x) ;
00057 } ;
00058
00059
00063 template<int N>
00064 struct TensorNPolynomFunction : public Function {
00065 int p[N] ;
00066 double c[N][100] ;
00067 double q ;
00068 void SetParameters(double *p) ;
00069 double Eval(double *x) ;
00070 } ;
00071
00080 struct SubFunction : public Function {
00081 Function *F ;
00082 int dir,dim ;
00083 double xdir ;
00084 void SetParameters(double *p) ;
00085 double Eval (double *x) ;
00086 } ;
00087
00091 template <int DIM>
00092 struct GeneralRadialFunction : public Function {
00093 double a,e,y[DIM] ;
00094 void SetParameters(double *p) ;
00095 double Eval (double *x) ;
00096 } ;
00097
00099 template <int DIM>
00100 struct GeneralRadialFunctionDX : public GeneralRadialFunction<DIM> {
00101 double Eval (double *x) ;
00102 } ;
00104 template <int DIM>
00105 struct GeneralRadialFunctionDY : public GeneralRadialFunction<DIM> {
00106 double Eval (double *x) ;
00107 } ;
00108
00110 template <int DIM>
00111 struct LaplaceGeneralRadialFunction : public GeneralRadialFunction<DIM> {
00112 double Eval (double *x) ;
00113 } ;
00114
00115
00116
00117
00118
00119
00120
00121 template<int N>
00122 SparseGridFunction<N>::SparseGridFunction() {
00123 for (int i=0; i<N; i++) MaxLevel[i]=MAXINT ;
00124 }
00125 template<int N>
00126 void SparseGridFunction<N>::SetParameters(double *p) {
00127 for (int i=0; i<N; i++) MaxLevel[i]=(int)(p[i]+1e-9) ;
00128 }
00129 template<int N>
00130 double SparseGridFunction<N>::Eval(double *x) {
00131 double s=0 ;
00132 for (int i=0; i<N; i++) {
00133 s += x[i];
00134 if (x[i]>MaxLevel[i]) return MAXINT ;
00135 }
00136 return s ;
00137 }
00138
00139
00140 template<int N>
00141 double FullGridFunction<N>::Eval(double *x) {
00142 double s=0 ;
00143 for (int i=0; i<N; i++) {
00144 s = s>fabs(x[i]) ? s : fabs(x[i]) ;
00145 if (x[i]>MaxLevel[i]) return MAXINT ;
00146 }
00147 return s ;
00148 }
00149
00150
00151 template<int N>
00152 void TensorNPolynomFunction<N>::SetParameters(double *par) {
00153 int j=0,n,i ;
00154 q=par[j++] ;
00155 for (n=0; n<N; n++) p[n]=(int)par[j++] ;
00156 for (n=0; n<N; n++)
00157 for (i=0; i<=p[n]; i++) c[n][i]=par[j++] ;
00158 }
00159
00160
00161 template<int N>
00162 double TensorNPolynomFunction<N>::Eval(double *x) {
00163 int n,i ;
00164 double w=1,ww ;
00165 for (n=0; n<N; n++) {
00166 ww=0 ;
00167 for (i=0; i<=p[n]; i++) ww +=c[n][i]*pow(x[n],i) ;
00168 w *= ww ;
00169 }
00170 return q*w ;
00171 }
00172
00173 void SubFunction::SetParameters(double *p) {
00174 if (sizeof(double)<sizeof(Function *)) {
00175 std::cout<<"SubFunction::SetParameters: works only, if sizeof(double) >= sizeof(Function *)\n" ;
00176 exit(-1) ;
00177 }
00178 F =*((Function **)p) ;
00179 dim = (int)(p[1]+1e-10);
00180 dir = (int)(p[2]+1e-10);
00181 xdir= p[3];
00182 }
00183
00184 double SubFunction::Eval(double *x) {
00185 double y[100] ;
00186 int q=0,i ;
00187 for (i=0; i<dim; i++) {
00188 if (i==dir) continue ;
00189 y[i]=x[q++] ;
00190 }
00191 y[dir]=xdir ;
00192 return F->Eval(y) ;
00193 }
00194
00195
00196 template <int DIM>
00197 void GeneralRadialFunction<DIM>::SetParameters(double *p) {
00198 a=p[0] ; e=p[1] ;
00199 for (int i=0; i<DIM; i++) y[i]=p[2+i] ;
00200 }
00201
00202 template <int DIM>
00203 double GeneralRadialFunction<DIM>::Eval(double *x) {
00204 double r=e ;
00205 for (int i=0; i<DIM; i++) r += sqr(x[i]-y[i]) ;
00206 return pow(r,a/2) ;
00207 }
00208
00209 template <int DIM>
00210 double GeneralRadialFunctionDX<DIM>::Eval(double *x) {
00211 double r=e ;
00212 for (int i=0; i<DIM; i++) r += sqr(x[i]-y[i]) ;
00213 return a*pow(r,a/2-1)*(x[0]-y[0]) ;
00214 }
00215
00216 template <int DIM>
00217 double GeneralRadialFunctionDY<DIM>::Eval(double *x) {
00218 double r=e ;
00219 for (int i=0; i<DIM; i++) r += sqr(x[i]-y[i]) ;
00220 return a*pow(r,a/2-1)*(x[1]-y[1]) ;
00221 }
00222
00223 template <int DIM>
00224 double LaplaceGeneralRadialFunction<DIM>::Eval(double *x) {
00225 double r=e ;
00226 for (int i=0; i<DIM; i++) r += sqr(x[i]-y[i]) ;
00227 return 2*a*pow(r,a/2-1)*( a/2 - (a/2-1)*e/r ) ;
00228 }
00229
00230 #endif