Esempio n. 1
0
    static int find_nearest(struct kdnode *node, const double *pos, double range, struct res_node *list, int ordered, int dim)
    {
        double dist_sq, dx;
        int i, ret, added_res = 0;

        if(!node) return 0;

        dist_sq = 0;
        for(i = 0; i< dim; i++){
            dist_sq += SQ(node->pos[i] - pos[i]);
        }

        if(dist_sq <= SQ(range)){
            if(rlist_insert(list, node, ordered ? dist_sq : -1.0) == -1){
                return -1;
            }
            added_res = 1;
        }

        dx = pos[node->dir] - node->pos[node->dir];

        ret = find_nearest(dx <= 0.0 ? node->left : node->right, pos, range, list, ordered, dim);
        if(ret >= 0 && fabs(dx) < range){
            added_res += ret;
            ret = find_nearest(dx <= 0.0 ? node->right : node->left, pos, range, list, ordered, dim);
        }

        if(ret == -1){
            return -1;
        }
        added_res += ret;

        return added_res;
    }
Esempio n. 2
0
static void
handle_biggest_offenders(int testtblsize, int maxcolors) {
    int i, j;
    float dEthresh = 0;
    CmapEntry *pCmap;

    num_offenders = 0;

    for (pCmap = virt_cmap, i = 0; i < num_virt_cmap_entries; i++, pCmap++) {
	if (pCmap->nextidx < 0) {
	    continue;
	}
	if (num_offenders == MAX_OFFENDERS
	    && pCmap->dE < offenders[MAX_OFFENDERS-1]->dE)
	{
	    continue;
	}
	find_nearest(pCmap);
	insert_in_list(pCmap);
    }

    if (num_offenders > 0) {
	dEthresh = offenders[num_offenders-1]->dE;
    }

    for (i = 0; (total < maxcolors) && (i < num_offenders); ++i) {
	pCmap = offenders[i];

	if (!pCmap) continue;

	j = add_color(pCmap->red, pCmap->green, pCmap->blue, FALSE);

	if (j) {
	    for (j = i+1; j < num_offenders; ++j) {
		float dE;

		pCmap = offenders[j];
		if (!pCmap) {
		    continue;
		}

		find_nearest(pCmap);

		dE = pCmap->dE;
		if (dE < dEthresh) {
		    offenders[j] = 0;
		} else {
		    if (offenders[i+1] == 0 || dE > offenders[i+1]->dE) {
			offenders[j] = offenders[i+1];
			offenders[i+1] = pCmap;
		    }
		}
	    }
	}
    }
}
Esempio n. 3
0
struct kdres *kd_generic_nearest_range(
	struct kdtree *kd, 
	const double *pos, 
	double range, 
	double (*distance_function)(const double *, const double *, int k), 
	int (*compare_function)(double, double)
)
{
	int ret;
	struct kdres *rset;

	if(!(rset = malloc(sizeof *rset))) {
		return 0;
	}
	if(!(rset->rlist = alloc_resnode())) {
		free(rset);
		return 0;
	}
	rset->rlist->next = 0;
	rset->tree = kd;

	if((ret = find_nearest(kd->root, pos, range, rset->rlist, 0, kd->dim, distance_function, compare_function)) == -1) {
		kd_res_free(rset);
		return 0;
	}
	rset->size = ret;
	kd_res_rewind(rset);
	return rset;
}
Esempio n. 4
0
    struct kdres *kd_nearest_range(struct kdtree *kd, const double *pos, double range)
    {
        int ret;
        struct kdres *rset;

        if(!(rset = new kdres)){
            return 0;
        }

        if(!(rset->rlist = new res_node)){
            delete rset;
            return 0;
        }

        rset->tlist->next=0;
        rset->tree = kd;

        if((ret = find_nearest(kd->root, pos, range, rset->rlist, 0, kd->dim))==-1){
            kd_res_free(rset);
            return 0;
        }
        rset->size = rst;
        kd_res_rewind(rset);
        return rset;
    }
Esempio n. 5
0
struct kdres *kd_nearest_range(struct kdtree *kd, const double *pos, double range)
{
	int ret;
	struct kdres *rset;
    
    //pthread_mutex_lock(&alloc_mutex2);
    rset = malloc(sizeof *rset);
    //pthread_mutex_unlock(&alloc_mutex2);

	if(!(rset)) {
		return 0;
	}
    
    //pthread_mutex_lock(&alloc_mutex2);
    rset->rlist = alloc_resnode();
    //pthread_mutex_unlock(&alloc_mutex2);
	if(!(rset->rlist)) {
		free(rset);
		return 0;
	}
	rset->rlist->next = 0;
	rset->tree = kd;
    
