name: Integral
synopsis:

>     g++ [flags ...] file ... -l /isip/tools/lib/$ISIP_BINARY/lib_system.a

>     #include <Integral.h>

>     static boolean getLoginDir(SysString& directory, const SysString& login_name);
>     static boolean expandName(SysString& exp_file, const SysString& in_file);
>     static boolean exit();

quick start:

>     SysString var(L"HOME");
>     SysString val;
>     boolean ret;
>     var.assign(L"root");
>     ret = Integral::getLoginDir(val, var);

>     if ((!ret) || (val.length() == 0)) {
>       Console::put(L"Error in getLoginDir");
>     }

>     var.assign(L"$isip/include/Integral.h");
>     ret = Integral::expandName(val, var);

>     if ((!ret) || (val.length() == 0)) {
>       Console::put(L"Error in expandName");
>     }

description:
The Integral class serves two purposes. First, it defines standard integral data types. The C data types which gcc uses are machine dependent rather than data dependent. While the ISIP environment uses C data types wherever possible for the sake of familiarity, in some cases we must diverge for compatibility with new languages (such as Java). Second, the Integral class wraps miscellaneous operating system and math functions at a unified point in the environment. All methods in the Integral class are static so that the programmer need not instantiate the class to access the common functions. In this class, we include the generic double precision functions that parallel the ANSI C library functions.
The complex number functions defined below follow implementations given in:

R.V. Churchill, J.W. Brown, and R.F. Verhey, Complex Variables and Applications, Mc-Graw Hill, New York, New York, USA, 1976, pp. 52-71.

Note that complex data types are defined in IntegralTypes using the system class SysComplex. This somewhat circular dependency allows complex numbers to be available to users as integral types much like floats and integers. A low-level complex number type is also required to allow scalar complex numbers to be implemented fairly cleanly. See the math classes for more information on this.
dependencies:

- stdio.h
- stdlib.h
- limits.h
- math.h
- unistd.h
- dmalloc.h
- IntegralConfigure
- IntegralTypes
- IntegralNameSpace
- SysString
- SysChar

public constants:

- define the class name:

      static const SysString CLASS_NAME = L"Integral";

- define environmental variables:

      static const SysString ENV_ISIP = L"isip";

      static const SysString ENV_HOME = L"HOME";

- define constants for parsing environment variables and file pathnames under UNIX:

      static const SysChar ENV_MARKER = L'$';

      static const SysChar DIR_DELIM = L'/';

      static const SysChar DIR_HOME = L'~';

- define some UNIX commands:

      static const SysString UNIX_CMD_COPY = L"cp";

      static const SysString UNIX_CMD_MOVE = L"mv";

      static const SysString UNIX_CMD_REDIR = L"2>&1";

- define some constants for temporary filename creation:

      static const SysString TMPDIR = L"/tmp";

      static const SysString TMP_FMT_0 = L"/tmp_";

      static const SysString TMP_FMT_1 = L"_";

      static const SysString TMP_TEMPLATE = L"XXXXXX";

- define some constants related to help message generation:

      static const SysString HELP_FORMAT = L"more %s";

      static const SysString HELP_OPTION = L"-help";

- define negative and positive sign:

      static const long NEGATIVE = -1;

      static const long POSITIVE = 1;

- define sorting and comparison constants:

      enum ORDER { ASCENDING = 0, DESCENDING, COLLATING, DEF_ORDER = ASCENDING };

      enum COMPARE { LESSER = 0, EQUAL, GREATER, DEF_COMPARE = EQUAL };

- define constants that control the behavior of the clear method:

      enum CMODE { RETAIN = 0, RESET, RELEASE, FREE, DEF_CMODE = RESET };

- define constants that control the behavior of the graph class:

      enum COLOR { WHITE = 0, GREY, BLACK, BLUE, GREEN, DEF_COLOR = WHITE };

