
/*
**  This file forms part of the GOBLIN C++ Class Library.
**
**  Written by Christian Fremuth-Paeger, November 2002.
**  
**  Copying, compiling, distribution and modification
**  of this source code is permitted only in accordance
**  with the GOBLIN general licence information.
*/             


#if !defined(_MATRIX_H_)

#define _MATRIX_H_

#include <absobj.h>
#include <hashtbl.h>


template <class TItem,class TCoeff>
class goblinMatrix : public virtual goblinDataObject
{
protected:

    TItem      k;      // Number of rows
    TItem      l;      // Number of columns
    bool       transp; // Switch between matrix and its transposed

public:

    goblinMatrix(TItem,TItem) throw();
    ~goblinMatrix() throw();

    unsigned long   Allocated() throw() {return 0;};
    
    char*   Display() throw();

    TItem   K() throw() {if (transp) return l; else return k;};
    TItem   L() throw() {if (transp) return k; else return l;};
    
    void    Transpose() throw() {transp = (transp==false);};
    
    virtual void    SetCoeff(TItem,TItem,TCoeff) throw(ERRange) = 0;
    virtual TCoeff  Coeff(TItem,TItem) throw(ERRange) = 0;
    
    void    Add(goblinMatrix&) throw(ERRange);
    void    Sum(goblinMatrix&,goblinMatrix&) throw(ERRange);
    void    Product(goblinMatrix&,goblinMatrix&) throw(ERRange);

    void    GaussElim(goblinMatrix&,TFloat=0) throw(ERRange,ERRejected);

};


template <class TItem,class TCoeff>
class denseMatrix : public virtual goblinMatrix<TItem,TCoeff>
{
private:

    TCoeff *coeff;

public:

    denseMatrix(TItem,TItem,
        goblinController & = goblinDefaultContext) throw();
    denseMatrix(goblinMatrix<TItem,TCoeff> &) throw();
    ~denseMatrix() throw();

    unsigned long   Allocated() throw();
    unsigned long   Size() throw();
    
    void    SetCoeff(TItem,TItem,TCoeff) throw(ERRange);
    TCoeff  Coeff(TItem,TItem) throw(ERRange);

};


template <class TItem,class TCoeff>
class sparseMatrix : public virtual goblinMatrix<TItem,TCoeff>
{
private:

    goblinHashTable<TItem,TCoeff> *coeff;

public:

    sparseMatrix(TItem,TItem,TItem,
        goblinController & = goblinDefaultContext) throw();
    sparseMatrix(goblinMatrix<TItem,TCoeff> &) throw();
    ~sparseMatrix() throw();

    unsigned long   Allocated() throw() {return 0;};
    unsigned long   Size() throw();
    
    void    SetCoeff(TItem,TItem,TCoeff) throw(ERRange);
    TCoeff  Coeff(TItem,TItem) throw(ERRange);

};


#endif
