VectorLib
Site Index:
OptiVec home
MatrixLib
CMATH
Download
Order
Update
Support

VectorLib
5. Error Handling
5.1 General Remarks
There are two general types of error handling: by the hardware, or by the software. In order to prevent uncontrolled program crash, it is highly desirable that conditions, leading to hardware errors, be recognized before the errors actually occur. All highlevel computer languages support this software errorhandling to various degrees of perfection. Within the
tightlydefined functions and routines of this OptiVec package, often an even more efficient error handling by the program itself is possible than provided by the compilers for userwritten code.
However, it should be noted that no absolute overflow protection is possible for the extendedprecision versions. They do not have a "safety margin" left as in the single and doubleprecision versions, where internally all calculations are performed in extended precision. Especially the VEx_ and VCEx_ versions may fail if constant parameters are very large, or if the X vector elements themselves are already near the overflow limit. To be on the safe side, constant parameters should not exceed about 1.E32 for float, 1.E150 for double, and 1.E2000 for extended parameters.
In the "expanded" versions of all functions with extended accuracy (those with the prefixes VEx_ and VCEx_; for example VEx_exp), there is generally no overflow protection for the calculation of A*X_{i}+B, but only for the core of the function itself and for the final multiplication by C.
A series of identical errors occurring within one and the same OptiVec function leads to one error message only. Subsequent identical messages are suppressed.
There is a fundamental difference between floatingpoint and integer numbers with respect to OVERFLOW and DOMAIN errors: for floatingpoint numbers, these are always serious errors, whereas for integer numbers, by virtue of the implicit modulo2^{n} arithmetics, this is not necessarily the case. In the following two paragraphs, details are given on the error handling of integer and floatingpoint numbers, respectively.
Back to VectorLib Table of Contents
OptiVec home
5.2 Integer Errors
The only genuine integer errors are ZERODIVIDE errors (if a division by 0 is attempted). Other integer errors are neglected due to the implicit definition of integer operations as being performed modulo the respective power of 2 (see chapter 4.4). For those situations in which implicit modulo 2^{n} arithmetics is not appropriate, OptiVec offers the possibility to trap these errors and print an error message and/or abort the program.
All functions where INTEGER OVERFLOW (e.g., in VI_ramp, VI_mulV, etc.) or INTEGER DOMAIN errors (e.g., in V_ItoU for negative Xvalues) may occur, exist in two versions: the "normal" version employs modulo 2^{n} arithmetics and interchanges signed and unsigned data types according to their bit pattern. For the 16bit and 32bit integer types (but not for 8bit and 64bit), there is a second version which also employs modulo 2^{n} arithmetics, but detects the errors. This second variant is denoted by the letter "o" (for "overflow detection") in the prefix: VIo_, VSIo_, VULo_, etc. (for the datatype interconversion functions, the prefix V_ is changed into Vo_). Here, the action to be taken in the case of INTEGER OVERFLOW or INTEGER DOMAIN errors has to be defined by calling V_setIntErrorHandling somewhere before the call to the VIo_ function. V_setIntErrorHandling takes an argument of the type V_ihand (defined in <VecLib.h> and the unit VecLib) with one of three possible values:
ierrNote  print an error message 
ierrAbort  print an error message and exit the program 
ierrIgnore  ignore the problem. With this last option, the error handling can be switched off intermediately. 
Although you may use a call to
V_setIntErrorHandling( ierrIgnore );
to switch the error handling off, it is always better simply to use the "normal" VI_ version rather than the VIo_ version with the errorhandling shortcut, as the normal version is always much faster.
C/C++ only:
To choose the overflowdetecting version not only for single function calls, but everywhere, the easiest way is to define symbolic constant V_trapIntError in the program header before(!) <VecLib.h> is included:
Example:
#define V_trapIntError 1
#include <VIstd.h>
#include <VImath.h>
.....
main() /* or WinMain(), or OwlMain() */
{
iVector I1, I2;
I1 = VI_vector( 1000 ); I2 = VI_vector( 1000 );
V_setIntErrorHandling( ierrNote );
VI_ramp( I1, 1000, 0, 50 ); /* an overflow will occur here! */
V_setIntErrorHandling( ierrIgnore );
VI_mulC( I2, I1, 1000, 5 );
/* here, even a whole series of overflows will occur;
they are all ignored. */
....
}
Back to VectorLib Table of Contents
OptiVec home
5.3 FloatingPoint Errors
5.3.1 C/C++ specific
In order to understand the details of the floatingpoint error handling outlined in the following sections, you may wish to refer to the description of the functions _matherr and signal in the documentation of your C++ compiler.
(Borland C++ only: prior to the version 4.0, instead of _matherr() the function matherr()  without the leading underbar  was used, see below).
Keep in mind that _matherr and _matherrl are the userdefinable focal points for the handling of all softwaredetected errors, whereas signal is used to install a handler for hardwaredetected errors (which should better be avoided in the first place). Within the VectorLib functions, _matherr is used for the error handling in the VF_, VCF_, VD_, and VCD_ versions. _matherrl is used in the VE_ and VCE_ versions (32bit Embarcadero / Borland C++ only, as neither Visual C++ nor 64bit RAD Studio support 80bit real numbers).
If the function in which an error occurs has one realvalued argument, only the parameter e>x is defined in calling _matherr and e>y is left undefined. Only if there are two arguments (like in VF_atan2 or in VF_cotrpi),
both e>x and e>y are needed to hold these arguments. For complex arguments, the real part is stored in e>x and the imaginary part in e>y.
Back to VectorLib Table of Contents
OptiVec home
5.3.2 Pascal/Delphi specific
The types of errors occurring in mathematical functions are described in detail below. How OptiVec handles each type of error is defined by a call to V_setFPErrorHandling. The possible options are set by the fperrXXX constants described with V_setFPErrorHandling. When calling V_setFPErrorHandling, combine these constants by the OR operator. Note that this influences only the way errors are handled within OptiVec functions. It does not affect the way how the standard Borland Pascal/Delphi functions handle errors.
In addition to the error handling "by element", the return values of the mathematical functions show if all elements have been processed errorfree (return value FALSE) or if an error occurred and was handled (return value TRUE).
Back to VectorLib Table of Contents
OptiVec home
5.3.3 Error Types (Both C/C++ and Pascal/Delphi)
For each VectorLibfunction, the types of errors that are detected and handled are noted in the individual descriptions. All functions derived from ANSI C or Pascal math functions (those whose declarations are to be found in <V?math.h> or the units V?math) contain a fullyfledged mathematical error handling. In addition to the error handling "by element", their return value shows if all elements have been processed errorfree (return value FALSE or 0) or if an error occurred and was handled (return value TRUE or different from 0).
In the following description of all floatingpoint error types, we denote by "HUGE_VAL" the largest number possible in the respective data type. Similarly, "TINY_VAL" is the smallest denormal number representable in the
respective data type; this is not the same as "MIN_VAL", which is the smallest fullaccuracy number of the respective data type.
 DOMAIN errors most often lead to the result NAN ("notanumber"). Even if nothing happens within the function itself that detects a DOMAIN error, an uncontrolled program crash may result if subsequent operations are performed on the vector element set to NAN. For C/C++, we therefore recommend to modify _matherr and _matherrl in such a way that the program is aborted if a DOMAIN error occurs (for an example, see below; alternatively, the UNIX style may be adopted; see the file MATHERR.C supplied with the your C/C++ compiler). Changing the return value of _matherr is another possiblity, but the better way very clearly is to avoid any DOMAIN errors by performing appropriate checks before calling functions like VF_sqrt, VF_log, VF_atan2 etc.
