home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Professional
/
OS2PRO194.ISO
/
os2
/
prgramer
/
adaptor
/
src
/
permutat.c
< prev
next >
Wrap
Text File
|
1994-01-02
|
11KB
|
385 lines
/*********************************************************************
* *
* Author : Dr. Thomas Brandes, GMD, I1.HR *
* Date : Mar 93 *
* Last Update : Mar 93 *
* *
* Module : permutations.c *
* *
*********************************************************************/
# include "permutat.h"
/*************************************************
* *
* some operations on Permutations *
* *
* make_id_permuatation (5) : 1 2 3 4 5 *
* *
*************************************************/
Permutation make_id_permutation (n) /* create identity */
int n;
{ Permutation perm;
int i;
if (n > MAX_DIMENSIONS)
{ printf ("AdaptDistriubtions: make_id_permutation, %d too big\n", n);
exit (-1);
}
perm.n = n;
for (i=1; i<=n; i++) perm.pa[i-1] = i;
return (perm);
} /* make_id_permutation */
bool is_id_permutation (perm)
Permutation perm;
{ bool ok;
int i;
ok = true;
for (i=1; i<=perm.n; i++)
ok = ok && perm.pa[i-1] == i;
return (ok);
} /* is_id_permutation */
int new_perm_position (perm, pos)
Permutation perm;
int pos;
{ int i, newpos;
newpos = 0;
for (i=1; i<=perm.n; i++)
if (perm.pa[i-1] == pos)
newpos = i;
if (newpos == 0)
{ printf ("internal error for new_perm_position\n");
exit(-1);
}
return (newpos);
}
/****************************************************
* *
* 1 2 3 4 5 *
* p : 3 4 5 2 1 *
* *
* olddim = 4 newdim = 2 *
* *
* n : 3 4 2 1 *
* *
****************************************************/
Permutation reduce_permutation (p, olddim, newdim)
Permutation p;
int olddim, newdim;
{ Permutation new_perm;
int i;
new_perm = p;
/* decrease all entries greater than olddim by */
for (i=0; i<new_perm.n; i++)
if (new_perm.pa[i] > olddim)
new_perm.pa[i] = new_perm.pa[i]-1;
/* remove entry for newdim, this should be olddim */
if (new_perm.pa[newdim-1] != olddim)
{ printf ("internal error for reduce_permutation\n");
exit (-1);
}
for (i=newdim; i<new_perm.n; i++)
new_perm.pa[i-1] = new_perm.pa[i];
new_perm.n = new_perm.n-1;
return (new_perm);
}
bool equal_permutations (perm1, perm2)
Permutation perm1, perm2;
{ bool ok;
int i;
ok = (perm1.n == perm2.n);
if (ok)
{ for (i=0; i<perm1.n; i++)
ok = ok && (perm1.pa[i] == perm2.pa[i]);
}
return (ok);
}
bool conform_permutations (perm1, perm2)
Permutation perm1, perm2;
{ bool ok;
if (perm1.n == 0)
ok = true;
else if (perm2.n == 0)
ok = true;
else
ok = equal_permutations (perm1, perm2);
return (ok);
} /* conform_permutations */
/****************************************************
* *
* transpose_permutations (perm1, perm2) *
* *
* true iff last dimensions are switched *
* *
****************************************************/
bool transpose_permutations (perm1, perm2)
Permutation perm1, perm2;
{ bool ok;
int i, n;
n = perm1.n;
if (n != perm2.n) return (false);
if (n < 2) return (false);
ok = true;
for (i=0; i<n-2; i++)
ok = ok && (perm1.pa[i] == perm2.pa[i]);
ok = ok && (perm1.pa[n-2] == perm2.pa[n-1]);
ok = ok && (perm1.pa[n-1] == perm2.pa[n-2]);
return (ok);
}
Permutation merge_permutation (perm1, perm2)
Permutation perm1, perm2;
{ if (perm1.n == 0)
return (perm2);
else
return (perm1);
} /* merge_permutation */
void print_permutation (perm)
Permutation perm;
{ int i;
printf ("Permutation (n=%d) : ", perm.n);
for (i=1; i<=perm.n; i++) printf ("%d ", perm.pa[i-1]);
printf ("\n");
}
/****************************************************
* *
* make permutation from the current distribution *
* *
* A (N1,N2,N3,N4,N5) (*,BLOCK,*,BLOCK,*) *
* *
* -> 1, 3, 5, 2, 4 *
* *
****************************************************/
Permutation implied_distribution_permutation (dist)
DistributedDimensions dist;
{ Permutation s_perm, d_perm;
int k, n;
int serial_n, dist_n;
n = dist.no_dims;
serial_n = 0;
dist_n = 0;
for (k=1; k<=n; k++)
{ if (dist.DimsArray[k-1] > 0) /* distributed */
{ /* distributed */
d_perm.pa[dist_n] = k;
dist_n += 1;
}
else
{ /* serial dimension */
s_perm.pa[serial_n] = k;
serial_n += 1;
}
}
/* serial dimensions are the first ones, append parallel dims */
for (k=0; k<dist_n; k++)
s_perm.pa[serial_n+k] = d_perm.pa[k];
s_perm.n = n;
return (s_perm);
} /* implied_distribution_permutation */
/****************************************************
* *
* index_list returns a sequence of ranks of index *
* *
* [1:n,A,I,J,B] -> 1 2 0 0 3 *
* *
****************************************************/
Permutation index_list (indexes)
tTree indexes;
{ Permutation perm;
int i, n, count;
tTree hl, elem;
n = TreeListLength (indexes);
perm.n = n;
count = 0;
hl = indexes;
for (i=0; i<n; i++)
{ elem = hl->BTE_LIST.Elem;
hl = hl->BTE_LIST.Next;
if (TreeRank (elem) > 0)
{ count ++;
perm.pa[i] = count;
}
else
perm.pa[i] = 0;
}
return (perm);
} /* index_list */
/****************************************************
* *
* get_rank_permutation : *
* *
* index_vector : 1 0 2 0 3 *
* perm : 4 1 5 2 3 *
* *
* results in : 0 1 3 0 2 *
* *
* compressed : 1 3 2 0 0 *
* *
****************************************************/
Permutation get_rank_permutation (index_vector, perm)
Permutation index_vector, perm;
{ Permutation new;
int i, count;
/* permute index_vector to new */
new.n = index_vector.n;
for (i=0; i<new.n; i++)
new.pa[i] = index_vector.pa [perm.pa[i] - 1];
/* compress the new index vector */
count = 0;
for (i=0; i<new.n; i++)
if (new.pa[i] > 0)
{ new.pa[count] = new.pa[i];
count ++;
}
new.n = count;
return (new);
} /* get_rank_permutation */
/****************************************************
* *
* switch_index_types : *
* switch_indexes : *
* *
* perm = 4 2 3 1 5 *
* *
* (N1,N2,N3,N4,N5) -> (N4,N2,N3,N1,N5) *
* *
****************************************************/
void switch_index_types (typelist, perm)
tTree typelist;
Permutation perm;
{ tTree tarray [MAX_DIMENSIONS];
tTree hlist;
int i;
hlist = typelist;
for (i=0; i<perm.n; i++)
{ tarray[i] = hlist->TYPE_LIST.Elem;
hlist = hlist->TYPE_LIST.Next;
}
hlist = typelist;
for (i=0; i<perm.n; i++)
{ hlist->TYPE_LIST.Elem = tarray[perm.pa[i]-1];
hlist = hlist->TYPE_LIST.Next;
}
} /* switch_index_types */
void switch_indexes (indexlist, perm)
tTree indexlist;
Permutation perm;
{ tTree tarray [MAX_DIMENSIONS];
tTree hlist;
int i;
/* put indexes in an array */
hlist = indexlist;
for (i=0; i<perm.n; i++)
{ tarray[i] = hlist->BTE_LIST.Elem;
hlist = hlist->BTE_LIST.Next;
}
/* refill with permuted list */
hlist = indexlist;
for (i=0; i<perm.n; i++)
{ hlist->BTE_LIST.Elem = tarray[perm.pa[i]-1];
hlist = hlist->BTE_LIST.Next;
}
} /* switch_indexes */
void switch_parameters (paramlist, perm)
tTree paramlist;
Permutation perm;
{ tTree tarray [MAX_DIMENSIONS];
tTree hlist;
int i;
/* put parameters in an array */
hlist = paramlist;
for (i=0; i<perm.n; i++)
{ tarray[i] = hlist->BTP_LIST.Elem;
hlist = hlist->BTP_LIST.Next;
}
/* refill with permuted list */
hlist = paramlist;
for (i=0; i<perm.n; i++)
{ hlist->BTP_LIST.Elem = tarray[perm.pa[i]-1];
hlist = hlist->BTP_LIST.Next;
}
} /* switch_parameters */