- define constants for representing the storage mode of a matrix: it is useful to have a global notion of the storage type of a matrix (Integral::SYMMETRIC) vs. MatrixFloat::SYMMETRIC)

      enum MTYPE { FULL = 0, DIAGONAL, SYMMETRIC, LOWER_TRIANGULAR, UPPER_TRIANGULAR, SPARSE, TYPE_UNCHANGED, TYPE_UNKNOWN, DEF_TYPE = FULL };

- define a return value for exiting:

      static const long SYS_RETURN_ERROR = 1;

      static const long SYS_RETURN_NOERROR = 0;

- define some debugging constants:

      enum DEBUG { NONE = 0, BRIEF, DETAILED, ALL, DEF_DEBUG = NONE };

- define some maximum sizes for i/o related functions:

      static const long MAX_FNAME_SIZE = PATH_MAX;

- define some constants related to geometry and pi:

      static const double PI = M_PI;

      static const double TWO_PI = (2.0*PI);

      static const double HALF_PI = (M_PI_2);

      static const double QUARTER_PI = (M_PI_4);

      static const double SQRT_TWO_PI = 2.506628274631;

      static const double INV_PI = M_1_PI;

      static const double TWO_INV_PI = M_2_PI;

      static const double SQRT_TWO = M_SQRT2;

      static const double INV_SQRT_TWO_PI = (1.0 / SQRT_TWO_PI);

      static const double DEGREES_IN_CIRCLE = 360.0;

- define an iteration count for testing random functions in diagnose method:

      static const long DIAG_ITER_COUNT = 100;

- default arguments to find methods:

      static const long NO_POS = -1;

- define important powers of two:

      static const double TWO_EXP7  = ((ulong)1 << 7);

      static const double TWO_EXP8  = ((ulong)1 << 8);

      static const double TWO_EXP15 = ((ulong)1 << 15);

      static const double TWO_EXP16 = ((ulong)1 << 16);

      static const double TWO_EXP23 = ((ulong)1 << 23);

      static const double TWO_EXP24 = ((ulong)1 << 24);

      static const double TWO_EXP31 = ((ulong)1 << 31);

      static const double TWO_EXP32 = (TWO_EXP16 * TWO_EXP16);

      static const double TWO_EXP63 = (TWO_EXP32 * TWO_EXP31);

      static const double TWO_EXP64 = (TWO_EXP32 * TWO_EXP32);

- define constants related to natural logarithms:

      static const double E = M_E;

      static const double LOG2E = M_LOG2E;

      static const double LOG10E = M_LOG10E;

      static const double LN2 = M_LN2;

      static const double LN10 = M_LN10;

- define constants related to the inverse of natural logarithms: currently, we only need to provide a scale factor for base 2 logarithms

      static const double INV_LN2 = 1.0 / M_LN2;

      static const double INV_LN10 = 1.0 / M_LN10;

- define the square root and inverse of square root of 2:

      static const double SQRT2 = M_SQRT2;

      static const double INV_SQRT2 = M_SQRT_1_2;

- define dB constants:

      static const double DB_POW_MIN_VALUE = 1.0e-10;

      static const double DB_POW_SCALE_FACTOR = 10.0;

      static const double DB_MAG_MIN_VALUE = 1.0e-10;

      static const double DB_MAG_SCALE_FACTOR = 20.0;

      static const double DB_MIN_VALUE = -100.0;

- define default arguments to methods:

      static const long DEF_GROW_SIZE = 1024;

- define precision-related constants:

      static const double DEF_PERCENTAGE = 0.1;

      static const double DEF_BOUND = 0.01;

error codes:

- error code indicating Integral class error:

      static const long ERR = 1500;

protected data:

- define the debug level:

      static Integral::DEBUG debug_level_d;

required public methods:

- static methods:

      static const SysString& name();

      static boolean diagnose(DEBUG debug_level);

- debug methods:

      static boolean setDebug(Integral::DEBUG level);

      static boolean debug(const unichar* message);

- destructor/constructor(s):

      the constructors and destructor are private so that Integral objects cannot be instantiated

- assign methods:

      these methods are omitted because Integral objects can not be instantiated

- operator= methods:

      these methods are omitted because Integral objects can not be instantiated

