Esempio n. 1
0
/**
 * Check that two maxsum::DiscreteFunction objects have the same domain.
 * Two functions have the same domain, if they depend on the same set of
 * variables.
 * @param[in] f1 First function to compare
 * @param[in] f2 Second functions to compare
 * @returns true if both function have the same domain.
 */
bool maxsum::sameDomain(const DiscreteFunction& f1, const DiscreteFunction& f2)
{
   if(f1.noVars()!=f2.noVars())
   {
      return false;
   }

   return std::equal(f1.varBegin(),f1.varEnd(),f2.varBegin());

} // function sameDomain
Esempio n. 2
0
/**
 * Check that two maxsum::DiscreteFunction objects are equal within a
 * specified tolerance. This function returns true if and only if, for all
 * <code>k</code>:
 * <p>
 * <code>
 * -tol < 1-f1(k)/f2(k) < tol
 * </code>
 * </p>
 * @param[in] f1 First function to compare
 * @param[in] f2 Second function to compare
 * @param[in] tol tolerance used for comparing values
 * @see maxsum::DEFAULT_VALUE_TOLERANCE
 */
bool maxsum::equalWithinTolerance
(
 const DiscreteFunction& f1,
 const DiscreteFunction& f2,
 ValType tol
)
{
   //***************************************************************************
   // Iterator over the combined domain of f1 and f2
   //***************************************************************************
   DomainIterator it(f1);
   it.addVars(f2.varBegin(),f2.varEnd());
   while(it.hasNext())
   {
      //************************************************************************
      // Check that the difference in value for the current positions are
      // equal within tolerance.
      //************************************************************************
      ValType diff = 1-f1(it)/f2(it);
      if( (diff > tol) || (diff < -tol) )
      {
         return false;
      }

      ++it;

   } // for loop

   //***************************************************************************
   // If we get to here, everything is equal within tolerance
   //***************************************************************************
   return true;

} // function equalWithinTolerance
Esempio n. 3
0
/**
 * Construct Domain Iterator using domain of a given function.
 * This is more efficient that creating from sratch.
 * @param[in] fun Function whose domain should be copied.
 */
DomainIterator::DomainIterator(const DiscreteFunction& fun)
   : vars_i(fun.varBegin(),fun.varEnd()),    // copy variables
     subInd_i(fun.noVars(),0),               // set all subindices to zero
     ind_i(0),                               // set linear index to zero
     fixed_i(fun.noVars(),false),            // all variables are initially free
     sizes_i(fun.sizeBegin(),fun.sizeEnd()), // copy variable sizes
     finished_i(false)                       // iterator is not done yet
   {}                   // nothing left to do in constructor body
Esempio n. 4
0
/**
 * Make the domain of this function include the domain of another.
 * If necessary, the domain of this function is expanded to include the
 * domain of the parameter fun.
 * @param[in] fun function whose domain we want to expand to.
 * @todo Make this more efficient by using fun.size_i cache.
 * @post domain of this is union of its previous domain, with that of fun.
 */
void DiscreteFunction::expand(const DiscreteFunction& fun)
{
   this->expand(fun.varBegin(),fun.varEnd());
}
Esempio n. 5
0
/**
 * Accessor method for factor function.
 * @param[in] id the unique identifier of the desired factor.
 * @param[in] factor the function representing this factor.
 * @returns a reference to the function associated with the factor with
 * unique identifier <code>id</code>.
 * @post A copy of <code>factor</code> is stored internally by
 * this maxsum::MaxSumController and used to form part of a factor graph.
 * @post Any previous value of the specified factor is overwritten.
 */
void MaxSumController::setFactor(FactorID id, const DiscreteFunction& factor)
{
   //***************************************************************************
   // Set the specified factor. (Note: oldValue is created automatically if
   // necessary).
   //***************************************************************************
   DiscreteFunction& oldValue = factors_i[id];

   //***************************************************************************
   // If this factor is currently related to any variables that it is no
   // longer related to, delete the appropriate edges.
   //***************************************************************************
   std::vector<VarID> toRemove(oldValue.noVars());
   std::set_difference(oldValue.varBegin(),oldValue.varEnd(),
         factor.varBegin(),factor.varEnd(),toRemove.begin());

   for(std::vector<VarID>::const_iterator it=toRemove.begin();
         it!=toRemove.end(); ++it)
   {
      //************************************************************************
      // Remove the redundant edges from the postoffice graphs
      //************************************************************************
      fac2varMsgs_i.removeEdge(id,*it);
      var2facMsgs_i.removeEdge(*it,id);

      //************************************************************************
      // If the variable is no longer related to any factors, then we remove
      // it from the value list.
      //************************************************************************
      if(!var2facMsgs_i.hasSender(*it))
      {
         values_i.erase(*it);
      }

   } // for loop

   //***************************************************************************
   // For each variable in this factor's domain
   //***************************************************************************
   for(DiscreteFunction::VarIterator it=factor.varBegin();
         it!=factor.varEnd(); ++it)
   {
      //************************************************************************
      // Initialise input and output messages between the factor and
      // the current variable
      //************************************************************************
      DiscreteFunction msgTemplate(*it,0);
      fac2varMsgs_i.addEdge(id,*it,msgTemplate);
      var2facMsgs_i.addEdge(*it,id,msgTemplate);

      //************************************************************************
      // Touch the variable to ensure that it is in the value list.
      //************************************************************************
      ValueMap::iterator pos = values_i.find(*it);
      if(values_i.end()==pos)
      {
         values_i[*it]=0;
      }

   } // for loop

   //***************************************************************************
   // Set the specified factor to its new value.
   //***************************************************************************
   factors_i[id] = factor;

   //***************************************************************************
   // Tell everyone to recheck their mail. Telling everyone to recheck is the
   // safest option, because the factor graph may have changed.
   //***************************************************************************
   var2facMsgs_i.notifyAll();

} // function setFactor