Error Handling

Introduction

The functions in IMSL Library for Python (PyNL) attempt to detect and report errors and invalid input. This error-handling capability provides automatic protection without requiring you to make any specific provisions for the treatment of error conditions. Depending on the type and severity, PyNL catches errors by exceptions and warnings.

In general, PyNL is written so that computations are not affected by underflow, provided the system (hardware or software) replaces an underflow with the value zero. Normally, you can ignore system error messages indicating underflow.

PyNL is also written to avoid overflow. A program that produces system error messages indicating overflow should be examined for programming errors, such as incorrect input data, mismatch of argument types, or improper dimensions.

In many cases, the documentation for a function points out common pitfalls that can lead to failure of the algorithm. Because output from documentation examples is generally system-dependent, your results may vary depending on your system.

Types of Errors

PyNL functions attempt to detect program errors and handle them in a way that provides as much information as possible. This entails recognizing various levels of error severity as well as the extent of the error in the context of the function’s purpose; a trivial error in one situation may be serious in another. Functions attempt to report as many errors as they can reasonably detect. Multiple errors present a difficult problem in error detection because input is interpreted in an uncertain context after the first error is detected.

PyNL handles two types of errors:

  • Input validation errors can be detected by the library before an algorithm is called. Examples include input arguments of an incorrect value or type. PyNL tries to catch as many errors as possible in this validation phase.
  • Algorithm errors occur during the call of a mathematical or statistical algorithm and cannot be caught earlier. For example, singularity of a matrix in general can be detected only if the matrix is actually factorized. Algorithm errors cause PyNL to raise exceptions or warnings using classes IMSLError and IMSLWarning, respectively.

Determining Error Severity

In some cases, the function’s input may be mathematically correct, but because of limitations of the computer arithmetic and the algorithm used, an answer cannot be computed accurately. In this case, the assessed degree of accuracy determines the severity of the error. In cases where the function computes several output quantities, if some are not computable but most are, an error condition exists, and its severity depends on an assessment of the overall impact of the error.

Exceptions and Warnings

PyNL handles input validation errors by throwing Python built-in exceptions like TypeError or ValueError.

When an algorithm error occurs, PyNL raises either an IMSLError exception or an IMSLWarning warning, depending on the severity of the error.

Class IMSLError is directly derived from Python’s built-in Exception class, while class IMSLWarning is derived from Python’s Warning class. All PyNL warnings are issued with the warnings.warn() function from Python’s warnings module. In contrast to an exception, a warning can behave in different ways. For example, it can be ignored (“ignore”), always printed (“always”) or turned into an exception (“error”). The default behavior for warnings of type IMSLWarning is “always”. You can configure the behavior of the PyNL warnings with the warnings module, in particular the warnings filter.

Each instance of classes IMSLWarning and IMSLError contains a message, i.e. a text string describing the warning and exception, respectively.

If several error conditions are reported during a call to a mathematical or statistical algorithm, PyNL generates a list of related exception or warning class instances that are processed upon return from the algorithm call.

This code example catches an IMSLError exception and prints the resulting error message:

import numpy as np
import imsl.linalg as la
import imsl.error as error

# Singular matrix example
a = np.array([[1.0, 0.0, 3.0],
              [1.0, 0.0, 4.0],
              [1.0, 0.0, 3.0]])

b = np.array([1.0, 4.0, -1.0])

try:
    x = la.lu_solve(a,b)
except error.IMSLError as e:
    print("Exception: {}".format(e))

In some cases it might be useful to treat IMSLWarning warnings as exceptions. For example, if a matrix is ill-conditioned, it is often inadvisable to solve linear systems using this matrix. You can use warnings.filterwarnings() to turn the IMSLWarning warning into an exception. The following code example illustrates how such a conversion can be achieved:

import numpy as np
import imsl.linalg as la
import imsl.error as error
import warnings

# Ill-conditioned matrix example
a = np.array([[2.0, 1.0],
              [2.0, 1.000000000000001]],
              dtype=np.float64)
b = np.array([4.0, 4.02], dtype=np.float64)

# Turn IMSLWarning into an exception
warnings.filterwarnings("error", category=error.IMSLWarning)
try:
    x = la.lu_solve(a, b)
except error.IMSLWarning as e:
    print("Exception: {}".format(e))

# Reset IMSLWarning back to its original behavior
warnings.filterwarnings("always", category=error.IMSLWarning)