//
// LiDIA - a library for computational number theory
//   Copyright (c) 1994, 1995, 1996 by the LiDIA Group
//
// File        : bigfloat_matrix.c 
// Author      : Thorsten Lauer (TL)
// Last change : TL, Oct 6 1996, initial version
//

#ifndef LIDIA_BIGFLOAT_MATRIX_H
#define LIDIA_BIGFLOAT_MATRIX_H

#if defined(HAVE_MAC_DIRS) || defined(__MWERKS__)
#include <LiDIA:bigfloat.h>
#include <LiDIA:bigfloat_int.h>
#include <LiDIA:math_matrix.h>
#include <LiDIA:base_vector.h>
#else
#include <LiDIA/bigfloat.h>
#include <LiDIA/bigfloat_int.h>
#include <LiDIA/math_matrix.h>
#include <LiDIA/base_vector.h>
#endif

// MM: included bigfloat_int, because it is used as a template
//     argument in bigfloat_matrix.c and the HP CC compiler
//     only examines the header file for class definitions.

class bigfloat_matrix : public math_matrix <bigfloat> {

	//
	// constructors 
	//

	public:
		inline bigfloat_matrix() : math_matrix <bigfloat>() {}
		inline bigfloat_matrix(lidia_size_t a, lidia_size_t b) : math_matrix <bigfloat>(a,b) {}
		inline bigfloat_matrix(lidia_size_t a, lidia_size_t b, const bigfloat **v) : math_matrix <bigfloat>(a,b,v) {}
		inline bigfloat_matrix(const math_matrix < bigfloat >& A) : math_matrix <bigfloat>(A) {}
		inline bigfloat_matrix(const bigfloat_matrix& A) : math_matrix <bigfloat>(A) {}

	//
	// destructor
	//

		inline ~bigfloat_matrix() {}

	//
	// public functions
	//
		
		void randomize();

		int equal(const bigfloat_matrix&) const;
		inline friend int operator ==(const bigfloat_matrix&, const bigfloat_matrix&);
		inline friend int operator !=(const bigfloat_matrix&, const bigfloat_matrix&);

		void invert(bigfloat_matrix &) const;

		void gauss_jordan(base_vector<bigfloat>&, const base_vector<bigfloat>&) const;
		base_vector <bigfloat> gauss_jordan(const base_vector<bigfloat>&) const;

		void cholesky(bigfloat_matrix &) const;
		void mod_cholesky(bigfloat_matrix &) const;

		void LR(bigfloat_matrix &, bigfloat_matrix &) const;
		void QR(bigfloat_matrix &, bigfloat_matrix &) const;

		inline friend void gauss_jordan(base_vector<bigfloat>& x, const bigfloat_matrix&, const base_vector<bigfloat>&);
		inline friend base_vector<bigfloat> gauss_jordan(const bigfloat_matrix&, const base_vector<bigfloat>&);
		inline friend void invert(math_matrix<bigfloat>&, const math_matrix<bigfloat>&);
};


int operator ==(const bigfloat_matrix& A, const bigfloat_matrix& B)
{
	return A.equal(B);
}

int operator !=(const bigfloat_matrix& A, const bigfloat_matrix& B)
{
	return !A.equal(B);
}

void gauss_jordan(base_vector<bigfloat>& x, const bigfloat_matrix& A, const base_vector<bigfloat>& b)
{
	A.gauss_jordan(x,b);
}

base_vector<bigfloat> gauss_jordan(const bigfloat_matrix& A, const base_vector<bigfloat>& b)
{
	return A.gauss_jordan(b);
}

void invert(math_matrix<bigfloat>& B, const math_matrix<bigfloat>& A)
{
	bigfloat_matrix C(A),D;
	C.invert(D);
	B.assign(D);
}

#endif

