freConstrainedMetricInterface.cxx

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   F.R.E.E. - flexible registration evaluation engine
00004   Version:   v.1.0.0
00005   Date:      $Date: 2006/09/01 12:00:00 $
00006   Module:    $RCSfile: freConstrainedMetricInterface.cxx,v $
00007   Language:  C++
00008 
00009 
00010 
00011   Copyright (c) 2007 Ralf o Floca (Department of Medical Informatics,
00012   Institute for Medical Biometry and Informatics, University of Heidelberg,
00013   Germany). All rights reserved.
00014   See FREECopyright.txt or http://www.mi.med.uni-hd.de/free/copyright.htm
00015   for details.
00016 
00017      This software is distributed WITHOUT ANY WARRANTY; without even 
00018      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
00019      PURPOSE.  See the above copyright notices for more information.
00020 
00021 =========================================================================*/
00022 
00023 #include "freConstrainedMetricInterface.h"
00024 
00025 #include "muParser.h"
00026 
00027 namespace FREE
00028 {
00029 
00030   
00031   void
00032         ConstrainedMetricInterface::
00033   ResetConstraints()
00034         {
00035                 this->m_Constraints.Reset();
00036                 this->m_BarrierSizes.clear();
00037         };
00038 
00039   
00040   void
00041         ConstrainedMetricInterface::
00042   AddConstraint(const SetupParameterConstraint& constraint, double dBarrierSize)
00043         {
00044                 this->m_Constraints.AddElement(constraint);
00045                 this->m_BarrierSizes.push_back(dBarrierSize);
00046         };
00047 
00048 
00049   bool
00050         ConstrainedMetricInterface::
00051 	ComputeConstraintPenalties( const CnstrParametersType & parameters, CnstrDecomposedMeasureType & penalties ) const
00052         {
00053     penalties.SetSize(m_Constraints.Size());
00054     penalties.Fill(0.0);
00055     double dPenaltySum = 0.0;
00056 
00057                 for (unsigned int iPos = 0; iPos < m_Constraints.Size(); ++iPos)
00058                 {
00059       double dPenalty = ComputeConstraintPenalty(iPos,parameters);
00060                         penalties.SetElement(iPos, dPenalty);
00061       dPenaltySum += dPenalty;
00062                 }
00063 
00064     if (m_FailureThreshold<=0) return true;
00065 
00066     return dPenaltySum<m_FailureThreshold;
00067         };
00068 
00069 
00070   double
00071         ConstrainedMetricInterface::
00072 	ComputeConstraintPenalty( const unsigned int iConstraintID, const CnstrParametersType & parameters ) const
00073         {
00074                 SetupParameterConstraint* pConstraint = this->m_Constraints.GetElement(iConstraintID);
00075                 double dConstraintTermValue = 0;
00076                 double dConstrainedValue = 0;
00077 
00078                 if (!pConstraint) throwExceptionMacro("Error. Metric constraint specified by ID does not exist. Cannot compute penalty. ID:"<<iConstraintID);
00079                 if ((pConstraint->GetDestinationID()<0)||(pConstraint->GetDestinationID()>=parameters.size()))
00080                           throwExceptionMacro("Error. Parameter specified by constraint is no part of the passed parameter values. Parameter ID:"<<pConstraint->GetDestinationID());
00081 
00082                 dConstrainedValue = parameters[pConstraint->GetDestinationID()];
00083 
00084     //define variable for parser
00085                 double* pParameterData = new double[parameters.size()];
00086     parameters.copy_out(pParameterData);
00087 
00088     mu::Parser parser;
00089 
00090     try
00091     {
00092                   for (unsigned int iPos = 0; iPos < parameters.size(); iPos++)
00093       {
00094         parser.DefineVar("_"+Convert::ToStr(iPos),pParameterData+iPos);
00095       }
00096       parser.SetExpr(pConstraint->GetConstraintTerm());   
00097     }
00098     catch(mu::Parser::exception_type &e)
00099     {
00100       std::string sE = e.GetMsg();
00101                   std::string sLocation;
00102                   GetClassLocationMacro( sLocation );
00103       FREE::LogException("muParser based exception", sE, sLocation); \
00104                   throw FREE::ExceptionBase( "muParser exception", "Error: "+sE, sLocation, __FILE__, __LINE__); \
00105     }
00106     catchAllNPassMacro("Unkown errer while setting parser parameter and expression.");
00107 
00108     try
00109     {
00110       dConstraintTermValue = parser.Eval();
00111     }
00112     catch(mu::Parser::exception_type &e)
00113     {
00114       std::string sE = e.GetMsg();
00115                   std::string sLocation;
00116                   GetClassLocationMacro( sLocation );
00117       FREE::LogException("muParser based exception", sE, sLocation); \
00118                   throw FREE::ExceptionBase( "muParser exception", "Error: "+sE, sLocation, __FILE__, __LINE__); \
00119     }
00120     catchAllNPassMacro("Error while evaluating constrained term by muParser.");
00121 
00122     parser.ClearVar();
00123                 delete [] pParameterData;
00124 
00125     //evaluate constraint
00126     if (pConstraint->GetRelationType() == SetupParameterConstraint::RTEqual)
00127     {
00128                         if (dConstraintTermValue == dConstrainedValue) return 0;
00129                         else return this->m_MaxConstraintPenalty;
00130     }
00131     else
00132     {
00133                         //transform into an inequality against 0.
00134                         //basic form of inequalities are dConstrainedValue (relation) dConstraintTermValue
00135                         double dTransformedTermValue = dConstraintTermValue - dConstrainedValue;
00136                         if (pConstraint->GetRelationType() == SetupParameterConstraint::RTGreaterOrEqual)
00137                         { // need the form 0 <= term, but right now it would be 0 >= term, so *-1
00138                                 dTransformedTermValue *= -1;
00139                         }
00140 
00141                         double dBarrierSize = abs((double)(this->m_BarrierSizes[iConstraintID]));
00142 
00143                         //Check if it would be the maximum penalty anyway.
00144                         if (dTransformedTermValue<=0) return this->m_MaxConstraintPenalty;
00145 
00146                         //Check if it is outside the barrier region
00147                         if (dTransformedTermValue>dBarrierSize)
00148                         { //the constrained value is outside the barrier region within a legal valid range.
00149                                 return 0;
00150                         }
00151 
00152                         // the constrained value seems to violate the constraint or at least is within the
00153                         // barrier region, so compute the penalty
00154 
00155                         //calculate the barrier function value
00156                         double dBarrierValue = -1*log(dTransformedTermValue/dBarrierSize);
00157 
00158                         return std::min(dBarrierValue, this->m_MaxConstraintPenalty);
00159                 }
00160 
00161                 return 0;
00162         };
00163 
00164         
00165 
00166 ConstrainedMetricInterface::
00167 ConstrainedMetricInterface()
00168 {
00169         this->m_MaxConstraintPenalty = 100000;
00170   this->m_FailureThreshold = 0;
00171         this->ResetConstraints();
00172 };
00173 
00174 } // end namespace FREE

Generated at Sat Oct 13 15:39:24 2007 for f.r.e.e. - Flexible Registration and Evaluation Engine by doxygen 1.5.3 written by Dimitri van Heesch, © 1997-2000