MODULE Utilities

Module Utilities Utilities exports subroutines and functions for simple and general computations.

Some of these routines can be used in place of intrinsic functions in the STATPACK library, like the dot_product2(), transpose2() and matmul2() functions described below, if the cpp macros _DOT_PRODUCT, _TRANSPOSE and _MATMUL are activated at compilation of the STATPACK library. See the section Preprocessor cpp macros for more details.

A large set of accurate routines for computing the 2-norm (i.e., the Euclidean norm) of (real or complex) vectors or the Frobenius norm of (real or complex) matrices using up-to-date algorithms with due regard to avoiding overflow and underflow [Anderson:2002] [Anderson:2018] [Hanson_Hopkins:2018] are also included, like the norm(), norme(), norm2e(), lassq(), lassqe(), lassq2e() routines described below.

Some of these routines are also adapted from public domain routines in Numerical Recipes.

Note, finally, that many of these routines are low-level routines, which do not include checking of the correctness of the size/shape of their array arguments for enhanced speed at execution. This means that the user must exercise care when using these low-level subroutines and functions.

In order to use one of these routines, you must include an appropriate use Utilities or use Statpack statement in your Fortran program, like:

use Utilities, only: transpose2

or :

use Statpack, only: transpose2

In order to replace the calls to the intrinsic functions dot_product(), transpose() or matmul() by the corresponding STATPACK functions dot_product2(), transpose2() and matmul2() in your Fortran program, include in your program a statement like:

use Utilities, only: transpose=>transpose2

or :

use Statpack, only: transpose=>transpose2

Here is the list of the public routines exported by module Utilities:

transpose2()

purpose:

transpose2() computes MATT for a given input (real, complex, integer or logical) matrix MAT.

If the cpp macro _OPENMP is activated at compilation, transpose2() will be parallelized with OpenMP if the input matrix is big enough.

Synopsis:

mat_t(:m,:n) = transpose2( mat(:n,:m) )  ! mat is a  real    matrix of kind stnd
mat_t(:m,:n) = transpose2( mat(:n,:m) )  ! mat is a  complex matrix of kind stnd
mat_t(:m,:n) = transpose2( mat(:n,:m) )  ! mat is an integer matrix of kind i4b
mat_t(:m,:n) = transpose2( mat(:n,:m) )  ! mat is a  logical matrix of kind lgl

Examples:

ex1_transpose2.F90

dot_product2()

purpose:

dot_product2() computes the scalar product of two input (real, complex, integer or logical) vectors.

dot_product2() will use BLAS1 subroutines through the BLAS_interfaces module for computing the dot product for real or complex arguments if the cpp macro _BLAS is activated at compilation of the STATPACK library.

Synopsis:

xy = dot_product2( vecx(:n) , vecy(:n) )  ! vecx and vecy are real    vectors of kind stnd
xy = dot_product2( vecx(:n) , vecy(:n) )  ! vecx and vecy are complex vectors of kind stnd
xy = dot_product2( vecx(:n) , vecy(:n) )  ! vecx and vecy are integer vectors of kind i4b
xy = dot_product2( vecx(:n) , vecy(:n) )  ! vecx and vecy are logical vectors of kind lgl
mmproduct()

purpose:

mmproduct() multiplies the two input (real, complex, integer or logical) matrices or vectors.

Synopsis:

array(:m)    = mmproduct( vec(:n)     , mat(:n,:m)  ) ! vec and mat   are real    arrays of kind stnd
array(:n)    = mmproduct( mat(:n,:m)  , vec2(:m)    ) ! mat and vec2  are real    arrays of kind stnd
array(:n,:m) = mmproduct( mat1(:n,:p) , mat2(:p,:m) ) ! mat1 and mat2 are real    arrays of kind stnd
array(:m)    = mmproduct( vec(:n)     , mat(:n,:m)  ) ! vec and mat   are complex arrays of kind stnd
array(:n)    = mmproduct( mat(:n,:m)  , vec2(:m)    ) ! mat and vec2  are complex arrays of kind stnd
array(:n,:m) = mmproduct( mat1(:n,:p) , mat2(:p,:m) ) ! mat1 and mat2 are complex arrays of kind stnd
matmul2()

purpose:

matmul2() multiplies the two input (real, complex, integer or logical) matrices or vectors.

