00001 /* 00002 * HippoPlot Exponential class implementation 00003 * 00004 * Copyright (C) 2000, 2003 The Board of Trustees of The Leland 00005 * Stanford Junior University. All Rights Reserved. 00006 * 00007 * $Id: Exponential.cxx,v 1.2 2003/07/23 00:20:39 jchiang Exp $ 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 "Exponential.h" 00020 00021 #include "FunctionHelper.h" 00022 00023 #include <cmath> 00024 #include <cassert> 00025 #include <iostream> 00026 00027 #ifdef ITERATOR_MEMBER_DEFECT 00028 using namespace std; 00029 #else 00030 using std::vector; 00031 #endif 00032 00033 Exponential::Exponential ( ) 00034 { 00035 initialize (); 00036 } 00037 00038 Exponential::Exponential ( double prefactor, double scale ) 00039 { 00040 initialize (); 00041 00042 m_parms[0] = prefactor; 00043 m_parms[1] = scale; 00044 } 00045 00046 void Exponential::initialize () 00047 { 00048 m_name = "Exponential"; 00049 m_parm_names.push_back ( "Prefactor" ); 00050 m_parm_names.push_back ( "Scale" ); 00051 00052 resize (); 00053 } 00054 00055 FunctionBase * Exponential::clone () const 00056 { 00057 return new Exponential ( *this ); 00058 } 00059 00060 double Exponential::operator () ( double x ) const 00061 { 00062 return m_parms[0]*exp( -x/m_parms[1] ); 00063 } 00064 00065 /* virtual */ 00066 void 00067 Exponential:: 00068 initialParameters ( const FunctionHelper * helper ) 00069 { 00070 double min_x = helper->minCoord (); 00071 double max_x = helper->maxCoord (); 00072 max_x = (min_x + max_x)/2.; 00073 00074 try { 00075 double min_y = helper->valueAt (min_x); 00076 double max_y = helper->valueAt (max_x); 00077 if (min_y != 0 && max_y != 0) { // success! 00078 m_parms[1] = ( min_x - max_x ) / log( max_y/min_y ); 00079 m_parms[0] = max_y / exp( -max_x/m_parms[1] ); 00080 return; 00081 } 00082 } catch (std::string &message) { 00083 std::cerr << message << std::endl; 00084 } 00085 00086 // All cleverness fails, so use default values.... 00087 m_parms[0] = 1.; 00088 m_parms[1] = 1.; 00089 } 00090 00091 double Exponential::derivByParm ( int i, double x ) const 00092 { 00093 switch ( i ) { 00094 case 0 : 00095 return exp( -x/m_parms[1] ); 00096 break; 00097 00098 case 1 : 00099 return operator()(x)*(x/m_parms[1]/m_parms[1]); 00100 break; 00101 00102 default: 00103 assert ( false ); 00104 break; 00105 } 00106 return 0.0; 00107 }