예제 #1
0
static VlHIKMNode *
xcreate (VlHIKMTree *tree, mxArray const *mnode, int i)
{
  mxArray const *mcenters, *msub ;
  VlHIKMNode *node ;
  vl_size M, node_K ;
  vl_uindex k ;

  /* sanity checks */
  mcenters = mxGetField(mnode, i, "centers") ;
  msub     = mxGetField(mnode, i, "sub") ;

  if (!mcenters                                 ||
      mxGetClassID (mcenters) != mxINT32_CLASS  ||
      !vlmxIsMatrix (mcenters, -1, -1)             ) {
    mexErrMsgTxt("NODE.CENTERS must be a INT32 matrix.") ;
  }

  M      = mxGetM (mcenters) ;
  node_K = mxGetN (mcenters) ;

  if (node_K > (vl_size)tree->K) {
    mexErrMsgTxt("A node has more clusters than TREE.K.") ;
  }

  if (tree->M < 0) {
    tree->M = M ;
  } else if (M != (vl_size)tree->M) {
    mexErrMsgTxt("A node CENTERS field has inconsistent dimensionality.") ;
  }

  node           = mxMalloc (sizeof(VlHIKMNode)) ;
  node->filter   = vl_ikm_new (tree->method) ;
  node->children = 0 ;

  vl_ikm_init (node->filter, mxGetData(mcenters), M, node_K) ;

  /* has any childer? */
  if (msub) {

    /* sanity checks */
    if (mxGetClassID (msub) != mxSTRUCT_CLASS) {
      mexErrMsgTxt("NODE.SUB must be a MATLAB structure array.") ;
    }
    if (mxGetNumberOfElements (msub) != node_K) {
      mexErrMsgTxt("NODE.SUB size must correspond to NODE.CENTERS.") ;
    }

    node-> children = mxMalloc (sizeof(VlHIKMNode *) * node_K) ;
    for(k = 0 ; k < node_K ; ++ k) {
      node-> children [k] = xcreate (tree, msub, k) ;
    }
  }
  return node ;
}
예제 #2
0
static VlHIKMNode *
xcreate(VlHIKMTree *tree, VlHIKMTree_python & inTree)
{
	VlHIKMNode *node;
	int M, node_K, k;

	PyArrayObject * centers = (PyArrayObject *) inTree.centers;
	M = centers->dimensions[0];
	node_K = centers->dimensions[1];

	if (node_K > tree->K) {
		printf("%d / %d\n", node_K, tree->K);
		printf("A node has more clusters than TREE.K.\n");
	}

	if (tree->M < 0) {
		tree->M = M;
	} else if (M != tree->M) {
		printf("%d / %d\n", M, tree->M);
		printf("A node CENTERS field has inconsistent dimensionality.\n");
	}

	node = new VlHIKMNode;
	node->filter = vl_ikm_new(tree->method);
	node->children = 0;

	vl_ikm_init(node->filter, (vl_ikm_acc*) centers->data, M, node_K);

	/* has any childer? */
	if (inTree.sub.size() > 0) {

		/* sanity checks */
		if (inTree.sub.size() != node_K) {
			printf("%d, %d\n", (int)inTree.sub.size(), node_K);
			printf("NODE.SUB size must correspond to NODE.CENTERS.\n");
		}

		node-> children = new VlHIKMNode*[node_K];
		for (k = 0; k < node_K; ++k) {
			PyArrayObject * centers = (PyArrayObject *) inTree.sub[k].centers;
			node-> children[k] = xcreate(tree, inTree.sub[k]);
		}
	}
	return node;
}
예제 #3
0
/* driver */
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  enum {IN_X=0,IN_C,IN_END} ;
  enum {OUT_ASGN=0} ;
  vl_uint*     asgn ;
  vl_ikm_acc*  centers ;
  vl_uint8* data ;

  int M,N,j,K=0 ;

  int             opt ;
  int             next = IN_END ;
  mxArray const  *optarg ;

  int method_type = VL_IKM_LLOYD ;
  int verb = 0 ;

  VlIKMFilt *ikmf ;

  VL_USE_MATLAB_ENV ;

  /** -----------------------------------------------------------------
   **                                               Check the arguments
   ** -------------------------------------------------------------- */

  if (nin < 2) {
    mexErrMsgTxt("At least two arguments required.") ;
  } else if (nout > 2) {
    mexErrMsgTxt("Too many output arguments.") ;
  }

  if(mxGetClassID(in[IN_X]) != mxUINT8_CLASS) {
    mexErrMsgTxt("X must be of class UINT8") ;
  }

  if(mxGetClassID(in[IN_C]) != mxINT32_CLASS) {
    mexErrMsgTxt("C must be of class INT32") ;
  }

  M = mxGetM(in[IN_X]) ;  /* n of components */
  N = mxGetN(in[IN_X]) ;  /* n of elements */
  K = mxGetN(in[IN_C]) ;  /* n of centers */

  if( (int) mxGetM(in[IN_C]) != M ) {
    mexErrMsgTxt("DATA and CENTERS must have the same number of columns.") ;
  }

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    char buf [1024] ;

    switch (opt) {

    case opt_verbose :
      ++ verb ;
      break ;

    case opt_method :
      if (!vlmxIsString (optarg, -1)) {
        mexErrMsgTxt("'Method' must be a string.") ;
      }
      if (mxGetString (optarg, buf, sizeof(buf))) {
        mexErrMsgTxt("Option argument too long.") ;
      }
      if (strcmp("lloyd", buf) == 0) {
        method_type = VL_IKM_LLOYD ;
      } else if (strcmp("elkan", buf) == 0) {
        method_type = VL_IKM_ELKAN ;
      } else {
        mexErrMsgTxt("Unknown cost type.") ;
      }

      break ;

    default :
      abort() ;
    }
  }

  /** -----------------------------------------------------------------
   **                                               Check the arguments
   ** -------------------------------------------------------------- */

  if (verb) {
    char const * method_name = 0 ;
    switch (method_type) {
    case VL_IKM_LLOYD: method_name = "Lloyd" ; break ;
    case VL_IKM_ELKAN: method_name = "Elkan" ; break ;
    default :
      abort() ;
    }
    mexPrintf("ikmeanspush: Method = %s\n", method_name) ;
    mexPrintf("ikmeanspush: ndata  = %d\n", N) ;
  }

  out[OUT_ASGN] = mxCreateNumericMatrix (1, N, mxUINT32_CLASS, mxREAL) ;

  data    = (vl_uint8*) mxGetData (in[IN_X]) ;
  centers = (vl_ikm_acc*)  mxGetData (in[IN_C]) ;
  asgn    = (vl_uint*)     mxGetData (out[OUT_ASGN]) ;
  ikmf    = vl_ikm_new (method_type) ;

  vl_ikm_set_verbosity  (ikmf, verb) ;
  vl_ikm_init           (ikmf, centers, M, K) ;
  vl_ikm_push           (ikmf, asgn, data, N) ;

  /* adjust for MATLAB indexing */
  for(j = 0 ; j < N ; ++j) ++ asgn[j] ;

  vl_ikm_delete (ikmf) ;
}
void ikm()
{
	const vl_size data_dim = 2;
	const vl_size num_data = 1000;

	vl_uint8 data[data_dim * num_data] = { 0, };
	for (vl_size i = 0; i < data_dim * num_data; ++i)
		data[i] = (vl_uint8)std::floor((((float)std::rand() / RAND_MAX) * 255) + 0.5f);

	//
	std::cout << "start processing ..." << std::endl;

	const vl_size num_clusters = 3;
	const VlIKMAlgorithms algorithm = VL_IKM_LLOYD;  // VL_IKM_LLOYD, VL_IKM_ELKAN.
	const vl_size num_max_iterations = 100;

	VlIKMFilt *ikm = vl_ikm_new(algorithm);

	vl_ikm_set_max_niters(ikm, num_max_iterations);

	// initialization.
#if 1
	vl_ikm_init_rand(ikm, data_dim, num_clusters);
#elif 0
	vl_ikm_init_rand_data(ikm, data, data_dim, num_data, num_clusters);
#else
	vl_ikm_acc init_centers[data_dim * num_clusters] = { 0, };
	for (vl_size i = 0; i < data_dim * num_clusters; ++i)
		init_centers[i] = (vl_ikm_acc)std::floor((((float)std::rand() / RAND_MAX) * 255) + 0.5f);
	vl_ikm_init(ikm, init_centers, data_dim, num_clusters);
#endif

	// training.
	if (-1 != vl_ikm_train(ikm, data, num_data))
	{
		const vl_ikmacc_t *centers = vl_ikm_get_centers(ikm);
		for (int i = 0; i < num_clusters; ++i)
		{
			std::cout << '(';
			for (int j = 0; j < data_dim; ++j)
			{
				if (j) std::cout << ',';
				std::cout << (int)centers[i * data_dim + j];
			}
			std::cout << ')' << std::endl;
		}

		//
		{
			vl_uint assignments[num_data] = { 0, };
			vl_ikm_push(ikm, assignments, data, num_data);
			for (int i = 0; i < num_data; ++i)
			{
				std::cout << '(';
				for (int j = 0; j < data_dim; ++j)
				{
					if (j) std::cout << ',';
					std::cout << (int)data[i * data_dim + j];  // TODO [check] >> is it correct?
				}
				std::cout << ") => " << assignments[i] << std::endl;
			}
		}

		// testing.
		{
			vl_uint8 test_sample[data_dim] = { 0, };
			for (vl_size i = 0; i < data_dim; ++i)
				test_sample[i] = (vl_uint8)std::floor((((float)std::rand() / RAND_MAX) * 255) + 0.5f);
			const vl_uint assignment = vl_ikm_push_one(centers, test_sample, data_dim, num_clusters);
		}
	}
	else
	{
		std::cerr << "an overflow may have occurred." << std::endl;
	}

	std::cout << "end processing ..." << std::endl;

	//
	if (ikm)
	{
		vl_ikm_delete(ikm);
		ikm = NULL;
	}
}
예제 #5
0
PyObject * vl_ikmeanspush_python(
		PyArrayObject & inputData,
		PyArrayObject & centers,
		char * method,
		int verb)
{

	// check types
	assert(inputData.descr->type_num == PyArray_UBYTE);
	assert(inputData.flags & NPY_FORTRAN);
	assert(centers.descr->type_num == PyArray_INT32);
	assert(centers.flags & NPY_FORTRAN);

	vl_ikm_acc* centers_data = (vl_ikm_acc *) centers.data;
	vl_uint8 * data = (vl_uint8 *) inputData.data;

	int j;
	npy_intp M, N, K = 0;

	VlIKMFilt *ikmf;

	/** -----------------------------------------------------------------
	 **                                               Check the arguments
	 ** -------------------------------------------------------------- */

	M = inputData.dimensions[0]; //mxGetM(in[IN_X]) ;  /* n of components */
	N = inputData.dimensions[1]; //mxGetN(in[IN_X]) ;  /* n of elements */
	K = centers.dimensions[1]; //mxGetN(in[IN_C]) ;  /* n of centers */

	if (centers.dimensions[0] != M) {
		printf("DATA and CENTERS must have the same number of columns.");
	}

	int method_type = VL_IKM_LLOYD;

	if (strcmp("lloyd", method) == 0) {
		method_type = VL_IKM_LLOYD;
	} else if (strcmp("elkan", method) == 0) {
		method_type = VL_IKM_ELKAN;
	} else {
		assert(0);
	}

	/** -----------------------------------------------------------------
	 **                                               Check the arguments
	 ** -------------------------------------------------------------- */

	if (verb) {
		char const * method_name = 0;
		switch (method_type) {
		case VL_IKM_LLOYD:
			method_name = "Lloyd";
			break;
		case VL_IKM_ELKAN:
			method_name = "Elkan";
			break;
		default:
			assert (0);
		}
		printf("ikmeanspush: Method = %s\n", method_name);
		printf("ikmeanspush: ndata  = %d\n", (int)N);
	}

	PyArrayObject * asgn = (PyArrayObject *) PyArray_SimpleNew(
			1, (npy_intp*) &N, PyArray_UINT32);
	unsigned int * asgn_data = (unsigned int*) asgn->data;

	ikmf = vl_ikm_new(method_type);

	vl_ikm_set_verbosity(ikmf, verb);
	vl_ikm_init(ikmf, centers_data, M, K);
	vl_ikm_push(ikmf, asgn_data, data, N);

	vl_ikm_delete(ikmf);

	return PyArray_Return(asgn);
}