00001 #ifndef __DIFFNUMBER_H__
00002 #define __DIFFNUMBER_H__
00003
00004 #include <stdlib.h>
00005 #include <iostream>
00006
00007 #include <coconut_vect.h>
00008
00009 const int STANDARD_MAXDEG_DIFFNUMBER=4;
00010
00011
00012
00013
00014
00015
00016
00017 class diffNumber
00018 {
00019 private:
00020 double *data;
00021 public:
00022 int MAXDEG;
00023 inline diffNumber(void);
00024 inline diffNumber(double a);
00025 inline diffNumber(int n);
00026 inline diffNumber(double a, int n);
00027 inline diffNumber(const diffNumber &a);
00028 inline virtual ~diffNumber();
00029
00030 inline diffNumber& operator=(const diffNumber &a);
00031 inline double& operator[] (int pos) const;
00032
00033 inline static diffNumber getVar(const double &x);
00034 inline static diffNumber getVar(const double &x, int n);
00035 inline void setDeg(int n);
00036 };
00037
00038 inline diffNumber operator +(const diffNumber &a, const diffNumber &b);
00039 inline diffNumber operator +(const double &a, const diffNumber &b);
00040 inline diffNumber operator +(const diffNumber &a, const double &b);
00041 inline diffNumber operator -(const diffNumber &a, const diffNumber &b);
00042 inline diffNumber operator -(const double &a, const diffNumber &b);
00043 inline diffNumber operator -(const diffNumber &a, const double &b);
00044 inline diffNumber operator -(const diffNumber &a);
00045 inline diffNumber operator *(const diffNumber &a, const diffNumber &b);
00046 inline diffNumber operator *(const double &a, const diffNumber &b);
00047 inline diffNumber operator *(const diffNumber &a, const double &b);
00048 inline diffNumber operator /(const diffNumber &a, const diffNumber &b);
00049 inline diffNumber operator /(const diffNumber &a, const double &b);
00050 inline diffNumber operator /(const double &a, const diffNumber &b);
00051
00052
00053 inline std::ostream &operator << (std::ostream &s, const diffNumber &a);
00054
00055
00056 inline diffNumber exp(const diffNumber &a);
00057 inline diffNumber sin(const diffNumber &a);
00058 inline diffNumber cos(const diffNumber &a);
00059 inline diffNumber sqrt(const diffNumber &a);
00060
00061 inline diffNumber power(const diffNumber &a, int n);
00062 inline diffNumber power(const diffNumber &a, const diffNumber &b);
00063
00064 inline diffNumber log(const diffNumber &a);
00065 inline diffNumber sinh(const diffNumber &a);
00066 inline diffNumber cosh(const diffNumber &a);
00067 inline diffNumber atan2(const diffNumber &a, const diffNumber &b);
00068 inline diffNumber atan(const diffNumber &a);
00069 inline diffNumber square(const diffNumber &a);
00070
00071
00072
00073
00074
00075
00076
00077
00078 inline diffNumber::diffNumber(void)
00079 {
00080
00081 MAXDEG=STANDARD_MAXDEG_DIFFNUMBER;
00082 data=new double[MAXDEG+1];
00083 for (int i=0; i<MAXDEG+1; i++)
00084 data[i]=0.;
00085 }
00086
00087 inline diffNumber::diffNumber(int n)
00088 {
00089 MAXDEG=n;
00090 data=new double[MAXDEG+1];
00091 for (int i=0; i<MAXDEG+1; i++)
00092 data[i]=0.;
00093 }
00094
00095 inline diffNumber::diffNumber(double a)
00096 {
00097 MAXDEG=STANDARD_MAXDEG_DIFFNUMBER;
00098 data= new double[MAXDEG+1];
00099 data[0]=a;
00100 for (int i=1; i<MAXDEG+1; i++)
00101 data[i]=0;
00102 }
00103
00104 inline diffNumber::diffNumber(double a, int n)
00105 {
00106 MAXDEG=n;
00107 data= new double[MAXDEG+1];
00108 data[0]=a;
00109 for (int i=1; i<MAXDEG+1; i++)
00110 data[i]=0;
00111 }
00112
00113 inline diffNumber::diffNumber(const diffNumber &d)
00114 {
00115 MAXDEG = d.MAXDEG;
00116 data = new double[MAXDEG+1];
00117 memcpy(data, d.data, (MAXDEG+1)*sizeof(double));
00118 }
00119
00120
00121 inline diffNumber& diffNumber::operator=(const diffNumber &a)
00122 {
00123 if ((MAXDEG!=-1) && (MAXDEG != a.MAXDEG)){
00124 std::cerr<<"= degree not the same: "<< MAXDEG <<" != "<< a.MAXDEG;
00125 abort();
00126 }
00127
00128 if (this != &a){
00129
00130 if (data) delete [] data;
00131
00132 data = new double[a.MAXDEG+1];
00133 for (int i=0; i<a.MAXDEG+1; i++)
00134 data[i]=a[i];
00135 }
00136 return (*this);
00137 }
00138
00139
00140 inline double& diffNumber::operator[] (int pos) const
00141 {
00142
00143
00144 return data[pos];
00145 }
00146
00147
00148
00149
00150 inline diffNumber diffNumber::getVar(const double &x)
00151 {
00152 diffNumber c;
00153 c[0]=x;
00154 c[1]=1;
00155 return c;
00156 }
00157
00158 inline diffNumber diffNumber::getVar(const double &x, int n)
00159 {
00160 diffNumber c(n);
00161 c[0]=x;
00162 c[1]=1;
00163 return c;
00164 }
00165
00166 inline void diffNumber::setDeg(int n)
00167 {
00168 __vectgen(double,tmp,n+1);
00169 if (MAXDEG>n){
00170 for (int i=0; i<n+1; i++)
00171 tmp[i]=data[i];
00172 delete [] data;
00173 data=new double[n+1];
00174 for (int i=0; i<n+1; i++)
00175 data[i]=tmp[i];
00176 }
00177 else {
00178 for (int i=0; i<MAXDEG+1; i++)
00179 tmp[i]=data[i];
00180 delete [] data;
00181 data=new double[n+1];
00182 for (int i=0; i<MAXDEG+1; i++)
00183 data[i]=tmp[i];
00184 for (int j=MAXDEG+1; j<n+1; j++)
00185 data[j]=0.;
00186 }
00187 MAXDEG=n;
00188 }
00189
00190
00191 inline diffNumber operator +(const diffNumber &a, const diffNumber &b)
00192 {
00193 if (a.MAXDEG != b.MAXDEG){
00194 std::cerr<<"+ degree not the same: "<< a.MAXDEG <<" != "<< b.MAXDEG;
00195 abort();
00196 }
00197 diffNumber c(a.MAXDEG);
00198 for (int i=0; i<a.MAXDEG+1; i++){
00199 c[i]=a[i] + b[i];
00200 }
00201 return c;
00202 }
00203
00204 inline diffNumber operator +(const double &a, const diffNumber &b)
00205 {
00206 diffNumber c(b.MAXDEG);
00207 c[0]=a+b[0];
00208 for (int i=1; i<b.MAXDEG+1; i++){
00209 c[i]=b[i];
00210 }
00211 return c;
00212 }
00213
00214 inline diffNumber operator +(const diffNumber &a, const double &b)
00215 {
00216 diffNumber c(a.MAXDEG);
00217 c[0]=a[0]+b;
00218 for (int i=1; i<a.MAXDEG+1; i++){
00219 c[i]=a[i];
00220 }
00221 return c;
00222 }
00223
00224 inline diffNumber operator -(const diffNumber &a, const diffNumber &b)
00225 {
00226 if (a.MAXDEG != b.MAXDEG){
00227 std::cerr<<"- degree not the same: "<< a.MAXDEG <<" != "<< b.MAXDEG;
00228 abort();
00229 }
00230 diffNumber c(a.MAXDEG);
00231 for (int i=0; i<a.MAXDEG+1; i++){
00232 c[i]=a[i] - b[i];
00233 }
00234 return c;
00235 }
00236
00237 inline diffNumber operator -(const double &a, const diffNumber &b)
00238 {
00239 diffNumber c(b.MAXDEG);
00240 c[0]=a-b[0];
00241 for (int i=1; i<b.MAXDEG+1; i++){
00242 c[i]=-b[i];
00243 }
00244 return c;
00245 }
00246
00247 inline diffNumber operator -(const diffNumber &a, const double &b)
00248 {
00249 diffNumber c(a.MAXDEG);
00250 c[0]=a[0]-b;
00251 for (int i=1; i<a.MAXDEG+1; i++){
00252 c[i]=a[i];
00253 }
00254 return c;
00255 }
00256
00257 inline diffNumber operator -(const diffNumber &a)
00258 {
00259 for (int i=0; i<a.MAXDEG+1; i++){
00260 a[i]=-a[i];
00261 }
00262 return a;
00263 }
00264
00265 inline diffNumber operator *(const diffNumber &a, const diffNumber &b)
00266 {
00267 if (a.MAXDEG != b.MAXDEG){
00268 std::cerr<<"* degree not the same: "<< a.MAXDEG <<" != "<< b.MAXDEG;
00269 abort();
00270 }
00271 diffNumber c(a.MAXDEG);
00272 for (int i=0; i<a.MAXDEG+1; i++){
00273
00274 for (int j=0; j<=i; j++){
00275 c[i]=c[i] + a[j] * b[i-j];
00276 }
00277 }
00278 return c;
00279 }
00280
00281 inline diffNumber operator *(const double &a, const diffNumber &b)
00282 {
00283 diffNumber c(b.MAXDEG);
00284 for (int i=0; i<b.MAXDEG+1; i++){
00285 c[i]=a * b[i];
00286 }
00287 return c;
00288 }
00289
00290 inline diffNumber operator *(const diffNumber &a, const double &b)
00291 {
00292 diffNumber c(a.MAXDEG);
00293 for (int i=0; i<a.MAXDEG+1; i++){
00294 c[i]=b * a[i];
00295 }
00296 return c;
00297 }
00298
00299 inline diffNumber operator /(const diffNumber &a, const diffNumber &b)
00300 {
00301 if (a.MAXDEG != b.MAXDEG){
00302 std::cerr<<"/ degree not the same: "<< a.MAXDEG <<" != "<< b.MAXDEG;
00303 abort();
00304 }
00305 diffNumber c(a.MAXDEG);
00306 c[0]=a[0] / b[0];
00307 for (int i=1; i<a.MAXDEG+1; i++){
00308 c[i]=0.;
00309 for (int j=0; j<i; j++){
00310 c[i] += c[j] * b[i-j];
00311 }
00312 c[i]=1. / b[0] * (a[i] - c[i]);
00313 }
00314 return c;
00315 }
00316
00317 inline diffNumber operator /(const double &a, const diffNumber &b)
00318 {
00319 diffNumber c(b.MAXDEG);
00320 c[0]=a / b[0];
00321 for (int i=1; i<b.MAXDEG+1; i++){
00322 c[i]=0.;
00323 for (int j=0; j<i; j++){
00324 c[i] += c[j] * b[i-j];
00325 }
00326 c[i]= - 1. / b[0] * c[i];
00327 }
00328 return c;
00329 }
00330
00331 inline diffNumber operator /(const diffNumber &a, const double &b)
00332 {
00333 diffNumber c(a.MAXDEG);
00334 for (int i=0; i<a.MAXDEG+1; i++){
00335 c[i]=a[i] / b;
00336 }
00337 return c;
00338 }
00339
00340 inline diffNumber exp(const diffNumber &a)
00341 {
00342 diffNumber c(a.MAXDEG);
00343 c[0]=std::exp(a[0]);
00344 for (int i=1; i<a.MAXDEG+1; i++){
00345 for (int j=1; j<=i; j++){
00346 c[i]=c[i] + j* a[j] * c[i-j] / i;
00347 }
00348 }
00349 return c;
00350 }
00351
00352 inline diffNumber sin(const diffNumber &a)
00353 {
00354 diffNumber c(a.MAXDEG);
00355 diffNumber d(a.MAXDEG);
00356 c[0]=std::sin(a[0]);
00357 d[0]=std::cos(a[0]);
00358 for (int i=1; i<a.MAXDEG+1; i++){
00359 for (int j=1; j<=i; j++){
00360 c[i]=c[i] + j* a[j] * d[i-j] / i;
00361 d[i]=d[i] - j* a[j] * c[i-j] / i;
00362 }
00363 }
00364 return c;
00365 }
00366
00367 inline diffNumber cos(const diffNumber &a)
00368 {
00369 diffNumber c(a.MAXDEG);
00370 diffNumber d(a.MAXDEG);
00371 c[0]=std::sin(a[0]);
00372 d[0]=std::cos(a[0]);
00373 for (int i=1; i<a.MAXDEG+1; i++){
00374 for (int j=1; j<=i; j++){
00375 c[i]=c[i] + j* a[j] * d[i-j] / i;
00376 d[i]=d[i] - j* a[j] * c[i-j] / i;
00377 }
00378 }
00379 return d;
00380 }
00381
00382 inline diffNumber sqrt(const diffNumber &a)
00383 {
00384 diffNumber c(a.MAXDEG);
00385 c[0]=std::sqrt(a[0]);
00386 for (int i=1; i<a.MAXDEG+1; i++){
00387 c[i]=a[i];
00388 int m = (i + (i%2))/2;
00389 for (int j=1; j<=m-1; j++){
00390 c[i]=c[i] - 2.* c[j] * c[i-j];
00391 }
00392 if (i%2==0) {
00393 int n=i/2;
00394 c[i]=c[i]-c[n]*c[n];
00395 }
00396 c[i]=c[i] * 0.5 / c[0];
00397 }
00398 return c;
00399 }
00400
00401 inline diffNumber power(const diffNumber &a, int n)
00402 {
00403 diffNumber c(a.MAXDEG);
00404
00405 if (a[0] == 0)
00406 for (int i=0; i<a.MAXDEG+1; i++) c[i] = 0;
00407 else
00408 {
00409 c[0]=std::pow(a[0],n);
00410
00411 for (int i=1; i<a.MAXDEG+1; i++) {
00412 for (int j=0; j<=i-1; j++){
00413 c[i] = c[i] + ( n * (i - j) - j)* c[j] * a[i-j] / i;
00414
00415 }
00416 c[i]=c[i] / a[0];
00417 }
00418 }
00419 return c;
00420 }
00421
00422 inline diffNumber power(const diffNumber &a, const diffNumber &b)
00423 {
00424 if (a.MAXDEG != b.MAXDEG){
00425 std::cerr<<"+ degree not the same: "<< a.MAXDEG <<" != "<< b.MAXDEG;
00426 abort();
00427 }
00428 diffNumber c(a.MAXDEG);
00429
00430 if (a[0] == 0.0)
00431 for (int i=0; i<a.MAXDEG+1; i++) c[i] = 0;
00432 else
00433 c= exp(b * log(a));
00434
00435 return c;
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568 inline diffNumber log(const diffNumber &a)
00569 {
00570 diffNumber c(a.MAXDEG);
00571 c[0]=std::log(a[0]);
00572 for (int i=1; i<a.MAXDEG+1; i++){
00573 for (int j=1; j<=i-1; j++){
00574 c[i]=c[i] - j* c[j] * a[i-j] / i;
00575 }
00576 c[i]=(c[i] + a[i]) / a[0];
00577 }
00578 return c;
00579 }
00580
00581 inline diffNumber sinh(const diffNumber &a)
00582 {
00583 diffNumber c(a.MAXDEG);
00584 diffNumber d(a.MAXDEG);
00585 c[0]=std::sinh(a[0]);
00586 d[0]=std::cosh(a[0]);
00587 for (int i=1; i<a.MAXDEG+1; i++){
00588 for (int j=1; j<=i; j++){
00589 c[i]=c[i] + j* a[j] * d[i-j] / i;
00590 d[i]=d[i] + j* a[j] * c[i-j] / i;
00591 }
00592 }
00593 return c;
00594 }
00595
00596 inline diffNumber cosh(const diffNumber &a)
00597 {
00598 diffNumber c(a.MAXDEG);
00599 diffNumber d(a.MAXDEG);
00600 c[0]=std::sinh(a[0]);
00601 d[0]=std::cosh(a[0]);
00602 for (int i=1; i<a.MAXDEG+1; i++){
00603 for (int j=1; j<=i; j++){
00604 c[i]=c[i] + j* a[j] * d[i-j] / i;
00605 d[i]=d[i] + j* a[j] * c[i-j] / i;
00606 }
00607 }
00608 return d;
00609 }
00610
00611 inline diffNumber atan2(const diffNumber &a, const diffNumber&b)
00612 {
00613 diffNumber c(a.MAXDEG);
00614 diffNumber d(a.MAXDEG);
00615 diffNumber e(a.MAXDEG);
00616 c=b/a;
00617 d=1.+c*c;
00618 e[0]=std::atan(c[0]);
00619 for (int i=1; i<a.MAXDEG+1; i++){
00620 e[i]=c[i]/d[0];
00621 for (int j=1; j<=i-1; j++){
00622 e[i]=e[i] - j* e[j] * d[i-j] / i;
00623 }
00624 }
00625 return e;
00626 }
00627
00628 inline diffNumber atan(const diffNumber &a)
00629 {
00630 diffNumber d(a.MAXDEG);
00631 diffNumber e(a.MAXDEG);
00632 d=1.+a*a;
00633 e[0]=std::atan(a[0]);
00634 for (int i=1; i<a.MAXDEG+1; i++){
00635 e[i]=a[i]/d[0];
00636 for (int j=1; j<=i-1; j++){
00637 e[i]=e[i] - j* e[j] * d[i-j] / i;
00638 }
00639 }
00640 return e;
00641 }
00642
00643
00644 inline diffNumber square(const diffNumber &a)
00645 {
00646 diffNumber c(a.MAXDEG);
00647 c[0]=a[0]*a[0];
00648 if (a.MAXDEG>=1)
00649 c[1]=2.*a[0]*a[1];
00650 if (a.MAXDEG>=2)
00651 c[2]=2.*(a[0]*a[2]+a[1]*a[1]);
00652 return c;
00653 }
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677 inline diffNumber::~diffNumber()
00678 {
00679
00680 if (data) delete[] data;
00681 }
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701 inline std::ostream &operator << (std::ostream &s, const diffNumber &a)
00702 {
00703 diffNumber b(a.MAXDEG);
00704 s<<"< ";
00705 s<<a[0];
00706 double fak=1.;
00707 for (int i=1; i<a.MAXDEG;i++)
00708 {
00709 s<<", ";
00710 fak=fak*i;
00711 b[i]=a[i]*fak;
00712 s << b[i];
00713 }
00714 s<<", ";
00715 fak=fak*a.MAXDEG;
00716 b[a.MAXDEG]=a[a.MAXDEG]*fak;
00717 s <<b[a.MAXDEG];
00718 s<<" >";
00719 return s;
00720 }
00721
00722 #endif