PASCAL-XSC: PASCAL for Extended Scientific Computing
Institut für Angewandte Mathematik,
Forschungsschwerpunkt CAVN,
Universität Karlsruhe
Wissenschaftliches Rechnen/Softwaretechnologie,
Universität Wuppertal
The programming language PASCAL-XSC was developed to supply
a powerful tool for the numerical solution of scientific
problems based upon a properly defined and implemented computer arithmetic
in the usual spaces of numerical computation.
The main concepts of PASCAL-XSC are
Interval arithmetic, complex arithmetic, complex interval arithmetic, and
the corresponding vector and matrix arithmetics are provided.
Application modules have been implemented in PASCAL-XSC for
solving common numerical problems, such as
- Linear systems of equations
- Matrix inversion
- Nonlinear systems of equations
- Eigenvalues and eigenvectors
- Evaluation of arithmetic expressions
- Evaluation of polynomials and zeros of polynomials
- Numerical quadrature
- Initial and boundary value problems in ordinary
differential equations
- Integral equations
- Automatic differentiation
- Optimization problems
All these problem-solving routines provide automatically verified results.
In the subsequent paragraphs, the most important new concepts are
considered briefly.
Universal Operator Concept and Arbitrary Result Type
PASCAL-XSC makes programming easier by allowing the programmer to
define functions and operators with arbitrary result
type. The advantages of these concepts are illustrated by
the simple example of polynomial addition.
Define the type polynomial by
const maximum_degree = 20;
type polynomial = array [0..maximum_degree] of real;
in Standard PASCAL, the addition of two polynomials is implemented as
a procedure
procedure add (a, b: polynomial; var c: polynomial);
{ Computes c = a + b for polynomials }
var i: integer;
begin
for i:= 0 to maximum_degree do
c[i]:= a[i] + b[i];
end;
Several calls of add have to be used to compute
the expression z = a + b + c + d:
add (a,b,z);
add (z,c,z);
add (z,d,z);
In PASCAL-XSC, we define a function with the result type
polynomial
function add (a, b: polynomial): polynomial;
{ Delivers the sum a + b for polynomials }
var i: integer;
begin
for i:= 0 to maximum_degree do
add[i]:= a[i] + b[i];
end;
Now, the expression z = a + b + c + d may be computed as
z:= add(a,add(b,add(c,d)))
Even clearer is the operator in PASCAL-XSC
operator + (a, b: polynomial) result_polynomial : polynomial;
{ Delivers the sum a + b for polynomials }
var i: integer;
begin
for i:= 0 to maximum_degree do
result_polynomial[i]:= a[i] + b[i];
end;
Now, the expression may be written in the common mathematical notation
z:= a+b+c+d
A programmer may also define a new name as an operator. A priority is
assigned in a preceding priority declaration.
Overloading of Procedures, Functions, and Operators
PASCAL-XSC permits the overloading of function and procedure identifiers.
A generic name concept allows the programmer to apply the identifiers
sin, cos, exp, ln, arctan,
and sqrt not only for real numbers but also for intervals,
complex numbers, or elements of other mathematical spaces.
Overloaded functions and procedures are distinguished by number,
order, and type of their parameters. The result type
is not used for distinction.
As illustrated above, operators may also be overloaded.
Even the assignment operator := may be overloaded so that the mathematical
notation may be used for assignments:
var
c: complex;
r: real;
operator := (var c : complex; r: real);
begin
c.re := r;
c.im := 0;
end;
...
r:= 1.5;
c:= r; {complex number with real part 1.5 and imaginary part 0}
Module Concept
The module concept allows the programmer to separate large programs into
modules and to develop and compile them independently of each other. The
control of syntax and semantics may be carried out beyond the bounds of the
modules. Modules are introduced by the reserved word module
followed by a name and a semicolon. The body of a module is built up quite
similarly to that of a common PASCAL program.
The significant exception is that the objects to be exported from the
module are characterized by the reserved word global
directly in front of the reserved words const, type,
var, procedure,
function, and operator and directly after use
and the equality sign in type declarations. Thus, private types as well
as non-private types can be declared and exported.
Modules are imported into other modules or programs
via a use-clause.
The semantics of the use-clause are that all objects declared
global in the imported module are also known in the importing
module or program.
The example of a polynomial arithmetic module illustrates the structure of
a module:
module poly;
use {other modules}
...
{local declarations}
...
{global declarations}
global type polynomial = ...
...
global procedure read (...
...
global procedure write (...
...
global operator + (...
...
global operator * (...
...
begin
{initialization part of the module}
...
end. {module poly}
Dynamic Arrays and Subarrays
The concept of dynamic arrays enables the programmer to implement algorithms
independently of the length of the arrays used. The index ranges of
dynamic arrays are not to be defined until run-time.
Procedures, functions, and operators may be programmed in a fully
dynamic manner, since allocation and release of local dynamic variables are
executed automatically. Hence, the memory is used optimally.
For example, a dynamic type polynomial may be declared
in the following form:
type polynomial = dynamic array [*] of real;
When declaring variables of this dynamic type, the index bounds have
to be specified:
var p, q : polynomial [0..2*n];
where the values of the expressions for the index range are computed
during program execution.
To get access to the bounds of dynamic arrays which are specified only
during execution of the program, the two functions lbound(...)
and ubound(...) and their abbreviations lb(...) and
ub(...) are supplied.
The multiplication of two polynomials may be realized dynamically as follows:
operator * (a, b: polynomial)
product: polynomial[0..ubound(a)+ubound(b)];
{ Delivers the product a * b of two polynomials a, b }
var i, j : integer;
result : polynomial[0..ubound(a)+ubound(b)];
begin
for i:= 0 to ubound(a)+ubound(b) do
result[i]:= 0;
for i:= 0 to ubound(a) do
for j:= 0 to ubound(b) do
result[i+j]:= result[i+j] + a[i] * b[j];
product:= result;
end;
A PASCAL-XSC program using dynamic arrays for polynomials follows the
template
program dynatest (input, output);
...
type polynomial = dynamic array [*] of real;
...
var maximum_degree : integer;
...
operator * (a, b:polynomial)...
...
procedure write (var f : text; p: polynomial);
...
procedure main (degree : integer);
var
p,q : polynomial[0..degree];
r : polynomial[0..2*degree];
begin
...
r:= p * q;
writeln ('p*q = ', r);
...
end;
begin {main program}
read (maximum_degree);
main (maximum_degree);
end. {main program}
The following example demonstrates that it is possible to
access a row or a column of dynamic arrays as a single object.
This is called slice notation.
type vector = dynamic array [*] of real;
type matrix = dynamic array [*] of vector;
var v : vector[1..n];
m : matrix[1..n,1..n];
...
v := m[i]; { i-th row of m }
m[*,j] := v; { j-th column of m }
Current releases (Version 3.0 and higher) of PASCAL-XSC include the concept
of flexible arrays. A dynamic array is called
flexible if it can be allocated
with new index bounds and new size at any time during its lifetime.
In the following example, we use a flexible real vector to perform
some computations until a desired accuracy is achieved.
type vector = dynamic array [*] of real;
procedure high_accuracy (basic_length: integer; result: real);
var
accurate : boolean;
rvec : vector;
k : integer;
begin
accurate := false; k := 0;
repeat
k:= k+1;
allocate (rvec, 1..k*basic_length);
... { computations }
accurate := ...
free (rvec); { might be omitted }
until accurate;
result := ...
end;
For a detailed description of flexible arrays, see the references below.
String Concept
A string concept is integrated into the language PASCAL-XSC to handle
character strings of variable length. Declaration, input, and output of
strings are simplified extensively compared to the facilities of
Standard PASCAL.
Special predefined functions and operators enable the programmer to formulate
and manipulate string expressions.
Arithmetic and Rounding
Compared with Standard PASCAL, the set of operators for real
numbers is extended by the directed-rounding operators
o< and o> with o in { +, -, *, / }. These symbols
denote the operations with upwardly and downwardly directed rounding.
In the arithmetic modules, the common operators are also provided
for complex numbers, intervals, complex intervals, and also for
vectors and matrices over these spaces.
Accurate Expressions
Please note: several of these books are now out of print.
They may be downloaded from our website
http://www2.math.uni-wuppertal.de/org/WRST/literatur/download.html.
How can I get the Pascal-XSC compiler?
There are several free versions of PASCAL-XSC available for
download from our www-server
http://www2.math.uni-wuppertal.de/wrswt/xsc/pxsc_download.html
or
http://www.xsc.de