예제 #1
0
int find_winner_euc(struct entries *codes, struct data_entry *sample, 
			struct winner_info *win, int knn)
{
  struct data_entry *codetmp;
  int dim, i, masked;
  float diffsf, diff, difference;
  eptr p;

  dim = codes->dimension;
  win->index = -1;
  win->winner = NULL;
  win->diff = -1.0;
  
  /* Go through all code vectors */
  codetmp = rewind_entries(codes, &p);
  diffsf = FLT_MAX;
  
  while (codetmp != NULL) {
    difference = 0.0;
    masked = 0;

    /* Compute the distance between codebook and input entry */
    for (i = 0; i < dim; i++)
      {
	if ((sample->mask != NULL) && (sample->mask[i] != 0))
	  {
	    masked++;
	    continue; /* ignore vector components that have 1 in mask */
	  }
	diff = codetmp->points[i] - sample->points[i];
	difference += diff * diff;
	if (difference > diffsf) break;
      }
    
    if (masked == dim)
      return 0; /* can't calculate winner, empty data vector */
    
    /* If distance is smaller than previous distances */
    if (difference < diffsf) {
      win->winner = codetmp;
      win->index = p.index;
      win->diff = difference;
      diffsf = difference;
    }
    
    codetmp = next_entry(&p);
  }
  
  if (win->index < 0)
    ifverbose(3)
      fprintf(stderr, "find_winner_euc: can't find winner\n");

  return 1; /* number of neighbours */
}
예제 #2
0
int find_winner_euc2(struct entries *codes, struct data_entry *sample, 
		     struct winner_info *win, int knn)
{
  struct data_entry *codetmp;
  int dim, i;
  float diffsf, diff, difference, *s, *c;
  eptr p;

  if (sample->mask != NULL)
    return find_winner_euc(codes, sample, win, knn);

  dim = codes->dimension;
  win->index = -1;
  win->winner = NULL;
  win->diff = -1.0;
  
  /* Go through all code vectors */
  codetmp = rewind_entries(codes, &p);
  diffsf = FLT_MAX;
  
  while (codetmp != NULL) {
    difference = 0.0;

    /* Compute the distance between codebook and input entry */
    c = codetmp->points; s = sample->points;
    for (i = 0; i < dim; i++)
      {
	diff = *c++ - *s++;
	difference += diff * diff;
      }
    
    /* If distance is smaller than previous distances */
    if (difference < diffsf) {
      win->winner = codetmp;
      win->index = p.index;
      win->diff = difference;
      diffsf = difference;
    }
    
    codetmp = next_entry(&p);
  }
  
  if (win->index < 0)
    ifverbose(3)
      fprintf(stderr, "find_winner_euc: can't find winner\n");

