00001
00002
00003
00004
00005 #include <stdlib.h>
00006 #include <stdio.h>
00007 #include <float.h>
00008 #include <math.h>
00009 #include <time.h>
00010
00011 #include "solvers.h"
00012
00013 #ifndef WIN32
00014 #define _finite isfinite
00015 #endif
00016
00017 #define SGNP(X,P) ((X)<-(P)?-1:((X)>(P)?+1:0))
00018
00019 int dual_decay_solve(double *ans, double prec, double start, double end, int f, double a, double n, double b, double m, double c)
00020 {
00021 #define EVAL(f,t,a,n,b,m,c) (a*pow(n,f)*exp(n*t) + b*pow(m,f)*exp(m*t) + c)
00022
00023
00024 double df_start = EVAL(f+1,start,a,n,b,m,c);
00025 double df_end = EVAL(f+1,end,a,n,b,m,c);
00026
00027 if(!_finite(df_start) || !_finite(df_end))
00028 return -1;
00029
00030 int sa = SGNP(df_start,prec);
00031 int sb = SGNP(df_end,prec);
00032
00033
00034 if (sa*sb==-1)
00035 {
00036
00037 double t;
00038 if (!dual_decay_solve(&t, prec, start, end, a*pow(n,f+1),n,b*pow(m,f+1),m,0))
00039
00040
00041 return -1;
00042
00043
00044 int n_right = dual_decay_solve(ans, prec, t, end, f, a,n,b,m,c);
00045 if (n_right<0)
00046 return -1;
00047
00048 int n_left = dual_decay_solve(ans, prec, start, t, f, a,n,b,m,c);
00049 if (n_left<0)
00050 return -1;
00051
00052 return n_left+n_right;
00053 }
00054 return dual_decay_solve(ans, prec, start, end, a,n,b,m,c);
00055 #undef EVAL
00056 }
00057
00058 int dual_decay_solve(double *ans, double prec, double start, double end, double a, double n, double b, double m, double c)
00059 {
00060 #define EVAL(t,a,n,b,m,c) (a*exp(n*t) + b*exp(m*t) + c)
00061
00062 double f_start = EVAL(start,a,n,b,m,c);
00063 double f_end = EVAL(end,a,n,b,m,c);
00064
00065 if (!_finite(f_start) ||!_finite(f_end))
00066 return -1;
00067
00068 int sa = SGNP(f_start,prec);
00069 int sb = SGNP(f_end,prec);
00070
00071
00072 if (sa*sb==1)
00073
00074
00075 return 0;
00076
00077
00078 else if (sa==0)
00079 *ans = start;
00080 else if (sb==0)
00081 *ans = end;
00082 else
00083 {
00084
00085 double t=(start+end)/2;
00086 int result = dual_decay_solve(ans,prec,start,t,a,n,b,m,c);
00087 if (result==0)
00088 result = dual_decay_solve(ans,prec,t,end,a,n,b,m,c);
00089 return result;
00090 }
00091
00092 return 1;
00093 }
00094
00095 #undef SGNP