matmul2() will use BLAS2 or BLAS3 subroutines through the BLAS_interfaces module for performing the multiplication for real or complex arguments if the cpp macro _BLAS is activated at compilation of the STATPACK library.

On the other hand, if the cpp macros _BLAS and _NOOPENMP3 are not activated, but the cpp macro _OPENMP is activated at compilation, matmul2() will be parallelized with OpenMP if the input matrices or vectors are big enough.

Synopsis:

array(:m)    = matmul2( vec(:n)     , mat(:n,:m)  ) ! vec and mat   are real    arrays of kind stnd
array(:n)    = matmul2( mat(:n,:m)  , vec2(:m)    ) ! mat and vec2  are real    arrays of kind stnd
array(:n,:m) = matmul2( mat1(:n,:p) , mat2(:p,:m) ) ! mat1 and mat2 are real    arrays of kind stnd
array(:m)    = matmul2( vec(:n)     , mat(:n,:m)  ) ! vec and mat   are complex arrays of kind stnd
array(:n)    = matmul2( mat(:n,:m)  , vec2(:m)    ) ! mat and vec2  are complex arrays of kind stnd
array(:n,:m) = matmul2( mat1(:n,:p) , mat2(:p,:m) ) ! mat1 and mat2 are complex arrays of kind stnd
array(:m)    = matmul2( vec(:n)     , mat(:n,:m)  ) ! vec and mat   are real    arrays of kind i4b
array(:n)    = matmul2( mat(:n,:m)  , vec2(:m)    ) ! mat and vec2  are real    arrays of kind i4b
array(:n,:m) = matmul2( mat1(:n,:p) , mat2(:p,:m) ) ! mat1 and mat2 are real    arrays of kind i4b
array(:m)    = matmul2( vec(:n)     , mat(:n,:m)  ) ! vec and mat   are logical arrays of kind lgl
array(:n)    = matmul2( mat(:n,:m)  , vec2(:m)    ) ! mat and vec2  are logical arrays of kind lgl
array(:n,:m) = matmul2( mat1(:n,:p) , mat2(:p,:m) ) ! mat1 and mat2 are logical arrays of kind lgl

Examples:

ex1_matmul2.F90

array_copy()

purpose:

array_copy() makes a (truncated) copy of the input one-dimensional array SRC into the output one-dimensional array DEST

Synopsis:

call array_copy( src(:) , dest(:) , n_copied, n_not_copied ) ! src and dest are integer vectors of kind i4b
call array_copy( src(:) , dest(:) , n_copied, n_not_copied ) ! src and dest are real    vectors of kind stnd
call array_copy( src(:) , dest(:) , n_copied, n_not_copied ) ! src and dest are complex vectors of kind stnd
swap()

purpose:

swap() swaps the corresponding elements of the two input arguments A and B.

For real or complex array arguments, swap() will use BLAS1 subroutines through the BLAS_interfaces module when possible if the cpp macro _BLAS is activated at compilation of the STATPACK library.

Synopsis:

call swap( a        , b                      ) ! a and b are integers of kind i4b
call swap( a        , b                      ) ! a and b are reals    of kind stnd
call swap( a        , b                      ) ! a and b are complex  of kind stnd
call swap( a(:n)    , b(:n)                  ) ! a and b are integer vectors of kind i4b
call swap( a(:n)    , b(:n)                  ) ! a and b are real vectors    of kind stnd
call swap( a(:n)    , b(:n)                  ) ! a and b are complex vectors of kind stnd
call swap( a(:n,:m) , b(:n,:m)               ) ! a and b are integer matrices of kind i4b
call swap( a(:n,:m) , b(:n,:m)               ) ! a and b are real matrices    of kind stnd
call swap( a(:n,:m) , b(:n,:m)               ) ! a and b are complex matrices of kind stnd
call swap( a        , b        , mask        ) ! a and b are integers of kind i4b
call swap( a        , b        , mask        ) ! a and b are reals    of kind stnd
call swap( a        , b        , mask        ) ! a and b are complex  of kind stnd
call swap( a(:n)    , b(:n)    , mask(:n)    ) ! a and b are integer vectors of kind i4b
call swap( a(:n)    , b(:n)    , mask(:n)    ) ! a and b are real vectors    of kind stnd
call swap( a(:n)    , b(:n)    , mask(:n)    ) ! a and b are complex vectors of kind stnd
call swap( a(:n,:m) , b(:n,:m) , mask(:n,:m) ) ! a and b are integer matrices of kind i4b
call swap( a(:n,:m) , b(:n,:m) , mask(:n,:m) ) ! a and b are real matrices    of kind stnd
call swap( a(:n,:m) , b(:n,:m) , mask(:n,:m) ) ! a and b are complex matrices of kind stnd
mvalloc()

