예제 #1
0
/*{{{  minfunc(optimize_struct *ostructp) {*/
LOCAL OPT_DTYPE
minfunc(optimize_struct *ostructp) {
 struct minfunc_struct *mfs=(struct minfunc_struct *)ostructp->fixed_args;
 int i, N=mfs->nr_of_points;
 OPT_DTYPE x= *((OPT_DTYPE *)ostructp->opt_args);
 OPT_DTYPE *points=mfs->points, sumsq=0.0;

 if (x<=0) return 1e5;
 for (i=0; i<N; i++) {
  sumsq+=square(distfun(points[2*i], x)-points[2*i+1]);
 }

 return sumsq;
}
예제 #2
0
/* the gateway function */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{

  /*  check for proper number of arguments */
    if (nrhs<2) {
        mexErrMsgIdAndTxt("stats:pdistmex:TooFewInputs",
                          "Two input arguments required.");
    } else if(nlhs>1) {
        mexErrMsgIdAndTxt("stats:pdistmex:TooManyOutputs",
                          "Too many output arguments.");
    }

  /* Check the type of the input array */
  /* Currently only works with double or single(float) */
    if (mxIsDouble(prhs[0])) {
        distfun(nlhs, plhs, nrhs, prhs, (double)1.0);
    } else if (mxIsSingle(prhs[0])) {
        distfun(nlhs, plhs, nrhs, prhs, (float)1.0);
    } else {
        mexErrMsgIdAndTxt("stats:pdistmex:BadInputType",
                          "PDISTMEX only supports real DOUBLE and SINGLE data.");
    }
}
예제 #3
0
void veg_distance(double *x, int *nr, int *nc, double *d, int *diag, int *method)
{
    int dc, i, j, ij;
    switch(*method) {
    case MANHATTAN:
    distfun = veg_manhattan;
    break;
    case EUCLIDEAN:
    distfun = veg_euclidean;
    break;
    case CANBERRA:
    distfun = veg_canberra;
    break;
    case BRAY:
    case JACCARD:
    distfun = veg_bray;
    break;
    case KULCZYNSKI:
    distfun = veg_kulczynski;
    break;
    case GOWER:
    distfun = veg_gower;
    break;
    case MORISITA:
    distfun = veg_morisita;
    break;
    case HORN:
    distfun = veg_horn;
    break;
    case MOUNTFORD:
    distfun = veg_mountford;
    break;
    case RAUP:
    distfun = veg_raup;
    break;
    case MILLAR:
    distfun = veg_millar;
    break;
    case CHAO:
    distfun = veg_chao;
    break;
    case GOWERDZ:
    distfun = veg_gowerDZ;
    break;
    case CAO:
        distfun = veg_cao;
        break;
    case MATCHING:
    distfun = veg_matching;
    break;
    case NOSHARED:
    distfun = veg_noshared;
    break;     
    default:
    error("Unknown distance in the internal C function");
    }

    dc = (*diag) ? 0 : 1;
    ij = 0;
    for (j=0; j <= *nr; j++)
    for (i=j+dc; i < *nr; i++) {
        d[ij++] = distfun(x, *nr, *nc, i, j);
    }
}
//===========================================================================
void 
ClosestPoint::closestPtSurfSurfPlaneFunctional(const std::vector<Point>& epoint, //plane description
				 const std::vector<Point>& epnt1, // start pt. in surf. 1
				 const std::vector<Point>& epnt2, // start pt. in surf. 2
				 const Point& epar1, // parameter start pt. in surf. 1
				 const Point& epar2, // parameter start pt. in surf. 2
				 const ParamSurface* psurf1, // ptr. to surf. 1
				 const ParamSurface* psurf2, // ptr. to surf. 2
				 double aepsge, // absolute tolerance
				 std::vector<Point>& gpnt1, // result of iter. in surf. 1
				 std::vector<Point>& gpnt2, // result of iter. in surf. 2
				 Point& gpar1, Point& gpar2, int& jstat) // results of param.
