Does C have a "canned" find function? 
Author Message
 Does C have a "canned" find function?

Hello:

I have used Matlab for several years, but for speed purposes it has been
suggested that I convert a data interpolation program into C.  I have always
relied heavily on Matlab's built-in "find" function.  Is there a similar
function in the C library?

Thanks,

dcw

PS:

I = FIND(X) returns the indices of the vector X that are non-zero. For
example, I = FIND(A>100), returns the indices of A (an array/matrix/vector)
where A is greater than 100.



Wed, 09 Mar 2005 02:20:39 GMT  
 Does C have a "canned" find function?

Quote:

> Hello:

> I have used Matlab for several years, but for speed purposes it has been
> suggested that I convert a data interpolation program into C.  I have always
> relied heavily on Matlab's built-in "find" function.  Is there a similar
> function in the C library?

Don't assume that everybody know what Matlab's "find" function does;
explain what it does please.

Stig
--
brautaset.org



Wed, 09 Mar 2005 02:41:38 GMT  
 Does C have a "canned" find function?

Quote:


>> Hello:

>> I have used Matlab for several years, but for speed purposes it has been
>> suggested that I convert a data interpolation program into C.  I have
>> always
>> relied heavily on Matlab's built-in "find" function.  Is there a similar
>> function in the C library?

> Don't assume that everybody know what Matlab's "find" function does;
> explain what it does please.

Hi did in his post scriptum.
Anyhow, there is no such function in c. But you can roll your own:

struct indices{
    int *indices;
    int n_alloc;
    int n_indices;

Quote:
};

struct indices *indices_create(void){
   struct indices *ind_p=malloc(sizeof *ind_p);
   if(ind_p){
      ind_p->indices=NULL;
      ind_p->n_alloc=0;
      ind_p->n_indices=0;
   }
   return ind_p;

Quote:
}