purpose:

mvalloc() reallocates an allocatable vector or matrix with a new size or shape, while preserving its contents. mvalloc() is only available if the cpp macro _F2003 is activated at compilation of the STATPACK library.

Synopsis:

call mvalloc( p(:)   , n     , ialloc )  ! p is an allocated integer vector of kind i4b
call mvalloc( p(:)   , n     , ialloc )  ! p is an allocated real vector of kind stnd
call mvalloc( p(:)   , n     , ialloc )  ! p is an allocated complex vector of kind stnd
call mvalloc( p(:)   , n     , ialloc )  ! p is an allocated character vector
call mvalloc( p(:,:) , n , m , ialloc )  ! p is an allocated integer matrix of kind i4b
call mvalloc( p(:,:) , n , m , ialloc )  ! p is an allocated real matrix of kind stnd
call mvalloc( p(:,:) , n , m , ialloc )  ! p is an allocated complex matrix of kind stnd
ifirstloc()

Synopsis:

index = ifirstloc( mask(:) )
imaxloc()

Synopsis:

index = imaxloc( arr(:n)            ) ! arr is an integer array of kind i4b
index = imaxloc( arr(:n) , mask(:n) ) ! arr is an integer array of kind i4b
index = imaxloc( arr(:n)            ) ! arr is a   real array   of kind stnd
index = imaxloc( arr(:n) , mask(:n) ) ! arr is a   real array   of kind stnd
iminloc()

Synopsis:

index = iminloc( arr(:n)            ) ! arr is an integer array of kind i4b
index = iminloc( arr(:n) , mask(:n) ) ! arr is an integer array of kind i4b
index = iminloc( arr(:n)            ) ! arr is a   real array   of kind stnd
index = iminloc( arr(:n) , mask(:n) ) ! arr is a   real array   of kind stnd
assert()

Synopsis:

call assert( n1 ,                string )
call assert( n1 , n2 ,           string )
call assert( n1 , n2 , n3 ,      string )
call assert( n1 , n2 , n3 , n4 , string )
call assert( n(:) ,              string )
assert_eq()

Synopsis:

n = assert_eq( n1 , n2 ,           string )
n = assert_eq( n1 , n2 , n3 ,      string )
n = assert_eq( n1 , n2 , n3 , n4 , string )
n = assert_eq( nn(:) ,             string )
merror()

Synopsis:

call merror( string , ierror=ierror )
arth()

Synopsis:

vec(:n)    = arth( first     , increment     , n ) ! first and increment are integers of kind i4b
vec(:n)    = arth( first     , increment     , n ) ! first and increment are reals    of kind stnd
vec(:n)    = arth( first     , increment     , n ) ! first and increment are complex  of kind stnd
vec(:m,:n) = arth( first(:m) , increment(:m) , n ) ! first and increment are integer vectors of kind i4b
vec(:m,:n) = arth( first(:m) , increment(:m) , n ) ! first and increment are real vectors    of kind stnd
vec(:m,:n) = arth( first(:m) , increment(:m) , n ) ! first and increment are complex vectors of kind stnd
geop()

Synopsis:

vec(:n)    = geop( first     , factor     , n ) ! first and factor are integers of kind i4b
vec(:n)    = geop( first     , factor     , n ) ! first and factor are reals    of kind stnd
vec(:n)    = geop( first     , factor     , n ) ! first and factor are complex  of kind stnd
vec(:m,:n) = geop( first(:m) , factor(:m) , n ) ! first and factor are integer vectors of kind i4b
vec(:m,:n) = geop( first(:m) , factor(:m) , n ) ! first and factor are real vectors    of kind stnd
vec(:m,:n) = geop( first(:m) , factor(:m) , n ) ! first and factor are complex vectors of kind stnd
cumsum()

Synopsis:

vec(:n) = cumsum( arr(:n) , seed ) ! arr is an integer array of kind i4b
vec(:n) = cumsum( arr(:n) , seed ) ! arr is a  real    array of kind stnd
vec(:n) = cumsum( arr(:n) , seed ) ! arr is a  complex array of kind stnd
cumprod()