	if((ret = find_nearest(kd->root, pos, range, rset->rlist, 0, kd->dim)) == -1) {
		kd_res_free(rset);
		return 0;
	}
	rset->size = ret;
	kd_res_rewind(rset);
	return rset;
}
Esempio n. 6
0
/* TODO: add > 16 dimensions handling */
static int find_nearest(
	struct kdnode *node, 
    const double *pos, 
    double range, 
    struct res_node *list, 
    int ordered, 
    int dim, 
    double (*distance_function)(const double *, const double *, int k), 
    int (*compare_function)(double, double)
)
{
	double dist, one_dim_dist, one_dim_relative_dist;
	int i, ret, added_res = 0;
	double one_dim_pos[16];

	if(!node) return 0;
	if(dim > 16) return -1;

	dist = (*distance_function)(node->pos, pos, dim);
	if((*compare_function)(dist, range) <= 0) {
		if(rlist_insert(list, node, ordered ? dist : -1.0) == -1) {
			return -1;
		}
		added_res = 1;
	}

	/* isolate single dimension position from node->pos into one_dim_pos for single dimension distance computation */
	for(i = 0; i < dim; i++) {
		one_dim_pos[i] = pos[i];
	}
	one_dim_pos[node->dir] = node->pos[node->dir];

	one_dim_dist = (*distance_function)(pos, one_dim_pos, dim);
	one_dim_relative_dist = pos[node->dir] - node->pos[node->dir];

	ret = find_nearest(one_dim_relative_dist <= 0.0 ? node->left : node->right, pos, range, list, ordered, dim, distance_function, compare_function);
	if(ret >= 0 && (*compare_function)(one_dim_dist, range) < 0) {
		added_res += ret;
		ret = find_nearest(one_dim_relative_dist <= 0.0 ? node->right : node->left, pos, range, list, ordered, dim, distance_function, compare_function);
	}
	if(ret == -1) {
		return -1;
	}
	added_res += ret;

	return added_res;
}
Esempio n. 7
0
color pathtracer::cast_ray(ray r, int step, bool internal) {
	intersection is = find_nearest(r);
	if (!is.object) // No intersection
		return *background_color;
	color out = color();
	for (std::shared_ptr<light> l : *lights) {
		color lcol = color();
		if (is.object.get() == dynamic_cast<const shape *>(l.get()))
			out += *is.object->shade(color(1, 1, 1), *is.norm, *is.norm, -r.d, *is.local_pos, internal);
		else {
			const std::shared_ptr<std::vector<intersection>> dirs = l->get_directions(*is.pos, cam->shadow_rays);
			for (intersection d : *dirs) {
				direction light_dir = (*is.pos - *d.pos) * 0.999;
				if (!cast_shadow(*is.pos, -light_dir)) {
					//light_dir = normalise(light_dir);
					lcol += *is.object->shade(*l->emit(light_dir, d), -normalise(light_dir), *is.norm, -r.d,
											  *is.local_pos, internal);
				}
			}
			if (dirs->size() > 0)
				out += lcol * (1.0f / dirs->size());
		}
	}
	if (step < cam->max_bounces - 1) {
		std::shared_ptr<ray> sctr_ray = is.object->scatter(-r.d, *is.norm, *is.pos);
		if (sctr_ray) {
			//color sctr_col = cast_ray(*sctr_ray, step + 1, internal);
			color sctr_col = *is.object->shade(cast_ray(*sctr_ray, step + 1, internal), sctr_ray->d, *is.norm, -r.d,
											   *is.local_pos, internal) * static_cast<float>(M_PI);
			out += sctr_col;
		}
		std::shared_ptr<ray> refl_ray = internal ? nullptr : is.object->reflect(-r.d, *is.norm, *is.pos);
		if (refl_ray) {
			color refl_col = cast_ray(*refl_ray, step + 1, internal);
			refl_col = refl_col * is.object->get_reflectance();
			out += refl_col;
		}
		std::shared_ptr<ray> refr_ray = is.object->refract(-r.d, internal ? -*is.norm : *is.norm, *is.pos,
														   internal);
		if (refr_ray) {
			color refr_col = color();
			refr_col += cast_ray(*refr_ray, step + 1,
								 dot(refr_ray->d, internal ? -*is.norm : *is.norm) < 0 == !internal);
			refr_col =
					refr_col * (internal ? std::exp(-(1 - is.object->get_transmittance()) * length(*is.pos - r.o))
										 : is.object->get_transmittance());
			out += refr_col;
		}
	}
	return out;
}
Esempio n. 8
0
int critbit_get(critbit_root *root, const char *key, void **out) {
    const int len = strlen(key);
    const uint8_t *bytes = (void *)key;

    pthread_rwlock_t *lock = root->cur_rwlock;
    pthread_rwlock_rdlock(lock);
    char *nearest = find_nearest(root->head, bytes, len);

    int ret = 1;
    if(strcmp(nearest, key) == 0) {
        nearest -= sizeof(void *);
        *out = *((void **)nearest);
        ret = 0;
    }
    pthread_rwlock_unlock(lock);

    return ret;
}
Esempio n. 9
0
int main(int argc, char* argv[])
{
    auto command_line = qflags::command_line(argc, argv);
    auto parser = qflags::parser();

    auto ignore_case = qflags::flag("ignore_case", "i");
    auto print_matrix = qflags::flag("print_matrix", "p");

    std::string errors;
    bool result = true;

    result &= parser.add_argument(&ignore_case);
    result &= parser.add_argument(&print_matrix);
    result &= parser.parse(command_line, &errors);

    fprintf(stdout, "%s", errors.c_str());

    // Compare two strings and print their edit distance.
    if (parser.remaining_argc() == 3) {
        unsigned long long distance = levenshtein(parser.remaining_argv()[1],
                                                  parser.remaining_argv()[2],
                                                  ignore_case,
                                                  print_matrix);
        fprintf(stdout, "%llu\n", distance);
    }
    // Compare multiple strings and find the two nearest strings.
    else if (parser.remaining_argc() > 3) {
        find_nearest(parser.remaining_argc() - 1,
                     parser.remaining_argv() + 1,
                     ignore_case,
                     print_matrix);
    }
    // Print usage string
    else {
        fprintf(stdout,
                "usage: levenshtein %s <string> <string> [<string>...]\n",
                parser.usage_string().c_str());
    }

    return result ? 0 : 1;
}
Esempio n. 10
0
void lspjvm_quantise(float *x, float *xq, int ndim)
{
  int i, n1, n2, n3;
  float err[LPC_ORD], err2[LPC_ORD], err3[LPC_ORD];
  float w[LPC_ORD], w2[LPC_ORD], w3[LPC_ORD];
  const float *codebook1 = lsp_cbjvm[0].cb;
  const float *codebook2 = lsp_cbjvm[1].cb;
  const float *codebook3 = lsp_cbjvm[2].cb;

  w[0] = MIN(x[0], x[1]-x[0]);
  for (i=1;i<ndim-1;i++)
    w[i] = MIN(x[i]-x[i-1], x[i+1]-x[i]);
  w[ndim-1] = MIN(x[ndim-1]-x[ndim-2], PI-x[ndim-1]);

  compute_weights(x, w, ndim);

  n1 = find_nearest(codebook1, lsp_cbjvm[0].m, x, ndim);

  for (i=0;i<ndim;i++)
  {
    xq[i] = codebook1[ndim*n1+i];
    err[i] = x[i] - xq[i];
  }
  for (i=0;i<ndim/2;i++)
  {
    err2[i] = err[2*i];
    err3[i] = err[2*i+1];
    w2[i] = w[2*i];
    w3[i] = w[2*i+1];
  }
  n2 = find_nearest_weighted(codebook2, lsp_cbjvm[1].m, err2, w2, ndim/2);
  n3 = find_nearest_weighted(codebook3, lsp_cbjvm[2].m, err3, w3, ndim/2);

  for (i=0;i<ndim/2;i++)
  {
    xq[2*i] += codebook2[ndim*n2/2+i];
    xq[2*i+1] += codebook3[ndim*n3/2+i];
  }
}
Esempio n. 11
0
void encode_lsps_vq(int *indexes, float *x, float *xq, int ndim)
{
  int i, n1, n2, n3;
  float err[LPC_ORD], err2[LPC_ORD], err3[LPC_ORD];
  float w[LPC_ORD], w2[LPC_ORD], w3[LPC_ORD];
  const float *codebook1 = lsp_cbjvm[0].cb;
  const float *codebook2 = lsp_cbjvm[1].cb;
  const float *codebook3 = lsp_cbjvm[2].cb;

  assert(ndim <= LPC_ORD);

  w[0] = MIN(x[0], x[1]-x[0]);
  for (i=1;i<ndim-1;i++)
    w[i] = MIN(x[i]-x[i-1], x[i+1]-x[i]);
  w[ndim-1] = MIN(x[ndim-1]-x[ndim-2], PI-x[ndim-1]);

  compute_weights(x, w, ndim);

  n1 = find_nearest(codebook1, lsp_cbjvm[0].m, x, ndim);

  for (i=0;i<ndim;i++)
  {
    xq[i]  = codebook1[ndim*n1+i];
    err[i] = x[i] - xq[i];
  }
  for (i=0;i<ndim/2;i++)
  {
    err2[i] = err[2*i];
    err3[i] = err[2*i+1];
    w2[i] = w[2*i];
    w3[i] = w[2*i+1];
  }
  n2 = find_nearest_weighted(codebook2, lsp_cbjvm[1].m, err2, w2, ndim/2);
  n3 = find_nearest_weighted(codebook3, lsp_cbjvm[2].m, err3, w3, ndim/2);

  indexes[0] = n1;
  indexes[1] = n2;
  indexes[2] = n3;
}
Esempio n. 12
0
int main(int argc,char **argv)
{
  char stdi=0;
  FILE *file=NULL;
  double min,inter=0.0,ind_inter,epsilon,av,ind_var;
  char *nearest,alldone;
  long i;
  unsigned int dim,emb;
  unsigned long donesofar;

  if (scan_help(argc,argv))
    show_options(argv[0]);
  
  scan_options(argc,argv);
#ifndef OMIT_WHAT_I_DO
  if (verbosity&VER_INPUT)
    what_i_do(argv[0],WID_STR);
#endif

  infile=search_datafile(argc,argv,NULL,verbosity);
  if (infile == NULL)
    stdi=1;

  if (outfile == NULL) {
    if (!stdi) {
      check_alloc(outfile=(char*)calloc(strlen(infile)+5,(size_t)1));
      strcpy(outfile,infile);
      strcat(outfile,".fnn");
    }
    else {
      check_alloc(outfile=(char*)calloc((size_t)10,(size_t)1));
      strcpy(outfile,"stdin.fnn");
    }
  }
  if (!stdo)
    test_outfile(outfile);

  if (column == NULL)
    series=(double**)get_multi_series(infile,&length,exclude,&comp,"",dimset,
				      verbosity);
  else
    series=(double**)get_multi_series(infile,&length,exclude,&comp,column,
				      dimset,verbosity);

  for (i=0;i<comp;i++) {
    rescale_data(series[i],length,&min,&ind_inter);
    variance(series[i],length,&av,&ind_var);
    if (i == 0) {
      varianz=ind_var;
      inter=ind_inter;
    }
    else {
      varianz=(varianz>ind_var)?ind_var:varianz;
      inter=(inter<ind_inter)?ind_inter:inter;
    }
  }

  check_alloc(list=(long*)malloc(sizeof(long)*length));
  check_alloc(nearest=(char*)malloc(length));
  check_alloc(box=(long**)malloc(sizeof(long*)*BOX));
  for (i=0;i<BOX;i++)
    check_alloc(box[i]=(long*)malloc(sizeof(long)*BOX));

  if (!stdo) {
    file=fopen(outfile,"w");
    if (verbosity&VER_INPUT)
      fprintf(stderr,"Opened %s for writing\n",outfile);
  }
  else {
    if (verbosity&VER_INPUT)
      fprintf(stderr,"Writing to stdout\n");
  }
  check_alloc(vcomp=(unsigned int*)malloc(sizeof(int)*(maxdim)));
  check_alloc(vemb=(unsigned int*)malloc(sizeof(int)*(maxdim)));
  for (i=0;i<maxdim;i++) {
    if (comp == 1) {
      vcomp[i]=0;
      vemb[i]=i;
    }
    else {
      vcomp[i]=i%comp;
      vemb[i]=(i/comp)*delay;
    }
  }
  for (emb=minemb;emb<=maxemb;emb++) {
    dim=emb*comp-1;
    epsilon=eps0;
    toolarge=0;
    alldone=0;
    donesofar=0;
    aveps=0.0;
    vareps=0.0;
    for (i=0;i<length;i++)
      nearest[i]=0;
    if (verbosity&VER_USR1)
      fprintf(stderr,"Start for dimension=%u\n",dim+1);
    while (!alldone && (epsilon < 2.*varianz/rt)) {
      alldone=1;
      mmb(vcomp[dim],vemb[dim],epsilon);
      for (i=0;i<length-maxemb*delay;i++)
	if (!nearest[i]) {
	  nearest[i]=find_nearest(i,dim,epsilon);
	  alldone &= nearest[i];
	  donesofar += (unsigned long)nearest[i];
	}
      if (verbosity&VER_USR1)
	fprintf(stderr,"Found %lu up to epsilon=%e\n",donesofar,epsilon*inter);
      epsilon*=sqrt(2.0);
      if (!donesofar)
	eps0=epsilon;
    }
    if (donesofar == 0) {
      fprintf(stderr,"Not enough points found!\n");
      exit(FALSE_NEAREST_NOT_ENOUGH_POINTS);
    }
    aveps *= (1./(double)donesofar);
    vareps *= (1./(double)donesofar);
    if (stdo) {
      fprintf(stdout,"%u %e %e %e\n",dim+1,(double)toolarge/(double)donesofar,
	      aveps*inter,sqrt(vareps)*inter);
      fflush(stdout);
    }
    else {
      fprintf(file,"%u %e %e %e\n",dim+1,(double)toolarge/(double)donesofar,
	      aveps*inter,sqrt(vareps)*inter);
      fflush(file);
    }
  }
  if (!stdo)
    fclose(file);

  if (infile != NULL)
    free(infile);
  if (outfile != NULL)
    free(outfile);
  free(series);
  free(list);
  free(nearest);
  for (i=0;i<BOX;i++)
    free(box[i]);
  free(box);

  return 0;
}
Esempio n. 13
0
File: dijkstra.c Progetto: pgrz/porr
int *dijkstra_distance ( int ohd[vertex_count][vertex_count]  )
{
    int *connected;
    int i;
    int md;
    int *mind;
    int mv;
    int my_first;
    int my_id;
    int my_last;
    int my_md;
    int my_mv;
    int my_step;
    int nth;
    /*
       Start out with only node 0 connected to the tree.
     */
    connected = ( int * ) malloc ( vertex_count * sizeof ( int ) );

    connected[0] = 1;
    for ( i = 1; i < vertex_count; i++ )
    {
        connected[i] = 0;
    }
    /*
       Initial estimate of minimum distance is the 1-step distance.
     */
    mind = ( int * ) malloc ( vertex_count * sizeof ( int ) );

    for ( i = 0; i < vertex_count; i++ )
    {
        mind[i] = ohd[0][i];
    }
    /*
       Begin the parallel region.
     */
    # pragma omp parallel private ( my_first, my_id, my_last, my_md, my_mv, my_step ) \
    shared ( connected, md, mind, mv, nth, ohd )
    {
        my_id = omp_get_thread_num ( );
        nth = omp_get_num_threads ( );
        my_first =   (   my_id       * vertex_count ) / nth;
        my_last  =   ( ( my_id + 1 ) * vertex_count ) / nth - 1;
        /*
           The SINGLE directive means that the block is to be executed by only
           one thread, and that thread will be whichever one gets here first.
         */
        # pragma omp single
        {
            log(DEBUG, my_id, "P%d: Parallel region begins with %d threads", my_id, nth );
        }

        log(DEBUG, my_id, "P%d:  First=%d  Last=%d", my_id, my_first, my_last );

        for ( my_step = 1; my_step < vertex_count; my_step++ )
        {
            /*
               Before we compare the results of each thread, set the shared variable
               MD to a big value.  Only one thread needs to do this.
             */
            # pragma omp single
            {
                md = INT_MAX;
                mv = -1;
            }
            /*
               Each thread finds the nearest unconnected node in its part of the graph.
               Some threads might have no unconnected nodes left.
             */
            find_nearest ( my_first, my_last, mind, connected, &my_md, &my_mv, my_id );
            /*
               In order to determine the minimum of all the MY_MD's, we must insist
               that only one thread at a time execute this block!
             */
            # pragma omp critical
            {
                if ( my_md < md )
                {
                    md = my_md;
                    mv = my_mv;
                }
            }
            /*
               This barrier means that ALL threads have executed the critical
               block, and therefore MD and MV have the correct value.  Only then
               can we proceed.
             */
            # pragma omp barrier
            /*
               If MV is -1, then NO thread found an unconnected node, so we're done early.
               OpenMP does not like to BREAK out of a parallel region, so we'll just have
               to let the iteration run to the end, while we avoid doing any more updates.

               Otherwise, we connect the nearest node.
             */
            # pragma omp single
            {
                if ( mv != - 1 )
                {
                    connected[mv] = 1;
                    log(DEBUG, my_id, "P%d: Connecting node %d", my_id, mv );
                    log(DEBUG, -1, "----------------------------");
                }
            }
            /*
               Again, we don't want any thread to proceed until the value of
               CONNECTED is updated.
             */
            # pragma omp barrier
            /*
               Now each thread should update its portion of the MIND vector,
               by checking to see whether the trip from 0 to MV plus the step
               from MV to a node is closer than the current record.
             */
            if ( mv != -1 )
            {
                update_mind ( my_first, my_last, mv, connected, ohd, mind, my_id );
            }
            /*
               Before starting the next step of the iteration, we need all threads
               to complete the updating, so we set a BARRIER here.
             */
            #pragma omp barrier
        }
        /*
           Once all the nodes have been connected, we can exit.
         */
        # pragma omp single
        {
            log(DEBUG, my_id, "P%d: Exiting parallel region.", my_id );
        }
    }

    free ( connected );

    return mind;
}
Esempio n. 14
0
static int critbit_insert_inplace(critbit_root *root,
        const char *key, int keylen, const void* value) {
    const uint8_t *bytes = (void *)key;

    uint8_t *p = root->head;
    if(!p) {
        p = alloc_string(key, keylen, value);
        if(!p)
            return 1;

        root->head = p;
        return 0;
    }

    p = find_nearest(root->head, bytes, keylen);

    uint32_t newbyte;
    uint8_t newotherbits;
    for(newbyte = 0; newbyte < keylen; ++newbyte) {
        if(p[newbyte] != bytes[newbyte]) {
            newotherbits = p[newbyte] ^ bytes[newbyte];
            goto found;
        }
    }
    if(p[newbyte]) {
        newotherbits = p[newbyte];
        goto found;
    }
    return 1;

found:
    while(newotherbits & (newotherbits - 1)) {
        newotherbits &= newotherbits - 1;
    }
    newotherbits ^= 0xFF;
    uint8_t c = p[newbyte];
    int newdirection = (1 + (newotherbits | c)) >> 8;

    struct critbit_node *node = alloc_aligned(sizeof(struct critbit_node));
    if(!node)
        return 1;

    char *x = alloc_string(key, keylen, value);
    if(!x) {
        free(node);
        return 1;
    }

    node->byte = newbyte;
    node->otherbits = newotherbits;
    node->child[1 - newdirection] = x;

    void **wherep = &root->head;
    for(;;) {
        uint8_t *p = *wherep;
        if(!IS_INTERNAL(p))
            break;

        struct critbit_node *q = TO_NODE(p);
        if(q->byte > newbyte)
            break;
        if(q->byte == newbyte && q->otherbits > newotherbits)
            break;

        wherep = q->child + get_direction(q, bytes, keylen);
    }
    node->child[newdirection] = *wherep;
    __sync_synchronize();
    *wherep = FROM_NODE(node);
    __sync_synchronize();

    return 0;
}
Esempio n. 15
0
void
img_makePalette(int cmapsize, int tablesize, int lookupsize,
		float lscale, float weight,
		int prevclrs, int doMac,
		unsigned char *reds,
		unsigned char *greens,
		unsigned char *blues,
		unsigned char *lookup)
{
    CmapEntry *pCmap;
    int i, ix;
#ifdef STATS
    double ave_dL, ave_dE;
    double max_dL, max_dE;
#endif /* STATS */
#ifdef TIMES
    clock_t start, mid, tbl, end;

    start = clock();
#endif /* TIMES */

    init_matrices();
    Lscale = lscale;
    Weight = weight;

    cmapmax = cmapsize;
    total = 0;
    for (i = 0; i < prevclrs; i++) {
	add_color(reds[i], greens[i], blues[i], TRUE);
    }

    add_color(0, 0, 0, TRUE);
    add_color(255,255,255, TRUE);

    /* do grays next; otherwise find_nearest may break! */
    init_grays();
    if (doMac) {
	init_mac_palette();
    }
    init_pastels();

    init_primaries();

    /* special case some blues */
    add_color(0,0,192,TRUE);
    add_color(0x30,0x20,0x80,TRUE);
    add_color(0x20,0x60,0xc0,TRUE);

    init_virt_cmap(lookupsize, tablesize);

    while (total < cmapsize) {
	handle_biggest_offenders(tablesize, cmapsize);
    }

    memcpy(reds, cmap_r, cmapsize);
    memcpy(greens, cmap_g, cmapsize);
    memcpy(blues, cmap_b, cmapsize);

#ifdef TIMES
    mid = clock();
#endif /* TIMES */

    pCmap = virt_cmap;
    for (i = 0; i < num_virt_cmap_entries; i++, pCmap++) {
	if (pCmap->nextidx < 0) {
	    continue;
	}
	if (pCmap->nextidx < total) {
	    ix = find_nearest(pCmap);
	}
    }

#ifdef TIMES
    tbl = clock();
#endif /* TIMES */

    pCmap = virt_cmap;
    if (tablesize != lookupsize) {
	int r, g, b;
	for (r = 0; r < lookupsize; ++r)
	{
	    for (g = 0; g < lookupsize; ++g)
	    {
		for (b = 0; b < lookupsize; ++b, pCmap++)
		{
		    float L, U, V;
		    float bestd = 0;
		    CmapEntry *pTest;

		    if (pCmap->nextidx >= 0) {
			continue;
		    }
#ifdef DEBUG
		    if (r == g && g == b) {
			jio_fprintf(stderr, "GRAY VALUE!?\n");
		    }
#endif /* DEBUG */
		    L = pCmap->L;
		    U = pCmap->U;
		    V = pCmap->V;
		    for (i = 0; i < 8; i++) {
			int ri, gi, bi;
			float d, t;
			ri = (i & 1) ? prevtest[r] : nexttest[r];
			gi = (i & 2) ? prevtest[g] : nexttest[g];
			bi = (i & 4) ? prevtest[b] : nexttest[b];
			pTest = &virt_cmap[((ri * lookupsize)
					    + gi) * lookupsize
					   + bi];
#ifdef DEBUG
			if (pTest->nextidx < 0) {
			    jio_fprintf(stderr, "OOPS!\n");
			}
#endif /* DEBUG */
			ix = pTest->bestidx;
			t = Ltab[ix] - L; d  = t * t * Lscale;
			if (i != 0 && d > bestd) continue;
			t = Utab[ix] - U; d += t * t;
			if (i != 0 && d > bestd) continue;
			t = Vtab[ix] - V; d += t * t;
			if (i != 0 && d > bestd) continue;
			bestd = d;
			pCmap->bestidx = ix;
		    }
		}
	    }
	}
    }
    pCmap = virt_cmap;
    for (i = 0; i < num_virt_cmap_entries; i++) {
	*lookup++ = (pCmap++)->bestidx;
    }

#ifdef TIMES
    end = clock();
#endif /* TIMES */

#ifdef STATS
    max_dL = 0.0;
    max_dE = 0.0;
    ave_dL = 0.0;
    ave_dE = 0.0;

    pCmap = virt_cmap;
    for (i = 0; i < num_virt_cmap_entries; i++, pCmap++) {
	double t, dL, dU, dV, dE;
	if (pCmap->nextidx < 0) {
	    int ix = pCmap->bestidx;
	    dL = pCmap->L - Ltab[ix]; dL *= dL;
	    dU = pCmap->U - Utab[ix]; dU *= dU;
	    dV = pCmap->V - Vtab[ix]; dV *= dV;
	    dE = dL * Lscale + dU + dV;
	    dE = WEIGHT_DIST(dE, pCmap->L);
	} else {
	    dL = pCmap->dL;
	    dE = pCmap->dE;
	}

	if (dL > max_dL) max_dL = dL;
	t = UNWEIGHT_DIST(dE,dL) - dL*(Lscale-1);
	if (t > max_dE) max_dE = t;

	ave_dL += (dL > 0) ? sqrt(dL) : 0.0;
	ave_dE += (t > 0) ? sqrt(t) : 0.0;
    }

    jio_fprintf(stderr, "colors=%d, tablesize=%d, cubesize=%d, ",
	    cmapsize, tablesize, lookupsize);
    jio_fprintf(stderr, "Lscale=%5.3f, Weight=%5.3f mac=%s\n",
	    (double)lscale, (double)weight, doMac ? "true" : "false");
    jio_fprintf(stderr, "Worst case error dL = %5.3f, dE = %5.3f\n", 
	    sqrt(max_dL), sqrt(max_dE));
    jio_fprintf(stderr, "Average error dL = %5.3f, dE = %5.3f\n", 
	    ave_dL / num_virt_cmap_entries,  ave_dE / num_virt_cmap_entries);
#endif /* STATS */
#ifdef TIMES
    jio_fprintf(stderr, "%f seconds to find colors\n",
	    (double)(mid - start) / CLOCKS_PER_SEC);
    jio_fprintf(stderr, "%f seconds to finish nearest colors\n",
	    (double)(tbl - mid) / CLOCKS_PER_SEC);
    jio_fprintf(stderr, "%f seconds to make lookup table\n",
	    (double)(end - tbl) / CLOCKS_PER_SEC);
    jio_fprintf(stderr, "%f seconds total\n",
	    (double)(end - start) / CLOCKS_PER_SEC);
#endif /* TIMES */

    free(virt_cmap);
    virt_cmap = 0;
}
Esempio n. 16
0
File: dijkstra.c Progetto: pgrz/porr
int *dijkstra_distance ( int ohd[vertex_count][vertex_count] )
{
    int *connected;
    int i;
    int my_min[2];
    int all_min[2];
    int *mind, *commonmind;
    int nth;
    int rc;

    connected = ( int * ) malloc ( vertex_count * sizeof ( int ) );

    connected[0] = 1;
    for ( i = 1; i < vertex_count; i++ )
    {
        connected[i] = 0;
    }

    mind = ( int * ) malloc ( vertex_count * sizeof ( int ) );
    commonmind = ( int * ) malloc ( vertex_count * sizeof ( int ) );

    for ( i = 0; i < vertex_count; i++ )
    {
        mind[i] = ohd[0][i];
    }

    my_first =   (   tid       * vertex_count ) / ntasks;
    my_last  =   ( ( tid + 1 ) * vertex_count ) / ntasks - 1;

    log_d(tid, "First=%d  Last=%d", my_first, my_last );

    for ( i = 1; i < vertex_count; i++ )
    {
        my_min[0] = INT_MAX;
        my_min[1] = -1;

        find_nearest ( mind, connected, my_min );

        if(MPI_Allreduce(my_min, all_min, 1, MPI_2INT, MPI_MINLOC, MPI_COMM_WORLD) != MPI_SUCCESS)
        {
            log_e(tid, "MPI_Allreduce failed!");
        }

        tid == 0 ? log_i(tid, "Common minimal node %d with distance %d", all_min[1], all_min[0]) : 0 ;

        if ( all_min[1] != -1 )
        {
            tid == 0 ? log_d(tid, "Connecting node %d", all_min[1]) : 0 ;

            connected[all_min[1]] = 1;
            update_mind ( all_min[1], connected, ohd, mind);
        }
        
        if(MPI_Allreduce(mind, commonmind, vertex_count, MPI_INT, MPI_MIN, MPI_COMM_WORLD) != MPI_SUCCESS)
        {
            log_e(tid, "MPI_Allreduce failed!");
        }

        for ( i = 0; i < vertex_count; i++ )
        {
            mind[i] = commonmind[i];
        }
    }

    free ( connected );
    free ( mind );

    return commonmind;
}
Esempio n. 17
0
int *dijkstra_distance ( int ohd[NV][NV]  )

