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