For Pascal/Delphi, we recommend not to change the default setting of V_FPErrorHandlingMode or to include "fperrAbortDOMAIN" in any changes.
Note: the pseudonumbers INF and NAN are not allowed as input for any functions of OptiVec. They are not tested for; their presence will normally result in a hardware interrupt.
 SING errors are treated like an extreme case of OVERFLOW (see below). In most cases, they arise from an implicit division by zero or from taking the logarithm of zero. The proposed result is never NAN, but always a "number", in most cases ±HUGE_VAL. Although it is recommended also in the case of SING errors to abort the program and take the necessary measures to avoid them, you may choose to continue program execution.
 OVERFLOW errors are the most abundant form of floatingpoint errors. They are always handled by proposing +HUGE_VAL or HUGE_VAL as the result. Within many user algorithms, OVERFLOW errors may occur for intermediate results; if subsequent steps perform operations like taking the inverse, the final result may be acceptable despite the error. Therefore, we recommend to accept the returnvalue proposal and not to abort the program.
C/C++ only: In principle, you may decide not to accept the returnvalue proposal of _matherr, but to substitute another one. However, for several reasons you are discouraged from doing that: the correct sign of the result is
set by the calling ("complaining") function in many cases only after returning from _matherr; the xvalue passed to _matherr (which should be inspected before the return value is modified) may either be X_{i}
or (as in some of the expanded complex math functions of the VCEx_... family) the intermediate result x' = Ax + B. Note, furthermore, that all xvalues are passed to _matherr as doubleprecision floatingpoint numbers, also in the case of integer input numbers (like in VF_tanrpi, where P_{i} and q are passed as x and y to _matherr).
 TLOSS ("total loss of precision") errors are detected only if a more serious error might occur in the respective function. For example, the sine function takes on values between 1 and +1 for all arguments. So, in case of an argument too big for the sine function to be evaluated with any accuracy, the result may nevertheless be "tacitly" set to 0.0 and no call to the OptiVec error handler is generated (whereas Borland C++ chooses NAN, "not a number", as the result, which is certainly even less correct than arbitrarily choosing 0.0).