int indices_append(struct indices *ind_p,int i){
   int *tmp=NULL;

   /* allocate memory for the new element if necessary */

   if(ind_p->n_alloc==0){
      /* first element */
      tmp=malloc(sizeof int);
      if(tmp){
         ind_p->n_alloc=1;
      }
   }else if(ind_p->n_alloc==ind_p->n_indices){
      /* all slots are taken, grow the array */
      tmp=realloc(ind_p->indices,ind_p->n_alloc*sizeof int*3/2){
      if(tmp){
         ind_p->n_alloc=3*ind_p->n_alloc/2;
      }
   }else{
      /* there are slots left */
      tmp=ind_p->indices;
   }

   if(tmp){
      /* there is memory available copy the new element */
      tmp[ind_p->n_indices]=i;
      ind_p->indices=tmp;
      ind_p->n_indices++;
   }

   return tmp!=NULL;

Quote:
}

struct indices *find(double *x,int n,int (*crit)(int x)){
   struct indices *ind_p;
   int i;

   ind_p=indices_create();
   if(ind_p){
      for(i=0;i<n;i++){
         if(crit(x[i]){
            /* x[i] satisfies the criterion function */
            indices_append(ind_p,i);
         }
      }
   }
   return ind_p;

Quote:
}

Not tested nor compiled
Tobias.

--
unix http://www.faqs.org/faqs/by-newsgroup/comp/comp.unix.programmer.html
clc http://www.eskimo.com/~scs/C-faq/top.html
fclc (french): http://www.isty-info.uvsq.fr/~rumeau/fclc/



Wed, 09 Mar 2005 03:24:00 GMT  
 Does C have a "canned" find function?

Quote:

> I = FIND(X) returns the indices of the vector X that are non-zero. For
> example, I = FIND(A>100), returns the indices of A (an array/matrix/vector)
> where A is greater than 100.

Doesn't this imply a definition for I where it may contain multiple values?

There is no such function in the standard C library, but one shouldn't
be too hard to write, once you clearly define the parameters.  Using
bsearch as a model, I came up woth something like this:

void find(const void *array, size_t count, size_t elemsize,
           const int *indices, size_t indices_size,
           size_t *indices_used, int (*testfn)(const void *));

where:
        array is an array of values you're searching
        count is the number of elements in array
        elemsize is the size of each element in the array
        indices is an array of integers to hold the result
        indices_size is the size of indices
        indices_used points to the number of matches that were found,
                     and may be greater than indices_size if indices
                     is not big enough to hold the result.
        testfn is a function to determine if each element matches.
               it accepts an object pointer and returns 1 if there's
               a match, or zero if no match.

Implementation:

void find(const void *array, size_t count, size_t elemsize,
           const int *indices, size_t indices_size,
           size_t *indices_used, int (*testfn)(const void *))
{
     int   current_elem, current_index;
     void *current_object

     current_index = 0;
     current_elem = 0;
     while(current_elem < count)
     {
         current_object = ((char *)array) + (elemsize * current_elem);
        if (testfn(current_object))
         {
             if (current_index < indices_size)
             {
                 indices[current_index] = current_elem;
             }
             current_index++;
         }
         current_elem++;
     }

     *indices_used = current_index;

Quote:
}

Example:

        typedef struct foo
        {
            /* The actual definition is immaterial */
        } foo;

        int testfoo(foo *object)
        {
            /* This is some test function returning 0 or 1 */
        }

        int main()
        {
            foo fooArray[1000];
            int matches[1000];
             int num_matches;
            int i;

            /* Pretend we did something here to load values into
               fooArray */

            find(fooArray, 1000, sizeof(foo), matches, 1000,
                 &num_matches, testfoo);

            printf("Matches found are array indices: \n")
            for (i=0; i<num_matches; i++)
            {
                printf("%d ", matches[i]);
            }
            printf("\n");

            return 0;
        }



Wed, 09 Mar 2005 03:34:36 GMT  
 Does C have a "canned" find function?

Quote:


>> I have used Matlab for several years, but for speed purposes it has been
>> suggested that I convert a data interpolation program into C.  I have always
>> relied heavily on Matlab's built-in "find" function.  Is there a similar
>> function in the C library?

> Don't assume that everybody know what Matlab's "find" function does;
> explain what it does please.

He did.  You truncated the end of his message:

 >> PS:
 >>
 >> I = FIND(X) returns the indices of the vector X that are non-zero.
 >> For example, I = FIND(A>100), returns the indices of A (an
 >> array/matrix/vector) where A is greater than 100.

-- David



Wed, 09 Mar 2005 03:35:59 GMT  
 Does C have a "canned" find function?

Quote:
> Hello:

> I have used Matlab for several years, but for speed purposes it has been
> suggested that I convert a data interpolation program into C.  I have
always
> relied heavily on Matlab's built-in "find" function.  Is there a similar
> function in the C library?

> Thanks,

> dcw

> PS:

> I = FIND(X) returns the indices of the vector X that are non-zero. For
> example, I = FIND(A>100), returns the indices of A (an

array/matrix/vector)

Quote:
> where A is greater than 100.

The C standard library does not contain a function to find a subset of a
vector.

I suspect you may be looking for "The Selection Problem" which is not solved
intrinsically with any C library function.

Or perhaps you need to sort the vector.  Since I don't know why you need to
locate a subset of the data, it is hard for me to say what you might be
after.

Here is selection in C -- maybe it will prove helpful:

#include <stdlib.h>
typedef double  Etype; /* Choose your poison here. */

extern Etype    RandomSelect(Etype * A, size_t p, size_t r, size_t i);
extern size_t   RandRange(size_t a, size_t b);
extern size_t   RandomPartition(Etype * A, size_t p, size_t r);
extern size_t   Partition(Etype * A, size_t p, size_t r);

/*
**
** In the following code, every reference to CLR means:
**
**    "Introduction to Algorithms"
**    By Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest
**    ISBN 0-07-013143-0
*/

/*
** CLR, page 187
*/
Etype           RandomSelect(Etype A[], size_t p, size_t r, size_t i)
{
    size_t          q,
                    k;
    if (p == r)
        return A[p];
    q = RandomPartition(A, p, r);
    k = q - p + 1;

    if (i <= k)
        return RandomSelect(A, p, q, i);
    else
        return RandomSelect(A, q + 1, r, i - k);

Quote:
}

size_t          RandRange(size_t a, size_t b)
{
    size_t          c = (size_t) ((double) rand() / ((double) RAND_MAX + 1)
* (b - a));
    return c + a;

Quote:
}

/*
** CLR, page 162
*/
size_t          RandomPartition(Etype A[], size_t p, size_t r)
{
    size_t          i = RandRange(p, r);
    Etype           Temp;
    Temp = A[p];
    A[p] = A[i];
    A[i] = Temp;
    return Partition(A, p, r);

Quote:
}

/*
** CLR, page 154
*/
size_t          Partition(Etype A[], size_t p, size_t r)
{
    Etype           x,
                    temp;
    size_t          i,
                    j;

    x = A[p];
    i = p - 1;
    j = r + 1;

    for (;;) {
        do {
            j--;
        } while (!(A[j] <= x));
        do {
            i++;
        } while (!(A[i] >= x));
        if (i < j) {
            temp = A[i];
            A[i] = A[j];
            A[j] = temp;
        } else
            return j;
    }

Quote:
}

--
C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
 "The C-FAQ Book" ISBN 0-201-84519-9
C.A.P. FAQ: ftp://cap.connx.com/pub/Chess%20Analysis%20Project%20FAQ.htm


Wed, 09 Mar 2005 03:34:08 GMT  
 Does C have a "canned" find function?

Quote:


> > Hello:

> > I have used Matlab for several years, but for speed purposes it has been
> > suggested that I convert a data interpolation program into C.  I have always
> > relied heavily on Matlab's built-in "find" function.  Is there a similar
> > function in the C library?

> Don't assume that everybody know what Matlab's "find" function does;
> explain what it does please.

    The explanation was in the piece you snipped.

    To the O.P.: No, the C library provides no such function.

--



Wed, 09 Mar 2005 03:22:26 GMT  
 Does C have a "canned" find function?

Quote:
> Hello:

> I have used Matlab for several years, but for speed purposes it has been
> suggested that I convert a data interpolation program into C.  I have
always
> relied heavily on Matlab's built-in "find" function.  Is there a similar
> function in the C library?

> Thanks,

> dcw

> PS:

> I = FIND(X) returns the indices of the vector X that are non-zero. For
> example, I = FIND(A>100), returns the indices of A (an

array/matrix/vector)

Quote:
> where A is greater than 100.

The library has no such function, but it's not hard to write:

#include <stdio.h>
#include <stdlib.h>

typedef enum
{
    GT, LT
    /* (add any other operations you need) */

Quote:
} op;

size_t find(int *vec, size_t elems, size_t *ind, op oper, int value)
{
    size_t cnt = 0;
    size_t i = 0;
    int *p = ind;

    for(i = 0; i < elems; ++i)
    {
        int elem = vec[i];

        switch(oper)
        {
        case GT:
            if(elem > value)
            {
                *p++ = i;
                ++cnt;
            }

            break;

        case LT:
            if(elem < value)
            {
                *p++ = i;
                ++cnt;
            }

            break;

        /* (add any other operations you need) */

        default:
            /* ignore undefined operations */
            break;
        }
    }

    return cnt; /* number of 'hits' (indices) */

Quote:
}

int main()
{
    /* test data */
    int vector[] = {0, 105, 0, 256, 24, 100, 42, 0, 8, 456, 0};

    size_t indices[sizeof vector / sizeof *vector] = {0};
/* (number of elements in array 'indices' *must* be
    at least equal to number of elements in array 'vector') */

    size_t count = sizeof vector / sizeof *vector; /* convenience object */
    size_t hits = 0;
    size_t i = 0;

    /* show vector */
    puts("vector contents:");

    for(i = 0; i < count; ++i)
        printf("element [%lu] == %d\n", (unsigned long)i, vector[i]);

    putchar('\n');

    /* call the find function */
    hits = find(vector, count, indices, GT, 100);

    /* show results */
    puts("indices of values > 100:");

    for(i = 0; i < hits; ++i)
        printf("%lu\n", (unsigned long)(indices[i]));

    return 0;

Quote:
}

Output:

vector contents:
element [0] == 0
element [1] == 105
element [2] == 0
element [3] == 256
element [4] == 24
element [5] == 100
element [6] == 42
element [7] == 0
element [8] == 8
element [9] == 456
element [10] == 0

indices of values > 100:
1
3
9

Warning: code not thoroughly tested.

HTH,
-Mike



Wed, 09 Mar 2005 04:13:49 GMT  
 Does C have a "canned" find function?

Quote:


> > Hello:

> > I have used Matlab for several years, but for speed purposes it has been
> > suggested that I convert a data interpolation program into C.  I have always
> > relied heavily on Matlab's built-in "find" function.  Is there a similar
> > function in the C library?

> Don't assume that everybody know what Matlab's "find" function does;
> explain what it does please.

He did.

"I = FIND(X) returns the indices of the vector X that are non-zero. For
example, I = FIND(A>100), returns the indices of A (an
array/matrix/vector) where A is greater than 100."

Answer to OP: There is no standard function to do what you want, but
such a function is not difficult to write. If the array is sorted, use a
binary search. If not, use a linear search.

--

"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton



Wed, 09 Mar 2005 03:51:10 GMT  
 Does C have a "canned" find function?

Quote:



>>> I have used Matlab for several years, but for speed purposes it has been
>>> suggested that I convert a data interpolation program into C.  I have always
>>> relied heavily on Matlab's built-in "find" function.  Is there a similar
>>> function in the C library?

>> Don't assume that everybody know what Matlab's "find" function does;
>> explain what it does please.

> He did.  You truncated the end of his message:

Oops... My apologies to the OP.

Stig
--
brautaset.org



Wed, 09 Mar 2005 07:55:13 GMT  
 Does C have a "canned" find function?

Quote:



> > > Hello:

> > > I have used Matlab for several years, but for speed purposes it has
> > > been suggested that I convert a data interpolation program into C.
> > > I have always relied heavily on Matlab's built-in "find" function.
> > > Is there a similar function in the C library?

> > Don't assume that everybody know what Matlab's "find" function does;
> > explain what it does please.

> He did.

> "I = FIND(X) returns the indices of the vector X that are non-zero. For
> example, I = FIND(A>100), returns the indices of A (an
> array/matrix/vector) where A is greater than 100."

> Answer to OP: There is no standard function to do what you want, but
> such a function is not difficult to write. If the array is sorted, use a
> binary search. If not, use a linear search.

A binary search won't help unless the condition is such that the
matching values are contiguous.

--

San Diego Supercomputer Center           <*>  <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"



Thu, 10 Mar 2005 02:24:04 GMT  
 Does C have a "canned" find function?

Quote:



<snip>

Quote:

> > "I = FIND(X) returns the indices of the vector X that are non-zero. For
> > example, I = FIND(A>100), returns the indices of A (an
> > array/matrix/vector) where A is greater than 100."

> > Answer to OP: There is no standard function to do what you want, but
> > such a function is not difficult to write. If the array is sorted, use a
> > binary search. If not, use a linear search.

> A binary search won't help unless the condition is such that the
> matching values are contiguous.

Right, which is why you have to sort it in such a way that they are! :-)

--

"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton



Thu, 10 Mar 2005 02:33:28 GMT  
 Does C have a "canned" find function?

...

Quote:
>    if(ind_p->n_alloc==0){
>       /* first element */
>       tmp=malloc(sizeof int);
>       if(tmp){
>          ind_p->n_alloc=1;
>       }
>    }else if(ind_p->n_alloc==ind_p->n_indices){
>       /* all slots are taken, grow the array */
>       tmp=realloc(ind_p->indices,ind_p->n_alloc*sizeof int*3/2){
>       if(tmp){
>          ind_p->n_alloc=3*ind_p->n_alloc/2;
>       }

Growing an initial allocation of 1 by 3/2 doesn't work, it's still 1.
You need to either grow by a factor of (at least) 2 (in all cases,
or at least the case of 1), or start with a larger base allocation.
Given the usual space and time overhead of heap allocations,
and especially for a small type like int, I prefer the latter.

--
- David.Thompson 1 now at worldnet.att.net



Fri, 18 Mar 2005 07:28:06 GMT  
 Does C have a "canned" find function?

Quote:


> ...
>>    if(ind_p->n_alloc==0){
>>       /* first element */
>>       tmp=malloc(sizeof int);
>>       if(tmp){
>>          ind_p->n_alloc=1;
>>       }
>>    }else if(ind_p->n_alloc==ind_p->n_indices){
>>       /* all slots are taken, grow the array */
>>       tmp=realloc(ind_p->indices,ind_p->n_alloc*sizeof int*3/2){
>>       if(tmp){
>>          ind_p->n_alloc=3*ind_p->n_alloc/2;
>>       }

> Growing an initial allocation of 1 by 3/2 doesn't work, it's still 1.
> You need to either grow by a factor of (at least) 2 (in all cases,
> or at least the case of 1), or start with a larger base allocation.
> Given the usual space and time overhead of heap allocations,
> and especially for a small type like int, I prefer the latter.

Good eye! Thanks for spotting that.
Tobias.

--
unix http://www.faqs.org/faqs/by-newsgroup/comp/comp.unix.programmer.html
clc http://www.eskimo.com/~scs/C-faq/top.html
fclc (french): http://www.isty-info.uvsq.fr/~rumeau/fclc/



Mon, 21 Mar 2005 03:33:55 GMT  
 
 [ 14 post ] 

 Relevant Pages 

1. Help with compiling a "canned" program

2. Having "namespace" issues with Program

3. Passing "callback" function to a function

4. "system" could not be found

5. Found the "createObject". Got casting problem

6. RegLoadKey returns "file not found".

7. WMI - "Not Found" ManagmentException

8. Code Farms "Organized C": Found information

9. "Item not Found In collection" error

10. "can not find debug information" message

11. can't find "unknown.idl"

12. "Data source not found" message

 

 
Powered by phpBB® Forum Software