#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <sys/types.h>
#include <time.h>
#define MEM_USAGE 0
#if MEM_USAGE
#include <sys/resource.h>
#endif
#include "egutils.h"
#define FREE_ARG char*
#define SHOWMEM 0
#if SHOWMEM
static int nfloat=0, nint=0, cumnfloat=0, cumnint=0, locnint, locnfloat;
int MemoryUsage()
{
if(locnint > 1000 || locnfloat > 1000)
printf("Memory used real %d %d %d int %d %d %d\n",
nfloat,cumnfloat,locnfloat,nint,cumnint,locnint);
locnfloat = locnint = 0;
}
#endif
void nrerror(const char error_text[])
{
fprintf(stderr,"run-time error...\n");
fprintf(stderr,"%s\n",error_text);
fprintf(stderr,"...now exiting to system...\n");
exit(1);
}
float *vector(int nl,int nh)
{
float *v;
v = (float*)malloc((size_t) (nh-nl+1+1)*sizeof(float));
if (!v) nrerror("allocation failure in vector()");
return(v-nl+1);
}
int *ivector(int nl,int nh)
{
int *v;
if( nh < nl ) {
printf("Allocation impossible in ivector: %d %d\n",nl,nh);
exit(1);
}
v=(int*) malloc((size_t) (nh-nl+1+1)*sizeof(int));
if (!v) nrerror("allocation failure in ivector()");
#if SHOWMEM
locnint = (nh-nl+1+1);
nint += locnint;
cumnint += locnint;
MemoryUsage();
#endif
return(v-nl+1);
}
char *cvector(int nl,int nh)
{
char *v;
v=(char *)malloc((size_t) (nh-nl+1+1)*sizeof(char));
if (!v) nrerror("allocation failure in cvector()");
return(v-nl+1);
}
unsigned long *lvector(int nl,int nh)
{
unsigned long *v;
v=(unsigned long *)malloc((size_t) (nh-nl+1+1)*sizeof(unsigned long));
if (!v) nrerror("allocation failure in lvector()");
return(v-nl+1);
}
double *dvector(int nl,int nh)
{
double *v;
if( nh < nl ) {
printf("Allocation impossible in dvector: %d %d\n",nl,nh);
exit(1);
}
v=(double *)malloc((size_t) (nh-nl+1+1)*sizeof(double));
if (!v) nrerror("allocation failure in dvector()");
#if SHOWMEM
locnfloat = nh-nl+1+1;
nfloat += locnfloat;
cumnfloat += locnfloat;
MemoryUsage();
#endif
return(v-nl+1);
}
float **matrix(int nrl,int nrh,int ncl,int nch)
{
int i, nrow=nrh-nrl+1, ncol=nch-ncl+1;
float **m;
m=(float **) malloc((size_t) (nrow+1)*sizeof(float*));
if (!m) nrerror("allocation failure 1 in matrix()");
m += 1;
m -= nrl;
m[nrl]=(float *) malloc((size_t)((nrow*ncol+1)*sizeof(float)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += 1;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++)
m[i]=m[i-1]+ncol;
return(m);
}
double **dmatrix(int nrl,int nrh,int ncl,int nch)
{
int i, nrow=nrh-nrl+1, ncol=nch-ncl+1;
double **m;
if( nrh < nrl || nch < ncl ) {
printf("Allocation impossible in dmatrix: %d %d %d %d\n",nrl,nrh,ncl,nch);
exit(1);
}
m=(double **) malloc((size_t) (nrow+1)*sizeof(double*));
if (!m) nrerror("allocation failure 1 in dmatrix()");
m += 1;
m -= nrl;
m[nrl]=(double *) malloc((size_t)((nrow*ncol+1)*sizeof(double)));
if (!m[nrl]) nrerror("allocation failure 2 in dmatrix()");
m[nrl] += 1;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++)
m[i]=m[i-1]+ncol;
#if SHOWMEM
locnfloat = (nrow+1 + (nrow*ncol+1));
nfloat += locnfloat;
cumnfloat += locnfloat;
MemoryUsage();
#endif
return(m);
}
int **imatrix(int nrl,int nrh,int ncl,int nch)
{
int i, nrow=nrh-nrl+1, ncol=nch-ncl+1;
int **m;
if( nrh < nrl || nch < ncl ) {
printf("Allocation impossible in imatrix: %d %d %d %d\n",nrl,nrh,ncl,nch);
exit(1);
}
m=(int **) malloc((size_t) (nrow+1)*sizeof(int*));
if (!m) nrerror("allocation failure 1 in imatrix()");
m += 1;
m -= nrl;
m[nrl]=(int *) malloc((size_t)((nrow*ncol+1)*sizeof(int)));
if (!m[nrl]) nrerror("allocation failure 2 in imatrix()");
m[nrl] += 1;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++)
m[i]=m[i-1]+ncol;
#if SHOWMEM
locnint = (nrow+1 + (nrow*ncol+1));
nint += locnint;
cumnint += locnint;
MemoryUsage();
#endif
return(m);
}
float **submatrix(float **a,int oldrl,int oldrh,int oldcl,int oldch,int newrl,int newcl)
{
int i,j, nrow=oldrh-oldrl+1, ncol=oldcl-newcl;
float **m;
m=(float **) malloc((size_t) ((nrow+1)*sizeof(float*)));
if (!m) nrerror("allocation failure in submatrix()");
m += 1;
m -= newrl;
for(i=oldrl,j=newrl;i<=oldrh;i++,j++)
m[j]=a[i]+ncol;
return(m);
}
double ***f3tensor(int nrl,int nrh,int ncl,int nch,int ndl,int ndh)
{
int i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1;
double ***t;
t=(double***) malloc((size_t)((nrow+1)*sizeof(double***)));
if (!t) nrerror("allocation failure 1 in f3tensor()");
t += 1;
t -= nrl;
t[nrl]=(double**) malloc((size_t)((nrow*ncol+1)*sizeof(double*)));
if(!t[nrl]) nrerror("allocation failure 2 in f3tensor()");
t[nrl] += 1;
t[nrl] -= ncl;
t[nrl][ncl]=(double*) malloc((size_t)((nrow*ncol*ndep+1)*sizeof(double)));
if(!t[nrl][ncl]) nrerror("allocation failure 3 in f3tensor()");
t[nrl][ncl] += 1;
t[nrl][ncl] -= ndl;
for(j=ncl+1;j<=nch;j++) t[nrl][j] = t[nrl][j-1]+ndep;
for(i=nrl+1;i<=nrh;i++) {
t[i] = t[i-1]+ncol;
t[i][ncl] = t[i-1][ncl]+ncol*ndep;
for(j=ncl+1;j<=nch;j++) t[i][j] = t[i][j-1]+ndep;
}
return(t);
}
void free_vector(float *v,int nl,int nh)
{
free((FREE_ARG) (v+nl-1));
}
void free_ivector(int *v,int nl,int nh)
{
#if SHOWMEM
cumnint -= (nh-nl+1+1);
#endif
free((FREE_ARG) (v+nl-1));
}
void free_cvector(char *v,int nl,int nh)
{
free((FREE_ARG) (v+nl-1));
}
void free_lvector(unsigned long *v,int nl,int nh)
{
free((FREE_ARG) (v+nl-1));
}
void free_dvector(double *v,int nl,int nh)
{
#if SHOWMEM
cumnfloat -= (nh-nl+1+1);
#endif
free((FREE_ARG) (v+nl-1));
}
void free_matrix(float **m,int nrl,int nrh,int ncl,int nch)
{
free((FREE_ARG) (m[nrl]+ncl-1));
free((FREE_ARG) (m+nrl-1));
}
void free_dmatrix(double **m,int nrl,int nrh,int ncl,int nch)
{
#if SHOWMEM
int nrow=nrh-nrl+1;
int ncol=nch-ncl+1;
cumnfloat -= (nrow+1 + (nrow*ncol+1));
#endif
free((FREE_ARG) (m[nrl]+ncl-1));
free((FREE_ARG) (m+nrl-1));
}
void free_imatrix(int **m,int nrl,int nrh,int ncl,int nch)
{
#if SHOWMEM
int nrow=nrh-nrl+1;
int ncol=nch-ncl+1;
cumnint -= (nrow+1 + (nrow*ncol+1));
#endif
free((FREE_ARG) (m[nrl]+ncl-1));
free((FREE_ARG) (m+nrl-1));
}
void free_submatrix(float **b,int nrl,int nrh,int ncl,int nch)
{
free((FREE_ARG) (b+nrl-1));
}
void free_f3tensor(double ***t,int nrl,int nrh,int ncl,int nch,int ndl,int ndh)
{
free((FREE_ARG) (t[nrl][ncl]+ndl-1));
free((FREE_ARG) (t[nrl]+ncl-1));
free((FREE_ARG) (t+nrl-1));
}
static Real timer_t0, timer_dt;
static int timer_active = FALSE;
static char timer_filename[600];
void timer_init()
{
timer_active = FALSE;
}
void timer_activate(const char *prefix)
{
Real time;
timer_active = TRUE;
time = clock() / (double)CLOCKS_PER_SEC;
AddExtension(prefix,timer_filename,"time");
printf("Activating timer (s): %.2f\n",time);
printf("Saving timer info to file %s\n",timer_filename);
timer_dt = time;
timer_t0 = time;
}
void timer_show()
{
static int visited = 0;
Real time;
FILE *out;
#if MEM_USAGE
int who,ret;
Real memusage;
static struct rusage usage;
#endif
if(!timer_active) return;
time = clock() / (double)CLOCKS_PER_SEC;
printf("Elapsed time (s): %.2f %.2f\n",time-timer_t0,time-timer_dt);
#if MEM_USAGE
who = RUSAGE_SELF;
ret = getrusage( who, &usage );
if( !ret ) {
printf("maxrss %ld\n",usage.ru_maxrss);
printf("ixrss %ld\n",usage.ru_ixrss);
printf("idrss %ld\n",usage.ru_idrss);
printf("isrss %ld\n",usage.ru_isrss);
memusage = (double) 1.0 * usage.ru_maxrss;
}
else {
printf("Failed to obtain resource usage!\n");
memusage = 0.0;
}
#endif
visited = visited + 1;
if( visited == 1 ) {
out = fopen(timer_filename,"w");
}
else {
out = fopen(timer_filename,"a");
}
#if MEM_USAGE
fprintf(out,"%3d %12.4le %12.4le %12.4le\n",visited,time-timer_t0,time-timer_dt,memusage);
#else
fprintf(out,"%3d %12.4le %12.4le\n",visited,time-timer_t0,time-timer_dt);
#endif
fclose(out);
timer_dt = time;
}
void bigerror(const char error_text[])
{
fprintf(stderr,"***** ERROR: We cannot continue with this! *****\n");
fprintf(stderr,"***** %s\n",error_text);
fprintf(stderr,"***** ...now exiting to system!\n");
exit(1);
}
void smallerror(const char error_text[])
{
fprintf(stderr,"***** WARNING: This should not happen but we try to continue! *****\n");
fprintf(stderr,"***** %s\n",error_text);
}
int FileExists(char *filename)
{
FILE *in;
if((in = fopen(filename,"r")) == NULL)
return(FALSE);
else {
fclose(in);
return(TRUE);
}
}
Real Minimum(Real *vector,int first,int last)
{
Real min;
int i;
min=vector[first];
for(i=first+1;i<=last;i++)
if(min>vector[i]) min=vector[i];
return(min);
}
int Minimi(Real *vector,int first,int last)
{
Real min;
int i,mini;
mini=first;
min=vector[first];
for(i=first+1;i<=last;i++)
if(min>vector[i])
min=vector[(mini=i)];
return(mini);
}
Real Maximum(Real *vector,int first,int last)
{
Real max;
int i;
max=vector[first];
for(i=first+1;i<=last;i++)
if(max<vector[i]) max=vector[i];
return(max);
}
int Maximi(Real *vector,int first,int last)
{
Real max;
int i,maxi;
maxi=-1;
max=vector[first];
for(i=first+1;i<=last;i++)
if(max<vector[i])
max=vector[(maxi=i)];
return(maxi);
}
void AddExtension(const char *fname1,char *fname2,const char *newext)
{
char *ptr1,*ptr2;
strcpy(fname2,fname1);
ptr1 = strrchr(fname2, '.');
if (ptr1) {
int badpoint=FALSE;
ptr2 = strrchr(fname2, '/');
if(ptr2 && ptr2 > ptr1) badpoint = TRUE;
if(!badpoint) *ptr1 = '\0';
}
strcat(fname2, ".");
strcat(fname2,newext);
}
int StringToStrings(const char *buf,char args[10][15],int maxcnt,char separator)
{
int i,cnt,totlen,finish;
char *ptr1 = (char *)buf, *ptr2;
totlen = strlen(buf);
finish = 0;
cnt = 0;
if (!buf[0]) return 0;
do {
ptr2 = strchr(ptr1,separator);
if(ptr2) {
for(i=0;i<15;i++) {
args[cnt][i] = ptr1[i];
if(ptr1 + i >= ptr2) break;
}
args[cnt][i] = '\0';
ptr1 = ptr2+1;
}
else {
for(i=0;i<15;i++) {
if(ptr1 + i >= buf+totlen) break;
args[cnt][i] = ptr1[i];
}
args[cnt][i] = '\0';
finish = 1;
}
cnt++;
} while (cnt < maxcnt && !finish);
return cnt;
}
int StringToReal(const char *buf,Real *dest,int maxcnt,char separator)
{
int cnt = 0;
char *ptr1 = (char *)buf, *ptr2;
if (!buf[0]) return 0;
do {
ptr2 = strchr(ptr1,separator);
if (ptr2) ptr2[0] = '\0';
dest[cnt++] = atof(ptr1);
if (ptr2) ptr1 = ptr2+1;
} while (cnt < maxcnt && ptr2 != NULL);
return cnt;
}
int StringToInteger(const char *buf,int *dest,int maxcnt,char separator)
{
int cnt = 0;
char *ptr1 = (char *)buf, *ptr2;
int ival;
if (!buf[0]) return 0;
do {
ptr2 = strchr(ptr1,separator);
if (ptr2) ptr2[0] = '\0';
ival = atoi(ptr1);
dest[cnt++] = ival;
if (ptr2) ptr1 = ptr2+1;
} while (cnt < maxcnt && ptr2 != NULL);
return cnt;
}
int StringToIntegerNoZero(const char *buf,int *dest,int maxcnt,char separator)
{
int cnt = 0;
char *ptr1 = (char *)buf, *ptr2;
int ival;
if (!buf[0]) return 0;
do {
ptr2 = strchr(ptr1,separator);
if (ptr2) ptr2[0] = '\0';
ival = atoi(ptr1);
if(ival == 0) break;
dest[cnt++] = ival;
if (ptr2) ptr1 = ptr2+1;
} while (cnt < maxcnt && ptr2 != NULL);
return cnt;
}
int next_int(char **start)
{
int i;
char *end;
i = strtol(*start,&end,10);
*start = end;
return(i);
}
int next_int_n(char **start, int n)
{
int i;
char *end = *start+n;
char saved = *end;
*end = '\0';
i = strtol(*start,NULL,10);
*end = saved;
*start = end;
return(i);
}
Real next_real(char **start)
{
Real r;
char *end;
r = strtod(*start,&end);
*start = end;
return(r);
}
void SortIndex( int N, double *Key, int *Ord )
{
double CurrentKey;
int CurrentOrd;
int CurLastPos;
int CurHalfPos;
int i;
int j;
for(i=1;i<=N;i++)
Ord[i] = i;
CurHalfPos = N / 2 + 1;
CurLastPos = N;
while( 1 ) {
if ( CurHalfPos > 1 ) {
CurHalfPos--;
CurrentKey = Key[CurHalfPos];
CurrentOrd = Ord[CurHalfPos];
} else {
CurrentKey = Key[CurLastPos];
CurrentOrd = Ord[CurLastPos];
Key[CurLastPos] = Key[1];
Ord[CurLastPos] = Ord[1];
CurLastPos--;
if ( CurLastPos == 1 ) {
Key[1] = CurrentKey;
Ord[1] = CurrentOrd;
return;
}
}
i = CurHalfPos;
j = 2 * CurHalfPos;
while( j <= CurLastPos ) {
if ( j < CurLastPos && Key[j] < Key[j + 1] ) {
j++;
}
if ( CurrentKey < Key[j] ) {
Key[i] = Key[j];
Ord[i] = Ord[j];
i = j;
j += i;
} else {
j = CurLastPos + 1;
}
}
Key[i] = CurrentKey;
Ord[i] = CurrentOrd;
}
}