On the other hand, the cosecant, i.e. the inverse of the sine, is not defined for arguments of integer multiples of p. Therefore, a more serious error (in this case a SING or an OVERFLOW error) might be hidden under the TLOSS for very big arguments. This possibility is taken into account by calling the error handler, although the proposed result is again set to 0.0 (which is the mean of the two extremes +HUGE_VAL and HUGE_VAL). Generally, the default result in the case of a TLOSS error is the mean of the results for arguments of +0.0 and 0.0.
 UNDERFLOW errors are never detected; underflowing results are always "tacitly" set to denormal numbers or finally to 0.0 by the floatingpoint processor itself. Indeed, you may very rarely wish to do something else in this case.
 As in all nonvectorized math functions of the Borland compilers and Visual C++, PLOSS ("partial loss of precision") errors are never detected and precision problems simply ignored.
Back to VectorLib Table of Contents
OptiVec home
5.4 The Treatment of Denormal Numbers
"Denormal" are very small numbers between zero and the smallest fullaccuracy number available in the respective data type. You may understand the underlying principle from a simplified example: 1.175494E38 is the smallest "normal" float, with 7digit accuracy. What about 1/1024 of this value? This can only be represented as
0.001145E38, which is accurate to only four digits, since the first three digits are needed to hold zeros. Thus, denormal numbers provide a smooth transition between the smallest representable normal numbers and zero.
In general, they may be treated just as ordinary numbers. In some instances, however, like taking the inverse, overflow errors may occur. In these cases, the somewhat academic distinction between SING and OVERFLOW errors is dropped
and a SING error signalled (as if it was a division by exactly 0).
On the other hand, for functions like the logarithms, very small input numbers may give perfectly reasonable results, although the exact number 0.0 is an illegal argument, leading to a SING error. Here, the possible loss of precision is neglected and denormals are considered valid arguments. (This treatment is quite different from that chosen for the math functions of
most compilers, where denormal arguments lead to SING errors also in these cases, which seems less appropriate to us.)
Back to VectorLib Table of Contents
OptiVec home
5.5 Advanced Error Handling: Writing Messages into a File
Quite generally, the libraries shipped with compilers do not offer the programmer much control over the way error messages are printed. While this is fine in most instances, there may be situations in which you might, for example, wish the error messages not to be printed to the screen, but rather into a file, so that you could check later what has gone wrong. An additional motivation could come from the fact that, for any error occurring in a Windows program, a message box is displayed and program execution interrupted until you acknowledge having taken notice of the error.
You might wish to circumvent this. To this end, OptiVec provides the function V_setErrorEventFile. This function needs as arguments the desired
name of your event file and a switch named ScreenAndFile which decides if the error message is printed only into the file, or additionally to the screen as well.
Note that this redirection of error messages is valid only for errors occurring in OptiVec routines. If you wish to do so, however, there is a way in C/C++ to extend the redirection also to the "nonOptiVec" functions: you may modify _matherr and _matherrl such that the statement
return 0;
(which signals an unresolved error) is replaced by the sequence
V_noteError( e>name, e>type ); return 1;
Thereby the task of printing the error message for unresolved errors is passed to the OptiVec function V_noteError. Keep in mind that it is the return value of _matherr which decides if an error message is printed by the default error handler of your compiler. Thus, after the call to V_noteError, the printing of the default error messages is bypassed by returning "1". (Also, do not forget that OptiVec uses your _matherr routine to determine which errors you accept and which not!)
Both C/C++ and Pascal/Delphi: The default printing of error messages on the screen alone is restored by V_closeErrorEventFile.
Back to VectorLib Table of Contents
OptiVec home
5.6 OptiVec Error Messages
Just as with any C/C++ or Pascal program, errors occurring within mathematical functions lead to the appropriate error messages. See paragraph 5.3.3 for details.
Apart from math errors, there are some runtime errors specific to OptiVec routines. These errors lead to the messages noted below. The name of the function where the error occurred is not always exactly the name you wrote
in your program. Instead of the prefix VI_, the message will read VLI_ or VSI_, depending on the memory model used. Similarly, instead of VU_, you will find VUL_ or VUS_.
VFs_FFT or VFl_FFT will be substituted for VF_FFT, again depending on the memory model. The reason for this behavior is that many functions share code and even names.
(00) OptiVec/CMATH not installed correctly (must use INSTALL.EXE !) 

