#ifndef __UTIL_H
#define __UTIL_H
#include <stdio.h>
#if SUPERLU > 0
#include "slu_ddefs.h"
#endif
#define MAX(x,y) (((x)>(y))?(x):(y))
#define MIN(x,y) (((x)<(y))?(x):(y))
#define MAX3(a,b,c) MAX(MAX(a,b),c)
#define MIN3(a,b,c) MIN(MIN(a,b),c)
#define MID3(a,b,c) ((MIN(a,b)<(c))?(MIN(MAX(a,b),c)):(MAX(MIN(a,b),c)))
#define MAX4(a,b,c,d) MAX(MAX(MAX(a,b),c),d)
#define MIN4(a,b,c,d) MIN(MIN(MIN(a,b),c),d)
#define DELTA 1.0e-6
#define LARGENUM 1.0e100
#define NULLFILE "(null)"
#define TRUE 1
#define FALSE 0
#define RAND_SEED 1500450271
#define STR_SIZE 512
#define LINE_SIZE 65536
#define MAX_ENTRIES 512
int eq(double x, double y);
int le(double x, double y);
int ge(double x, double y);
void fatal (char *s);
void warning (char *s);
void swap_ival (int *a, int *b);
void swap_dval (double *a, double *b);
int tolerant_ceil(double val);
int tolerant_floor(double val);
double *dvector(int n);
void free_dvector(double *v);
void dump_dvector(double *v, int n);
void copy_dvector (double *dst, double *src, int n);
void zero_dvector (double *v, int n);
int *ivector(int n);
void free_ivector(int *v);
void dump_ivector(int *v, int n);
void copy_ivector (int *dst, int *src, int n);
void zero_ivector (int *v, int n);
double sum_dvector (double *v, int n);
double **dmatrix(int nr, int nc);
void free_dmatrix(double **m);
void dump_dmatrix(double **m, int nr, int nc);
void copy_dmatrix(double **dst, double **src, int nr, int nc);
void zero_dmatrix(double **m, int nr, int nc);
void resize_dmatrix(double **m, int nr, int nc);
void mirror_dmatrix(double **m, int n);
int **imatrix(int nr, int nc);
void free_imatrix(int **m);
void dump_imatrix(int **m, int nr, int nc);
void copy_imatrix(int **dst, int **src, int nr, int nc);
void resize_imatrix(int **m, int nr, int nc);
double ***dcuboid_tail(int nr, int nc, int nl, int xtra);
void free_dcuboid(double ***m);
void init_rand(void);
int rand_upto(int max);
double rand_fraction(void);
typedef struct str_pair_st
{
char name[STR_SIZE];
char value[STR_SIZE];
}str_pair;
int read_str_pairs(str_pair *table, int max_entries, char *file);
int parse_cmdline(str_pair *table, int max_entries, int argc, char **argv);
void dump_str_pairs(str_pair *table, int size, char *file, char *prefix);
int get_str_index(str_pair *table, int size, char *str);
int str_pairs_remove_duplicates(str_pair *table, int size);
int bsearch_double(double *arr, int n, double ele, double **loc);
int bsearch_insert_double(double *arr, int n, double ele);
int contains(int *array, int size, int value);
unsigned int ones8(register unsigned char n);
int count_significant_lines(FILE *fp);
int coo2csc(int size, int nnz,
int *cooX, int *cooY, double *cooV,
int *cscRowInd, int *cscColPtr, double *cscV);
int c2c_cmp( const void *a , const void *b);
void gaussj(double **a, int n, double *b);
#if SUPERLU > 0
typedef struct diagonal_matrix_t_st
{
int n;
double *vals;
} diagonal_matrix_t;
int diagonal_add_SparseMatrix(double c, diagonal_matrix_t *diag, SuperMatrix *A);
int diagonal_mul_vector(double c, diagonal_matrix_t *diag, double **vector);
int vector_add_vector(int n, double c1, double *vector1, double c2, double *vector2);
int SparseMatrix_mul_vector(SuperMatrix *A, double *vector);
void cooTocsv(char *filename, int size, int nnz, int *cooX, int *cooY, double *cooV);
void diagTocsv(char *filename, diagonal_matrix_t *diag);
void vectorTocsv(char *filename, int size, double *vector);
#endif
#endif