Synopsis:

vec(:n) = cumprod( arr(:n) , seed ) ! arr is an integer array of kind i4b
vec(:n) = cumprod( arr(:n) , seed ) ! arr is a  real    array of kind stnd
vec(:n) = cumprod( arr(:n) , seed ) ! arr is a  complex array of kind stnd
poly()

Synopsis:

y     = poly( x     , coeffs(:)            ) ! x is a real    scalar of kind stnd and coeffs is a real    array of kind stnd
y     = poly( x     , coeffs(:)            ) ! x is a complex scalar of kind stnd and coeffs is a real    array of kind stnd
y     = poly( x     , coeffs(:)            ) ! x is a complex scalar of kind stnd and coeffs is a complex array of kind stnd
y(:n) = poly( x(:n) , coeffs(:)            ) ! x and coeffs are real arrays of kind stnd
y(:n) = poly( x(:n) , coeffs(:) , mask(:n) ) ! x and coeffs are real arrays of kind stnd and mask is a logical array of kind lgl
poly_term()

Synopsis:

y(:n) = poly_term( coeffs(:n) , x ) ! x is a real    scalar of kind stnd and coeffs is a real    array of kind stnd
y(:n) = poly_term( coeffs(:n) , x ) ! x is a complex scalar of kind stnd and coeffs is a complex array of kind stnd
zroots_unity()

Synopsis:

x(:nn) = zroots_unity( n, nn )
update_rk1()

Synopsis:

call update_rk1( mat(:m,:n) , u(:m) , v(:n) ) ! all are integer arrays of kind i4b
call update_rk1( mat(:m,:n) , u(:m) , v(:n) ) ! all are real    arrays of kind stnd
call update_rk1( mat(:m,:n) , u(:m) , v(:n) ) ! all are complex arrays of kind stnd
update_rk2()

Synopsis:

call update_rk2( mat(:m,:n) , u(:m) , v(:n) , u2(:m) , v2(:n) ) ! all are integer arrays of kind i4b
call update_rk2( mat(:m,:n) , u(:m) , v(:n) , u2(:m) , v2(:n) ) ! all are real    arrays of kind stnd
call update_rk2( mat(:m,:n) , u(:m) , v(:n) , u2(:m) , v2(:n) ) ! all are complex arrays of kind stnd
outerprod()

Synopsis:

mat(:n,:m) =  outerprod( a(:n) , b(:m) ) ! a and b are integer arrays of kind i4b
mat(:n,:m) =  outerprod( a(:n) , b(:m) ) ! a and b are real    arrays of kind stnd
mat(:n,:m) =  outerprod( a(:n) , b(:m) ) ! a and b are complex arrays of kind stnd
outerdiv()

Synopsis:

mat(:n,:m) =  outerdiv( a(:n) , b(:m) ) ! a and b are real    arrays of kind stnd
mat(:n,:m) =  outerdiv( a(:n) , b(:m) ) ! a and b are complex arrays of kind stnd
outersum()

Synopsis:

mat(:n,:m) =  outersum( a(:n) , b(:m) ) ! a and b are integer arrays of kind i4b
mat(:n,:m) =  outersum( a(:n) , b(:m) ) ! a and b are real    arrays of kind stnd
mat(:n,:m) =  outersum( a(:n) , b(:m) ) ! a and b are complex arrays of kind stnd
outerdiff()

Synopsis:

mat(:n,:m) = outerdiff( a(:n) , b(:m) ) ! a and b are integer arrays of kind i4b
mat(:n,:m) = outerdiff( a(:n) , b(:m) ) ! a and b are real    arrays of kind stnd
mat(:n,:m) = outerdiff( a(:n) , b(:m) ) ! a and b are complex arrays of kind stnd
outerand()

Synopsis:

mat(:n,:m) = outerand( a(:n) , b(:m) ) ! a and b are logical arrays of kind lgl
outeror()

Synopsis:

mat(:n,:m) = outeror( a(:n) , b(:m) ) ! a and b are logical arrays of kind lgl
triangle()

Synopsis:

mat(:j,:k) = triangle( upper , j , k , extra=extra )

Examples:

ex2_trid_inviter.F90

ex2_trid_deflate.F90

abse()

purpose:

abse() computes the 2-norm (i.e., the Euclidean norm) of a (real or complex) vector or the Frobenius norm of a (real or complex) matrix.

abse() is based on methods from [Hanson_Hopkins:2018] and uses compensated summation in order to minimize rounding errors.

Synopsis:

l2norm     = abse( vec(:)   ) ! vec is real    array of kind stnd
l2norm     = abse( vec(:)   ) ! vec is complex array of kind stnd
fnorm      = abse( mat(:,:) ) ! mat is real    array of kind stnd
fnorm      = abse( mat(:,:) ) ! mat is complex array of kind stnd
l2norm(:)  = abse( mat(:,:) , dim ) ! mat is real    array of kind stnd
l2norm(:)  = abse( mat(:,:) , dim ) ! mat is complex array of kind stnd
norm()

purpose:

norm() computes the 2-norm (i.e., the Euclidean norm) of a (real or complex) vector or the Frobenius norm of a (real or complex) matrix.

norm() is based on an updated version of the Blue’s algorithm [Blue:1978] [Anderson:2018].

Synopsis:

l2norm     = norm( vec(:)   ) ! vec is real    array of kind stnd
l2norm     = norm( vec(:)   ) ! vec is complex array of kind stnd
fnorm      = norm( mat(:,:) ) ! mat is real    array of kind stnd
fnorm      = norm( mat(:,:) ) ! mat is complex array of kind stnd
l2norm(:)  = norm( mat(:,:) , dim ) ! mat is real    array of kind stnd
l2norm(:)  = norm( mat(:,:) , dim ) ! mat is complex array of kind stnd
lassq()

purpose:

lassq() computes a scaled sum of squares based on an updated version of the Blue’s algorithm [Blue:1978] [Anderson:2018].

Synopsis:

call lassq( vec(:)   , scal, ssq ) ! vec is real    array of kind stnd
call lassq( vec(:)   , scal, ssq ) ! vec is complex array of kind stnd
call lassq( mat(:,:) , scal, ssq ) ! mat is real    array of kind stnd
call lassq( mat(:,:) , scal, ssq ) ! mat is complex array of kind stnd
norme()

purpose:

norme() computes the 2-norm (i.e., the Euclidean norm) of a (real or complex) vector or the Frobenius norm of a (real or complex) matrix.

norme() is based on an updated version of the Blue’s algorithm [Blue:1978] [Anderson:2018] and uses compensated summation in order to minimize rounding errors [Hanson_Hopkins:2018].

Synopsis:

l2norm     = norme( vec(:)   ) ! vec is real    array of kind stnd
l2norm     = norme( vec(:)   ) ! vec is complex array of kind stnd
fnorm      = norme( mat(:,:) ) ! mat is real    array of kind stnd
fnorm      = norme( mat(:,:) ) ! mat is complex array of kind stnd
l2norm(:)  = norme( mat(:,:) , dim ) ! mat is real    array of kind stnd
l2norm(:)  = norme( mat(:,:) , dim ) ! mat is complex array of kind stnd
lassqe()

purpose:

lassqe() computes a scaled sum of squares based on an updated version of the Blue’s algorithm [Blue:1978] [Anderson:2018] and uses compensated summation in order to minimize rounding errors [Hanson_Hopkins:2018].

Synopsis:

call lassqe( vec(:)   , scal, ssq ) ! vec is real    array of kind stnd
call lassqe( vec(:)   , scal, ssq ) ! vec is complex array of kind stnd
call lassqe( mat(:,:) , scal, ssq ) ! mat is real    array of kind stnd
call lassqe( mat(:,:) , scal, ssq ) ! mat is complex array of kind stnd
norm2e()

purpose:

norm2e() computes the 2-norm (i.e., the Euclidean norm) of a (real or complex) vector or the Frobenius norm of a (real or complex) matrix.

norm2e() is based on an updated version of the LAPACK3E’ algorithm [Anderson:2002] [Anderson:2018] and uses compensated summation in order to minimize rounding errors [Hanson_Hopkins:2018].

Synopsis:

l2norm     = norm2e( vec(:)   ) ! vec is real    array of kind stnd
l2norm     = norm2e( vec(:)   ) ! vec is complex array of kind stnd
fnorm      = norm2e( mat(:,:) ) ! mat is real    array of kind stnd
fnorm      = norm2e( mat(:,:) ) ! mat is complex array of kind stnd
l2norm(:)  = norm2e( mat(:,:) , dim ) ! mat is real    array of kind stnd
l2norm(:)  = norm2e( mat(:,:) , dim ) ! mat is complex array of kind stnd
lassq2e()

