int core_oph_quantile (oph_stringPtr byte_array, char *result)
{
#ifdef GSL_SUPPORTED
	if (!byte_array || (byte_array->param<0.0) || (byte_array->param>1.0))
	{
		pmesg(1, __FILE__, __LINE__, "Wrong parameter\n");
		return -1;
	}
        int k;
        switch(byte_array->type)
	{
                case OPH_DOUBLE:{
			double sum;
			memcpy(byte_array->extend, byte_array->content, *byte_array->length);
			gsl_sort((double*)byte_array->extend,1,byte_array->numelem);
			double delta = (byte_array->numelem-1) * byte_array->param;
			k = floor(delta);
			delta = delta - k;
			sum = (1-delta) * (*(((double*)byte_array->extend)+k)) + delta * (*(((double*)byte_array->extend)+k+1));
			memcpy(result, (void*)(&sum), core_sizeof(OPH_DOUBLE));
                        break;
                }
                case OPH_FLOAT:{
			float sum;
			memcpy(byte_array->extend, byte_array->content, *byte_array->length);
                        gsl_sort_float((float*)byte_array->extend,1,byte_array->numelem);
			float delta = (byte_array->numelem-1) * byte_array->param;
			k = floor(delta);
			delta = delta - k;
			sum = (1-delta) * (*(((float*)byte_array->extend)+k)) + delta * (*(((float*)byte_array->extend)+k+1));
			memcpy(result, (void*)(&sum), core_sizeof(OPH_FLOAT));
                        break;
                }
                case OPH_INT:{
			float sum; //The quantile is a float number
			memcpy(byte_array->extend, byte_array->content, *byte_array->length);
			gsl_sort_int((int*)byte_array->extend,1,byte_array->numelem);
			float delta = (byte_array->numelem-1) * byte_array->param;
			k = floor(delta);
			delta = delta - k;
			sum = (1-delta) * (*(((int*)byte_array->extend)+k)) + delta * (*(((int*)byte_array->extend)+k+1));
			memcpy(result, (void*)(&sum), core_sizeof(OPH_FLOAT));
                        break;
                }
                case OPH_SHORT:{
			float sum; //The quantile is a float number
			memcpy(byte_array->extend, byte_array->content, *byte_array->length);
			gsl_sort_short((short*)byte_array->extend,1,byte_array->numelem);
			float delta = (byte_array->numelem-1) * byte_array->param;
			k = floor(delta);
			delta = delta - k;
			sum = (1-delta) * (*(((short*)byte_array->extend)+k)) + delta * (*(((short*)byte_array->extend)+k+1));
			memcpy(result, (void*)(&sum), core_sizeof(OPH_FLOAT));
                        break;
                }
                case OPH_BYTE:{
			float sum; //The quantile is a float number
			memcpy(byte_array->extend, byte_array->content, *byte_array->length);
			gsl_sort_char((char*)byte_array->extend,1,byte_array->numelem);
			float delta = (byte_array->numelem-1) * byte_array->param;
			k = floor(delta);
			delta = delta - k;
			sum = (1-delta) * (*(((char*)byte_array->extend)+k)) + delta * (*(((char*)byte_array->extend)+k+1));
			memcpy(result, (void*)(&sum), core_sizeof(OPH_FLOAT));
                        break;
                }
		case OPH_LONG:{
			double sum; //The quantile is a double number
			memcpy(byte_array->extend, byte_array->content, *byte_array->length);
			gsl_sort_long((long*)byte_array->extend,1,byte_array->numelem);
			double delta = (byte_array->numelem-1) * byte_array->param;
			k = floor(delta);
			delta = delta - k;
			sum = (1-delta) * (*(((long long*)byte_array->extend)+k)) + delta * (*(((long long*)byte_array->extend)+k+1));
			memcpy(result, (void*)(&sum), core_sizeof(OPH_DOUBLE));
                        break;
                }
                default:
                        pmesg(1, __FILE__, __LINE__, "Type non recognized\n");
                        return -1;
        }
        return 0;
#else
	pmesg(1, __FILE__, __LINE__, "Operation not allowed\n");
	return -1;
#endif
}
Exemplo n.º 2
0
static void
test_bst_int(const size_t n, const gsl_bst_type * T, const enum array_order order, gsl_rng * r)
{
  int *data = malloc(n * sizeof(int));
  int *data_delete = malloc(n * sizeof(int));
  int *sorted_data = malloc(n * sizeof(int));
  gsl_bst_workspace * w = gsl_bst_alloc(T, NULL, compare_ints, NULL);
  gsl_bst_trav trav;
  int *p;
  int i;
  size_t nodes;

  /* generate data to be inserted in tree */
  gen_int_array(n, order, data, r);

  for (i = 0; i < (int) n; ++i)
    sorted_data[i] = data[i];

  gsl_sort_int(sorted_data, 1, n);

  if (order != ORD_RANDOM_DUP)
    {
      /* generate random order to delete data from tree */
      gen_int_array(n, ORD_RANDOM, data_delete, r);
    }
  else
    {
      for (i = 0; i < (int) n; ++i)
        data_delete[i] = sorted_data[i];
    }

  /* insert data */
  for (i = 0; i < (int) n; ++i)
    {
      p = gsl_bst_insert(&data[i], w);
      gsl_test(p != NULL, "bst_int %s[n=%zu,order=%d] insert i=%d", gsl_bst_name(w), n, order, i);
    }

  if (order != ORD_RANDOM_DUP)
    {
      nodes = gsl_bst_nodes(w);
      gsl_test(nodes != n, "bst_int %s[n=%zu,order=%d] after insertion count = %zu/%zu",
               gsl_bst_name(w), n, order, nodes, n);
    }

  /* test data was inserted and can be found */
  for (i = 0; i < (int) n; ++i)
    {
      p = gsl_bst_find(&data[i], w);
      gsl_test(*p != data[i], "bst_int %s[n=%zu,order=%d] find [%d,%d]",
               gsl_bst_name(w), n, order, *p, data[i]);

      p = gsl_bst_trav_find(&data[i], &trav, w);
      gsl_test(p == NULL, "bst_int %s[n=%zu,order=%d] trav_find unable to find item %d",
               gsl_bst_name(w), n, order, data[i]);

      check_traverser(n, order, &trav, data[i], "post-insertion", w);
    }

  /* traverse tree in-order */
  p = gsl_bst_trav_first(&trav, w);
  i = 0;
  while (p != NULL)
    {
      int *q = gsl_bst_trav_cur(&trav);

      gsl_test(*p != sorted_data[i], "bst_int %s[n=%zu,order=%d] traverse i=%d [%d,%d]",
               gsl_bst_name(w), n, order, i, *p, sorted_data[i]);

      gsl_test(*p != *q, "bst_int %s[n=%zu,order=%d] traverse cur i=%d [%d,%d]",
               gsl_bst_name(w), n, order, i, *p, *q);

      p = gsl_bst_trav_next(&trav);
      ++i;
    }

  gsl_test(i != (int) n, "bst_int %s[n=%zu,order=%d] traverse number=%d",
           gsl_bst_name(w), n, order, i);

  /* traverse tree in reverse order */
  p = gsl_bst_trav_last(&trav, w);
  i = n - 1;
  while (p != NULL)
    {
      int *q = gsl_bst_trav_cur(&trav);

      gsl_test(*p != sorted_data[i], "bst_int %s[n=%zu,order=%d] traverse reverse i=%d [%d,%d]",
               gsl_bst_name(w), n, order, i, *p, sorted_data[i]);

      gsl_test(*p != *q, "bst_int %s[n=%zu,order=%d] traverse reverse cur i=%d [%d,%d]",
               gsl_bst_name(w), n, order, i, *p, *q);

      p = gsl_bst_trav_prev(&trav);
      --i;
    }

  gsl_test(i != -1, "bst_int %s[n=%zu,order=%d] traverse reverse number=%d",
           gsl_bst_name(w), n, order, i);

  /* test traversal during tree modifications */
  for (i = 0; i < (int) n; ++i)
    {
      gsl_bst_trav x, y, z;

      gsl_bst_trav_find(&data[i], &x, w);
      check_traverser(n, order, &x, data[i], "pre-deletion", w);

      if (data[i] == data_delete[i])
        continue;

      p = gsl_bst_remove(&data_delete[i], w);
      gsl_test(*p != data_delete[i], "bst_int %s[n=%zu,order=%d] remove i=%d [%d,%d]",
               gsl_bst_name(w), n, order, i, *p, data_delete[i]);

      p = gsl_bst_trav_copy(&y, &x);
      gsl_test(*p != data[i], "bst_int %s[n=%zu,order=%d] copy i=%d [%d,%d]",
               gsl_bst_name(w), n, order, i, *p, data[i]);

      /* re-insert item */
      p = gsl_bst_trav_insert(&data_delete[i], &z, w);

      check_traverser(n, order, &x, data[i], "post-deletion", w);
      check_traverser(n, order, &y, data[i], "copied", w);
      check_traverser(n, order, &z, data_delete[i], "insertion", w);

#if 0
      /* delete again */
      gsl_bst_remove(&data[i], w);
#endif
    }

  /* emmpty tree */
  gsl_bst_empty(w);

  nodes = gsl_bst_nodes(w);
  gsl_test(nodes != 0, "bst_int %s[n=%zu,order=%d] empty count = %zu",
           gsl_bst_name(w), n, order, nodes);

  gsl_bst_free(w);
  free(data);
  free(data_delete);
  free(sorted_data);
}