- i/o methods:

      these methods are omitted because Integral objects can not be instantiated

- equality methods:

      these methods are omitted because Integral objects can not be instantiated

- memory management methods:

      these methods are omitted because Integral objects can not be instantiated

class-specific public methods:

- wrappers for operating system functions: environmental variables

      static boolean getEnv(SysString& val, const SysString& var);

      static boolean getLoginDir(SysString& directory, const SysString& login_name);

      static boolean expandName(SysString& exp_file, const SysString& in_file);

- wrappers for operating system functions: process id numbers

      static long getPid();

      static long getParentPid();

      static long getHostid();

- wrappers for operating system functions: clean exit and static memory registration

      static long exit();

- wrappers for operating system functions: temporary files

      static boolean makeTemp(SysString& tmp_file);

      static boolean makeTemp(SysString& tmp_file, const SysString& name);

- bit-level methods:

      template <class TIntegral> static boolean almostEqual(TIntegral arg1, TIntegral arg2, double percent = DEF_PERCENTAGE, double bound = DEF_BOUND);

      static boolean almostEqual(float arg1, float arg2, double percent = DEF_PERCENTAGE, double bound = DEF_BOUND);

      static boolean almostEqual(double arg1, double arg2, double percent = DEF_PERCENTAGE, double bound = DEF_BOUND);

      static boolean almostEqual(const complexfloat& arg1, const complexfloat& arg2, double percent = DEF_PERCENTAGE, double bound = DEF_BOUND);

      static boolean almostEqual(const complexdouble& arg1, const complexdouble& arg2, double percent = DEF_PERCENTAGE, double bound = DEF_BOUND);

- inlined wrappers for math and C functions: these are listed alphabetically

      static double abs(double arg);

      static double acos(double arg);

      static double acosh(double arg);

      static double asin(double arg);

      static double asinh(double arg);

      static double atan(double arg);

      static double atanh(double arg);

      static double ceil(double arg);

      static double cos(double arg);

      static double cosh(double arg);

      static double exp(double arg);

      static double exp2(double arg);

      static double exp10(double arg);

  #if ISIP_WCHAR_MODE == ISIP_WCHAR_NONE

      static long fgetc(FILE* stream);

  #endif
  #if ISIP_WCHAR_MODE == ISIP_WCHAR_NONE

      static char* fgets(char* s, int n, FILE* stream);

  #endif
  #if ISIP_WCHAR_MODE != ISIP_WCHAR_NONE

      static wint_t fgetwc(FILE* stream);

  #endif
  #if ISIP_WCHAR_MODE != ISIP_WCHAR_NONE

      static unichar* fgetws(unichar* s, int n, FILE* stream);

  #endif

      static double floor(double arg);

  #if ISIP_WCHAR_MODE == ISIP_WCHAR_NONE

      static long fputc(int c, FILE* stream);

  #endif
  #if ISIP_WCHAR_MODE == ISIP_WCHAR_NONE

      static long fputs(char* s, FILE* stream);

  #endif
  #if ISIP_WCHAR_MODE != ISIP_WCHAR_NONE

      static wint_t fputwc(wint_t c, FILE* stream);

  #endif
  #if ISIP_WCHAR_MODE != ISIP_WCHAR_NONE

      static long fputws(const unichar* s, FILE* stream);

  #endif

      static double fraction(double arg);

      static long fseek(FILE* fptr, long offset, int whence);

      static ulong hash(byte val, ulong capacity);

      static ulong hash(ushort val, ulong capacity);

      static ulong hash(short val, ulong capacity);

      static ulong hash(ulong val, ulong capacity);

      static ulong hash(llong val, ulong capacity);

      static ulong hash(ullong val, ulong capacity);

      static ulong hash(float val, ulong capacity);

      static ulong hash(double val, ulong capacity);

      static ulong hash(long val, ulong capacity);

      static ulong hash_32(ulong val, ulong capacity);

      static ulong hash_64(ullong val, ulong capacity);

      static long hash(ulong* vector, long num_elements, long capacity);

      static double integer(double arg);

      static double log(double arg);

      static double log1p(double arg);

      static double log2(double arg);

      static double log10(double arg);

      static double max(double arg1, double arg2);

      static double min(double arg1, double arg2);

      static double pow(double arg, double exponent);

      static double round(double arg);

      static double sin(double arg);

      static double sinh(double arg);

      static double sleep(long sleep_seconds);

      static double sqrt(double arg);

      static double tan(double arg);

      static double tanh(double arg);

  #if ISIP_WCHAR_MODE == ISIP_WCHAR_SOLARIS

      static unichar* wcswcs(const unichar* ws1, const unichar* ws2);

  #endif
  #if ISIP_WCHAR_MODE != ISIP_WCHAR_SOLARIS

      static unichar* wcsstr(const unichar* ws1, const unichar* ws2);

  #endif
  #if ISIP_WCHAR_MODE == ISIP_WCHAR_SOLARIS

      static unichar* wcstok(unichar* ws, const unichar* delim, unichar** ptr);

  #endif
  #if ISIP_WCHAR_MODE != ISIP_WCHAR_SOLARIS

      static unichar* wcstok(unichar* ws, const unichar* delim, unichar** ptr);

  #endif
