void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])

{
			
	unsigned char *X8, *B8; double *X, *B; int N;
	
	int k;
	
	double *y;
	
	//--
	// UINT8 image
	//--

	if (mxIsUint8(prhs[0])) {

		//--
		// INPUT
		//--

		// input image

		X8 = (unsigned char *) mxGetPr(prhs[0]);
		N = mxGetM(prhs[0]) * mxGetN(prhs[0]);

  		//--
  		// OUTPUT
  		//--
    	
    	// median
  		  		
  		y = mxGetPr(plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL));
  		
		//--
		// COMPUTATION
		//--

		// buffer image
    	    
		B8 = mxCalloc(N,sizeof(unsigned char));
	    	
		for (k = 0; k < N; k++) {
			*(B8 + k) = *(X8 + k);
		}
  		
  		// compute median
  		
	  	if (N % 2) {
	  		*y = (double) median_uint8(B8,N);
	  	} else {
	  		*y = ((double) kth_smallest_uint8(B8,N,N/2 - 1) + 
				(double) kth_smallest_uint8(B8,N,N/2)) / 2.0;
	  	}

	} else {

		//--
		// INPUT
		//--

		// input image

		X = mxGetPr(prhs[0]);
		N = mxGetM(prhs[0]) * mxGetN(prhs[0]);

  		//--
  		// OUTPUT
  		//--
    	
    	// median
  		  		
  		y = mxGetPr(plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL));
  		
		//--
		// COMPUTATION
		//--

		// buffer image
    	    
		B = mxCalloc(N,sizeof(double));
	    	
		for (k = 0; k < N; k++) {
			*(B + k) = *(X + k);
		}
  		
  		// compute median
  		
	  	if (N % 2) {
	  		*y = median_double(B,N);
	  	} else {
	  		*y = (kth_smallest_double(B,N,N/2 - 1) + kth_smallest_double(B,N,N/2)) / 2.0;
	  	}

	}

}
Beispiel #2
0
/** Look through the routerlist, the Mean Time Between Failure history, and
 * the Weighted Fractional Uptime history, and use them to set thresholds for
 * the Stable, Fast, and Guard flags.  Update the fields stable_uptime,
 * stable_mtbf, enough_mtbf_info, guard_wfu, guard_tk, fast_bandwidth,
 * guard_bandwidth_including_exits, and guard_bandwidth_excluding_exits.
 *
 * Also, set the is_exit flag of each router appropriately. */
