Chapter4
Basic Dense Matrix Operations
The following routines are described in the following pages:
Catch errors
Error handlers and extensions
Error handling style
Copy objects
Input object from file
Output to file
General input/output
Deallocate (destroy) objects
Create and initialise objects
Extract column/row from matrix
Initialisation routines
Input object from
stdin
Inner product
Operations on integer vectors
Resize data structures
Machine epsilon
Matrix addition and multiplication
Memory allocation information
Static workspace control functions
Matrix transposes, adjoints and multiplication
Matrix norms
Matrix-vector multiplication
Continued
...
49
51
53
57
59
62
65
67
68
70
72
73
62
75
76
77
80
81
83
88
93
94
96
50
CHAPTER 4. BASIC DENSE MATRIX OPERATIONS
Output
object to
stdout
Permutation identity, multiplication and inverse
Permute columns/rows
& permute vectors
Set column/row
of
matrix
Scalar-vector multiplication/addition
Componentwise operations
Linear combinations
of
arrays and lists
VectQJ:-~'norffis
~
,~
Operations on complex numbers
Core low level routines
To use these routines use the include statement
.
#include
"matrix.h"
To use the complex variants use the include statement
#include
"zmatrix.h"
65
98
99
101'
102
104
107
'109.•
111
113
NAME
catch,
catchall,
catch_FPE,
tracecatch-catcherrors
SYNOPSIS
#include
"matrix.h"
catch(int
err_num,
normal_code_to_execute,
code_to_execute_if_error)
catchall(normal_code_to_execute,
code_to_exectue_if_error)
tracecatch(normal_code_to_execute,
char
*fn_name)
catch_FPE()
DESCRIPTION
51
The
catch
()
macro provides a way
of
interposing your own error-handling
routines and code in the
usual error-handling procedures. The
catch
()
macro works
like this: The global variable
restart
(of type
jmp_buf)
is saved. Then the code
normal_code_to_execute
is executed.
If
an
error with error number
err_num
is raised, then
code_to_execute_if_error
is executed.
If
an error with another
error number
is raised, an error will be raised with the same error number
as
the original
error, but
win
appear to have come from the
catch
()
macro.
If
no error
is
raised
then the macro will exit and
restart
is reset to its old values.
The
catchall
()
macro works just like the
catch
()
macro except that
code_to_execute_if_error
is executed
if
any error is raised.
The
tracecatch
()
macro is really a specialised version
of
the
catchall
()
macro that sets the error-handling flag to print out the underlying error when it is raised.
In every case the old error handling status will be restored on exiting the macro.
The routine
catch_FPE
()
sets up a signal handler so that
if
a SIGFPE signal
is raised, it
is caught and
error
( } is called
as
appropriate. The error raised by
error
()
is an E_SIGNAL
en-or.
EXAMPLE
main()
{
MAT
*A;
PERM
*pivot;
VEC
*x,
*b;
tracecatch(
LUfactor(A,pivot);
LUsolve(A,pivot,b,x);
,
"main");
52 CHAPTER
4.
BASIC DENSE MATRIX OPERATIONS
would result in the error messages
"lufactor.c",
line
28:
NULL
objects
passed
in
function
LUfactor()
"junk.c",
line
20:
NULL
objects
passed
in
function
main()
Sorry,
exiting
program
being printed to
stdout
if
one
ofAorpivot
orb
were
NULL.
These messages would
also be printed out to
stderr
if
stdout
is not a terminal.
On the other hand,
catch(E_NULL,
LUfactor(A,pi);
LUsolve(A,pi,b,x);
,
printf("Ooops,
found
a
NULL
object\n"));
simply produces the message
Ooops,
found
a
NULL
object
in this case.
However,
if
another error occurs (say, b is the wrong size) then
LUsol
ve
()
raises
an
e_SIZES
error, and
"junk.c",
line
22:
sizes
of
objects
don't
match
in
function
catch
()
Sorry,
exiting
program
is printed out.
SEE ALSO
signal
(),
error
(),
set_err_flag
(),
ERREXIT
()
etc.
BUGS
If
a different error to the one caught in
catch
( ) is raised, then the file and line
numbers
of
the original error are lost.
In an if-then-else statement,
tracecatch
()
needs to be enclosed by braces
( { ... }
).
SOURCE FILE:
matrix.h
53
NAME
error,
set_err_flag,
ev_err,
err_list_attach,
err_is_list_attached,
err_list_free,
warning-
raise errors and
warnings
SYNOPSIS
#include
"matrix.h"
int
error(int
err_num,
char
*func_name)
int
ev_err(char
*file,
int
err_num,
int
line_num,
char
*fn_name,
int
list_num)
int
set_err_flag(int
new_flag)
int
err_list_attach(int
list_num,
int
list_len,
char
**err_ptr,
int
warn)
int
err_list_free(int
list_num)
int
err_is_list_attached(int
list_num)
int
warning(int
warn_num,
char
*func_name)
DESCRIPTION
This is where errors are flagged in the system. The call
error
(
err_num,
func_name)
is in fact a macro which expands to
ev_err(
__
FILE
__
,err_num,
__
LINE
__
,func_name,O)
This call does not return.
Warnings are raised by
warning
(warn_num,
func_name)
which are expands
to
ev_err(
__
FILE
__
,warn_num,
__
LINE
__
,func_name,l)
This call returns zero.
The
call to
ev
_err
()
prints out a message to
stderr
indicating that an error
has occurred, and where in which function
it occurred, and the list
of
error messages
to use
(0 is the default).
For
example, it could look like:
"testl.c",
line
79:
sizes
of
objects
donut
match
in
function
f
()
which indicates that an error was flagged in file
"testl.
c"
at line 79, function
"f"
where the sizes
of
two objects (vectors in this case) were incompatible.
Once
this information is printed out, control is passed to the the address saved in the
buffer called
restart
by the last associated call to
setjmp.
The most convenient
way
of
setting up
restart
is to use a
•••
catch
.•.
()
macro
or
by an ERREXIT
()
or
ERRABORT
()
macro.
If
restart
has not been set then the program exits.