Shareware version only: Either you are running a program containing OptiVec functions on a different computer than the one on which you installed OptiVec. The distribution of applications containing OptiVec functions is possible only with the Registered version.
Or you attempted to install OptiVec by unzipping the package by hand, without using INSTALL.EXE. This is not possible, as INSTALL.EXE also starts the clock for the trial period.
(0) Trial period for OptiVec/CMATH has expired! 

Shareware version only: Consider ordering the registered version!
You are trying to allocate memory, but there is not enough left. This error occurs mostly in connection with "forgotten" vectors that are allocated but never freed. Try these solutions:
* Look out for vectors that might be no longer needed and free them as soon as possible. Be sure that any vectors allocated in subroutines are freed before leaving the subroutine.
* Are you still working with 16bit models? If you need to work with large amounts of data, the memory model FLAT should be used, working with Win32, WindowsNT, or Windows95/98.
* Store data intermediately on disk, using VF_store, and retrieve them using VF_recall, when needed. This method is slow and should be used only if really unavoidable.
(2) Vector > 64 kB not possible (16bit).
(2) Vector > 4 GB not possible (32bit). 

* Either you are trying to allocate a vector whose size exceeds the maximum of 4 GB (32bit) or 64 kB (16bit except HUGE).
* Or you are in the HUGE model and attempt to process a huge vector in a function where the size is limited to 64 kB even in this model. This might happen, e.g., if the table is too large in one of the interpolation routines. In this case, you must either use the model FLAT or split up your problem into smaller vectors.
(3) Vectors/matrices must not be identical. 

