\documentclass[twoside]{MATH77}
\usepackage{multicol}
\begin{document}

\intro{0}
\begappc C Usage of the {\em mathc90} Library

\silentfootnote{$^\copyright$1997 Calif. Inst. of Technology, \thisyear \ Math \`a la Carte, Inc.}

\begin{tabular*}{3.3in}{l}
\multicolumn{1}{c}{\bf Table of Contents\rule[-10pt]{0pt}{8pt}}\\
1.1\ \ Introduction \dotfill \pageref{Intro}\\
1.2\ \ Usage documentation \dotfill \pageref{Usage}\\
1.3\ \ Header files \dotfill \pageref{Headers}\\
\rule{20pt}{0pt}1.3.a\ \ The library file, {\tt fhelp.c} \dotfill \pageref{libfile}\\
\rule{20pt}{0pt}1.3.b\ \ A library archive file \dotfill \pageref{libarc}\\
\parbox{3.3in}
{1.4\ \ Correspondence between Fortran and C
types \dotfill \pageref{corr}}\\
\rule{20pt}{0pt}1.4.a\ \ CHARACTER arguments \dotfill \pageref{chararg}\\
\rule{60pt}{0pt}STRING \dotfill \pageref{string}\\
\rule{60pt}{0pt}CHAR\_INT \dotfill \pageref{char}\\
\rule{60pt}{0pt}{\em byte} \dotfill \pageref{byte}\\
\rule{60pt}{0pt}{\em byte*}, or {\em byte}{$[\,]$} \dotfill \pageref{bytestar}\\
1.5\ \ Using the type {\em float} in C. \dotfill \pageref{caution_float}\\
1.6\ \ Specification of functions to be passed\\
\rule{20pt}{0pt}to library procedures \dotfill \pageref{functions}\\
1.7\ \ User-accessible COMMON blocks \dotfill \pageref{common}\\
1.8\ \ Codes in MATH77 but not in {\em mathc90} \dotfill \pageref{MATH77_not_mathc90}\\
1.9\ \ Codes in {\em mathc90} and not in MATH77 \dotfill \pageref{mathc90_not_MATH77}\\
\parbox{3.3in}
{1.10\ \ Testing the portability of the {\em mathc90} library
\dotfill \pageref{testport}}
\end{tabular*}

\subsection{Introduction\label{Intro}}

{\em mathc90} is a conversion to the ANSI C language of the MATH77 library of
Fortran 77 mathematical subprograms.  We recommend organizing the {\em
  mathc90} library into two subdirectories: {\tt libsrc} containing files of
library source code and their associated header files, and {\tt demo} a
subdirectory of this containing source code files for demonstration drivers
and their associated header files.

\subsection{Usage documentation.\label{Usage}}

Usage of procedures in the (Fortran) MATH77 library is thoroughly
documented in this manual.  We do not provide similar documentation for the
{\em mathc90} library.  Rather, we have attempted to produce the {\em
mathc90} code with a consistent correspondence between its functions and
the subprograms of MATH77.  Thus we hope a user can understand how to use
{\em mathc90} by referring to the MATH77 (Fortran) documentation and applying
the conventions given in this appendix for translating information about
the declaration of variables.  This approach can be supplemented by
looking at the function prototypes in the header file {\tt mathc90.h},
which is listed in Appendix D, and by studying the {\em mathc90}
demonstration drivers.

Most of the user-callable C functions in {\em mathc90} have the same name,
number of arguments, and functionality as the corresponding Fortran
subprogram in MATH77. The types of arguments and results correspond
according to conventions that will be described subsequently.

Exceptions as to the number of arguments occur for some procedures
that have character arguments. For CSORT we have omitted the last
argument which was work space of type CHARACTER. Also for CSORT, and
for other procedures discussed under CHAR\_INT on
Page~C--\pageref{char}, we have added a character length argument of
type {\em int} immediately following an argument that was a CHARACTER
array in the Fortran version.

Exceptions as to functionality occur in procedures DSVA/SSVA
(Chapter~4.3), DNLxxx/SNLxxx (Chapter 9.3), MESS (Chapter 19.3), and I1MACH
(Chapter~19.1).  The Fortran subroutines DSVA/SSVA, DNLxxx/SNLxxx, and MESS
allow the user to specify a Fortran output unit number to be written to. The
{\em mathc90} function mess() emulates this functionality by writing to a
file named {\tt messf\_nn}, where {\tt nn} is the requested unit number. The {\em
mathc90} functions dsva() and dnlxxx() simply write any requested
output to {\em stdout}.

Calls to R1MACH, D1MACH, and I1MACH in the MATH77 library are replaced
using functionality in the C language.  Thus these subroutines
are not included in the {\em mathc90} library.

A few codes are only in MATH77 or only in {\em mathc90}.  These are
discussed in Sections 1.8 and 1.9.

\subsection{Header files.\label{Headers}}

There is one large header file {\tt mathc90.h} which contains all the
declarations required by any of the library files.  This file is only provided
with the entire mathc90 library, but in most cases we recommend using instead
the header files corresponding to the individual routines.  Each library
routine except for {\tt csort1.c} has a corresponding header file with the
``.c'' replaced by ``.h''.  A user-written program that uses functions from
{\em mathc90} should reference either {\tt mathc90.h} in a {\tt \#include}
directive or reference all the ``.h'' files with names corresponding to the
names of the library files being referenced directly by the user's code.  The
library is not designed to work in a pre-ANSI C90 environment.

In addition there are header files for the library codes required by each
of the demonstration drivers.  A demonstration driver with a name of the
form {\tt drxxxx.c} uses a header file of the form {\tt p\_xxxx.h}.  When
calling only library routines that are called by a demonstration driver,
one may want to include the appropriate one of these headers.  Also a few of
the drivers require a header file with the same name as the demonstration
driver, but with the suffix ``.c'' replaced by ``.h''.

{\tt fcrt.h} contains definitions of a number of macros whose use is
needed in some of the converted codes, due to the way the commercial
conversion processor we use produces some of the conversions.  A user code
should not reference {\tt fcrt.h}, as we may change or delete items in
this file without notice.  {\bf If one is compiling single precision codes
in {\em mathc90} changes may be required in {\tt fcrt.h} as described in
Section~\ref{caution_float} below.}

\subsubsection{The library file, {\tt fhelp.c}\label{libfile}}

The library file, {\tt fhelp.c}, contains a number of functions supporting
operations that are built-in in Fortran but not in C. Functions in this
file are not intended to be called by users. They may be changed or deleted
in the future without notice.

\subsubsection{A library archive file\label{libarc}}

We suggest that on UNIX systems the object files for all of the library be
collected into a library archive file with the name {\tt libmathc90.a}. This
can easily be done using the UNIX {\tt ar} command. Then this library can be
referenced from a compile or link command using the option {\tt -l mathc90}.
We provide a Gnu make file that does this, as well as compiling all of the
demos and running them.  Analogous methods of creating and referencing a
pre-compiled library file exist on other systems.

\subsection{Correspondence between Fortran and C types.\label{corr}}

\begin{tabular}{ll}
{\bf Fortran 77 declaration} & {\bf C declaration}\\
{\bf in user code.} & {\bf in user code.}\\
double precision a  & {\tt double a;}\\
double precision a(5) & {\tt double a[5];}\\
double precision a(5,10) & {\tt double a[10][5];}\\
real a & {\tt float a;}\\
real a(5) & {\tt float a[5];}\\
real a(5,10) & {\tt float a[10][5];}\\
integer i & {\tt long i;}\\
integer i(5) & {\tt long i[5];}\\
integer i(5,10) & {\tt long i[10][5];}\\
logical p & LOGICAL32 p;\\
logical p(5) & LOGICAL32 p[5];\\
character ... & See: {\bf CHARACTER}\\
 & {\bf arguments}, Page C--\pageref{chararg}.\\
external sname & Function declaration for\\
 & sname.\\
\end{tabular}

In converting Fortran 77 code to ANSI C there are different choices one
could make as to how to convert types.  The specifications above relate
specifically to the way we intend the {\em mathc90} library to be used.
For subprogram arguments whose specification in the MATH77 (Fortran)
documentation is as given in the first column below, we recommend a C
declaration as specified in the second column.

A reference to an element of a 1-dimensional array, whose Fortran indexing
begins at 1, has a corresponding reference in C with the index decremented
by 1.  Thus a(j) in Fortran 77 should be replaced by a[\,j-1] in C.

In a reference to an element of a 2-dimensional array, whose Fortran
indexing begins at (1,1), the indices must be interchanged, and each
decremented by 1. Thus a(i,j) in Fortran 77 should be replaced by %
a[\,j-1,i-1] in C.

If MATH77 documentation specifies an argument of a procedure to be an
array of any type, or a CHARACTER variable with length that could be
greater than one, the actual argument in referencing a {\em mathc90}
function must be an address, {\em i.e.}, a pointer. (Recall that in C
an array name is a pointer.) For an argument that is specified in the
MATH77 documentation as numeric, LOGICAL, or CHARACTER*1, and not an
array, it must be passed by address $(i.e$. a pointer) or by value
depending on whether its value can or cannot be modified by the
procedure. The MATH77 documentation identify each variable as having the
intent {\em in} if it cannot be modified, and one of the intents {\em
out} or {\em inout} (or {\em work} or {\em scratch}) if it can be
modified. If in doubt about the correct typing of an argument look at
the function prototype in the header file {\tt mathc90.h} or at
Appendix~D.

Any argument to a library procedure that is specified in the MATH77
documentation as a 2-dimensional numeric array with the first dimension
being adjustable will be declared within the corresponding {\em mathc90}
function as a 1-dimensional array, and subscript computation will be
expressed explicitly.  (From the point of view of the MATH77
documentation, a 2-dimensional array has an adjustable first dimension if
the size of the first dimension is one of the arguments in the same
argument list as the array name.) Thus if the user declares the array to
be used as the corresponding actual argument as 2-dimensional, as we
recommend, the user should also use ``cast" syntax in the function
reference statement to force agreement of the type of the argument.  For
example, if an array specified to have an adjustable first dimension is
declared as

\hspace{.2in}{\tt double a[10][5];}

it should appear in the function reference as

\hspace{.2in}{\tt(double*)a}

Some C compilers may not require this but some, {\em e.g}. HP-720,
do.\rule[-6pt]{0pt}{8pt}

On the other hand, if the first dimension of a 2-dimensional array is
specified in the MATH77 documentation to be a fixed value, such as 2 in some
subprograms dealing with double precision complex data and in Chapter 9.3,
then the array name in the function reference should not be prefixed with
{\tt(double*}). Check the function prototypes in {\tt mathc90.h}
(listed in Appendix D) or the associated header file when in doubt.

\subsubsection{CHARACTER arguments\label{chararg}}

\begin{minipage}{2.6in}
In Fortran each CHARACTER variable has a declared length which may be
specified using ``*" notation or has the default length 1 otherwise. This
declared length is automatically passed with the character variable whenever
it is passed as a subprogram argument.

In C it is more common to think in terms of what could be called the
operational length of a character string,
{\em i.e.}, the length up to but not
including a terminating null character. (The ASCII null character has the
numeric value of zero and is written in C as $^{\prime}\backslash
0^{\prime}.)$ This model of a character string is supported by a number of
standard C library functions that do operations on null-terminated strings.
\end{minipage}

The notation $^\prime $A$^\prime $ denotes a constant of type {\em
char} whose value is the integer, 65, associated with the ASCII
character A. The notation $^{\prime \prime } $A$^{\prime \prime } $
denotes a pointer of type {\em char*} pointing to an array of length
2 whose components are $^\prime $A$^\prime $ and $^{\prime}\backslash
0^{\prime}$. This later notation can also be used for longer strings,
{\em e.g.}, $^{\prime \prime }$Mars$^{\prime \prime }$ denotes
(a pointer to) an array of length 5 with components
$^{\prime}$M$^{\prime}$, $^\prime $a$^\prime $,
$^{\prime}r^{\prime}$, $^{\prime}$s$^{\prime}$, and
$^{\prime}\backslash 0^{\prime}.$

Following conventions introduced by the commercial conversion
processor that we use, we use the defined terms {\em byte}, STRING,
and CHAR\_INT to distinguish different usages of character variables.
These three terms are synonyms for {\em char}, {\em char*}, and {\em
char*,int}. Note that {\em byte*} is therefore another synonym for
{\em char*}.

We choose these different terms as follows:\vspace{-7pt}
\begin{description}

\item[STRING\label{string}] \ The translation of a non-array CHARACTER*$k$
argument of intent {\em in} whose purpose is just to be printed.  In the C
version such an argument must be null-terminated.  If the actual argument
in C is written as a literal, it must be a string literal delimited by
(double) quotes, {\em e.g.}, $^{\prime \prime}$Venus$^{\prime \prime}$.
Occurrences in user-callable procedures are in the table at the top of the
next column.

\item[CHAR\_INT\label{char}] The translation of an array of
CHARACTER*$k$ variables for which both the array size and CHARACTER
length are user specified and the length $k$ is not present in the
same (Fortran) argument list. In this case the single argument in
Fortran becomes two arguments in C. This pair of arguments must be of
types {\em char*} and {\em int}, respectively. The {\em int}
parameter should be one greater than the $k$ in the corresponding
Fortran declaration to allow space for null terminators. Occurrences
in user-callable procedures:

\hspace{-1in}\fbox{\begin{tabular}{r@{}ll}
\multicolumn{1}{c}{Chapter} & \multicolumn{1}{c}{Procedure
Name\rule{40pt}{0pt}} &
\multicolumn{1}{c}{\hspace{-16pt}CHARACTER*$k$ Argument}\\
6.1\rule{15pt}{0pt} & dmatp, dvecp, imatp, & text\\
& ivecp, smatp, svecp\\
6.2\rule{15pt}{0pt} & dmatpr, dvecpr, imatpr, & text\\
 & ivecpr, smatpr, svecpr\\
14.1\rule{15pt}{0pt} & divadb, sivadb & text\\
16.2\rule{15pt}{0pt} & dtcst, stcst & tcs, mode\\
16.3\rule{15pt}{0pt} & dcft, scft & mode\\
16.3\rule{15pt}{0pt} & dplot, splot & copt\\
19.2\rule{15pt}{0pt} & ermsg, & subnam, mess\\
19.2\rule{15pt}{0pt} & derm1, ierm1, serm1 & subnam, mess, label\\
19.2\rule{15pt}{0pt} & derv1, ierv1, serv1 & label\\
19.2\rule{15pt}{0pt} & ermor & mess\\
21.1\rule{15pt}{0pt} & dprpl1, dprpl2 & title, xname, yname\\
 & sprpl1, sprpl2\\
\end{tabular}}\vspace{5pt}

\begin{tabular}{r@{}l@{}l}
&\multicolumn{1}{c}{Procedure \rule{10pt}{0pt}}& \multicolumn{1}{c}{\hspace{-10pt}CHARACTER}\\
\multicolumn{1}{c}{Chapter} & \multicolumn{1}{c}{Name \rule{10pt}{0pt}} &
\multicolumn{1}{c}{\hspace{-10pt}Array Argument}\\
4.3\rule{15pt}{0pt} & dsva, ssva & \rule{10pt}{0pt} names\\
18.1\rule{15pt}{0pt} & csort, csortp, & \rule{10pt}{0pt} c\\
 & csortq\\
19.2\rule{15pt}{0pt} & dervn, & \rule{10pt}{0pt} labels\\
 & servn\\
19.3\rule{15pt}{0pt} & dmess, mess, smess & \rule{10pt}{0pt} text\\
\end{tabular}

\item[{\em byte}\label{byte}] The translation of a non-array CHARACTER*1
argument whose intent is {\em in}.
If the actual argument in C is written as a literal, it must be a
character literal delimited by apostrophes, {\em e.g.}, $^\prime $A$^\prime $.
Occurrences in user-callable procedures:

\begin{tabular}{@{}r@{}l@{}l}
& \multicolumn{1}{c}{Procedure} & \multicolumn{1}{c}{CHARACTER*1}\\
\multicolumn{1}{c}{Chapter} & \multicolumn{1}{c}{Name} &
\multicolumn{1}{c}{Argument}\\
16.1\rule{15pt}{0pt} & drft1, srft1 & \rule{20pt}{0pt}mode\\
16.4\rule{15pt}{0pt} & drft, srft & \rule{20pt}{0pt}mode\\
19.2\rule{15pt}{0pt} & derm1, derv1, dervn, & \rule{20pt}{0pt}flag\\
& ermor, ermsg, ierm1,\\
& ierv1, serm1, serv1,\\
& servn\\
21.2\rule{15pt}{0pt} & dprpl, sprpl & \rule{20pt}{0pt}symbol
\end{tabular}

\item[{\em byte*}, or {\em byte}{$[\,]$}\label{bytestar}] The translation
of an array or non-array CHARACTER*$k$ argument whose length $k$ is known
to the procedure by some means other than the implicit passing of the
length in Fortran.  The non-array argument of intent {\em in}, {\em i.e.},
symbol, is not required to be null-terminated, however if the actual
argument is written as a literal it must be a string literal delimited by
(double) quotes, {\em e.g.}, $^{\prime \prime } $A$^{\prime \prime } $.

In the procedures DSFITC/SSFITC of Chapter 11.5, the argument, CCODE, is
an array of intent {\em in}, declared as

\hspace{.2in}CHARACTER CCODE(mdim)*(4)

In C, ccode should be declared as

\hspace{.2in}{\tt char ccode[mdim][5];}

If the main program in Fortran would have made an assignment such as CCODE(I)
= $^{\prime}$10$\sim $a$^{\prime}$, then the corresponding assignment in C
could be ccode[i-1] = $^{\prime \prime }$10$\sim $a$^{\prime \prime } $.

In the Fortran subroutines DPRPL1/SPRPL1 and DPRPL2/SPRPL2, the declaration
of the argument IMAGE depends on two other arguments, NLINES and NCHARS:

\hspace{.2in}CHARACTER IMAGE(NLINES)*(NCHARS)

In C, {\em image} should be declared as

\hspace{.2in}{\tt char image[nlines][nchars + 1];}

and the actual argument should be written as {\tt char* image}
in the reference to dprpl1/sprpl1() or dprpl2/sprpl2(). On return, null
terminators will have been stored in image[$i$][nchars], for $i$ = 0,
..., {\em nlines} $-$ 1.

In the Fortran subroutines DPRPL/SPRPL, the declaration of the argument IMAGE
depends on another argument, NCHAR:

\hspace{.2in}CHARACTER IMAGE*(NCHAR)

In C, {\em image} should be declared as

\hspace{.2in}{\tt char image[nchar + 1];}

On return there will be a null terminator in {\em image}[{\em nchar}].

Occurrences in user-callable procedures:\vspace{5pt}

\hspace{-.1in}\begin{tabular}{rll@{}l}
& \multicolumn{1}{c}{Procedure} & \multicolumn{1}{c}{CHARACTER*$k$}\\
\multicolumn{1}{c}{Chapter} & \multicolumn{1}{c}{Name} &
\multicolumn{1}{c}{Argument} & \multicolumn{1}{c}{Intent}\\
11.5\rule{10pt}{0pt} & dsfitc, ssfitc & \hspace{20pt} ccode &
\rule{5pt}{0pt}{\em in}\\
21.1\rule{10pt}{0pt} & dprpl1, sprl1 & \hspace{20pt} image &
 \rule{5pt}{0pt}{\em out}\\
21.1\rule{10pt}{0pt} & dprpl2, sprl2 & \hspace{20pt} image &
 \rule{5pt}{0pt}{\em out}\\
 & & \hspace{20pt} symbol & \rule{5pt}{0pt}{\em in}\\
21.2\rule{10pt}{0pt} & dprpl,sprpl & \hspace{20pt} image &
 \rule{5pt}{0pt}{\em inout}
\end{tabular}
\end{description}

\subsection{Using the type {\em float} in C.\label{caution_float}}

The ANSI C language standard does not support the type {\em float}
as completely as it supports the type {\em double}.  In particular, there
is a set of twenty-two elementary mathematical functions that are
required by the ANSI C standard to be provided for operations on data
of type {\em double}.  The standard does not require these to be provided
for type {\em float}, but does specify names these functions should have
if they are provided.

The names of these functions for type {\em double} are {\em acos, asin, atan,
atan2, cos, sin, tan, cosh, sinh, tanh, exp, frexp, ldexp, log, log10,
modf, pow, sqrt, ceil, fabs, floor}, and {\em fmod}.  The corresponding names
for type {\em float} are {\em acosf, asinf, atanf,
atan2f, cosf, sinf, tanf, coshf, sinhf, tanhf,
expf, frexpf, ldexpf, logf, log10f,
modff, powf, sqrtf, ceilf, fabsf, floorf}, and {\em fmodf}.
Function prototypes for these functions of type {\em float} are
contained in the header file {\tt mathf.h}.

The end of {\tt fcrt.h} contains definitions for these single precision
``intrinsic'' functions.  Three methods for defining these functions are
provided, the method is selected by the value in the preprocessor variable
{\tt SINGLE\_MATH\_FUNCS}.  If this variable has the value {\tt
intrinsic}, it is assumed that the same names can be used for the single
as for the double precision versions.  If this variable has the value {\tt
use\_double} the double precision functions are used with the arguments
cast to {\em double}, and the result cast back to type {\em float}.  If
{\tt SINGLE\_MATH\_FUNCS} has neither of these values, the names used for
these functions are the usual double names followed by an ``f'', thus for
example {\tt sin} becomes {\tt sinf} in the single precision codes.
{\large \bf It is critical that the user choose the correct value for}
{\tt SINGLE\_MATH\_FUNCS} if the single precision routines are compiled.

Note that the following two function headers do not have the same meaning:

\begin{tabular}{ll}
Example H1: & {\em fname(x)}\\
& {\em float x;}\\
\\
Example H2: & {\em fname(float x)}
\end{tabular}

The first example is in the K\&R or pre-ANSI style.  It implies that
the argument $x$ is expected to be passed as type {\em double} and will be
coerced to type {\em float} before being used within the function.  In the
second example the argument $x$ is expected to be passed as type {\em float}.

Similarly there are distinct pre-ANSI and ANSI styles for use in a code
that references a function:

\begin{tabular}{l@{\ }l}
\hspace{-5pt}Example R1: & {\em void fname();}\\
&  {\em float x;}\\
&  ...\\
&  {\em fname(x);}\\
\vspace{5pt}
\hspace{-5pt}Example R2: & {\em void fname(float);}\\
&  {\em float x;}\\
&  ...\\
&  {\em fname(x);}
\end{tabular}

In Example R1, which is the pre-ANSI style, $x$ will be coerced from
{\em float} to {\em double} when it is passed to fname,
whereas in Example R2, which is the ANSI style, $x$ will be passed as
type {\em float}.  The ANSI standard allows usage of either pre-ANSI
or ANSI style.  Note, however, that R1 is compatible with H1, and R2
is compatible with H2, but mixing the styles gives erroneous results.

\begin{minipage}{1.95in}
We have used the ANSI style, i.e., as in Example H2, in the codes of
mathc90 that have arguments of type {\em float}.  Thus a user must use
the ANSI style, i.e., as in Example R2, in code that references a
library function that has an argument of type {\em float}.  The needed
function prototypes can be easily obtained by simply including the
header file {\em mathc90.h}.

\subsection{Specification of\newline
functions to be\newline
passed to library\newline
procedures.\label{functions}}

For some library procedures one or more of the arguments is the name of a
user-coded procedure. As a documentation aid, we list prototypes for these
procedures to the right, using the MATH77 names.

\subsection{User-accessible COMMON blocks.\label{common}}

We have generally avoided user-accessible COMMON blocks in MATH77,
however in specialized usages of the code of Chapter 14.1 for
Ordinary Differential Equations there is a need to access the COMMON
block DIVASC.

In {\em mathc90} this is represented as an external data structure named {\em
divasc} and having type {\em t\_divasc}. \hfill See the file {\tt diva.c} for
\end{minipage}\vspace{-3pt}

the components of this structure. If you are working from the
``mangled'' code, the names will be different than those in the documentation,
but the names in the structure appear in the same order as given in the
documentation.  For type {\em float}, replace ``diva" with ``siva" in the text
above.

\subsection{Codes in MATH77 but not in {\em mathc90}.\label{MATH77_not_mathc90}}

Since ANSI C does not have a complex data type, some codes using a complex
data type are in MATH77 but not in {\em mathc90}.  In particular codes in
Chapters~4.1,``Square Nonsingular Systems of Equations", and 6.3, ``Basic
Linear Algebra Subprograms" which use complex arguments are not
available in {\em mathc90}. \hfill When the Fortran codes

\hspace{-1.5in}\begin{tabular}{|@{\hspace{-4pt}}r@{}l@{}l
@{\hspace{1pt}}|}\hline
&\multicolumn{1}{c}{\hspace{-8pt}Library}& ~\rule{0pt}{12pt}\\
\multicolumn{1}{|c}{Chap.} &\multicolumn{1}{c}{\hspace{-8pt}Functions} &
\multicolumn{1}{c|}{Prototypes for user-coded functions
\rule[-8pt]{0pt}{8pt}}\\\hline
\rule{0pt}{14pt}8.2 \rule{10pt}{0pt} & dnqsol() & {\tt void dnqfj(long,%
double[\,],double[\,],double*,long*);}\\
 & snqsol() & {\tt void snqfj(long,float[\,],float[\,],%
float*,long*);}\rule[-8pt]{0pt}{20pt}\\\hline

\rule{0pt}{14pt}9.2 \rule{10pt}{0pt} & dmlc01() & {\tt void dmlcfg(long,%
double[\,],double*,double[\,],}\\
 & & {\tt LOGICAL32*);}\\
 & smlc01() & {\tt void smlcfg(long,float[\,],float*,float[\,],}\\
 & & {\tt LOGICAL32*);}\rule[-8pt]{0pt}{20pt}\\\hline

9.3 \rule{10pt}{0pt} & dnlafu() & {\tt void dcalcr(long,long,%
double[\,],long*,double[\,]);}\rule{0pt}{12pt}\\
 & dnlagu() & {\tt void dcalcj(long,long,double[\,],
long*,double*);}\\
 & dnlafb() & ~\\
 & dnlagb() & \\
 & snlafu() & {\tt void scalcr(long,long,float[\,],%
long*,float[\,]);}\rule{0pt}{12pt}\\
 & snlagu() & {\tt void scalcj(long,long,float[\,],long*,double*);}\\
 & snlafb() & ~\\
 & snlagb() & ~\rule[-8pt]{0pt}{8pt}\\\hline

9.3 \rule{10pt}{0pt} & dnlsfu() & {\tt void dcalca(long,long,%
long,double[\,],long*,double*);}\rule{0pt}{12pt}\hspace{-4pt}\\
 & dnlsgu() & {\tt void dcalcb(long,long,long,double[\,],long*,%
double*);}\hspace{-4pt}\\
 & dnlsfb() & ~\\
 & dnlsgb() & \\
 & snlsfu() & {\tt void scalca(long,long,long,float[\,],long*,
float*);}\rule{0pt}{12pt}\\
 & snlsgu() & {\tt void scalcb(long,long,long,float[\,],long*,float*);}\\
 & snlsfb() & ~\\
 & snlsgb() & ~\rule[-8pt]{0pt}{8pt}\\\hline

14.4 \rule{10pt}{0pt} & diva() & {\tt void derivs(double[\,],double[\,],%
double[\,],long[\,]);} \rule{0pt}{12pt}\\
 & divaa() & {\tt void output(double[\,],double[\,],double[\,],long[\,]);}\\
 & siva() & {\tt void derivs(float[\,],float[\,],float[\,],long[\,]);}
\rule{0pt}{12pt}\\
 & sivaa() & {\tt void output(float[\,],float[\,],float[\,],long[\,]);}
\rule[-8pt]{0pt}{8pt}\\\hline

18.3 \rule{10pt}{0pt} & insort() & {\tt long compar(long,long);}
\rule[-8pt]{0pt}{20pt}\\\hline

18.4 \rule{10pt}{0pt} & exsort() & {\tt void dataop(long,long,%
long,long*);}\rule[-8pt]{0pt}{20pt}\\\hline
\end{tabular}

implement a complex version by using real or double precision arrays, such
versions are also available in C.

\subsection{Codes in {\em mathc90} but not in MATH77.\label{mathc90_not_MATH77}}

There is one additional sorting function and a few additional single
precision complex arithmetic functions in {\em mathc90}.

To the functions {\em csort}(), {\em csortp}(), and {\em csortq}() of
Chapter 18.1, we have added a character string sorting function
named {\em csort1}().  For {\em csort}(), {\em csortp}(), and {\em
csortq}(), the character data to be sorted must be in an array declared in
a form such as

\hspace{.2in}{\tt char c[100][11];}

which would provide space for 100 character strings each having up to 10
meaningful character positions plus a null termination character. The second
dimensioning value, {\em e.g}. 11 in this example, must be passed as the second
argument to {\em csort}(), {\em csortp}(), or {\em csortq}(). Note that the operational length
of each character string in the array is determined by the position of its
null terminator, but a total of 11 character positions of storage are
allocated for each string.

For {\em csort1}() the character data to be sorted are referenced via an array of
pointers to {\em char}. Such an array, say for 100 character strings, can be
declared as

\hspace{.2in}{\tt char *pc[100];}

With this method of storing character strings, each string need not occupy
any more storage than is needed for its meaningful characters, its null
terminator, and its pointer. The procedure {\em csort1}() operates by swapping C
pointers, whereas {\em csortp}() and {\em csortq}() operate by swapping indices, and
{\em csort}() operates by swapping the actual character strings.

The~statement for referencing {\em csort1}() is

\hspace{.2in}{\tt csort1( pc, m, n, k, l);}

where {\tt pc} must be declared as described above and the other four arguments
are {\em long int'}s with the same interpretation as in the other character
sorting procedures.

In MATH77, Chapter 17.2, there are subprograms for double precision
complex arithmetic named ZSUM, ZDIF, ZPRO, ZQUO, ZSQRTX, and DZABS.  These
are provided because double precision complex arithmetic is not directly
supported in standard Fortran 77.  There is no need in Fortran for single
precision versions of these since single precision complex arithmetic is
directly supported in standard Fortran 77.

In C, however, there is no direct support for complex arithmetic, so
there is potential use for both single precision and double precision
versions of these complex operations.  Thus, in {\em mathc90}
we provide routines named
{\em csum, cdif, cpro, cquo, csqrtx}, and {\em scabs},
with arguments (and the returned value from {\em scabs}) of type
{\em float}, as well as the ``$z$" procedures for type {\em double}.

\subsection{Testing the portability of the {\em mathc90} library.
\label{testport}}

The {\em mathc90} library has been tested for portability on the same
machines as the MATH77 library.  This test involves running the set of
demonstration drivers and comparing the results with those obtained in
Fortran and with results in C on other machines.
\begcodenp
\end{document}


\subsection{Testing the portability of the {\em mathc90} library.
\label{testport}}

The {\em mathc90} library has been tested on a variety of computer systems.
It appears to be portable as long as the compiler supports C90 ANSI standard.

.
