sorting of double[][]based on a double[]

J

jimgardener

hi
i have a double[] ,the elements of which correspond to columns of a
double[][]. I need to get the double[][] sorted such that column
corresponding to largest element of double[] is first ,and column
corresponding to smallest element of double[] is last

for example if
double[] evalues=new double[]{2.1,3.2,1.5,7.4,5.2};

double[][] evectors=new double[][]{
{4.0,5.0,7.0,1.0,2.0},
{1.0,2.0,3.0,4.0,5.0},
{8.0,6.0,9.0,3.0,1.0},
{4.0,3.0,1.0,7.0,3.0},
{5.0,8.0,3.0,1.0,2.0}
};

after sorting i should get
evalues==>
7.4, 5.2 ,3.2, 2.1 ,1.5
and evectors==>
1.0, 2.0, 5.0, 4.0, 7.0
4.0, 5.0 ,2.0, 1.0, 3.0
3.0, 1.0, 6.0, 8.0, 9.0
7.0, 3.0, 3.0, 4.0, 1.0
1.0, 2.0, 8.0, 5.0, 3.0


I tried to write a function as below,but it looks too bulky and
superfluous..can someone suggest a more compact way

private void sortEigVectors(double[] eigValue,double[][]eigVector){
Hashtable<Double,double[]> table = new Hashtable<Double,double[]>
();
Double[] evals=new Double[eigValue.length];
for(int i=0;i<eigValue.length;i++){
evals=new Double(eigValue);
}
//put evals and evects into hashtable
for(int i=0;i<eigValue.length;i++){
Double key=evals;
double[] value=getVecOfCol(eigVector ,i);

table.put(key,value);
}
Enumeration<Double> keysen=table.keys();
ArrayList<Double> keylist=Collections.list(keysen);

//sort now Collections.sort(keylist,Collections.reverseOrder());//
largest first

for(int i=0;i<evals.length;i++){
double[] ret=table.get(keylist.get(i));//coumn i
setColumn(eigVector,ret,i);//update the double[][]
}

Double[] sortedkeys=new Double[keylist.size()];
keylist.toArray(sortedkeys);//store the sorted list elements in an
array
//use the array to update the original double[]eigValue
for(int i=0;i<sortedkeys.length;i++){
Double dbl=sortedkeys;
double dblval=dbl.doubleValue();
eigValue=dblval;
}

}

private static double[] getVecOfCol( double[][] mat, int j ){
int m = mat.length;
double[] res = new double[m];
for ( int i = 0; i < m; ++i ){
res = mat[j];
}
return(res);
}
private static void setColumn(double[][] mat,double[] col,int c){
int len=col.length;
for(int row=0;row<len;row++){
mat[row][c]=col[row];
}
}


thanks
jim
 
J

Joshua Cranmer

jimgardener said:
hi
i have a double[] ,the elements of which correspond to columns of a
double[][]. I need to get the double[][] sorted such that column
corresponding to largest element of double[] is first ,and column
corresponding to smallest element of double[] is last

for example if
double[] evalues=new double[]{2.1,3.2,1.5,7.4,5.2};

double[][] evectors=new double[][]{
{4.0,5.0,7.0,1.0,2.0},
{1.0,2.0,3.0,4.0,5.0},
{8.0,6.0,9.0,3.0,1.0},
{4.0,3.0,1.0,7.0,3.0},
{5.0,8.0,3.0,1.0,2.0}
};

The code would look something along the lines of this:

double[][] sortee = new double[evectors[0].length][evectors.length+1];
for (int c=0;c<evectors[0].length;c++) {
for (int r=0; r<evectors.length; r++) {
sortee[c][r+1] = evectors[r][c];
}
sortee[c][0] = evalues[c];
}
Arrays.sort(sortee, new Comparator<double[]>() {
public int compare(double[] valAndVec1, double[] valAndVec2) {
return valAndVec1[0] - valAndVec2[1];
}
});
for (int c=0;c<evectors[0].length;c++) {
for (int r=0; r<evectors.length; r++) {
evectors[r][c] = sortee[c][r+1];
}
evalues[c] = sortee[c][0];
}