In some functions where more than one input vector (or matrix) is used to calculate more than one output vector (or matrix), attention has to be paid, which output data may or may not overwrite which input data. See the specification of the function where the error occurred.
(4) Cannot use requested format (too many entries per line). 

This error occurs with the printing functions. The parameter nperline was chosen too large. The function automatically selects the maximum nperline possible and continues execution, but you should nevertheless consider adapting your program.
(6) Not possible with fewer than n elements. 

Some functions require a minimum size of n elements of the vector processed.
(7) Not possible with more than n elements. 

Some functions are limited to a maximum size of n elements. This is true, for example, for VF_polyinterpol, where only up to 10 table elements may be used for the each interpolation.
(8) Size must be an integer power of 2. 

For all functions using  explicitly or implicitly  Fast Fourier Transform methods, the size has to be an integer power of 2. Enlarge or truncate your vector(s) to meet that condition.
(9) Invalid parameter(s). 

In some functions, certain combinations of input parameters are illegal. For example, it is not possible to perform a 9point interpolation on only 5 data points.
(10) Cannot scale symbols by more than a factor of 50. 

(Windows only.) The symbols used in VectorLib plotting functions cannot be magnified by more than a factor of 50 (which means already filling the screen with a single symbol). Program execution is continued with a value of 50.0.
(11) Cannot use line thicker than 500 pixels. 

(Windows only.) The lines used in VectorLib plotting functions cannot be thicker than 500 pixels (which is already nonsense). Program execution is continued with a value of 500.
(12) Cannot free nonexistent vector. 

You called V_free or V_nfree for a vector that has no memory allocated. Program execution is continued without freeing anything.
Back to VectorLib Table of Contents
OptiVec home
6. TroubleShooting
In case of problems, please check first if OptiVec is correctly installed. If this is the case, carefully check the following points whose violation would inevitably lead to failure.
 The choice of the OptiVec library must match your selection of memory model, processor, and environment. With Borland C++, you are not going to have much fun with the libraries designed for Visual C++ and vice versa.
 You must not use vectors with a size of 0. All functions tacitly assume that the vectors have at least one element and do not waste your computer time testing for that.
 You must not use vectors that are only declared, but have no allocated memory (see the description of VF_vector). If you did not switch off warnings, you may be warned also by the compiler not to do that ("possible use of xxx before definition").
 Constant parameters should not exceed 1.E32 for floats, 1.E150 for doubles, or 1.E2000 for long doubles. Normally, these ranges should suffice for any application...
