// ************************************************************
//	Clean Linear Algebra Subroutines - CLAS
//	Version 0.6 - February 23, 1998 - Thorsten Zoerner
// 	Catholic University of Nijmegen - zoerner@cs.kun.nl
// ************************************************************

definition module Clas1

import SampleVec, StdBool

dot		:: .Vector .Vector -> Real			//	x^T y

nrm1	:: .Vector -> Real					//	||x||_1
nrm2	:: .Vector -> Real					//	||x||_2
nrmInf	:: .Vector -> Real					//	||x||_inf

amax   :: .Vector -> Int					//  {k : max_j |x_j|}
											//	||x||_inf=|x_k|

											//  Givens rotation:
											//  [ c -s ] [ a ] = [ r ]
											//  [ s  c ] [ b ]   [ 0 ]
rotg :: Real Real -> (Real, Real)    		//  a b -> (c, s)
											//  applied Givens rotation
rot :: Real Real -> (Real, Real)    		//  a b -> (r, 0)
  
swap :: *(a b) .Int .Int -> .(a b) | update_u , uselect_u b & Array .a
											//	swaps entries i and j
											// 	of any unique array

instance + {# a} | + , ArrayElem a
instance - {# a} | - , ArrayElem a
instance * {# a} | * , ArrayElem a			// Hadamard product
instance / {# a} | / , ArrayElem a			// Hadamard division

class ScalarProduct a
where
	(.*) infix 7 :: Real a -> a

instance ScalarProduct Real
instance ScalarProduct {# a} | ScalarProduct , ArrayElem a

class ScalarDivision a
where
	(/.) infix 7 :: a Real -> a

instance ScalarDivision Real
instance ScalarDivision {# a} | ScalarDivision , ArrayElem a

// ************************************************************
//	Clean Linear Algebra Subroutines - CLAS
//	Version 0.6 - February 23, 1998 - Thorsten Zoerner
// 	Catholic University of Nijmegen - zoerner@cs.kun.nl
// ************************************************************

definition module Clas2

import Clas1, SampleMat

class MatrixVectorProduct a
where
	(**) infix 7 :: a .Vector -> .Vector
	
instance MatrixVectorProduct {# {# Real}}

// instance MatrixVectorProduct {# Int}			// Permutes a vector
// not allowed in Clean

transpose 		:: .Matrix -> .Matrix

perVec 			:: {# Int} .Vector -> .Vector	// Permutes a vector

forwardSubst 	:: Matrix Vector -> *Vector		// Solves a system
												// with a lower left
												// triangular system *)
backwardSubst 	:: Matrix Vector -> *Vector		// Solves a system
												// with a upper right
												// triangular system 
// To be used with LU factorization Ax=LUx=b <==> Ly=b, Ux=y,
// or LU factorization with partial pivoting PAx=LUx=Pb <==> Ly=Pb, Ux=y.
// (cf. solve and solvePartPiv in Clas3)

// *)	assuming that only ones are on the diagonal, which is the case 
//		after the LU factorization

// ************************************************************
//	Clean Linear Algebra Subroutines - CLAS
//	Version 0.6 - February 23, 1998 - Thorsten Zoerner
// 	Catholic University of Nijmegen - zoerner@cs.kun.nl
// ************************************************************

definition module Clas3

import Clas2, StdMisc

class MatrixMatrixProduct a
where
	(***) infix 7 :: a a -> a

instance MatrixMatrixProduct {# {# Real}}

solve 			:: *Matrix .Vector -> .Vector
solvePartPiv	:: *Matrix .Vector -> .Vector

lu 		:: *Matrix -> *Matrix					// LU factorization A=LU
// overwrites the input matrix A with both factors L and U:
//        u_00      u_01    ..        ..        u_0(n-1)
//        l_10      u_11    ..        ..           ..
//         ..       l_21    ..        ..           ..
//         ..        ..     ..  u_(n-2)(n-1)  u_(n-2)(n-1)
//      l_(n-1)0  l_(n-1)1  ..  l_(n-1)(n-1)  u_(n-1)(n-1)
// The diagonal l_ii, i=1,...,n of L is constant 1 by construction.

luPartPiv :: *Matrix -> (*Matrix, *{# Int})		// LU factorization with
												// partial pivoting PA=LU
// Overwrites the input matrix A with both factors L and U (cf. above)
// and returns the permutation P as an array of integers. The right hand side 
// vector has to be permuted accordingly.

invert 	:: *Matrix -> .Matrix					// inverts matrix by means of
												// the Gauss-Jordan algorithm

// ************************************************************
//	Clean Linear Algebra Subroutines - CLAS
//	Version 0.6 - February 23, 1998 - Thorsten Zoerner
// 	Catholic University of Nijmegen - zoerner@cs.kun.nl
// ************************************************************

definition module SampleVec

import StdArray, StdEnum, StdList, StdReal, StdString

:: Vector :== {# Real}

uniVec :: .Vector -> *Vector

zeros :: Int -> .Vector			// returns the zero vector of given length
ones  :: Int -> .Vector			// returns a vector containing all ones 
								// of given length
one2n :: Int -> .Vector			// returns a vector containing the numbers 
								// 1 till n of given length n
ek    :: Int Int -> .Vector		// returns the k-th unit vector

prettyRowVector    :: Vector -> String
prettyColumnVector :: Vector -> String

// ************************************************************
//	Clean Linear Algebra Subroutines - CLAS
//	Version 0.6 - February 23, 1998 - Thorsten Zoerner
// 	Catholic University of Nijmegen - zoerner@cs.kun.nl
// ************************************************************

definition module SampleMat

import SampleVec

:: Matrix :== {# .Vector}

uniMat		:: .Matrix -> *Matrix	// returns a unique matrix

zeroMatrix	:: Int Int -> .Matrix	// returns the zero matrix of given size
In			:: Int -> .Matrix		// returns the unit matrix of given size
hilbert		:: Int -> .Matrix		// returns the Hilbert matrix of given size
// Elements of a Hilbert matrix are defined as 
// h_ij = 1 / (i+j+1), i,j = 0,...,n-1
// Remark: This matrix reveals particularly bad properties for direct methods
// like LU factorization.

prettyMatrix :: Matrix -> String