- complex versions of math and C functions: these are listed alphabetically

      static double abs(const complexdouble& arg);

      static complexdouble acos(const complexdouble& arg);

      static complexdouble acosh(const complexdouble& arg);

      static complexdouble asin(const complexdouble& arg);

      static complexdouble asinh(const complexdouble& arg);

      static complexdouble atan(const complexdouble& arg);

      static complexdouble atanh(const complexdouble& arg);

      static complexdouble ceil(const complexdouble& arg);

      static complexdouble cos(const complexdouble& arg);

      static complexdouble cosh(const complexdouble& arg);

      static complexdouble exp(const complexdouble& arg);

      static complexdouble exp2(const complexdouble& arg);

      static complexdouble exp10(const complexdouble& arg);

      static complexdouble floor(const complexdouble& arg);

      static complexdouble log(const complexdouble& arg);

      static complexdouble log2(const complexdouble& arg);

      static complexdouble log10(const complexdouble& arg);

      static complexdouble log1p(const complexdouble& arg);

      static complexdouble max(const complexdouble& arg1, const complexdouble& arg2);

      static complexdouble min(const complexdouble& arg1, const complexdouble& arg2);

      static complexdouble pow(const complexdouble& arg, const complexdouble& exponent);

      static complexdouble round(const complexdouble& arg);

      static complexdouble sin(const complexdouble& arg);

      static complexdouble sinh(const complexdouble& arg);

      static complexdouble sqrt(const complexdouble& arg);

      static complexdouble tan(const complexdouble& arg);

      static complexdouble tanh(const complexdouble& arg);

- other math functions that are useful for speech research:

      static double logAddLog(const double x, const double y);

- functions that are useful for time measurements:

      static long time();

      static boolean cTime(SysString& time);

      static boolean utcTime(SysString& time);

private methods:

- declare the destructor/constructor(s): these are private so the class cannot be instantiated

      ~Integral();

      Integral();

      Integral(const Integral& arg);

examples:

- This example shows how to perform basic math operations:

      double x = 27;
      double y = Integral::cos(27);
      complexdouble z(27, 27);
      double zz = Integral::cos(z);

- This example shows how to get environmental variables and process id numbers:

      SysString var(L"HOME");
      SysString val;
      boolean ret;

      ret = Integral::getEnv(val, var);

      long pid = getPid();
      long ppid = getParentPid();

notes:

- In this release of Integral, we have made extensive use of inlined functions for wrappers for operating system functions.
- Note however that we don't use the keyword "inline" in the function declaration. Rather than force the compiler to inline, which might lead to gross inefficiencies, we let the compiler decide whether to inline functions.
- The implementation of almostEqual has also been significantly overhauled to make it more user-friendly and predictable. The previous version examined bits directly; the current version just looks at the magnitude of the difference compared to the size of the numbers producing the difference.