/* University College London Dept of P&A course in C++ 3C59 | all rights reserved 2000 | | Module: Consolidation excercise: | | Title: Compton Analysis | | Data type: Minimiser | | Description: | | A minimiser is a very simple thing (really!) | | - It keeps track of the value of some parameter which it is allowed to change. | Each time you ask it for this parameter it gives it to you. | | - You tell it the chisqared which you calculate for the value of the parameter | it gave you. | | - It compares this chisquared with the last value you gave it. | If the chisq is decreasing is continues to change the value of the parameter in the | same direction as before. (to start with it has to guess a direction, but after | that it all follows) | If the chisquared is increasing it changes it in the opposite direction, and reduces the amount | of the change. | | - You keep going like this until the minimiser tells you it is finished. It does this | when the change in the chisquared is below some threshold value. | | Note for experts : in reality Minimiser would not be done quite the way it is | presented below. The minimiser would call back to the client to obtain the | chisquared rather than rely on being given it. | However this involves (i) interfaces and inheritance and (ii) the concept | of the minimiser storing a pointer to its client - this complexity has not | been covered in the course so far. | | Author: P.Clarke */ #ifndef _minimiser_h #define _minimiser_h 1 #include // needed to use the abs() function // ---------------------- // class definition starts here class Minimiser { private: float m_parameterValue ; // Holds current value of parameter being minimised float m_increment ; // Amount to increment parameter by each iteration float m_lastChisq ; // The chisquared for previous parameter value float m_convergenceThreshold ; // Mimimum change in chisquared to declare finished bool m_stillGoing ; // true if minimisation still going on. public: // ----------------------------------------------- // Begining of method void initialise( float initial, float increment, float convergence ) { // Set member variables from arguments: m_parameterValue = initial ; m_increment = increment ; m_convergenceThreshold = convergence ; // Initialise other variables to something m_lastChisq = 1000000000 ; m_stillGoing = true ; } // ----------------------------------------------- // Begininning of Method // // This method trivially returns to the client the current value of the // minimisation parameter float currentParameter( ) { return m_parameterValue ; } // ----------------------------------------------- // Begininning of Method // // This method is called by the client when it wants to know if if needs // to continue the minimisation process. bool stillGoing( ) { return m_stillGoing ; } // ------------------------------------------------ // Beginning of method // // This is the method which does all the work. The client calls it to give it the // chisq corresponding to the lass parameter value given to the client. // This method compared old and new chisquared and determines how to modify // the parameter in order to try and reduce the chisq further void setChisq( float newChisq ) { // We have been given a new chisq. Firstly we determine whether the change // is within the convergence limit, if so we stop. Otherwise we adjust // the parameter in he appropriate direction. if( fabs( newChisq - m_lastChisq ) < m_convergenceThreshold ) { // Ok we can stop now. Set the flag to indicate this m_stillGoing = false ; } else if( newChisq < m_lastChisq ) { // Chisquared seems to still be going down, so carry on changing parameter // in same direction as last time m_parameterValue += m_increment ; } else if( newChisq > m_lastChisq ) { // Oh dear - chisquared seems to be going back up, so start changing parameter // in other direction, and make the increment smaller. m_increment = -1.0 * m_increment / 10.0 ; m_parameterValue += m_increment ; } // Record this chisqared as being the last chisquared for next time m_lastChisq = newChisq ; return ; } }; // End of Minimiser class #endif