IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 38579


Ignore:
Timestamp:
Jul 7, 2015, 11:16:18 PM (11 years ago)
Author:
eugene
Message:

update to uniq algorith: sort first then look at sequences

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20150625/Ohana/src/opihi/cmd.data/uniq.c

    r20936 r38579  
    11# include "data.h"
     2// NOTE: if there are only a few uniq values, the old algorithm is not bad. 
     3// for 10000 uniq values, 30M points take ~20sec in the new algorithm,
     4// 3M points takess 45 sec in the old method.
    25
    36int uniq (int argc, char **argv) {
    47 
    5   int Nnew, i, j, found;
     8  int Nnew, i, N;
    69  Vector *ivec, *ovec;
    710
     11  Vector *cvec = NULL;
     12  if ((N = get_argument (argc, argv, "-c"))) {
     13    remove_argument (N, &argc, argv);
     14    if ((cvec = SelectVector (argv[N], ANYVECTOR, TRUE)) == NULL) {
     15      gprint (GP_ERR, "invalid vector %s\n", argv[N]);
     16      return FALSE;
     17    }
     18    remove_argument (N, &argc, argv);
     19  }
     20
    821  if (argc != 3) {
    9     gprint (GP_ERR, "USAGE: uniq (in) (out)\n");
     22    gprint (GP_ERR, "USAGE: uniq (in) (out) -c count\n");
    1023    return (FALSE);
    1124  }
     
    1629  /* allocate the maximum possible needed */
    1730  ResetVector (ovec, ivec->type, ivec->Nelements);
     31  if (cvec) {
     32    ResetVector (cvec, OPIHI_INT, ivec->Nelements);
     33  }
    1834
    1935  Nnew = 0;
    2036
    2137  if (ivec->type == OPIHI_FLT) {
    22     opihi_flt *v1 = ivec[0].elements.Flt;
    23     for (i = 0; i < ivec[0].Nelements; i++, v1++) {
    24       opihi_flt *v2 = ovec[0].elements.Flt;
    25       found = FALSE;
    26       for (j = 0; !found && (j < Nnew); j++, v2++) {
    27         if (*v1 == *v2) found = TRUE;
     38    // copy the input data to a temporary array to avoid damaging it with sort
     39    opihi_flt *indata = NULL;
     40    ALLOCATE (indata, opihi_flt, ivec[0].Nelements);
     41    memcpy (indata, ivec->elements.Flt, ivec[0].Nelements*sizeof(opihi_flt));
     42
     43    dsort (indata, ivec->Nelements);
     44
     45    Nnew = 0;
     46    opihi_flt *vtgt = ovec[0].elements.Flt;
     47
     48    opihi_flt *vsrc = indata;
     49
     50    for (i = 0; i < ivec->Nelements; Nnew++) {
     51      vtgt[Nnew] = *vsrc;
     52      int Ndup = 0;
     53      opihi_flt lastValue = *vsrc;
     54      while ((i < ivec->Nelements) && (*vsrc == lastValue)) {
     55        i++;
     56        vsrc ++;
     57        Ndup ++;
    2858      }
    29       if (!found) {
    30         ovec[0].elements.Flt[Nnew] = *v1;
    31         Nnew ++;
     59      if (cvec) {
     60        cvec->elements.Int[Nnew] = Ndup;
    3261      }
    3362    }
     63    free (indata);
    3464  } else {
    35     opihi_int *v1 = ivec[0].elements.Int;
    36     for (i = 0; i < ivec[0].Nelements; i++, v1++) {
    37       opihi_int *v2 = ovec[0].elements.Int;
    38       found = FALSE;
    39       for (j = 0; !found && (j < Nnew); j++, v2++) {
    40         if (*v1 == *v2) found = TRUE;
     65    // copy the input data to a temporary array to avoid damaging it with sort
     66    opihi_int *indata = NULL;
     67    ALLOCATE (indata, opihi_int, ivec[0].Nelements);
     68    memcpy (indata, ivec->elements.Int, ivec[0].Nelements*sizeof(opihi_int));
     69
     70    isort (indata, ivec->Nelements);
     71
     72    Nnew = 0;
     73    opihi_int *vtgt = ovec[0].elements.Int;
     74
     75    opihi_int *vsrc = indata;
     76
     77    for (i = 0; i < ivec->Nelements; Nnew++) {
     78      vtgt[Nnew] = *vsrc;
     79      int Ndup = 0;
     80      opihi_int lastValue = *vsrc;
     81      while ((i < ivec->Nelements) && (*vsrc == lastValue)) {
     82        i++;
     83        vsrc ++;
     84        Ndup ++;
    4185      }
    42       if (!found) {
    43         ovec[0].elements.Int[Nnew] = *v1;
    44         Nnew ++;
     86      if (cvec) {
     87        cvec->elements.Int[Nnew] = Ndup;
    4588      }
    4689    }
     90    free (indata);
    4791  }
    4892
    4993  // free up extra memory
    5094  ResetVector (ovec, ivec->type, Nnew);
     95  if (cvec) ResetVector (ovec, OPIHI_INT, Nnew);
    5196
    5297  return (TRUE);
Note: See TracChangeset for help on using the changeset viewer.