📄 corr.c
字号:
/*---------------------------------------------------------------------- File : corr.c Contents: covariances/correlation coefficients computation program Author : Christian Borgelt History : 07.04.1999 file created from file xmat.c 10.04.1999 first version completed 11.04.1999 options -x, -v, and -c added 14.04.1999 option -k (expected values from known pairs) 01.12.1999 bug in connection with option -d removed 10.11.2000 adapted to new module mvnorm 07.06.2002 LaTeX output option added 16.08.2003 slight changes in error message output 22.04.2004 bug in function dblout fixed (log(0))----------------------------------------------------------------------*/#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <float.h>#include <math.h>#include <assert.h>#include "symtab.h"#include "tfscan.h"#include "mvnorm.h"#ifdef STORAGE#include "storage.h"#endif/*---------------------------------------------------------------------- Preprocessor Definitions----------------------------------------------------------------------*/#define PRGNAME "corr"#define DESCRIPTION "compute covariance matrix/correlation coefficients"#define VERSION "version 2.6 (2003.04.15) " \ "(c) 1999-2004 Christian Borgelt"/* --- sizes --- */#define BUFSIZE 512 /* size of read buffer */#define BLKSIZE 32 /* block size for column vector *//* --- error codes --- */#define OK 0 /* no error */#define E_NONE 0 /* no error */#define E_NOMEM (-1) /* not enough memory */#define E_FOPEN (-2) /* file open failed */#define E_FREAD (-3) /* file read failed */#define E_FWRITE (-4) /* file write failed */#define E_OPTION (-5) /* unknown option */#define E_OPTARG (-6) /* missing option argument */#define E_ARGCNT (-7) /* wrong number of arguments */#define E_STDIN (-8) /* double assignment of stdin */#define E_FLDNAME (-9) /* illegal field name */#define E_VALUE (-10) /* illegal value */#define E_EMPFLD (-11) /* empty field name */#define E_DUPFLD (-12) /* duplicate field name */#define E_FLDCNT (-13) /* wrong number of fields */#define E_UNKNOWN (-14) /* unknown error *//*---------------------------------------------------------------------- Type Definitions----------------------------------------------------------------------*/typedef struct { /* --- set of table columns --- */ int colvsz; /* size of column vector */ int colcnt; /* number of matrix columns */ int vldcnt; /* number of valid matrix columns */ int maxlen; /* maximal length of a column name */ const char **names; /* table column names */ double *vals; /* current values */} COLSET; /* (set of table columns) *//*---------------------------------------------------------------------- Constants----------------------------------------------------------------------*/static const char *errmsgs[] = { /* error messages */ /* E_NONE 0 */ "no error\n", /* E_NOMEM -1 */ "not enough memory\n", /* E_FOPEN -2 */ "cannot open file %s\n", /* E_FREAD -3 */ "read error on file %s\n", /* E_FWRITE -4 */ "write error on file %s\n", /* E_OPTION -5 */ "unknown option -%c\n", /* E_OPTARG -6 */ "missing option argument\n", /* E_ARGCNT -7 */ "wrong number of arguments\n", /* E_STDIN -8 */ "double assignment of standard input\n", /* E_FLDNAME -9 */ "illegal field name \"%s\"\n", /* E_VALUE -10 */ "file %s, record %d: " "illegal value \"%s\" in field %d\n", /* E_EMPFLD -11 */ "file %s, record %d: " "empty name%s in field %d\n", /* E_DUPFLD -12 */ "file %s, record %d: " "duplicate field name \"%s\"\n", /* E_FLDCNT -13 */ "file %s, record %d: " "%d field(s) expected\n", /* E_UNKNOWN -14 */ "unknown error\n"};/*---------------------------------------------------------------------- Global Variables----------------------------------------------------------------------*/static char *prgname; /* program name for error messages */static TFSCAN *tfscan = NULL; /* table file scanner */static SYMTAB *symtab = NULL; /* symbol table */static COLSET *colset = NULL; /* column descriptions */static MVNORM *mvnorm = NULL; /* multivariate normal distribution */static FILE *in = NULL; /* input file */static FILE *out = NULL; /* output file */static char rdbuf[BUFSIZE]; /* read buffer */static char fnbuf[BUFSIZE]; /* field name buffer *//*---------------------------------------------------------------------- Column Set Functions----------------------------------------------------------------------*/#define cs_create() (COLSET*)calloc(1, sizeof(COLSET))#define cs_colcnt(s) ((s)->colcnt)#define cs_proc(s,m,w) mvn_add (m, (s)->vals, w)#define cs_procx(s,m,w) mvn_addx(m, (s)->vals, w)/*--------------------------------------------------------------------*/#ifndef NDEBUGstatic void cs_delete (COLSET *cset){ /* --- delete a column set */ if (cset->names) /* if there is a names vector, */ free((void*)cset->names); /* delete it */ if (cset->vals) /* if there is a value vector, */ free((void*)cset->vals); /* delete it */ free(cset); /* delete the column set body */} /* cs_delete() */#endif/*--------------------------------------------------------------------*/static int cs_add (COLSET *cset, const char *name){ /* --- add a column to a column set */ int n; /* new column vector size, buffer */ void *p; /* new names/values vector */ assert(cset && name); /* check the function arguments */ n = cset->colvsz; /* get the column vector size and */ if (cset->colcnt >= n) { /* if the column vector is full */ n += (n > BLKSIZE) ? (n >> 1) : BLKSIZE; p = realloc((void*)cset->names, n *sizeof(const char*)); if (!p) return -1; /* enlarge the names vector */ cset->names = (const char**)p; p = realloc(cset->vals, n *sizeof(double)); if (!p) return -1; /* enlarge the names vector */ cset->vals = (double*)p; cset->colvsz = n; } /* set the new vectors and their size */ cset->names[cset->colcnt ] = name; cset->vals [cset->colcnt++] = MVN_UNKNOWN; return 0; /* note the table column's name */} /* cs_add() */ /* and return 'ok' *//*--------------------------------------------------------------------*/static void cs_set (COLSET *cset, int colid, const char *name){ /* --- set a column value */ char *s; /* end pointer for conversion */ double *val; /* pointer to the value to set */ assert(cset && (colid >= 0) && (colid < cset->colcnt)); if (!cset->names[colid]) /* if the column name has been */ return; /* deleted, abort the function */ val = cset->vals +colid; /* get the value buffer */ if (!name) { /* if no value name is given, */ *val = MVN_UNKNOWN; return; } /* the value is unknown */ *val = strtod(name, &s); /* convert the attribute value */ if (*s || (s == name)) { /* if it is symbolic */ *val = MVN_UNKNOWN; cset->names[colid] = NULL; } } /* cs_set() */ /* invalidate the column *//*--------------------------------------------------------------------*/static void cs_prepare (COLSET *cset){ /* --- prepare columns for output */ int i, len; /* loop variable, length of a name */ const char *name; /* to traverse the column names */ cset->vldcnt = 0; /* init. the number of valid columns */ cset->maxlen = 9; /* and the maximal length of a name */ for (i = 0; i < cset->colcnt; i++) { name = cset->names[i]; /* traverse the columns */ if (!name) continue; /* skip invalidated columns */ cset->vldcnt++; /* count the valid columns */ len = (int)strlen(name); /* determine the length of the name */ if (len > cset->maxlen) cset->maxlen = len; } /* adapt the maximal length */} /* cs_prepare() *//*---------------------------------------------------------------------- Auxiliary Functions----------------------------------------------------------------------*/static void dblout (FILE *out, double num, int len){ /* --- print a floating point number */ int n, d; /* number of characters/decimals */ char m[16], e[8]; /* mantissa and exponent */ if (num >= 0.0) { m[0] = ' '; } else { num = -num; m[0] = '-'; } len--; /* determine and store the sign */ n = (num == 0) /* calculate the decimal exponent */ ? 0 : (int)floor(log10(num)); if ((n > len) || (n <= -3)) { /* if an exponent is needed, */ num /= pow(10, n); /* comp. mantissa and note exponent */ d = len -2 -(n = sprintf(e, "e%d", n)); } else { /* if no exponent is needed, */ d = len -((n > 0) ? n+2 : 2); /* compute the number */ e[0] = n = 0; /* of decimal places possible */ } /* and clear the exponent */ n += sprintf(m+1, "%.*f", (d <= 0) ? 0 : d, num); while (n < len) { /* format the mantissa, */ fputc(' ', out); n++; } /* fill to the requested length, */ fputs(m, out); fputs(e, out); /* and print mantissa and exponent */} /* dblout() *//*----------------------------------------------------------------------The above function is needed, because a format string used with thefunction fprintf does not yield appropriate results.----------------------------------------------------------------------*/static int isunk (TFSCAN *tfscan, const char *s){ /* --- test for an unknown value */ assert(tfscan && s); /* check arguments */ while (*s) /* while not at end of string */ if (!tfs_istype(tfscan, TFS_OTHER, *s++)) return 0; /* if a character is not marked, */ return 1; /* return 'not an unknown value', */} /* isunk() */ /* otherwise return 'unknown value' *//*----------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -