<commit_before>package ml.wolfe

/**
 * A set of operators used in typical machine learning workflows. This trait provides
 * default implementations to all operators. These (a) serve as a definition of the semantics
 * of the operator, and (b) are used in [[ml.wolfe.BruteForceOperators]] for clients to access directly.
 *
 * @author <NAME>
 */
trait Operators {

  import scala.language.implicitConversions

  import Wolfe._

  /**
   * Returns the argmax of the given objective over the given domain
   * @param dom the domain to argmax over.
   * @param obj the objective to optimize
   * @tparam T the type of objects in the domain.
   * @tparam N the type of values the objective returns (usually Doubles)
   * @return an element `x` in `dom` with maximal objective value `obj(x)`.
   */
  def argmax[T, N: Ordering](dom: Iterable[T])(obj: T => N) = dom.maxBy(obj)

  /**
   * Returns the argmin of the given objective over the given domain
   * @param dom the domain to argmin over.
   * @param obj the objective to optimize
   * @tparam T the type of objects in the domain.
   * @tparam N the type of values the objective returns (usually Doubles)
   * @return an element `x` in `dom` with minimal objective value `obj(x)`.
   */
  def argmin[T, N: Ordering](dom: Iterable[T])(obj: T => N) = dom.minBy(obj)

  /**
   * Applies a function to a sequence of values and sums up the results.
   * @param dom the values that the `obj` function will be applied to.
   * @param obj the function to apply to the values.
   * @tparam T type of objects in the sequence of values.
   * @tparam N return type of `obj`, usually `Double` or `Vector`.
   * @return sum of `obj(x)` over all `x` in `dom`.
   */
  def sum[T, N: Numeric](dom: Iterable[T])(obj: T => N) = dom.map(obj).sum

  /**
   * Calculates the log-partition function of a log-linear model.
   * @param dom the domain of objects to sum over.
   * @param obj the unnormalized log-linear model to calculate the log partition function for.
   * @tparam T type of objects in domain.
   * @return the logarithm of the partition function of `obj` with respect to domain `dom`.
   */
  def logZ[T](dom: Iterable[T])(obj: T => Double) = math.log((dom map (x => math.exp(obj(x)))).sum)

  /**
   * Returns the maximal value of a function with respect to a domain.
   * @param dom the domain to max over.
   * @param obj the objective to maximize.<commit_msg>Updated Operators.sum to use foldLeft (to save memory, and to work when dom is a Set)<commit_after>package ml.wolfe

/**
 * A set of operators used in typical machine learning workflows. This trait provides
 * default implementations to all operators. These (a) serve as a definition of the semantics
 * of the operator, and (b) are used in [[ml.wolfe.BruteForceOperators]] for clients to access directly.
 *
 * @author <NAME>
 */
trait Operators {

  import scala.language.implicitConversions

  import Wolfe._

  /**
   * Returns the argmax of the given objective over the given domain
   * @param dom the domain to argmax over.
   * @param obj the objective to optimize
   * @tparam T the type of objects in the domain.
   * @tparam N the type of values the objective returns (usually Doubles)
   * @return an element `x` in `dom` with maximal objective value `obj(x)`.
   */
  def argmax[T, N: Ordering](dom: Iterable[T])(obj: T => N) = dom.maxBy(obj)

  /**
   * Returns the argmin of the given objective over the given domain
   * @param dom the domain to argmin over.
   * @param obj the objective to optimize
   * @tparam T the type of objects in the domain.
   * @tparam N the type of values the objective returns (usually Doubles)
   * @return an element `x` in `dom` with minimal objective value `obj(x)`.
   */
  def argmin[T, N: Ordering](dom: Iterable[T])(obj: T => N) = dom.minBy(obj)

  /**
   * Applies a function to a sequence of values and sums up the results.
   * @param dom the values that the `obj` function will be applied to.
   * @param obj the function to apply to the values.
   * @tparam T type of objects in the sequence of values.
   * @tparam N return type of `obj`, usually `Double` or `Vector`.
   * @return sum of `obj(x)` over all `x` in `dom`.
   */
  def sum[T, N: Numeric](dom: Iterable[T])(obj: T => N) = dom.foldLeft(implicitly[Numeric[N]].zero)( (acc, t) =>
    implicitly[Numeric[N]].plus(acc, obj(t)))

  /**
   * Calculates the log-partition function of a log-linear model.
   * @param dom the domain of objects to sum over.
   * @param obj the unnormalized log-linear model to calculate the log partition function for.
   * @tparam T type of objects in domain.
   * @return the logarithm of the partition function of `obj` with respect to domain `dom`.
   */
  def logZ[T](dom: Iterable[T])(obj: T => Double) = math.log((dom map (x => math.exp(obj(x)))).sum)

  /**
   * Returns the maximal value of a function with respect to a domain.
   * @param dom the domain to max over.
   * @param obj the objective to maximize.
{'fraction_non_alphanumeric': 0.10635303578608765, 'fraction_numerical': 0.0, 'mean_word_length': 3.3374019180470795, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5445323', 'n_tokens_mistral': 1541, 'n_tokens_neox': 1504, 'n_words': 684}