Have a look at our support page for recent known problems.
Although OptiVec has been tested thoroughly, there is, of course, always the possibility that a problem might have escaped our attention. Should you feel you discovered a "bug" in OptiVec, please try to specify the situation causing the problem as exactly as possible and let us know at support@optivec.com!
Back to VectorLib Table of Contents
OptiVec home
7. The IncludeFiles and Units of OptiVec
All OptiVec C/C++ includefiles have the same names as the corresponding Pascal/Delphi units. Naturally, the extension is different: ".H" for the C/C++ includefiles, ".DCU" for Delphi units. Below, only the names are listed, without the extension.
C/C++ only: Declare the use of OptiVec functions with #include statements. If you are using MFC (Microsoft Foundation Classes) or the OWL (ObjectWindows Library) with old Borland compilers, the MFC or OWL includefiles have to be #included before (!) the OptiVec includefiles.
Pascal/Delphi only: Declare the use of OptiVec functions with the uses clause.
Includefile (add suffix .H) or unit  Contents 
VecLib  Basic definitions of the data types along with the functions common to all data types (prefix V_) except for the graphics initialization functions. 
VFstd, VDstd, VEstd  Floatingpoint "standard operations:" generation and initialization of vectors, indexoriented manipulations, datatype interconversions, statistics, analysis, geometrical vector arithmetics, FourierTransform related functions, I/O operations. 
VCFstd, VCDstd, VCEstd, VPFstd, VPDstd, VPEstd  Standard operations for cartesian and polar complex vectors 
VIstd, VBIstd, VSIstd, VLIstd, VQIstd  Standard operations for signed integer vectors 
VUstd, VUBstd, VUSstd, VULstd, VUIstd  Standard operations for unsigned integer vectors (VUIstd only for C/C++) 
VFmath, VDmath, VEmath  Algebraic, arithmetical and mathematical functions for floatingpoint vectors 
VCFmath, VCDmath, VCEmath, VPFmath, VPDmath, VPEmath  Arithmetical and mathematical functions for complex vectors 
VImath, VBImath, VSImath, VLImath, VQImath  Arithmetical and mathematical functions for signed integer vectors 
VUmath, VUBmath, VUSmath, VULmath, VUImath  Arithmetical and mathematical functions for unsigned integer vectors (VUImath only for C/C++) 
Vgraph  Graphics functions for all data types 
VFNLFIT, VDNLFIT, VENLFIT  Nonlinear fitting functions (Pascal/Delphi only; in C/C++, they are in M?std) 
VFMNLFIT, VDMNLFIT, VEMNLFIT  Nonlinear fitting functions for multiple data sets (Pascal/Delphi only; in C/C++, they are in M?std) 
MFstd, MDstd, MEstd  Matrix operations for realvalued matrices 
MCFstd, MCDstd, MCEstd  Matrix operations for cartesian complex matrices 
Mgraph  Matrix graphics functions for all data types 
MFNLFIT, MDNLFIT, MENLFIT  Nonlinear fitting functions for Z = f(X, Y) data (Pascal/Delphi only; in C/C++, they are in M?std) 
MFMNLFIT, MDMNLFIT, MEMNLFIT  Nonlinear fitting functions for multiple Z = f(X, Y) data sets (Pascal/Delphi only; in C/C++, they are in M?std) 
NEWCPLX  complex class library CMATH; C++ only 
CMATH  complex library CMATH for Pascal/Delphi and plain C 
CFMATH, CDMATH, CEMATH  C/C++ only: typespecific parts of CMATH. 
XMATH  A few nonvectorized math functions needed internally by other OptiVec functions; they are publically accessible. C/C++: declares also the sine, cosec, and tangent tables for VF_sinrpi2 etc. 
FSINTAB2, DSINTAB2, ESINTAB3, FSINTAB3, DSINTAB3, ESINTAB3  sine tables (Pascal/Delphi only; for C/C++, they are in XMATH) 
FCSCTAB2, DCSCTAB2, ECSCTAB3, FCSCTAB3, DCSCTAB3, ECSCTAB3  cosecant tables (Pascal/Delphi only; for C/C++, they are in XMATH) 
FTANTAB2, DTANTAB2, ETANTAB3, FTANTAB3, DTANTAB3, ETANTAB3  tangent tables (Pascal/Delphi only; for C/C++, they are in XMATH) 
VecObj  basic definitions for VecObj, the objectoriented interface for C++ 
fVecObj, dVecObj, eVecObj  VecObj member functions for realvalued vector objects (C++ only) 
cfVecObj, cdVecObj, ceVecObj pfVecObj, pdVecObj, peVecObj  VecObj member functions for complex vector objects (C++ only) 
iVecObj, biVecObj, siVecObj, liVecObj, qiVecObj  VecObj member functions for signedinteger vector objects (C++ only) 
uVecObj, ubVecObj, usVecObj, ulVecObj, uiVecObj  VecObj member functions for unsignedinteger vector objects (C++ only) 
OptiVec  includes the whole OptiVec package (C++ only) 
VecAll  includes all VectorLib and CMATH functions (C or C++ only) 
MatAll  includes all MatrixLib functions (C or C++ only) 
Back to VectorLib Table of Contents
OptiVec home
Copyright © 19982016 OptiCode  Dr. Martin Sander Software Development