//===========================================================================
{
    // we formulate the problem as minimizing f(x) + c_k P(x), where f(x) is the distance
    // of the points in surface 1 and surface 2, and P(x) is the distance to the plane.
    // The criteria that the points must be lying in the plane is approached as the 
    // multiplicative constant c_k increases.  By choosing a sufficiently high value
    // for c_k, we expect to converge within the specified tolerance. 

    gpar1 = gpar2 = Point(2);
    gpnt1.resize(3); gpnt2.resize(3);

    const Point plane_normal = epoint[1] / epoint[1].length();

    double C = 1; // = compute_constraint_multiplier(plane_normal, epnt1, epnt2, aepsge);

    double dist_to_plane, old_dist_to_plane;
    double seed[4];
    seed[0] = epar1[0]; seed[1] = epar1[1];
    seed[2] = epar2[0]; seed[3] = epar2[1];

    dist_to_plane = numeric_limits<double>::max();

    while(true) {
	old_dist_to_plane = dist_to_plane;
	
	// make function object here
	SurfDistFun distfun(psurf1, psurf2, C, epoint[0], plane_normal);
	
	// specify function minimizer
	FunctionMinimizer<SurfDistFun> dfmin(4, distfun, seed, aepsge);
	
	// use conjugated gradient algorithm to minimize this function
	minimise_conjugated_gradient(dfmin);//, 5); // number of iterations in each cycle
	
	dist_to_plane = 
	    compute_distance_to_plane(psurf1->point(dfmin.getPar(0), dfmin.getPar(1)),
				      psurf2->point(dfmin.getPar(2), dfmin.getPar(3)),
				      epoint[0],
				      plane_normal);
	
	if ( (dist_to_plane < aepsge) || (dist_to_plane >= old_dist_to_plane)) {
	    // we will quit the loop at this point
	    gpar1[0] = dfmin.getPar(0);
	    gpar1[1] = dfmin.getPar(1);
	    gpar2[0] = dfmin.getPar(2);
	    gpar2[1] = dfmin.getPar(3);
	    
	    gpnt1.resize(3);
	    gpnt2.resize(3);
	    psurf1->point(gpnt1, gpar1[0], gpar1[1], 1);
	    psurf2->point(gpnt2, gpar2[0], gpar2[1], 1);
	    
	    if (dist_to_plane < aepsge) {
		jstat = (gpnt1[0].dist(gpnt2[0]) < aepsge) ? 1 : 2;
	    } else {
		// we are not able to converge properly to plane
		jstat = 3;
	    }

	    // to fulfill the contract that second derivatives and normal should also
	    // be computed, we will do that here.  Note, however, that these values
	    // were used nowhere else in this algorithm.
	    gpnt1.resize(7);
	    gpnt2.resize(7);
	    psurf1->point(gpnt1, gpar1[0], gpar1[1], 2);
	    psurf2->point(gpnt2, gpar2[0], gpar2[1], 2);
	    gpnt1[6] = gpnt1[1].cross(gpnt1[2]); // nb: not normalized here!
	    gpnt2[6] = gpnt2[1].cross(gpnt2[2]); // nb: not normalized here!
	    return;
	}
	
	cout << "multiplying C!  New C is : " << C * 10 << endl;
	C *= 10; // if we redo the loop, we need to augment the value of C
	copy(dfmin.getPar(), dfmin.getPar() + 4, seed);
    } 
}
예제 #5
0
int main(int argc, char *argv[]) {
 int i=1, start=0, end=0, freqno;
 DATATYPE *new_tsdata, hold;
 array D;
 OPT_DTYPE ax, bx, cx, fa, fb, fc, xmin, sumsq, weight, sumweight, ave, min_power, optimize_arg, *points;
 optimize_struct ostruct;
 struct minfunc_struct mfs;
 struct transform_info_struct firsttinfo;
 transform_info_ptr tinfo, tinfo_next;
 struct transform_methods_struct methods[2];
 struct external_methods_struct emethod;


 tinfo= &firsttinfo;
 /*{{{  Process command line*/
 while (*argv[1]=='-') {
  switch (argv[1][1]) {
  }
  argv++; argc--;
 }
 if (argc!=3) {
  fprintf(stderr, "Usage: %s ascdatafile outfile\n"
    , argv[0]);
  return 1;
 }

 if (start<0) start=0;
 if (end<=0) end=start;
 /*}}}  */

 clear_external_methods(&emethod);
 firsttinfo.methods= methods;
 firsttinfo.emethods= &emethod;

 /*{{{  Read all data sets*/
 select_readasc(tinfo);
 (*tinfo->methods->transform_defaults)(tinfo);
 firsttinfo.filename=argv[1];
 firsttinfo.epochs= -1; firsttinfo.fromepoch=1;
 (*tinfo->methods->transform_init)(tinfo);
 if (start!=0) {
  while (i<start) {
   (*tinfo->methods->transform)(tinfo);
   i++;
  }
 }
 while ((end==0 || i<=end) && (*tinfo->methods->transform)(tinfo)!=NULL) {
  if ((tinfo_next=malloc(sizeof(struct transform_info_struct)))==NULL) {
   ERREXIT(&emethod, "similarity: Error malloc'ing tinfo struct\n");
  }
  *(tinfo_next)=firsttinfo;
  tinfo_next->previous=tinfo;
  tinfo_next->next=NULL;
  tinfo->next=tinfo_next;
  tinfo=tinfo_next;
  i++;
 }
 /* The last tinfo structure was allocated in vein, throw away */
 tinfo=tinfo->previous;
 free(tinfo->next);
 tinfo->next=NULL;
 (*firsttinfo.methods->transform_exit)(&firsttinfo);
 /*}}}  */

 points=malloc(2*firsttinfo.nr_of_channels*sizeof(OPT_DTYPE));
 for (freqno=0; freqno<firsttinfo.nr_of_channels; freqno++) {
  /*{{{  Construct symmetrical function*/
  sumweight=ave=0.0;
  min_power=1e10;
  for (i=0, tinfo= &firsttinfo; tinfo!=NULL; tinfo=tinfo->next, i++) {
   tinfo_array(tinfo, &D);
   array_transpose(&D);
   array_reset(&D);

   D.current_vector=freqno;
   D.current_element=i;
   hold=array_readelement(&D);
   D.current_element=0;
   do {
    points[D.current_element*2]=100*channel_distance(tinfo, i, D.current_element);
    points[D.current_element*2+1]=array_scan(&D)/hold;
   } while (D.message==ARRAY_CONTINUE);
   ostruct.function= &minfunc;
   mfs.nr_of_points=firsttinfo.nr_of_channels;
   mfs.points=points;
   ostruct.fixed_args=(void *)&mfs;
   ostruct.num_opt_args=1;
   ostruct.opt_args=(void *)&optimize_arg;
   ax=0.1; bx=12;
   opt_mnbrak(&ostruct, &ax, &bx, &cx, &fa, &fb, &fc);
   sumsq=opt_brent(&ostruct, ax, bx, cx, 1e-4, &xmin);
#   ifdef VERBOSE
   printf("%d %g %g %g\n", i, xmin, sumsq, hold);
#   endif
   weight= 1.0/sumsq;
   sumweight+=weight;
   ave+=weight*xmin;
   if (hold<min_power) min_power=hold;
  }
  ave/=sumweight;
#  ifdef VERBOSE
  printf("Consensus: %g %g\n", ave, min_power);
#  endif
  /*}}}  */
  /*{{{  Subtract symmetrical function*/
  for (i=0, tinfo= &firsttinfo; tinfo!=NULL; tinfo=tinfo->next, i++) {
   tinfo_array(tinfo, &D);
   array_transpose(&D);
   array_reset(&D);
   D.current_vector=freqno;
   D.current_element=0;
   do {
    hold= min_power*distfun(100*channel_distance(tinfo, i, D.current_element), ave);
    array_write(&D, array_readelement(&D)-hold);
   } while (D.message==ARRAY_CONTINUE);
  }
  /*}}}  */
 }
 free(points);

 /*{{{  Write all data sets*/
 tinfo= &firsttinfo;

 select_extract_item(tinfo);	/* Output real part only */
 (*tinfo->methods->transform_defaults)(tinfo);
 tinfo->methods->local_storage=(void *)0;
 (*tinfo->methods->transform_init)(tinfo);
 tinfo->methods++;

 select_writeasc(tinfo);
 (*tinfo->methods->transform_defaults)(tinfo);
 tinfo->outfname=argv[2];
 tinfo->methods->local_storage=(void *)1;
 (*tinfo->methods->transform_init)(tinfo);

 for (; tinfo!=NULL; tinfo=tinfo->next) {
  tinfo->outfptr=firsttinfo.outfptr;
  tinfo->methods=methods;
  if ((new_tsdata=(*tinfo->methods->transform)(tinfo))==NULL) {
   ERREXIT(tinfo->emethods, "extract_item failed !\n");
  }
  free(tinfo->tsdata);
  tinfo->tsdata=new_tsdata;
  tinfo->methods++;
  (*tinfo->methods->transform)(tinfo);
 }

 tinfo= &firsttinfo;
 tinfo->methods=methods;
 (*tinfo->methods->transform_exit)(tinfo);
 tinfo->methods++;
 (*tinfo->methods->transform_exit)(tinfo);
 /*}}}  */

 return 0;
}
예제 #6
0
파일: distance.c 프로젝트: hvsarma/pqR
void R_distance(double *x, int *nr, int *nc, double *d, int *diag,
                int *method, double *p)
{
    int dc, i, j;
    size_t  ij;  /* can exceed 2^31 - 1 */
    double (*distfun)(double*, int, int, int, int) = NULL;
#ifdef _OPENMP
    int nthreads;
#endif

    switch(*method) {
    case EUCLIDEAN:
        distfun = R_euclidean;
        break;
    case MAXIMUM:
        distfun = R_maximum;
        break;
    case MANHATTAN:
        distfun = R_manhattan;
        break;
    case CANBERRA:
        distfun = R_canberra;
        break;
    case BINARY:
        distfun = R_dist_binary;
        break;
    case MINKOWSKI:
        if(!R_FINITE(*p) || *p <= 0)
            error(_("distance(): invalid p"));
        break;
    default:
        error(_("distance(): invalid distance"));
    }
    dc = (*diag) ? 0 : 1; /* diag=1:  we do the diagonal */
#ifdef _OPENMP
    if (R_num_math_threads > 0)
        nthreads = R_num_math_threads;
    else
        nthreads = 1; /* for now */
    if (nthreads == 1) {
        /* do the nthreads == 1 case without any OMP overhead to see
           if it matters on some platforms */
        ij = 0;
        for(j = 0 ; j <= *nr ; j++)
            for(i = j+dc ; i < *nr ; i++)
                d[ij++] = (*method != MINKOWSKI) ?
                          distfun(x, *nr, *nc, i, j) :
                          R_minkowski(x, *nr, *nc, i, j, *p);
    }
    else
        /* This produces uneven thread workloads since the outer loop
           is over the subdiagonal portions of columns.  An
           alternative would be to use a loop on ij and to compute the
           i and j values from ij. */
        #pragma omp parallel for num_threads(nthreads) default(none)	\
        private(i, j, ij)						\
        firstprivate(nr, dc, d, method, distfun, nc, x, p)
        for(j = 0 ; j <= *nr ; j++) {
            ij = j * (*nr - dc) + j - ((1 + j) * j) / 2;
            for(i = j+dc ; i < *nr ; i++)
                d[ij++] = (*method != MINKOWSKI) ?
                          distfun(x, *nr, *nc, i, j) :
                          R_minkowski(x, *nr, *nc, i, j, *p);
        }
#else
    ij = 0;
    for(j = 0 ; j <= *nr ; j++)
        for(i = j+dc ; i < *nr ; i++)
            d[ij++] = (*method != MINKOWSKI) ?
                      distfun(x, *nr, *nc, i, j) : R_minkowski(x, *nr, *nc, i, j, *p);
#endif
}