  return 1; /* number of neighbours */
}
예제 #3
0
int main(int argc, char **argv)
{
  long nod, buffer;
  float qerror;
  char *in_data_file;
  char *in_code_file;
  struct teach_params teach;
  int qmode;
  struct entries *data, *codes;
  
  global_options(argc, argv);
  if (extract_parameter(argc, argv, "-help", OPTION2))
    {
      printhelp();
      exit(0);
    }

  in_data_file = extract_parameter(argc, argv, IN_DATA_FILE, ALWAYS);
  in_code_file = extract_parameter(argc, argv, IN_CODE_FILE, ALWAYS);
  buffer = oatoi(extract_parameter(argc, argv, "-buffer", OPTION), 0);
  teach.radius = oatof(extract_parameter(argc, argv, TRAINING_RADIUS, OPTION), 1.0);
  qmode = oatoi(extract_parameter(argc, argv, "-qetype", OPTION), 0);

  label_not_needed(1);

  ifverbose(2)
    fprintf(stdout, "Input entries are read from file %s\n", in_data_file);
  data = open_entries(in_data_file);
  
  if (data == NULL)
    {
      fprintf(stderr, "Can't open datafile: %s\n", in_data_file);
      exit(1);
    }

  ifverbose(2)
    fprintf(stdout, "Codebook entries are read from file %s\n", in_code_file);
  codes = open_entries(in_code_file);
  
  if (codes == NULL)
    {
      fprintf(stderr, "Can't open code file '%s'\n", in_code_file);
      close_entries(data);
      exit(1);
    }

  if (codes->topol < TOPOL_HEXA) {
    fprintf(stderr, "File %s is not a map file\n", in_code_file);
    close_entries(data);
    close_entries(codes);
    exit(1);
  }

  if (data->dimension != codes->dimension) {
    fprintf(stderr, "Data and codebook vectors have different dimensions (%d != %d)",
	    data->dimension, codes->dimension);
    close_entries(data);
    close_entries(codes);
    exit(1);
  }

  set_teach_params(&teach, codes, data, buffer);
  set_som_params(&teach);

  if (qmode > 0)
    qerror = find_qerror2(&teach);
  else
    qerror = find_qerror(&teach);

  nod = teach.data->num_entries;

  ifverbose(1)
    fprintf(stdout, "Quantization error of %s with map %s is %f per sample (%d samples)\n",
	    in_data_file, in_code_file, qerror / (float) nod, nod);
  else
예제 #4
0
int main(int argc, char **argv)
{
  int not, bnot, error;
  int xdim, ydim;
  int topol, neigh;
  float alpha1, radius1;
  int fixed, weights;
  float alpha2, radius2;
  float qerror, qerrorb;
  char *in_data_file, *in_test_file, *out_code_file, *alpha_s;
  struct entries *data = NULL;
  struct entries *testdata = NULL;
  struct entries *codes = NULL;
  struct entries *codess = NULL;
  struct entries *tmp;
  struct teach_params params;
  long buffer, length1, length2, noc, nod;
  int qmode;
  struct typelist *type_tmp;

  error = 0;
  global_options(argc, argv);
  print_description();

  not = get_int("Give the number of trials", 0);
  in_data_file = get_str("Give the input data file name");
  in_test_file = get_str("Give the input test file name");
  out_code_file = get_str("Give the output map file name");

  topol = topol_type(get_str("Give the topology type"));
  if (topol == TOPOL_UNKNOWN) {
    ifverbose(2)
      fprintf(stderr, "Unknown topology type, using hexagonal\n");
    topol = TOPOL_HEXA;
  }
  neigh = neigh_type(get_str("Give the neighborhood type"));
  if (neigh == NEIGH_UNKNOWN) {
    ifverbose(2)
      fprintf(stderr, "Unknown neighborhood type, using bubble\n");
    neigh = NEIGH_BUBBLE;
  }

  xdim = get_int("Give the x-dimension", 0);
  ydim = get_int("Give the y-dimension", 0);

  length1 = get_int("Give the training length of first part", 0);
  alpha1 = get_float("Give the training rate of first part", 0.0);
  radius1 = get_float("Give the radius in first part", 0.0);
  length2 = get_int("Give the training length of second part", 0);
  alpha2 = get_float("Give the training rate of second part", 0.0);
  radius2 = get_float("Give the radius in second part", 0.0);

  printf("\n");

  fixed = (int) oatoi(extract_parameter(argc, argv, FIXPOINTS, OPTION), 0);
  weights = (int) oatoi(extract_parameter(argc, argv, WEIGHTS, OPTION), 0);
  buffer = oatoi(extract_parameter(argc, argv, "-buffer", OPTION), 0);
  alpha_s = extract_parameter(argc, argv, "-alpha_type", OPTION);
  qmode = oatoi(extract_parameter(argc, argv, "-qetype", OPTION), 0);

  use_fixed(fixed);
  use_weights(weights);

  label_not_needed(1);

  ifverbose(2)
    fprintf(stderr, "Input entries are read from file %s\n", in_data_file);
  data = open_entries(in_data_file);
  if (data == NULL)
    {
      fprintf(stderr, "Can't open data file '%s'\n", in_data_file);
      error = 1;
      goto end;
    }
  set_buffer(data, buffer);

  ifverbose(2)
    fprintf(stderr, "Test entries are read from file %s\n", in_test_file);
  testdata = open_entries(in_test_file);
  if (testdata == NULL)
    {
      fprintf(stderr, "Can't open test data file '%s'\n", in_test_file);
      error = 1;
      goto end;
    }
  set_buffer(testdata, buffer);

  noc = xdim * ydim;
  if (noc <= 0) 
    {
      fprintf(stderr, "Dimensions of map (%d %d) are incorrect\n", xdim, ydim);
      error = 1;
      goto end;
    }
  if (xdim < 0) 
    {
      fprintf(stderr, "Dimensions of map (%d %d) are incorrect\n", xdim, ydim);
      error = 1;
      goto end;
    }

  if (alpha_s)
    {
      type_tmp = get_type_by_str(alpha_list, alpha_s);
      if (type_tmp->data == NULL)
	{
	  fprintf(stderr, "Unknown alpha type %s\n", alpha_s);
	  error = 1;
	  goto end;
	}
    }
  else
    type_tmp = get_type_by_id(alpha_list, ALPHA_LINEAR);

  params.alpha_type = type_tmp->id;
  params.alpha_func = type_tmp->data;


  codess = NULL;
  qerrorb = FLT_MAX;
  bnot = 0;
  while (not) {
    init_random(not);

    ifverbose(2)
      fprintf(stderr, "Initializing codebook\n");
    
    codes = randinit_codes(data, topol, neigh, xdim, ydim);
    if (codes == NULL)
      {
	fprintf(stderr, "Error initializing random codebook, aborting\n");
	error = 1;
	goto end;
      }

    set_teach_params(&params, codes, NULL, 0);
    set_som_params(&params);
    params.data = data;
    
    params.length = length1;
    params.alpha = alpha1;
    params.radius = radius1;

    ifverbose(2)
      fprintf(stderr, "Training map, first part, rlen: %ld alpha: %f\n", 
	      params.length, params.alpha);
    codes = som_training(&params);

    params.length = length2;
    params.alpha = alpha2;
    params.radius = radius2;
    ifverbose(2)
      fprintf(stderr, "Training map, second part, rlen: %ld alpha: %f\n", 
	      params.length, params.alpha);
    codes = som_training(&params);

    params.data = testdata;
    ifverbose(2)
      fprintf(stderr, "Calculating quantization error\n");

    if (qmode > 0)
      qerror = find_qerror2(&params);
    else
      qerror = find_qerror(&params);
    nod = testdata->num_entries;

    if (qerror < qerrorb) {
      qerrorb = qerror;
      bnot = not;

      tmp = codess;
      codess = codes;
      codes = tmp;
    }

    close_entries(codes);
    codes = NULL;
    ifverbose(1)
      fprintf(stderr, "%3d: %f\n", not, qerror/(float) nod);
    not--;
  }

  if (codess != NULL) 
    {
      ifverbose(2)
	fprintf(stdout, "Codebook entries are saved to file %s\n", out_code_file);
      save_entries(codess, out_code_file);
      ifverbose(1)
	fprintf(stdout, "Smallest error with random seed %3d: %f\n",
                bnot, qerrorb/(float) nod);
    }

 end:
  if (codess)
    close_entries(codess);
  if (data)
    close_entries(data);
  if (testdata)
    close_entries(testdata);
  
  return(error);
}
예제 #5
0
struct snapshot_info *get_snapshot(char *filename, long interval, int type)
{
  struct snapshot_info *shot;
  int len = 0;
  shot = malloc(sizeof(struct snapshot_info));
  if (shot == NULL)
    {
      fprintf(stderr, "get_snapshot: Can't allocate structure\n");
      perror("get_snapshot");
      return NULL;
    }

  shot->flags = 0;
  shot->fi = NULL;
#ifndef NO_BACKGROUND_SNAP
  shot->pid = -1;
#endif
  shot->counter = 0;
  shot->data = NULL;

  /* allocate room for string */
  shot->filename = NULL;
  if (filename)
    {
      len = strlen(filename);
      if ((shot->filename = malloc(len + 1)) == NULL)
	{
	  fprintf(stderr, "get_snapshot: Can't allocate mem for string\n");
	  perror("get_snapshot");
	  free(shot);
	  return NULL;
	}
      else
	strcpy(shot->filename, filename);
    }
  
  if (len > 0)
    if (shot->filename[len - 1] == '&')
      {
	shot->filename[len - 1] = '\0';
	shot->flags |= SNAPFLAG_BACKGROUND;
      }
  shot->interval = interval;
  shot->type = type;
  switch (type)
    {
    case SNAPSHOT_KEEPOPEN:
      shot->flags |= SNAPFLAG_KEEPOPEN;
      shot->flags &= (~SNAPFLAG_NOWAIT);
      break;
#ifndef NO_BACKGROUND_SNAP
    case SNAPSHOT_ASYNC:
      shot->flags |= SNAPFLAG_BACKGROUND;
      break;
    case SNAPSHOT_ASYNC_NOWAIT:
      shot->flags |= SNAPFLAG_BACKGROUND|SNAPFLAG_NOWAIT;
      break;
#endif
    default:
      break;
    }

  ifverbose(2)
    fprintf(stderr, "snapshot: filename: '%s', interval: %ld, type: %s\n",
	    shot->filename, shot->interval, get_str_by_id(snapshot_list, type));

  return shot;
}
예제 #6
0
int save_snapshot(struct teach_params *teach, long iter)
{
  struct entries *codes = teach->codes;
  struct snapshot_info *shot = teach->snapshot;
  struct data_entry *entry;
  eptr p;
  char filename[1024]; /* hope this is enough */
  struct file_info *fi = NULL;
  int retcode = 0;
  int bg = shot->flags & SNAPFLAG_BACKGROUND;
  int ko = shot->flags & SNAPFLAG_KEEPOPEN;

  shot->counter++;
  if (ko)
    if ((fi = shot->fi) == NULL)
      {
	if ((shot->fi = open_file(shot->filename, "w")) == NULL)
	  return 1;
	
	fi = shot->fi;
      }
    else
      fi = shot->fi;

#ifndef NO_BACKGROUND_SNAP
  if (bg)
    {
      if (shot->pid > 0)
	{
	  int statptr;
	  if (!(shot->flags & SNAPFLAG_NOWAIT))
	    {
	      /* fprintf(stderr, "Snap: waiting for pid %d\n", (int)shot->pid); */
	      /* wait for previous child before forking a new one */
	      waitpid(shot->pid, &statptr, 0);
	      shot->pid = -1;
	    }
	}

      if ((shot->pid = fork()) < 0)
	{
	  perror("save_snapshot(background):");
	  return 1;
	}
      if (shot->pid == 0)
	{
	  /* fprintf(stderr, "saving snapshot\n"); */
	}
      else
	{
	  /* fprintf(stderr, "forked pid %d\n", (int)shot->pid); */
	  return 0;
	}
    }
#endif /* NO_BACKGROUND_SNAP */

  if (fi == NULL)
    {
      /* make filename */
      sprintf(filename, shot->filename, iter);
      if ((fi = open_file(filename, "w")) == NULL)
	return 1;
    }

  if (ko)
    fprintf(fi2fp(fi), "#start %d\n", shot->counter);

  if (write_header(fi, codes))
    {
      fprintf(stderr, "save_snapshot: Error writing headers\n");
      close_file(shot->fi);
      shot->fi = NULL;
      return 1;
    }

  /* open file for writing */

  ifverbose(3)
    fprintf(stderr, "saving snapshot: file '%s', type '%s'\n", filename, 
	    get_str_by_id(snapshot_list, shot->type));

  fprintf(fi2fp(fi), "#SNAPSHOT FILE\n#iterations: %ld/%ld\n",
	  iter, teach->length);

  for (entry = rewind_entries(codes, &p); entry != NULL; entry = next_entry(&p))
    {
      if (write_entry(fi, codes, entry))
	{
	  fprintf(stderr, "save_entries: Error writing entry, aborting\n");
	  retcode = 1;
	  break;
	}
    }

  if (ko)
    {
      fprintf(fi2fp(fi), "#end\n");
      fflush(fi2fp(fi));
    }
  else
    close_file(fi);
  
#ifndef NO_BACKGROUND_SNAP
  if (bg)
    exit(retcode);
  else
#endif
    return(retcode);
}
예제 #7
0
int find_winner_knn2(struct entries *codes, struct data_entry *sample, 
		     struct winner_info *win, int knn)
{
  struct data_entry *codetmp;
  int dim, i, j;
  float difference, diff, *s, *c;
  eptr p;

  if (sample->mask != NULL)
    return find_winner_knn(codes, sample, win, knn);

  if (knn == 1) /* might be a little faster */
    return find_winner_euc2(codes, sample, win, 1);

  dim = codes->dimension;
  
  for (i = 0; i < knn; i++)
    {
      win[i].index = -1;
      win[i].winner = NULL;
      win[i].diff = FLT_MAX;
    }
  /* Go through all code vectors */

  codetmp = rewind_entries(codes, &p);
  
  while (codetmp != NULL) {
    difference = 0.0;
    
    /* Compute the distance between codebook and input entry */
    c = codetmp->points; s = sample->points;
    for (i = 0; i < dim; i++)
      {
	diff = *c++ - *s++;
	difference += diff * diff;
      }

    /* If distance is smaller than previous distances */
    for (i = 0; (i < knn) && (difference > win[i].diff); i++);

    if (i < knn) 
      {
	for (j = knn - 1; j > i; j--)
	  {
	    win[j].diff = win[j - 1].diff;
	    win[j].index = win[j - 1].index;
	    win[j].winner = win[j - 1].winner;
	  }

	win[i].diff = difference;
	win[i].index = p.index;
	win[i].winner = codetmp;
      }
    
    codetmp = next_entry(&p);
  }
  
  if (win->index < 0)
    ifverbose(3)
      fprintf(stderr, "find_winner_knn: can't find winner\n");

  return knn; /* number of neighbours */
}
예제 #8
0
int find_winner_knn(struct entries *codes, struct data_entry *sample, 
		    struct winner_info *win, int knn)
{
  struct data_entry *codetmp;
  int dim, i, j, masked;
  float difference, diff;
  eptr p;

  if (knn == 1) /* might be a little faster */
    return find_winner_euc(codes, sample, win, 1);

  dim = codes->dimension;
  
  for (i = 0; i < knn; i++)
    {
      win[i].index = -1;
      win[i].winner = NULL;
      win[i].diff = FLT_MAX;
    }
  /* Go through all code vectors */

  codetmp = rewind_entries(codes, &p);
  
  while (codetmp != NULL) {
    difference = 0.0;
    
    masked = 0;
    /* Compute the distance between codebook and input entry */
    for (i = 0; i < dim; i++)
      {
	/* pitaisiko ottaa huomioon myos codebookissa olevat?? */
	if ((sample->mask != NULL) && (sample->mask[i] != 0))
	  {
	    masked++;
	    continue; /* ignore vector components that have 1 in mask */
	  }
	diff = codetmp->points[i] - sample->points[i];
	difference += diff * diff;
	if (difference > win[knn-1].diff) break;
      }

    if (masked == dim)
      return 0;
    
    /* If distance is smaller than previous distances */
    for (i = 0; (i < knn) && (difference > win[i].diff); i++);

    if (i < knn) 
      {
	for (j = knn - 1; j > i; j--)
	  {
	    win[j].diff = win[j - 1].diff;
	    win[j].index = win[j - 1].index;
	    win[j].winner = win[j - 1].winner;
	  }

	win[i].diff = difference;
	win[i].index = p.index;
	win[i].winner = codetmp;
      }
    
    codetmp = next_entry(&p);
  }
  
  if (win->index < 0)
    ifverbose(3)
      fprintf(stderr, "find_winner_knn: can't find winner\n");

  return knn; /* number of neighbours */
}