/* IV.c */
#include "../Utilities.h"
#include "../../Drand.h"
/*--------------------------------------------------------------------*/
/*
-------------------------------------------------------
purpose -- given the pair of arrays (x1[],y1[]),
create a pair of arrays (x2[],y2[]) whose
entries are pairwise chosen from (x1[],y1[])
and whose distribution is an approximation.
return value -- the size of the (x2[],y2[]) arrays
created -- 95sep22, cca
-------------------------------------------------------
*/
int
IVcompress (
int size1,
int x1[],
int y1[],
int size2,
int x2[],
int y2[]
) {
double delta, dx, dy, path, totalPath ;
double *ds ;
int i, j ;
/*
--------------------
check the input data
--------------------
*/
if ( size1 <= 0 || size2 <= 0 ) {
return(0) ;
} else if ( x1 == NULL || y1 == NULL || x2 == NULL || y2 == NULL ) {
fprintf(stderr, "\n fatal error in IVcompress, invalid data"
"\n size1 = %d, x1 = %p, y1 = %p"
"\n size2 = %d, x2 = %p, y2 = %p\n",
size1, x1, y1, size2, x2, y2) ;
exit(-1) ;
}
/*
----------------------------------------
compute the path length and its segments
----------------------------------------
*/
ds = DVinit(size1, 0.0) ;
for ( j = 1 ; j < size1 ; j++ ) {
dx = x1[j] - x1[j-1] ;
dy = y1[j] - y1[j-1] ;
ds[j-1] = sqrt((double) (dx*dx + dy*dy)) ;
}
totalPath = DVsum(size1, ds) ;
delta = totalPath / (size2-2) ;
#if MYDEBUG > 0
fprintf(stdout, "\n totalPath = %12.4e, delta = %12.4e, ds",
totalPath, delta) ;
DVfprintf(stdout, size1, ds) ;
#endif
/*
---------------------
fill the second array
---------------------
*/
i = 0 ;
x2[i] = x1[i] ;
y2[i] = y1[i] ;
i++ ;
path = 0. ;
for ( j = 1 ; j < size1 - 1 ; j++ ) {
path += ds[j-1] ;
#if MYDEBUG > 0
fprintf(stdout, "\n j %d, path %12.4e", j, path) ;
#endif
if ( path >= delta ) {
#if MYDEBUG > 0
fprintf(stdout, ", accepted") ;
#endif
x2[i] = x1[j] ;
y2[i] = y1[j] ;
i++ ;
path = 0. ;
}
}
x2[i] = x1[size1-1] ;
y2[i] = y1[size1-1] ;
i++ ;
/*
------------------------
free the working storage
------------------------
*/
DVfree(ds) ;
return(i) ; }
/*--------------------------------------------------------------------*/
/*
-------------------------------
purpose -- to copy y[*] := x[*]
created -- 95sep22, cca
-------------------------------
*/
void
IVcopy (
int size,
int y[],
int x[]
) {
if ( size > 0 ) {
if ( y == NULL || x == NULL ) {
fprintf(stderr, "\n fatal error in IVcopy, invalid data"
"\n size = %d, y = %p, x = %p", size, y, x) ;
exit(-1) ;
} else {
int i ;
for ( i = 0 ; i < size ; i++ ) {
y[i] = x[i] ;
}
}
}
return ; }
/*--------------------------------------------------------------------*/
/*
-----------------------------------------------
purpose -- to fill a int vector with a value
created -- 95sep22, cca
-----------------------------------------------
*/
void
IVfill (
int size,
int y[],
int ival
) {
if ( size > 0 ) {
if ( y == NULL ) {
fprintf(stderr, "\n fatal error in IVfill, invalid data"
"\n size = %d, y = %p, ival = %d\n",
size, y, ival) ;
exit(-1) ;
} else {
int i ;
for ( i = 0 ; i < size ; i++ ) {
y[i] = ival ;
}
}
}
return ; }
/*--------------------------------------------------------------------*/
/*
------------------------------------
purpose -- to print out a int vector
created -- 95sep22, cca
------------------------------------
*/
void
IVfprintf (
FILE *fp,
int size,
int y[]
) {
if ( fp != NULL && size > 0 ) {
if ( y == NULL ) {
fprintf(stderr, "\n fatal error in IVfprintf, invalid data"
"\n fp = %p, size = %d, y = %p\n",
fp, size, y) ;
exit(-1) ;
} else {
int i ;
for ( i = 0 ; i < size ; i++ ) {
if ( i % 16 == 0 ) fprintf(fp, "\n") ;
fprintf(fp, " %4d", y[i]) ;
}
}
}
return ; }
/*--------------------------------------------------------------------*/
/*
-------------------------------------------------------------------
purpose -- to write out an integer vector with eighty column lines
input --
fp -- file pointer, must be formatted and write access
size -- length of the vector
y -- integer vector
column -- present column
pierr -- pointer to int to hold return value,
should be 1 if any print was successful,
if fprintf() failed, then ierr = -1
return value -- present column
created -- 95sep22, cca
mods -- 95sep29, cca
added ierr argument to handle error returns from fprintf()
-------------------------------------------------------------------
*/
int
IVfp80 (
FILE *fp,
int size,
int y[],
int column,
int *pierr
) {
*pierr = 1 ;
if ( fp != NULL && size > 0 ) {
if ( y == NULL ) {
fprintf(stderr, "\n fatal error in IVfp80, invalid input"
"\n fp = %p, size = %d, y = %p, column = %d\n",
fp, size, y, column) ;
exit(-1) ;
} else {
int i, inum, nchar ;
for ( i = 0 ; i < size ; i++ ) {
inum = y[i] ;
if ( inum < 0 ) {
inum = -inum ;
nchar = 2 ;
} else if ( inum == 0 ) {
nchar = 2 ;
} else {
nchar = 1 ;
}
while ( inum > 0 ) {
nchar++ ;
inum /= 10 ;
}
if ( (column += nchar) >= 80 ) {
fprintf(fp, "\n") ;
column = nchar ;
}
if ( (*pierr = fprintf(fp, " %d", y[i])) < 0 ) {
/*
--------------------
error with fprintf()
--------------------
*/
break ;
}
}
}
}
return(column) ; }
/*--------------------------------------------------------------------*/
/*
----------------------------------------------------------
purpose -- to free the storage taken by an integer vector.
note : y must have been returned by IVinit
created -- 95sep22, cca
----------------------------------------------------------
*/
void
IVfree (
int y[]
) {
if ( y != NULL ) {
FREE(y) ;
}
return ; }
/*--------------------------------------------------------------------*/
/*
-----------------------------------
purpose -- to read in an int vector
created -- 95sep22, cca
-----------------------------------
*/
int
IVfscanf (
FILE *fp,
int size,
int y[]
) {
int i = 0 ;
if ( fp != NULL && size > 0 ) {
if ( y == NULL ) {
fprintf(stderr, "\n fatal error in IVfscanf, invalid data"
"\n fp = %p, size = %d, y = %p\n", fp, size, y) ;
exit(-1) ;
} else {
for ( i = 0 ; i < size ; i++ ) {
if ( fscanf(fp, " %d", y + i) != 1 ) {
break ;
}
}
}
}
return(i) ; }
/*--------------------------------------------------------------------*/
/*
---------------------------------------
purpose -- to gather y[*] = x[index[*]]
created -- 95sep22, cca
---------------------------------------
*/
void
IVgather (
int size,
int y[],
int x[],
int index[]
) {
if ( size > 0 ) {
if ( y == NULL || x == NULL || index == NULL ) {
fprintf(stderr, "\n fatal error in IVgather, invalid data"
"\n size = %d, y = %p, x = %p, index = %p\n",
size, y, x, index) ;
exit(-1) ;
} else {
int i ;
for ( i = 0 ; i < size ; i++ ) {
y[i] = x[index[i]] ;
}
}
}
return ; }
/*--------------------------------------------------------------------*/
/*
---------------------------------------------------
purpose -- allocate a int array with size entries
and fill with value ival
return value -- a pointer to the start of the array
created : 95sep22, cca
---------------------------------------------------
*/
int *
IVinit (
int size,
int ival
) {
int *y = NULL ;
if ( size > 0 ) {
y = IVinit2(size) ;
IVfill(size, y, ival) ;
}
return(y) ; }
/*--------------------------------------------------------------------*/
/*
---------------------------------------------------
purpose -- allocate a int array with size entries
return value -- a pointer to the start of the array
created : 95sep22, cca
---------------------------------------------------
*/
int *
IVinit2 (
int size
) {
int *y = NULL ;
if ( size > 0 ) {
ALLOCATE(y, int, size) ;
}
return(y) ; }
/*--------------------------------------------------------------------*/
/*
-------------------------------------------------------------
purpose -- allocate an int array and fill with the inverse of
y[]. note, y[] must be a permutation vector.
created : 95sep22, cca
-------------------------------------------------------------
*/
int *
IVinverse (
int size,
int y[]
) {
int *x = NULL ;
if ( size > 0 ) {
if ( y == NULL ) {
fprintf(stderr, "\n fatal error in IVinverse, invalid data"
"\n size = %d, y = %p\n", size, y) ;
exit(-1) ;
} else {
int i, j ;
x = IVinit(size, -1) ;
for ( i = 0 ; i < size ; i++ ) {
j = y[i] ;
if ( j < 0 || j >= size || x[j] != -1 ) {
fprintf(stderr,
"\n fatal error in IVinverse"
"\n y[%d] = %d, value out-of-range or repeated",
i, j) ;
exit(-1) ;
}
x[j] = i ;
}
}
}
return(x) ; }
/*--------------------------------------------------------------------*/
/*
------------------------------
purpose -- to permute a vector
y[index[*]] := y[*]
created -- 95sep22, cca
------------------------------
*/
void
IVinvPerm (
int size,
int y[],
int index[]
) {
if ( size > 0 ) {
if ( y == NULL || index == NULL ) {
fprintf(stderr, "\n fatal error in IVinvPerm, invalid data"
"\n size = %d, y = %p, index = %p\n", size, y, index) ;
exit(-1) ;
} else {
int *x ;
int i ;
x = IVinit2(size) ;
IVcopy(size, x, y) ;
for ( i = 0 ; i < size ; i++ ) {
y[index[i]] = x[i] ;
}
IVfree(x) ;
}
}
return ; }
/*--------------------------------------------------------------------*/
/*
-----------------------------------------------------
purpose -- to return the first entry of maximum size,
*ploc contains its index
created -- 95sep22, cca
-----------------------------------------------------
*/
int
IVmax (
int size,
int y[],
int *ploc
) {
int maxval = 0 ;
int loc = -1 ;
if ( size > 0 ) {
if ( y == NULL ) {
fprintf(stderr, "\n fatal error in IVmax, invalid data"
"\n size = %d, y = %p, ploc = %p\n", size, y, ploc) ;
exit(-1) ;
} else {
int i ;
maxval = y[0] ;
loc = 0 ;
for ( i = 1 ; i < size ; i++ ) {
if ( maxval < y[i] ) {
maxval = y[i] ;
loc = i ;
}
}
*ploc = loc ;
}
}
*ploc = loc ;
return(maxval) ; }
/*--------------------------------------------------------------------*/
/*
---------------------------------------------------------------
purpose -- to return the first entry of maximum absolute value,
*ploc contains its index
created -- 95sep22, cca
---------------------------------------------------------------
*/
int
IVmaxabs (
int size,
int y[],
int *ploc
) {
int maxval = 0 ;
int loc = -1 ;
if ( size > 0 ) {
if ( y == NULL ) {
fprintf(stderr, "\n fatal error in IVmaxabs, invalid data"
"\n size = %d, y = %p, ploc = %p\n", size, y, ploc) ;
exit(-1) ;
} else {
int i, val ;
maxval = (y[0] >= 0) ? y[0] : -y[0] ;
loc = 0 ;
for ( i = 1 ; i < size ; i++ ) {
val = (y[i] >= 0) ? y[i] : -y[i] ;
if ( maxval < val ) {
maxval = val ;
loc = i ;
}
}
*ploc = loc ;
}
}
*ploc = loc ;
return(maxval) ; }
/*--------------------------------------------------------------------*/
/*
------------------------------------------------------
purpose -- to return the first entry of minimum value,
*ploc contains its index
created -- 95sep22, cca
------------------------------------------------------
*/
int
IVmin (
int size,
int y[],
int *ploc
) {
int minval = 0 ;
int loc = -1 ;
if ( size > 0 ) {
if ( y == NULL ) {
fprintf(stderr, "\n fatal error in IVmin, invalid data"
"\n size = %d, y = %p, ploc = %p\n", size, y, ploc) ;
exit(-1) ;
} else {
int i ;
minval = y[0] ;
loc = 0 ;
for ( i = 1 ; i < size ; i++ ) {
if ( minval > y[i] ) {
minval = y[i] ;
loc = i ;
}
}
*ploc = loc ;
}
}
*ploc = loc ;
return(minval) ; }
/*--------------------------------------------------------------------*/
/*
---------------------------------------------------------------
purpose -- to return the first entry of minimum absolute value,
*ploc contains its index
created -- 95sep22, cca
---------------------------------------------------------------
*/
int
IVminabs (
int size,
int y[],
int *ploc
) {
int minval = 0 ;
int loc = -1 ;
if ( size > 0 ) {
if ( y == NULL ) {
fprintf(stderr, "\n fatal error in IVminabs, invalid data"
"\n size = %d, y = %p, ploc = %p\n", size, y, ploc) ;
exit(-1) ;
} else {
int i, val ;
minval = (y[0] >= 0) ? y[0] : -y[0] ;
loc = 0 ;
for ( i = 1 ; i < size ; i++ ) {
val = (y[i] >= 0) ? y[i] : -y[i] ;
if ( minval > val ) {
minval = val ;
loc = i ;
}
}
*ploc = loc ;
}
}
*ploc = loc ;
return(minval) ; }
/*--------------------------------------------------------------------*/
/*
------------------------------
purpose -- to permute a vector
y[*] := y[index[*]]
created -- 95sep22, cca
------------------------------
*/
void
IVperm (
int size,
int y[],
int index[]
) {
if ( size > 0 ) {
if ( y == NULL || index == NULL ) {
fprintf(stderr, "\n fatal error in IVperm, invalid data"
"\n size = %d, y = %p, index = %p\n",
size, y, index) ;
exit(-1) ;
} else {
int *x ;
int i ;
x = IVinit2(size) ;
IVcopy(size, x, y) ;
for ( i = 0 ; i < size ; i++ ) {
y[i] = x[index[i]] ;
}
IVfree(x) ;
}
}
return ; }
/*--------------------------------------------------------------------*/
/*
----------------------------------------------------
purpose -- to fill a int vector with a ramp function
created -- 95sep22, cca
----------------------------------------------------
*/
void
IVramp (
int size,
int y[],
int start,
int inc
) {
if ( size > 0 ) {
if ( y == NULL ) {
fprintf(stderr, "\n fatal error in IVramp, invalid data"
"\n size = %d, y = %p, start = %d, inc = %d\n",
size, y, start, inc) ;
exit(-1) ;
} else {
int i, j ;
for ( i = 0, j = start ; i < size ; i++, j += inc ) {
y[i] = j ;
}
}
}
return ; }
/*--------------------------------------------------------------------*/
/*
----------------------------------------
purpose -- to scatter y[index[*]] = x[*]
created -- 95sep22, cca
----------------------------------------
*/
void
IVscatter (
int size,
int y[],
int index[],
int x[]
) {
if ( size > 0 ) {
if ( y == NULL || x == NULL || index == NULL ) {
fprintf(stderr, "\n fatal error in IVscatter, invalid data"
"\n size = %d, y = %p, index = %p, x = %p\n",
size, y, index, x) ;
exit(-1) ;
} else {
int i ;
for ( i = 0 ; i < size ; i++ ) {
y[index[i]] = x[i] ;
}
}
}
return ; }
/*--------------------------------------------------------------------*/
/*
-----------------------------------------------
purpose -- to return the sum of a int vector
created -- 95sep22, cca
-----------------------------------------------
*/
int
IVsum (
int size,
int y[]
) {
int sum = 0 ;
if ( size > 0 ) {
if ( y == NULL ) {
fprintf(stderr, "\n fatal error in IVsum, invalid data"
"\n size = %d, y = %p\n", size, y) ;
exit(-1) ;
} else {
int i ;
for ( i = 0, sum = 0 ; i < size ; i++ ) {
sum += y[i] ;
}
}
}
return(sum) ; }
/*--------------------------------------------------------------------*/
/*
---------------------------------------------------
purpose -- to return the sum of the absolute values
of the entries in an int vector
created -- 95sep22, cca
---------------------------------------------------
*/
int
IVsumabs (
int size,
int y[]
) {
int sum = 0 ;
if ( size > 0 ) {
if ( y == NULL ) {
fprintf(stderr, "\n fatal error in IVsumabs, invalid data"
"\n size = %d, y = %p\n", size, y) ;
exit(-1) ;
} else {
int i, sum ;
for ( i = 0, sum = 0 ; i < size ; i++ ) {
sum += ((y[i] >= 0) ? y[i] : -y[i]) ;
}
}
}
return(sum) ; }
/*--------------------------------------------------------------------*/
/*
--------------------------------
purpose -- to swap y[*] and x[*]
created -- 95sep22, cca
--------------------------------
*/
void
IVswap (
int size,
int y[],
int x[]
) {
if ( size > 0 ) {
if ( y == NULL || x == NULL ) {
fprintf(stderr, "\n fatal error in IVswap, invalid data"
"\n size = %d, y = %p, x = %p\n", size, y, x) ;
exit(-1) ;
} else {
int i, temp ;
for ( i = 0 ; i < size ; i++ ) {
temp = x[i] ;
x[i] = y[i] ;
y[i] = temp ;
}
}
}
return ; }
/*--------------------------------------------------------------------*/
/*
----------------------------------
purpose -- to zero a int vector
created -- 95sep22, cca
----------------------------------
*/
void
IVzero (
int size,
int y[]
) {
if ( size > 0 ) {
if ( y == NULL ) {
fprintf(stderr, "\n fatal error in IVzero, invalid data"
"\n size = %d, y = %p\n", size, y) ;
exit(-1) ;
} else {
int i ;
for ( i = 0 ; i < size ; i++ ) {
y[i] = 0 ;
}
}
}
return ; }
/*--------------------------------------------------------------------*/
/*
-------------------------------------------------
purpose -- to permute an integer vector,
procedure uses the Drand object
input --
size -- size of the vector
y -- vector to be permuted
seed -- seed for the random number generator
if seed <= 0, simple return
created -- 95sep22, cca
-------------------------------------------------
*/
void
IVshuffle (
int size,
int y[],
int seed
) {
if ( size > 0 && seed > 0 ) {
if ( y == NULL ) {
fprintf(stderr, "\n fatal error in IVshuffle, invalid data"
"\n size = %d, y = %p, seed = %d\n", size, y, seed) ;
exit(-1) ;
} else {
int i, j, temp ;
double value ;
Drand drand ;
Drand_setDefaultFields(&drand) ;
Drand_setSeed(&drand, seed) ;
Drand_setUniform(&drand, 0.0, 1.0) ;
for ( i = 0 ; i < size ; i++ ) {
value = Drand_value(&drand) ;
j = (int) (size * value) ;
temp = y[i] ;
y[i] = y[j] ;
y[j] = temp ;
}
}
}
return ; }
/*--------------------------------------------------------------------*/
/*
------------------------------------------------------
locate an instance of target in the vector ivec[size].
we assume that ivec[] is sorted in ascending order
so we can use binary search to locate target.
return value --
-1 -- if target not found in ivec[]
loc -- where target = ivec[loc]
created -- 96may27, cca
------------------------------------------------------
*/
int
IVlocateViaBinarySearch (
int size,
int ivec[],
int target
) {
int left, mid, right ;
if ( size <= 0 || ivec == NULL ) {
return(-1) ;
}
left = 0 ;
right = size - 1 ;
if ( target < ivec[left] || ivec[right] < target ) {
return(-1) ;
} else if ( target == ivec[left] ) {
return(left) ;
} else if ( target == ivec[right] ) {
return(right) ;
} else {
while ( right > left + 1 ) {
mid = (left + right)/2 ;
if ( target < ivec[mid] ) {
right = mid ;
} else if ( target > ivec[mid] ) {
left = mid ;
} else {
return(mid) ;
}
}
}
return(-1) ; }
/*--------------------------------------------------------------------*/
syntax highlighted by Code2HTML, v. 0.9.1