<commit_before>
typedef union
{
   float s[2];
   float2 v2;
} Vector2;






#define vectorInitZero(a) \
   (a)->s[0] = 0; \
   (a)->s[1] = 0;






#define vectorAdd(a, b) \
   (a)->s[0] += (b)->s[0]; \
   (a)->s[1] += (b)->s[1];






#define vectorScale(a, c) \
   (a)->s[0] *= (c); \
   (a)->s[1] *= (c);






#define SQR(x) ((x)*(x))
#define vectorDiffNorm(a, b) \
   sqrt(SQR((a)->s[0] - (b)->s[0]) + SQR((a)->s[1] - (b)->s[1]))






/**
 * Implementation of rand(), taken from POSIX example.
 *
 * @param state
 */
int rand(ulong *state)
{
   *state = (*state) * 1103515245 + 12345;
   return ((unsigned)((*state)/65536) % 32768);
}





/**
 * Fetch and build data matrix X for a pair of genes, skipping any expressions
 * that are missing for either gene.
 *
 * @param expressions
 * @param size
 * @param pair
 * @param minExpression
 * @param X
 * @param labels
 * @return number of rows in X
 */
int fetchData(
   __global const float *expressions, int size,
   int2 pair,
   int minExpression,
   __global Vector2 *X,
   __global char *labels)
{
   int numSamples = 0;

   pair.x *= size;
   pair.y *= size;

   // build data matrix from expressions and indices
   for ( int i = 0; i < size; ++i )
   {
      float2 v = (float2) (
         expressions[pair.x + i],
         expressions[pair.y + i]
      );

      if ( isnan(v.x) || isnan(v.y) )
      {
         labels[i] = -9;
      }
      else if ( v.x < minExpression || v.y < minExpression )
      {
         labels[i] = -6;
      }
      else
      {
         X[numSamples].v2 = v;
         numSamples++;

         labels[i] = 0;
      }
   }

   // return size of X
   return numSamples;
}






/**
 * Compute the log-likelihood of a K-means model given data X.
 *
 * @param X
 * @param N
 * @param y
 * @param means
 * @param K
 */
float computeLogLikelihood(
   __global const Vector2 *X, int N,
   __global const char *y,
   __global const Vector2 *means, int K)
{
   // compute within-class scatter
   float S = 0;

   for ( int k = 0; k < K; ++k )
   {
      for ( int i = 0; i < N; ++i )
      {
         if ( y[i] != k )
         {
            continue;
         }

         float dist = vectorDiffNorm(&X[i], &means[k]);

         S += dist * dist;
      }
   }

   return -S;
}






/**
 * Compute a K-means clustering model from a dataset.
 */
void fit(
   __global const Vector2 *X, int N, int K,
   __global int *y,
   float *logL,
   __global Vector2 *means,
   __global char *y_next)
{
   ulong state = 1;

   // initialize means randomly from X
   for ( int k = 0; k < K; ++k )<commit_msg>Fixed bug that caused k-means to hang<commit_after>
typedef union
{
   float s[2];
   float2 v2;
} Vector2;






#define vectorInitZero(a) \
   (a)->s[0] = 0; \
   (a)->s[1] = 0;






#define vectorAdd(a, b) \
   (a)->s[0] += (b)->s[0]; \
   (a)->s[1] += (b)->s[1];






#define vectorScale(a, c) \
   (a)->s[0] *= (c); \
   (a)->s[1] *= (c);






#define SQR(x) ((x)*(x))
#define vectorDiffNorm(a, b) \
   sqrt(SQR((a)->s[0] - (b)->s[0]) + SQR((a)->s[1] - (b)->s[1]))






/**
 * Implementation of rand(), taken from POSIX example.
 *
 * @param state
 */
int rand(ulong *state)
{
   *state = (*state) * 1103515245 + 12345;
   return ((unsigned)((*state)/65536) % 32768);
}





/**
 * Fetch and build data matrix X for a pair of genes, skipping any expressions
 * that are missing for either gene.
 *
 * @param expressions
 * @param size
 * @param pair
 * @param minExpression
 * @param X
 * @param labels
 * @return number of rows in X
 */
int fetchData(
   __global const float *expressions, int size,
   int2 pair,
   int minExpression,
   __global Vector2 *X,
   __global char *labels)
{
   int numSamples = 0;

   pair.x *= size;
   pair.y *= size;

   // build data matrix from expressions and indices
   for ( int i = 0; i < size; ++i )
   {
      float2 v = (float2) (
         expressions[pair.x + i],
         expressions[pair.y + i]
      );

      if ( isnan(v.x) || isnan(v.y) )
      {
         labels[i] = -9;
      }
      else if ( v.x < minExpression || v.y < minExpression )
      {
         labels[i] = -6;
      }
      else
      {
         X[numSamples].v2 = v;
         numSamples++;

         labels[i] = 0;
      }
   }

   // return size of X
   return numSamples;
}






/**
 * Compute the log-likelihood of a K-means model given data X.
 *
 * @param X
 * @param N
 * @param y
 * @param means
 * @param K
 */
float computeLogLikelihood(
   __global const Vector2 *X, int N,
   __global const char *y,
   __global const Vector2 *means, int K)
{
   // compute within-class scatter
   float S = 0;

   for ( int k = 0; k < K; ++k )
   {
      for ( int i = 0; i < N; ++i )
      {
         if ( y[i] != k )
         {
            continue;
         }

         float dist = vectorDiffNorm(&X[i], &means[k]);

         S += dist * dist;
      }
   }

   return -S;
}






/**
 * Compute a K-means clustering model from a dataset.
 */
void fit(
   __global const Vector2 *X, int N, int K,
   __global char *y,
   float *logL,
   __global Vector2 *means,
   __global char *y_next)
{
   ulong state = 1;

   // initialize means randomly from X
   for ( int k = 0; k < K; ++k )
{'fraction_non_alphanumeric': 0.1618129218900675, 'fraction_numerical': 0.023915139826422373, 'mean_word_length': 1.9668192219679634, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 27, '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': '1961171', 'n_tokens_mistral': 2086, 'n_tokens_neox': 1902, 'n_words': 568}