00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifdef HAVE_CONFIG_H
00012 #include "config.h"
00013 #else
00014 #ifdef _MSC_VER
00015 #include "msdevstudio/MSconfig.h"
00016 #endif
00017 #endif
00018
00019 #include "BrokenPowerLaw.h"
00020
00021 #include "FunctionHelper.h"
00022
00023 #include <cmath>
00024 #include <cassert>
00025
00026 #ifdef ITERATOR_MEMBER_DEFECT
00027 using namespace std;
00028 #else
00029 using std::max;
00030 using std::vector;
00031 #endif
00032
00033 BrokenPowerLaw::BrokenPowerLaw ( )
00034 {
00035 initialize ();
00036 }
00037
00038 BrokenPowerLaw::BrokenPowerLaw ( double prefactor, double index1,
00039 double index2, double x_break)
00040 {
00041 initialize ();
00042
00043 m_parms[0] = prefactor;
00044 m_parms[1] = index1;
00045 m_parms[2] = index2;
00046 m_parms[3] = x_break;
00047 }
00048
00049 void BrokenPowerLaw::initialize ()
00050 {
00051 m_name = "BrokenPowerLaw";
00052 m_parm_names.push_back ( "Prefactor" );
00053 m_parm_names.push_back ( "Index1" );
00054 m_parm_names.push_back ( "Index2" );
00055 m_parm_names.push_back ( "Break" );
00056
00057 resize ();
00058 }
00059
00060 FunctionBase * BrokenPowerLaw::clone () const
00061 {
00062 return new BrokenPowerLaw ( *this );
00063 }
00064
00065 double BrokenPowerLaw::operator () ( double x ) const
00066 {
00067 if (x < m_parms[3]) {
00068 return m_parms[0]*pow(x/m_parms[3], m_parms[1]);
00069 } else {
00070 return m_parms[0]*pow(x/m_parms[3], m_parms[2]);
00071 }
00072 }
00073
00074
00075 void
00076 BrokenPowerLaw::
00077 initialParameters ( const FunctionHelper * helper )
00078 {
00079 double min_x = helper->minCoord ();
00080 double max_x = helper->maxCoord ();
00081 max_x = (min_x + max_x)/2.;
00082
00083 double min_y, max_y;
00084 try {
00085 min_y = helper->valueAt(min_x);
00086 max_y = helper->valueAt(max_x);
00087 if (min_y != 0 && max_y != 0) {
00088 m_parms[1] = log( max_y/min_y ) / log( max_x/min_x );
00089 m_parms[2] = m_parms[1];
00090 m_parms[3] = helper->meanCoord();
00091 m_parms[0] = max_y/pow(max_x/m_parms[3], m_parms[1]);
00092 return;
00093 }
00094 } catch (...) {
00095
00096 }
00097
00098
00099 min_y = max(helper->minValue(), 1.);
00100 max_y = helper->maxValue();
00101 m_parms[1] = log( max_y/min_y ) / log( max_x/min_x );
00102 m_parms[2] = m_parms[1];
00103 m_parms[3] = helper->meanCoord();
00104 m_parms[0] = max_y/pow(max_x/m_parms[3], m_parms[1]);
00105 }
00106
00107 double BrokenPowerLaw::derivByParm ( int i, double x ) const
00108 {
00109 switch ( i ) {
00110 case 0 :
00111 return operator()(x)/m_parms[0];
00112 break;
00113
00114 case 1 :
00115 if (x < m_parms[3]) {
00116 return operator()(x)*log(x/m_parms[3]);
00117 } else {
00118 return 0;
00119 }
00120 break;
00121
00122 case 2 :
00123 if (x < m_parms[3]) {
00124 return 0;
00125 } else {
00126 return operator()(x)*log(x/m_parms[3]);
00127 }
00128 break;
00129
00130 case 3 :
00131 if (x < m_parms[3]) {
00132 return -m_parms[1]*operator()(x)/m_parms[3];
00133 } else {
00134 return -m_parms[2]*operator()(x)/m_parms[3];
00135 }
00136 break;
00137
00138 default:
00139 assert ( false );
00140 break;
00141 }
00142 return 0.0;
00143 }