I neglect good formatting here, and you should really have some more
error checking, but this is a rough guide to do what you want.

WARNING: Untested, see sig.
 
S

Stefan Ram

jimgardener said:
i have a double[] ,the elements of which correspond to columns of a
double[][]. I need to get the double[][] sorted such that column
corresponding to largest element of double[] is first ,and column
corresponding to smallest element of double[] is last

(I have recently observed that very often articles are missing
in this newsgroup that I deem to be mandatory. For example,
above »such that column ...«. To me (not a native speaker),
only »such that /the/ column ...« sounds correct.)
for example if
double[] evalues=new double[]{2.1,3.2,1.5,7.4,5.2};

double[][] evectors=new double[][]{
{4.0,5.0,7.0,1.0,2.0},
{1.0,2.0,3.0,4.0,5.0},
{8.0,6.0,9.0,3.0,1.0},
{4.0,3.0,1.0,7.0,3.0},
{5.0,8.0,3.0,1.0,2.0}
};

after sorting i should get
evalues==>
7.4, 5.2 ,3.2, 2.1 ,1.5
and evectors==>
1.0, 2.0, 5.0, 4.0, 7.0
4.0, 5.0 ,2.0, 1.0, 3.0
3.0, 1.0, 6.0, 8.0, 9.0
7.0, 3.0, 3.0, 4.0, 1.0
1.0, 2.0, 8.0, 5.0, 3.0

class Main
{
final static double[] eValues = new double[]{ 2.1, 3.2, 1.5, 7.4, 5.2};

final static double[][] eVectors = new double[][]
{ { 4.0, 5.0, 7.0, 1.0, 2.0 },
{ 1.0, 2.0, 3.0, 4.0, 5.0 },
{ 8.0, 6.0, 9.0, 3.0, 1.0 },
{ 4.0, 3.0, 1.0, 7.0, 3.0 },
{ 5.0, 8.0, 3.0, 1.0, 2.0 }};

public static void swap( final double[] v, final int i )
{ final double tmp = v[ i + 1 ]; v[ i + 1 ]= v[ i ]; v[ i ]= tmp; }

public static void swap( final double[][] v, final int i )
{ for( int j = 0; j < v.length; ++j )swap( v[ j ], i ); }

public static void main( final java.lang.String[] args )
{ boolean looping = true;
while( looping )
{ looping = false;
for( int i = 0; i < eValues.length - 1; ++i )
{ if( eValues[ i + 1 ]> eValues[ i ] )
{ looping = true; swap( eValues, i ); swap( eVectors, i ); }}}}}
 
J

Joshua Cranmer

Eric said:
Joshua said:
The code would look something along the lines of this:
[...]
Arrays.sort(sortee, new Comparator<double[]>() {
public int compare(double[] valAndVec1, double[] valAndVec2) {
return valAndVec1[0] - valAndVec2[1];
}
});

ITYM [0] and [0], not [0] and [1]. But there's another
problem: This is not a valid way to compare doubles: numbers
that differ by less than unity will be deemed equal, because
the subtraction gives a result strictly between -1 and +1,
and this becomes zero on conversion to int (which needs a
cast, BTW). Thus, 0.5 equals 1.4, 1.4 equals 2.3, ...

Also, for double, float, long, and int the subtraction
may yield a result outside the range of an int, and this
will give, er, "surprising" results ... You can get away
with this dodge when comparing shorts or chars or bytes, but
don't use it with other numeric types.

Oops, right, the real line should be:
return Double.compare(valAndVec1[0], valAndVec2[0]);

Thanks for catching that. As I said, read my sig :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,701
Latest member
XavierQ83

Latest Threads

Top