|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T r
Length: 6050 (0x17a2)
Types: TextFile
Names: »ranksort.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/stat-5.3/eu/stat/src/ranksort.c«
/* Copyright 1985 Gary Perlman */
#include "stat.h"
/*LINTLIBRARY*/
FUN(ranksort,sort column array into ranks,1.1,01/07/87)
/* ranksort: shell sort a vector into ranks */
int
ranksort (vec, svec, ivec, n)
float *vec; /* input vector of values */
int *ivec; /* integer order vector */
float *svec; /* sorted input vector, may be ignored, used for space */
unsigned n;
{
int gap, i, j;
float temp; /* temp var for swapping */
int itemp; /* temp var for swapping */
int dupcount; /* number of duplicates */
int sumranks; /* sum of duplicate ranks */
double averank; /* average rank of duplicates */
int needivec = (ivec == NULL);
int needsvec = (svec == NULL);
if (needivec)
ivec = myalloc (int, n);
if (needsvec)
svec = myalloc (float, n);
if (ivec == NULL || svec == NULL)
return (1);
for (i = 0; i < n; i++)
{
svec[i] = vec[i];
ivec[i] = i;
}
/* shellsort algorithm */
for (gap = n/2; gap > 0; gap /= 2)
for (i = gap; i < n; i++)
for (j = i-gap; j >= 0 && svec[j] > svec[j+gap]; j -= gap)
{
temp = svec[j];
svec[j] = svec[j+gap];
svec[j+gap] = temp;
itemp = ivec[j];
ivec[j] = ivec[j+gap];
ivec[j+gap] = itemp;
}
/*
Now svec is the sorted input vec and ivec has the order
svec[i] = vec[ivec[i]];
To convert vec to ranks, march through svec, looking for
duplicates, and assign the ranks back to vec. Duplicate
values get the average of their ranks.
*/
sumranks = 0;
dupcount = 0;
for (i = 0; i < n; i++)
{
sumranks += i;
dupcount++;
if ((svec[i] != svec[i+1]) || (i == n-1))
{
averank = (double) sumranks / (double) dupcount + 1.0;
for (j = i - dupcount + 1; j <= i; j++)
vec[ivec[j]] = averank;
sumranks = 0;
dupcount = 0;
}
}
if (needivec)
free ((char *) ivec);
if (needsvec)
free ((char *) svec);
return (0);
}
#ifdef RANKSORT
PGM(ranksort,Rank Order Data in Columns,5.1,11/28/86)
#define MAXDATA 100 /* max number of data points */
#define MAXVAR 100 /* max number of variables */
#define MAXCHARS BUFSIZ /* maximum number of chars in lines */
Boole InfoVersion; /* print version information */
Boole InfoLimits; /* print program limits */
Boole InfoOptions; /* print usage information */
int Ndata;
int Maxdata = MAXDATA;
int Nvars;
Boole Reverse = FALSE; /* reverse rank ordering */
float **readmatrix ();
main (argc, argv) char **argv;
{
float **matrix;
ARGV0;
initial (argc, argv);
checkstdin ();
if (matrix = readmatrix ())
{
rankmatrix (matrix, Nvars, Ndata);
if (Reverse)
revmatrix (matrix, Nvars, Ndata);
printmatrix (matrix, Nvars, Ndata);
}
else if (Ndata == 0)
ERRDATA
else
ERRMSG0 (Can not read matrix)
exit (0);
}
/*FUNCTION initial: returns local version of optind, index to first operand */
int
initial (argc, argv) char **argv;
{
extern char *optarg; /* option value accessed through this by getopt */
extern int optind; /* will be index to first operand */
int opterr = 0; /* count of number of errors */
int flag; /* option flag characters read in here */
while ((flag = getopt (argc, argv, "l:rLOV")) != EOF)
switch (flag)
{
default:
opterr++;
break;
/* put option cases here */
case 'O': InfoOptions = TRUE; break;
case 'V': InfoVersion = TRUE; break;
case 'L': InfoLimits = TRUE; break;
case 'l':
if (setint (Argv0, flag, optarg, &Maxdata, 0, MAXINT))
opterr++;
break;
case 'r': Reverse = TRUE; break;
}
if (optind < argc-1) /* too many args */
opterr++;
if (opterr) /* print usage message and bail out */
USAGE ([-r] [-l lines])
ERROPT (optind)
usinfo ();
return (optind);
}
float **
makematrix (nvars, ndata)
unsigned nvars;
unsigned ndata;
{
float **matrix;
int var;
if (matrix = myalloc (float *, nvars))
for (var = 0; var < nvars; var++)
{
matrix[var] = myalloc (float, ndata);
if (matrix[var] == NULL)
return (NULL);
}
return (matrix);
}
float **
readmatrix ()
{
char line[MAXCHARS];
char *array[MAXVAR];
float **matrix = NULL;
int n;
while (gets (line))
{
if (n = parselin (line, array, MAXVAR))
{
if (Nvars == 0)
{
if (n > MAXVAR)
ERRMANY (columns, MAXVAR)
Nvars = n;
matrix = makematrix (Nvars, Maxdata);
if (matrix == NULL)
ERRSPACE (data)
}
else if (n != Nvars)
ERRRAGGED
if (Ndata == Maxdata)
ERRMANY (rows of data, Maxdata)
for (n = 0; n < Nvars; n++)
if (!number (array[n]))
ERRNUM(array[n],column value)
else
matrix[n][Ndata] = atof (array[n]);
Ndata++;
}
}
return (matrix);
}
rankmatrix (matrix, nvars, ndata)
float **matrix;
int nvars;
int ndata;
{
int var;
int *ivec = myalloc (int, ndata);
float *svec = myalloc (float, ndata);
if (ivec != NULL && svec != NULL)
{
for (var = 0; var < nvars; var++)
ranksort (matrix[var], svec, ivec, ndata);
free ((char *) ivec);
free ((char *) svec);
}
}
printmatrix (matrix, nvars, ndata)
float **matrix;
int nvars;
int ndata;
{
int i, var;
for (i = 0; i < ndata; i++)
for (var = 0; var < nvars; var++)
printf ("%g%c", matrix[var][i], var == nvars - 1 ? '\n' : '\t');
}
revmatrix (matrix, nvars, ndata)
float **matrix;
int nvars;
int ndata;
{
int i, var;
double delta = ndata + 1.0;
for (i = 0; i < ndata; i++)
for (var = 0; var < nvars; var++)
matrix[var][i] = delta - matrix[var][i];
}
usinfo ()
{
if (InfoVersion)
pver (Version);
if (InfoLimits)
{
plim (Argv0);
const (MAXVAR, "maximum number of variables");
const (MAXDATA, "default maximum number of lines");
const (MAXCHARS, "maximum number of characters in lines");
}
if (InfoOptions)
{
ppgm (Argv0, Purpose);
lopt ('r', "reverse rank ordering", Reverse);
iopt ('l', "lines", "maximum number of input lines", Maxdata);
}
if (InfoVersion || InfoLimits || InfoOptions)
exit (0);
}
#endif RANKSORT