void
dirserv_compute_performance_thresholds(digestmap_t *omit_as_sybil)
{
  int n_active, n_active_nonexit, n_familiar;
  uint32_t *uptimes, *bandwidths_kb, *bandwidths_excluding_exits_kb;
  long *tks;
  double *mtbfs, *wfus;
  smartlist_t *nodelist;
  time_t now = time(NULL);
  const or_options_t *options = get_options();

  /* Require mbw? */
  int require_mbw =
    (dirserv_get_last_n_measured_bws() >
     options->MinMeasuredBWsForAuthToIgnoreAdvertised) ? 1 : 0;

  /* initialize these all here, in case there are no routers */
  stable_uptime = 0;
  stable_mtbf = 0;
  fast_bandwidth_kb = 0;
  guard_bandwidth_including_exits_kb = 0;
  guard_bandwidth_excluding_exits_kb = 0;
  guard_tk = 0;
  guard_wfu = 0;

  nodelist_assert_ok();
  nodelist = nodelist_get_list();

  /* Initialize arrays that will hold values for each router.  We'll
   * sort them and use that to compute thresholds. */
  n_active = n_active_nonexit = 0;
  /* Uptime for every active router. */
  uptimes = tor_calloc(smartlist_len(nodelist), sizeof(uint32_t));
  /* Bandwidth for every active router. */
  bandwidths_kb = tor_calloc(smartlist_len(nodelist), sizeof(uint32_t));
  /* Bandwidth for every active non-exit router. */
  bandwidths_excluding_exits_kb =
    tor_calloc(smartlist_len(nodelist), sizeof(uint32_t));
  /* Weighted mean time between failure for each active router. */
  mtbfs = tor_calloc(smartlist_len(nodelist), sizeof(double));
  /* Time-known for each active router. */
  tks = tor_calloc(smartlist_len(nodelist), sizeof(long));
  /* Weighted fractional uptime for each active router. */
  wfus = tor_calloc(smartlist_len(nodelist), sizeof(double));

  /* Now, fill in the arrays. */
  SMARTLIST_FOREACH_BEGIN(nodelist, node_t *, node) {
    if (options->BridgeAuthoritativeDir &&
        node->ri &&
        node->ri->purpose != ROUTER_PURPOSE_BRIDGE)
      continue;

    routerinfo_t *ri = node->ri;
    if (ri) {
      node->is_exit = (!router_exit_policy_rejects_all(ri) &&
                       exit_policy_is_general_exit(ri->exit_policy));
    }

    if (router_counts_toward_thresholds(node, now, omit_as_sybil,
                                        require_mbw)) {
      const char *id = node->identity;
      uint32_t bw_kb;

      /* resolve spurious clang shallow analysis null pointer errors */
      tor_assert(ri);

      uptimes[n_active] = (uint32_t)real_uptime(ri, now);
      mtbfs[n_active] = rep_hist_get_stability(id, now);
      tks  [n_active] = rep_hist_get_weighted_time_known(id, now);
      bandwidths_kb[n_active] = bw_kb = dirserv_get_credible_bandwidth_kb(ri);
      if (!node->is_exit || node->is_bad_exit) {
        bandwidths_excluding_exits_kb[n_active_nonexit] = bw_kb;
        ++n_active_nonexit;
      }
      ++n_active;
    }
  } SMARTLIST_FOREACH_END(node);

  /* Now, compute thresholds. */
  if (n_active) {
    /* The median uptime is stable. */
    stable_uptime = median_uint32(uptimes, n_active);
    /* The median mtbf is stable, if we have enough mtbf info */
    stable_mtbf = median_double(mtbfs, n_active);
    /* The 12.5th percentile bandwidth is fast. */
    fast_bandwidth_kb = find_nth_uint32(bandwidths_kb, n_active, n_active/8);
    /* (Now bandwidths is sorted.) */
    if (fast_bandwidth_kb < RELAY_REQUIRED_MIN_BANDWIDTH/(2 * 1000))
      fast_bandwidth_kb = bandwidths_kb[n_active/4];
    guard_bandwidth_including_exits_kb =
      third_quartile_uint32(bandwidths_kb, n_active);
    guard_tk = find_nth_long(tks, n_active, n_active/8);
  }

  if (guard_tk > TIME_KNOWN_TO_GUARANTEE_FAMILIAR)
    guard_tk = TIME_KNOWN_TO_GUARANTEE_FAMILIAR;

  {
    /* We can vote on a parameter for the minimum and maximum. */
#define ABSOLUTE_MIN_VALUE_FOR_FAST_FLAG 4
    int32_t min_fast_kb, max_fast_kb, min_fast, max_fast;
    min_fast = networkstatus_get_param(NULL, "FastFlagMinThreshold",
      ABSOLUTE_MIN_VALUE_FOR_FAST_FLAG,
      ABSOLUTE_MIN_VALUE_FOR_FAST_FLAG,
      INT32_MAX);
    if (options->TestingTorNetwork) {
      min_fast = (int32_t)options->TestingMinFastFlagThreshold;
    }
    max_fast = networkstatus_get_param(NULL, "FastFlagMaxThreshold",
                                       INT32_MAX, min_fast, INT32_MAX);
    min_fast_kb = min_fast / 1000;
    max_fast_kb = max_fast / 1000;

    if (fast_bandwidth_kb < (uint32_t)min_fast_kb)
      fast_bandwidth_kb = min_fast_kb;
    if (fast_bandwidth_kb > (uint32_t)max_fast_kb)
      fast_bandwidth_kb = max_fast_kb;
  }
  /* Protect sufficiently fast nodes from being pushed out of the set
   * of Fast nodes. */
  if (options->AuthDirFastGuarantee &&
      fast_bandwidth_kb > options->AuthDirFastGuarantee/1000)
    fast_bandwidth_kb = (uint32_t)options->AuthDirFastGuarantee/1000;

  /* Now that we have a time-known that 7/8 routers are known longer than,
   * fill wfus with the wfu of every such "familiar" router. */
  n_familiar = 0;

  SMARTLIST_FOREACH_BEGIN(nodelist, node_t *, node) {
      if (router_counts_toward_thresholds(node, now,
                                          omit_as_sybil, require_mbw)) {
        routerinfo_t *ri = node->ri;
        const char *id = ri->cache_info.identity_digest;
        long tk = rep_hist_get_weighted_time_known(id, now);
        if (tk < guard_tk)
          continue;
        wfus[n_familiar++] = rep_hist_get_weighted_fractional_uptime(id, now);
      }
  } SMARTLIST_FOREACH_END(node);
  if (n_familiar)
    guard_wfu = median_double(wfus, n_familiar);
  if (guard_wfu > WFU_TO_GUARANTEE_GUARD)
    guard_wfu = WFU_TO_GUARANTEE_GUARD;

  enough_mtbf_info = rep_hist_have_measured_enough_stability();

  if (n_active_nonexit) {
    guard_bandwidth_excluding_exits_kb =
      find_nth_uint32(bandwidths_excluding_exits_kb,
                      n_active_nonexit, n_active_nonexit*3/4);
  }

  log_info(LD_DIRSERV,
      "Cutoffs: For Stable, %lu sec uptime, %lu sec MTBF. "
      "For Fast: %lu kilobytes/sec. "
      "For Guard: WFU %.03f%%, time-known %lu sec, "
      "and bandwidth %lu or %lu kilobytes/sec. "
      "We%s have enough stability data.",
      (unsigned long)stable_uptime,
      (unsigned long)stable_mtbf,
      (unsigned long)fast_bandwidth_kb,
      guard_wfu*100,
      (unsigned long)guard_tk,
      (unsigned long)guard_bandwidth_including_exits_kb,
      (unsigned long)guard_bandwidth_excluding_exits_kb,
      enough_mtbf_info ? "" : " don't");

  tor_free(uptimes);
  tor_free(mtbfs);
  tor_free(bandwidths_kb);
  tor_free(bandwidths_excluding_exits_kb);
  tor_free(tks);
  tor_free(wfus);
}
Beispiel #3
0
/** Run unit tests for getting the median of a list. */
static void
test_container_order_functions(void *arg)
{
  int lst[25], n = 0;
  uint32_t lst_2[25];
  //  int a=12,b=24,c=25,d=60,e=77;

#define median() median_int(lst, n)

  (void)arg;
  lst[n++] = 12;
  tt_int_op(12,OP_EQ, median()); /* 12 */
  lst[n++] = 77;
  //smartlist_shuffle(sl);
  tt_int_op(12,OP_EQ, median()); /* 12, 77 */
  lst[n++] = 77;
  //smartlist_shuffle(sl);
  tt_int_op(77,OP_EQ, median()); /* 12, 77, 77 */
  lst[n++] = 24;
  tt_int_op(24,OP_EQ, median()); /* 12,24,77,77 */
  lst[n++] = 60;
  lst[n++] = 12;
  lst[n++] = 25;
  //smartlist_shuffle(sl);
  tt_int_op(25,OP_EQ, median()); /* 12,12,24,25,60,77,77 */
#undef median

#define third_quartile() third_quartile_uint32(lst_2, n)

  n = 0;
  lst_2[n++] = 1;
  tt_int_op(1,OP_EQ, third_quartile()); /* ~1~ */
  lst_2[n++] = 2;
  tt_int_op(2,OP_EQ, third_quartile()); /* 1, ~2~ */
  lst_2[n++] = 3;
  lst_2[n++] = 4;
  lst_2[n++] = 5;
  tt_int_op(4,OP_EQ, third_quartile()); /* 1, 2, 3, ~4~, 5 */
  lst_2[n++] = 6;
  lst_2[n++] = 7;
  lst_2[n++] = 8;
  lst_2[n++] = 9;
  tt_int_op(7,OP_EQ, third_quartile()); /* 1, 2, 3, 4, 5, 6, ~7~, 8, 9 */
  lst_2[n++] = 10;
  lst_2[n++] = 11;
  /* 1, 2, 3, 4, 5, 6, 7, 8, ~9~, 10, 11 */
  tt_int_op(9,OP_EQ, third_quartile());

#undef third_quartile

  double dbls[] = { 1.0, 10.0, 100.0, 1e4, 1e5, 1e6 };
  tt_double_eq(1.0, median_double(dbls, 1));
  tt_double_eq(1.0, median_double(dbls, 2));
  tt_double_eq(10.0, median_double(dbls, 3));
  tt_double_eq(10.0, median_double(dbls, 4));
  tt_double_eq(100.0, median_double(dbls, 5));
  tt_double_eq(100.0, median_double(dbls, 6));

  time_t times[] = { 5, 10, 20, 25, 15 };

  tt_assert(5 == median_time(times, 1));
  tt_assert(5 == median_time(times, 2));
  tt_assert(10 == median_time(times, 3));
  tt_assert(10 == median_time(times, 4));
  tt_assert(15 == median_time(times, 5));

  int32_t int32s[] = { -5, -10, -50, 100 };
  tt_int_op(-5, ==, median_int32(int32s, 1));
  tt_int_op(-10, ==, median_int32(int32s, 2));
  tt_int_op(-10, ==, median_int32(int32s, 3));
  tt_int_op(-10, ==, median_int32(int32s, 4));

  long longs[] = { -30, 30, 100, -100, 7 };
  tt_int_op(7, ==, find_nth_long(longs, 5, 2));

 done:
  ;
}
Beispiel #4
0
double median(int n, double *data)
{
  return median_double(n, data);
}