/******************************************************************************/
/*
  Purpose:

    DIJKSTRA_DISTANCE uses Dijkstra's minimum distance algorithm.

  Discussion:

    We essentially build a tree.  We start with only node 0 connected
    to the tree, and this is indicated by setting CONNECTED[0] = 1.

    We initialize MIND[I] to the one step distance from node 0 to node I.
    
    Now we search among the unconnected nodes for the node MV whose minimum
    distance is smallest, and connect it to the tree.  For each remaining
    unconnected node I, we check to see whether the distance from 0 to MV
    to I is less than that recorded in MIND[I], and if so, we can reduce
    the distance.

    After NV-1 steps, we have connected all the nodes to 0, and computed
    the correct minimum distances.

  Licensing:

    This code is distributed under the GNU LGPL license. 

  Modified:

    02 July 2010

  Author:

    Original C version by Norm Matloff, CS Dept, UC Davis.
    This C version by John Burkardt.

  Parameters:

    Input, int OHD[NV][NV], the distance of the direct link between
    nodes I and J.

    Output, int DIJKSTRA_DISTANCE[NV], the minimum distance from 
    node 0 to each node.
*/
{
  int *connected;
  int i;
  int i4_huge = 2147483647;
  int md;
  int *mind;
  int mv;
  int my_first;
  int my_id;
  int my_last;
  int my_md;
  int my_mv;
  int my_step;
  int nth;
/*
  Start out with only node 0 connected to the tree.
*/
  connected = ( int * ) malloc ( NV * sizeof ( int ) );

  connected[0] = 1;
  for ( i = 1; i < NV; i++ )
  {
    connected[i] = 0;
  }
/*
  Initial estimate of minimum distance is the 1-step distance.
*/
  mind = ( int * ) malloc ( NV * sizeof ( int ) );

  for ( i = 0; i < NV; i++ )
  {
    mind[i] = ohd[0][i];
  }
/*
  Begin the parallel region.
*/
  # pragma omp parallel private ( my_first, my_id, my_last, my_md, my_mv, my_step ) \
  shared ( connected, md, mind, mv, nth, ohd )
  {
    my_id = omp_get_thread_num ( );
    nth = omp_get_num_threads ( ); 
    my_first =   (   my_id       * NV ) / nth;
    my_last  =   ( ( my_id + 1 ) * NV ) / nth - 1;
/*
  The SINGLE directive means that the block is to be executed by only
  one thread, and that thread will be whichever one gets here first.
*/
    # pragma omp single
    {
      printf ( "\n" );
      printf ( "  P%d: Parallel region begins with %d threads\n", my_id, nth );
      printf ( "\n" );
    }
    fprintf ( stdout, "  P%d:  First=%d  Last=%d\n", my_id, my_first, my_last );

    for ( my_step = 1; my_step < NV; my_step++ )
    {
/*
  Before we compare the results of each thread, set the shared variable 
  MD to a big value.  Only one thread needs to do this.
*/
      # pragma omp single 
      {
        md = i4_huge;
        mv = -1; 
      }
/*
  Each thread finds the nearest unconnected node in its part of the graph.
  Some threads might have no unconnected nodes left.
*/
      find_nearest ( my_first, my_last, mind, connected, &my_md, &my_mv );
/*
  In order to determine the minimum of all the MY_MD's, we must insist
  that only one thread at a time execute this block!
*/
      # pragma omp critical
      {
        if ( my_md < md )  
        {
          md = my_md;
          mv = my_mv;
        }
      }
/*
  This barrier means that ALL threads have executed the critical
  block, and therefore MD and MV have the correct value.  Only then
  can we proceed.
*/
      # pragma omp barrier
/*
  If MV is -1, then NO thread found an unconnected node, so we're done early. 
  OpenMP does not like to BREAK out of a parallel region, so we'll just have 
  to let the iteration run to the end, while we avoid doing any more updates.

  Otherwise, we connect the nearest node.
*/
      # pragma omp single 
      {
        if ( mv != - 1 )
        {
          connected[mv] = 1;
          printf ( "  P%d: Connecting node %d.\n", my_id, mv );
        }
      }
/*
  Again, we don't want any thread to proceed until the value of
  CONNECTED is updated.
*/
      # pragma omp barrier
/*
  Now each thread should update its portion of the MIND vector,
  by checking to see whether the trip from 0 to MV plus the step
  from MV to a node is closer than the current record.
*/
      if ( mv != -1 )
      {
        update_mind ( my_first, my_last, mv, connected, ohd, mind );
      }
/*
  Before starting the next step of the iteration, we need all threads 
  to complete the updating, so we set a BARRIER here.
*/
      #pragma omp barrier
    }
/*
  Once all the nodes have been connected, we can exit.
*/
    # pragma omp single
    {
      printf ( "\n" );
      printf ( "  P%d: Exiting parallel region.\n", my_id );
    }
  }

  free ( connected );

  return mind;
}