Ejemplo n.º 1
0
/**
 * Marginalise a maxsum::DiscreteFunction by averaging.
 * This function reduces the domain of inFun to that of outFun by
 * averaging, and stores the result in outFun.
 * @pre variables in domain of outFun are a subset of variables in inFun.
 * @post previous content of outFun is overwritten.
 * @post The domains of outFun and inFun remain unchanged.
 * @param[in] inFun function to marginalise
 * @param[out] outFun maxsum::DiscreteFunction in which to store result.
 * @throws maxsum::BadDomainException is the domain of outFun is not a
 * subset of inFun.
 * @see maxsum::marginal()
 * @see maxsum::minMarginal()
 * @see maxsum::maxMarginal()
 */
void maxsum::meanMarginal
(
 const DiscreteFunction& inFun,
 DiscreteFunction& outFun
)
{
   //**************************************************************************
   // Marginalise over free domain by summation
   //**************************************************************************
   marginal(inFun,add_m,outFun);

   //**************************************************************************
   // Now each element of the output is the sum over the relevant values
   // in the input function, so we need to normalise to get the average.
   //
   // Note: another way to do this would be to marginalise using a functor
   // class Mean, which is constructed using the size of the free domain, so
   // that it knows the number of values to average over. This might be
   // more numerically stable, and also only requires one pass rather than 
   // two. However, its not clear that the extra complexity would be worth it.
   //**************************************************************************
   ValType w = outFun.domainSize();
   w = w / inFun.domainSize();
   for(int k=0; k<outFun.domainSize(); ++k)
   {
      outFun(k) *= w;
   }

} // meanMarginal
Ejemplo n.º 2
0
/**
 * Returns the element-wise maximum of this function and a specified
 * scalar. That is, if M = N.max(s) then M(k)=max(N(k),s).
 * @param[in] s the scalar value to compare
 * @param[out] result the result of the operation.
 */
void DiscreteFunction::max(const ValType s, DiscreteFunction& result)
{

// If possible use eigen array op
#if ((EIGEN_WORLD_VERSION == 3) && (EIGEN_MAJOR_VERSION >= 1)) || (EIGEN_WORLD_VERSION > 3)
   result.values_i = this->values_i.max(s);

// Otherwise use basic implementation
#else
    result = *this;
    for(int k=0; k<result.domainSize(); k++)
    {
        result(k) = (s > result(k)) ? s : result(k);
    }

#endif

} // max
Ejemplo n.º 3
0
int testMarginals(const DiscreteFunction inFun)
{
   int errorCount = 0;

   //***************************************************************************
   // Calculate aggregates over entire domain of input function
   //***************************************************************************
   double mean=0;
   double max=-DBL_MAX;
   double maxnorm=-DBL_MAX;
   long argmax=-1;
   double domainSize = inFun.domainSize();
   for(int k=0; k<inFun.domainSize(); ++k)
   {
      double val = inFun(k);
      double absVal = std::fabs(val);
      mean += val / domainSize;

      if(maxnorm<absVal)
      {
         maxnorm=absVal;
      }

      if(max<val)
      {
         max=val;
         argmax=k;
      }

   } // for loop

   //***************************************************************************
   // Check results for consistency
   //***************************************************************************
   const double funMean = inFun.mean();
   const double funMax = inFun.max();
   const double funMaxnorm = inFun.maxnorm();
   const long funArgMax = inFun.argmax();

   if(!nearlyEqual_m(max,funMax))
   {
      std::cout << "max: " << funMax << " should be " << max << '\n';
      ++errorCount;
   }

   if(!nearlyEqual_m(mean,funMean))
   {
      std::cout << "mean: " << funMean << " should be " << mean << '\n';
      ++errorCount;
   }

   if(!nearlyEqual_m(maxnorm,funMaxnorm))
   {
      std::cout << "maxnorm: " << funMaxnorm << " should be "
         << maxnorm << '\n';
      ++errorCount;
   }

   if(funArgMax!=argmax)
   {
      std::cout << "argmax: " << funArgMax << " should be " << argmax << '\n';
      ++errorCount;
   }

   //***************************************************************************
   // Return number of errors
   //***************************************************************************
   return errorCount;

} // testMarginals