Exemplo n.º 1
0
//
// compute prefix sums of a grid
// 
prefix_sums *compute_psums(grid *g)
{
   // allocate structure 
   prefix_sums *p = (prefix_sums *) ALLOC(prefix_sums);
   p->gridref = g;
   
   // allocate memory for prefix sums
   int size = g->width * g->height; 
   p->A = (cell *) ALLOCV(cell,size);
   p->B = (cell *) ALLOCV(cell,size);
   p->X = (cell *) ALLOCV(cell,size);
   p->Y = (cell *) ALLOCV(cell,size);

   // fill in computation
   compute_sumA(p);
   compute_sumB(p);
   compute_sumX(p);
   compute_sumY(p);

   // check whether results are correct
   assert (check_sumA(p) && "computation of prefix A failed");
   assert (check_sumB(p) && "computation of prefix B failed");
   assert (check_sumX(p) && "computation of prefix X failed");
   assert (check_sumY(p) && "computation of prefix Y failed");

   return p;
}
Exemplo n.º 2
0
//
// naive implementation of LRT
//
// the complexity of the naive implementation is O(n^6) and
// hence not practical for larger grids.
//
// Steps:
//   1. allocate memory for resulting rectangles and their scores
//   2. compute grid totals
//   2. compute lrt for each rectangle
//     2.a) compute rectangle total
//     2.b) compute score
//   3. sort all rectangles according to their score
//
rectangle *naive_lrt(grid *g,int kbest)
{
    int idx=0;           // output index
    int i,j;             // index for regions in grid

    // set width and height
    int width=g->width;
    int height=g->height;

    // compute number of rectangles in the grid and allocate
    // memory to store result
    size_t size = (size_t)(width + 1) *
                  (size_t)width  *
                  (size_t)(height + 1) *
                  (size_t)height / 4;
    rectangle *r = (rectangle *) ALLOCV(rectangle,size);

    // compute grid totals, ratio, and likelihood
    int g_n = 0;
    int g_k = 0;
    for (i=0; i<height; i++) {
        for (j=0; j<width; j++) {
            g_n += g->cells[I(i,j)].n;
            g_k += g->cells[I(i,j)].k;
        }
    }
    float g_q = (float)g_k / (float)g_n;
    float g_l = g_k * log(g_q);

    // compute LRT for all rectangle in grid
    int j1,i1,j2,i2;  // coordinates of a rectangle
    for (i1=0; i1<height; i1++) {
        for (j1=0; j1<width; j1++) {
            for (i2=i1; i2<height; i2++) {
                for (j2=j1; j2<width; j2++) {

                    // set rectangle width and height
                    int r_width = j2 - j1 + 1;
                    int r_height = i2 - i1 + 1;

                    // compute rectangle totals, ratio and likelihood
                    int r_n=0;
                    int r_k=0;
                    cell *c = &g->cells[i1*width+j1];
                    for (i=0; i<r_height; i++) {
                        for (j=0; j<r_width; j++) {
                            r_n += c[I(i,j)].n;
                            r_k += c[I(i,j)].k;
                        }
                    }
                    float r_q = (float)r_k / (float)r_n;
                    float r_l = r_k * log(r_q) - r_k;

                    // compute rectangle's complement totals, ratio, and likelihood
                    int   c_n = g_n - r_n;
                    int   c_k = g_k - r_k;
                    float c_q = (float)c_k / (float)c_n;
                    float c_l = c_k * log(c_q) - c_k;

                    // compute score
                    float score = r_l + c_l - g_l;

                    // store result in array r
                    r[idx].score = score;
                    r[idx].i1 = i1;
                    r[idx].j1 = j1;
                    r[idx].i2 = i2;
                    r[idx].j2 = j2;
                    idx = idx + 1;
                }
            }
        }
    }

    // sort result and return it
    qsort(r,size,sizeof(rectangle),rectangle_compare);
    return r;
}
Exemplo n.º 3
0
//
// fast implementation of LRT using prefix sums
//
rectangle *fast_lrt(grid *g,int kbest)
{
   // heap size (initialized with zero and grows up to kbest)
   int heap_size=0;  

   // set width and height
   int width = g->width;
   int height = g->height;

   // allocate heap with size k
   rectangle *r = (rectangle *) ALLOCV(rectangle,kbest);
   
   // compute prefix sums
   prefix_sums *p = compute_psums(g);

   // compute grid totals, ratio, and likelihood
   int g_n = p->A[width * height - 1].n;
   int g_k = p->A[width * height - 1].k;
   float g_q = (float)g_k / (float)g_n;
   float g_l = g_k * log(g_q);
   
   // compute LRT for each rectangle
   int j1,i1,j2,i2;                       // coordinates of a rectangle
   for (i1=0;i1<height;i1++){ 
      for (j1=0;j1<width;j1++){
         for (i2=i1;i2<height;i2++){ 
            for (j2=j1;j2<width;j2++){ 
               
               // compute rectangle totals, ratio and likelihood
               int   a_n = p->A[I(i2,j2)].n;
               int   a_k = p->A[I(i2,j2)].k;
               int   b_n = p->B[I(i1,j1)].n;
               int   b_k = p->B[I(i1,j1)].k;
               int   y_n = p->Y[I(i1,j2)].n;
               int   y_k = p->Y[I(i1,j2)].k;
               int   x_n = p->X[I(i2,j1)].n;
               int   x_k = p->X[I(i2,j1)].k;
               int   r_n = a_n + b_n + x_n + y_n - g_n;
               int   r_k = a_k + b_k + x_k + y_k - g_k;
               float r_q = (float)r_k / (float)r_n;
               float r_l = r_k * log(r_q) - r_k; 
               
               // check whether prefix sums are correct
               #if DEBUG_LEVEL > 0
               int t_n=0; 
               int t_k=0; 
               int i,j;
               int r_width = j2 - j1 + 1; 
               int r_height = i2 - i1 + 1; 
               cell *c = &g->cells[i1*width+j1]; 
               for (i=0;i<r_height;i++) { 
                  for (j=0;j<r_width;j++) { 
                     t_n += c[I(i,j)].n; 
                     t_k += c[I(i,j)].k; 
                  }  
               } 
               assert((t_n == r_n && t_k == r_k) && "problems with prefix");
               #endif

               // compute rectangle's complement totals, ratio, and likelihood
               int   c_n = g_n - r_n;
               int   c_k = g_k - r_k;
               float c_q = (float)c_k / (float)c_n;
               float c_l = c_k * log(c_q) - c_k;
               
               // compute score 
               float score = r_l + c_l - g_l; 

               // populate current rectangle
               rectangle current;
               current.score = score; 
               current.i1 = i1;
               current.j1 = j1;
               current.i2 = i2;
               current.j2 = j2;
                  
               // store result in heap
               // if the heap size is still smaller than kbest, add rectangle to the end of the heap
               // and rise the last element until the heap condition holds 
               if (heap_size < kbest) { 
                  r[heap_size].score = score; 
                  r[heap_size].j1 = j1;
                  r[heap_size].i1 = i1;
                  r[heap_size].j2 = j2;
                  r[heap_size].i2 = i2;
                  heap_size = heap_size + 1;
                  minheap_rise(r,heap_size,sizeof(rectangle),heap_rcmp);
               // otherwise check whether the current score is greater than the smallest element (=first element) 
               // if so, replace the first element with current rectangle and sink the current element until 
               // the heap condition holds. 
               } else if (heap_rcmp(&current,r) > 0) {
                  r[0] = current;
                  minheap_sink(r,kbest,sizeof(rectangle),heap_rcmp);
               } 
            }
         } 
      }
   }

   // sort result and return it
   qsort(r,kbest,sizeof(rectangle),rectangle_compare);

   return r; 
}
Exemplo n.º 4
0
static VALUE
function_call(int argc, VALUE argv[], VALUE self)
{
    struct nogvl_ffi_call_args args = { 0 };
    fiddle_generic *generic_args;
    VALUE cfunc, types, cPointer;
    int i;
    VALUE alloc_buffer = 0;

    cfunc    = rb_iv_get(self, "@ptr");
    types    = rb_iv_get(self, "@args");
    cPointer = rb_const_get(mFiddle, rb_intern("Pointer"));

    Check_Max_Args("number of arguments", argc);
    if (argc != (i = RARRAY_LENINT(types))) {
	rb_error_arity(argc, i, i);
    }

    TypedData_Get_Struct(self, ffi_cif, &function_data_type, args.cif);

    if (rb_safe_level() >= 1) {
	for (i = 0; i < argc; i++) {
	    VALUE src = argv[i];
	    if (OBJ_TAINTED(src)) {
		rb_raise(rb_eSecurityError, "tainted parameter not allowed");
	    }
	}
    }

    generic_args = ALLOCV(alloc_buffer,
	(size_t)(argc + 1) * sizeof(void *) + (size_t)argc * sizeof(fiddle_generic));
    args.values = (void **)((char *)generic_args +
			    (size_t)argc * sizeof(fiddle_generic));

    for (i = 0; i < argc; i++) {
	VALUE type = RARRAY_AREF(types, i);
	VALUE src = argv[i];
	int argtype = FIX2INT(type);

	if (argtype == TYPE_VOIDP) {
	    if(NIL_P(src)) {
		src = INT2FIX(0);
	    } else if(cPointer != CLASS_OF(src)) {
		src = rb_funcall(cPointer, rb_intern("[]"), 1, src);
	    }
	    src = rb_Integer(src);
	}

	VALUE2GENERIC(argtype, src, &generic_args[i]);
	args.values[i] = (void *)&generic_args[i];
    }
    args.values[argc] = NULL;
    args.fn = NUM2PTR(cfunc);

    (void)rb_thread_call_without_gvl(nogvl_ffi_call, &args, 0, 0);

    rb_funcall(mFiddle, rb_intern("last_error="), 1, INT2NUM(errno));
#if defined(_WIN32)
    rb_funcall(mFiddle, rb_intern("win32_last_error="), 1, INT2NUM(errno));
#endif

    ALLOCV_END(alloc_buffer);

    return GENERIC2VALUE(rb_iv_get(self, "@return_type"), args.retval);
}