purpose:

lassq2e() computes a scaled sum of squares based on an updated version of the LAPACK3E’ algorithm [Anderson:2002] [Anderson:2018] and uses compensated summation in order to minimize rounding errors [Hanson_Hopkins:2018].

Synopsis:

call lassq2e( vec(:)   , scal, ssq ) ! vec is real    array of kind stnd
call lassq2e( vec(:)   , scal, ssq ) ! vec is complex array of kind stnd
call lassq2e( mat(:,:) , scal, ssq ) ! mat is real    array of kind stnd
call lassq2e( mat(:,:) , scal, ssq ) ! mat is complex array of kind stnd
scatter_add()

Synopsis:

call scatter_add( dest(:) , source(:n) , dest_index(:n) ) ! dest and sources are integer arrays of kind i4b
call scatter_add( dest(:) , source(:n) , dest_index(:n) ) ! dest and sources are real    arrays of kind stnd
call scatter_add( dest(:) , source(:n) , dest_index(:n) ) ! dest and sources are complex arrays of kind stnd
scatter_max()

Synopsis:

call scatter_max( dest(:) , source(:n) , dest_index(:n) ) ! dest and sources are integer arrays of kind i4b
call scatter_max( dest(:) , source(:n) , dest_index(:n) ) ! dest and sources are real    arrays of kind stnd
diagadd()

Synopsis:

call diagadd( mat(:,:)   , diag            ) ! mat is a real    array of kind stnd
call diagadd( mat(:,:)   , diag            ) ! mat is a complex array of kind stnd
call diagadd( mat(:n,:m) , diag(:min(n,m)) ) ! diag and mat are real    arrays of kind stnd
call diagadd( mat(:n,:m) , diag(:min(n,m)) ) ! diag and mat are complex arrays of kind stnd
diagmult()

Synopsis:

call diagmult( mat(:,:)   , diag            ) ! mat is a real    array of kind stnd
call diagmult( mat(:,:)   , diag            ) ! mat is a complex array of kind stnd
call diagmult( mat(:n,:m) , diag(:min(n,m)) ) ! diag and mat are real    arrays of kind stnd
call diagmult( mat(:n,:m) , diag(:min(n,m)) ) ! diag and mat are complex arrays of kind stnd
get_diag()

Synopsis:

diag(:min(n,m)) = get_diag( mat(:n,:m) ) ! mat is a real    array of kind stnd
diag(:min(n,m)) = get_diag( mat(:n,:m) ) ! mat is a complex array of kind stnd
put_diag()

Synopsis:

call put_diag( diag             , mat(:,:)  ) ! mat is a real    array of kind stnd
call put_diag( diag             , mat(:,:)  ) ! mat is a complex array of kind stnd
call put_diag( diag(:min(n,m)) , mat(:n,:m) ) ! diagv and mat are real    arrays of kind stnd
call put_diag( diag(:min(n,m)) , mat(:n,:m) ) ! diagv and mat are complex arrays of kind stnd
unit_matrix()

Synopsis:

call unit_matrix( mat(:,:) ) ! mat is a real    array of kind stnd
call unit_matrix( mat(:,:) ) ! mat is a complex array of kind stnd

Examples:

ex2_trid_inviter.F90

ex2_trid_deflate.F90

lascl()

Synopsis:

call lascl( x        , cfrom , cto )
call lascl( x(:)     , cfrom , cto )
call lascl( x(:,:)   , cfrom , cto )
call lascl( x(:,:)   , cfrom , cto , type        )
call lascl( x        , cfrom , cto , mask        )
call lascl( x(:n)    , cfrom , cto , mask(:n)    )
call lascl( x(:n,:m) , cfrom , cto , mask(:n,:m) )
pythag()

purpose:

Computes \sqrt{ a^2 + b^2 } without destructive underflow or overflow.

Synopsis:

x = pythag( a , b )
pythage()

purpose:

Computes \sqrt{ a^2 + b^2 } without destructive underflow or overflow using the Blue’s scaling method [Blue:1978] [Anderson:2018].

Synopsis:

x = pythage( a , b )
Flag Counter