<commit_before>// Copyright 2007 Georgia Institute of Technology. All rights reserved.
// ABSOLUTELY NOT FOR DISTRIBUTION
/**
 * @file discrete.cc
 *
 * Helpers for discrete math (implementation).
 */

#include "discrete.h"

#include <stdlib.h>

double math::BinomialCoefficient(int n, int k) {
  int n_k = n - k;
  double nchsk = 1;
  int i;
  
  if(k > n)
    return 0;
  
  if(k < n_k) {
    k = n_k;
    n_k = n - k;
  }
  
  for(i = 1; i <= n_k; i++) {
    nchsk *= (++k);
    nchsk /= i;
  }
  return nchsk;
}

double math::Factorial(int d) {
  double v = 1;
  
  DEBUG_ASSERT(d >= 0);
  
  for (int i = 2; i <= d; i++) {
    v *= i;
  }
  
  return v;
}

void math::MakeIdentityPermutation(index_t size, index_t *array) {
  for (index_t i = 0; i < size; i++) {
    array[i] = i;
  }
}

void math::MakeRandomPermutation(index_t size, index_t *array) {
  // Regular permutation algorithm.
  // This is cache inefficient for large sizes; large caches might
  // warrant a more sophisticated blocked algorithm.
  
  if (unlikely(size == 0)) {
    return;
  }
  
  array[0] = 0;
  
  for (index_t i = 1; i < size; i++) {
    index_t victim = rand() % i;
    array[i] = array[victim];
    array[victim] = i;
  }
}

void math::MakeInversePermutation(index_t size,
    const index_t *original, index_t *reverse) {
  for (index_t i = 0; i < size; i++) {
    reverse[original[i]] = i;
  }
}
<commit_msg>Bug fix for math::BinomialCoefficient(n, k); the previous implementation returned 1 for negative k values, which is not correct (should be zero.<commit_after>// Copyright 2007 Georgia Institute of Technology. All rights reserved.
// ABSOLUTELY NOT FOR DISTRIBUTION
/**
 * @file discrete.cc
 *
 * Helpers for discrete math (implementation).
 */

#include "discrete.h"

#include <stdlib.h>

double math::BinomialCoefficient(int n, int k) {
  int n_k = n - k;
  double nchsk = 1;
  int i;
  
  if(k > n || k < 0) {
    return 0;
  }
  
  if(k < n_k) {
    k = n_k;
    n_k = n - k;
  }
  
  for(i = 1; i <= n_k; i++) {
    nchsk *= (++k);
    nchsk /= i;
  }
  return nchsk;
}

double math::Factorial(int d) {
  double v = 1;
  
  DEBUG_ASSERT(d >= 0);
  
  for (int i = 2; i <= d; i++) {
    v *= i;
  }
  
  return v;
}

void math::MakeIdentityPermutation(index_t size, index_t *array) {
  for (index_t i = 0; i < size; i++) {
    array[i] = i;
  }
}

void math::MakeRandomPermutation(index_t size, index_t *array) {
  // Regular permutation algorithm.
  // This is cache inefficient for large sizes; large caches might
  // warrant a more sophisticated blocked algorithm.
  
  if (unlikely(size == 0)) {
    return;
  }
  
  array[0] = 0;
  
  for (index_t i = 1; i < size; i++) {
    index_t victim = rand() % i;
    array[i] = array[victim];
    array[victim] = i;
  }
}

void math::MakeInversePermutation(index_t size,
    const index_t *original, index_t *reverse) {
  for (index_t i = 0; i < size; i++) {
    reverse[original[i]] = i;
  }
}

{'fraction_non_alphanumeric': 0.14731839782756279, 'fraction_numerical': 0.011541072640868975, 'mean_word_length': 2.68375, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 9, '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': '4871294', 'n_tokens_mistral': 1200, 'n_tokens_neox': 1138, 'n_words': 334}