PDA

View Full Version : function or subroutine to find the unique elements of vector



umit
05-09-2006, 02:30 PM
Hi,

I am a beginner in Fortran and having some naive questions here.

I wish to find the unique elements of a vactor x, say if the vector x is (1, 3, 2, 3, 2), the return should be (1, 2, 3).

Another question could be to find the unique rows of a matrix, like for matrix
1 2
3 4
1 2
the return should be
1 2
3 4

I know in matlab, the function 'unique' can do this. I guess this looks naive, but I can not really find such a function or subroutine. Will anyone help me?

Thanks in advance.

ed
05-10-2006, 05:45 AM
There are a number of options here as Fortran doesn't have an intrinsic "UNIQUE" function. Have a look at ORDERPACK 2.0 (http://www.fortran-2000.com/rank/index.html) which contains links to source and includes a unique ranking and unique sorting subroutines.

umit
05-10-2006, 10:31 AM
Thanks a lot.

So, does that mean I should include the whole source code into my program in order to use those subroutines?

ed
05-10-2006, 11:22 AM
Thanks a lot.

So, does that mean I should include the whole source code into my program in order to use those subroutines?
You don't have to include it all. But if you look at the source for UNISTA, you'll find that it calls UNIINV. It probably is just easiest to include the large orderpack.f90 source code in your project, however, unless you want to split out only the functions you'll use.

diraviam
05-12-2006, 07:35 AM
Is there similar functionality in JMSL.

ed
05-12-2006, 10:17 AM
There's no functions in IMSL (or JMSL) that returns the unique elements of a vector, but it's not hard to write yourself. The basic methodology would be similar for any language, however: sort the array and accumulate values that are not equal to a neighbor. If you look at the Orderpack source, it's focus is largely on the sorting algorithm, but you'll see the 'unique' part in UNISTA.

The concern is often around performance. For example, you don't know the size of the output array before hand, so in Java should you use a regular double[] array and trim it down later? Or should you use an ArrayList or Vector and grow it with each new unique item found?

Working on the premise that it's faster to track unique elements in a boolean array and then loop through again, here's some Java code that'll work well.


/**
* Return just the unique elements of an array
*
* @param a The array
* @return The unique elements of a, sorted
*/
public static double[] unique(double[] a) {
final int len = a.length;
// Sort modifies the input, so make a copy first
double[] ac = new double[len];
System.arraycopy(a, 0, ac, 0, len);
com.imsl.stat.Sort.ascending(ac);

boolean[] b = new boolean[len];
b[0] = true;
int ct = 0;
for (int i=1; i<len; i++) {
if (ac[i] != ac[i-1]) {
b[i] = true;
ct++;
}
}

double[] u = new double[ct];
ct = 0;
for (int i=0; i<len; i++) {
if (b[i]) u[ct++] = ac[i];
}

return u;
}