//
// LiDIA - a library for computational number theory
//   Copyright (c) 1994, 1995 by the LiDIA Group
//
// File        : lattice_kernel.h
// Author      : Werner Backes (WB), Thorsten Lauer (TL)
// Last change : WB/TL, May 09 1996, 
//         	   	initial version, previously class bigint_lattice_gensys
//         	   	and bigint_lattice_basis 
//		 WB/TL, Jun 30 1996, 
//		 	new concept for more flexibility and hopefully better 
//		 	performance, introduction of helpful classes :
//		        (Only for internal use !!)
//		        - base_vector_op           
//		          -> vector operations for double/bigint/bigfloat
//		 	- basis_vector_op          
//		 	  -> implementation for basis algortihms
//		        - basis_SP_vector_op       
//		          -> implementation for self defined scalar product
//		        - gensys_vector_op         
//		          -> implementation for gensys algorithms
//		        - gensys_SP_vector_op 	 
//		          -> implementation for self defined scalar product
//			- schnorr_euchner_bigint   
//			  -> real implementation of the lll - algorithms
//               WB/TL, Jul 27 1996,
//                      redesign of the class structur mentioned above
//               WB/TL, Aug 06 1996, 
//                      removed all classes mentioned above
//                      splited vector functions (see p_vector.h) and 
//                      basis/gensys functions (see lattice_modules.h)
//                      - lll_kernel_bin_op
//                        -> kernel lll for bigint and operators
//                      - lll_kernel_bin_fu
//                        -> kernel lll for bigint and functions
//                       
//

#ifndef __lattice_kernel_h__
#define __lattice_kernel_h__

//
// Special include format for compatibility with MAC's
//
#if defined(HAVE_MAC_DIRS) || defined(__MWERKS__)
#include <LiDIA:xdouble.h>
#include <LiDIA:bigint.h>
#include <LiDIA:bigfloat.h>
#include <LiDIA:base_vector.h>
#include <LiDIA:bigint_matrix.h>
#include <LiDIA:p_vector.h>
#include <LiDIA:lattice_defs.h>
#include <LiDIA:lattice_modules.h>
#else
#include <LiDIA/xdouble.h>
#include <LiDIA/bigint.h>
#include <LiDIA/bigfloat.h>
#include <LiDIA/base_vector.h>
#include <LiDIA/bigint_matrix.h>
#include <LiDIA/p_vector.h>
#include <LiDIA/lattice_defs.h>
#include <LiDIA/lattice_modules.h>
#endif

class bigint_lattice;
class bigfloat_lattice;

//
// class lll_kernel_{op,fu}
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// These classes feature the real implementation of the 
// variation of Schnorr - Euchner - lll we support for
// the class bigint/bigfloat_lattice. These algorithms are 
// working row by row.
//
// Warning :
// ~~~~~~~~~
// These classes is for internal use only !!!
// There are many things you have to do before running
// an algorithm of these classes ! These things are done
// by the class bigint_lattice !
// For internal use only !
//
// This class is working with operators
//
template <class E, class A, class VectorOp, class AlgParts>
class lll_kernel_op
{
  protected :
    VectorOp vector;
    AlgParts alg;

  public :
    lll_kernel_op() { };
    ~lll_kernel_op() { };

    VectorOp& vector_operations() { return (vector); };

//
// Dense Lattice :
// ~~~~~~~~~~~~~~~
// Schnorr - Euchner - lll algorithms using a datatype
// with fixed precision for approximation of the lattice 
// The computation is done with implemented operators
// (like the double datatype)
// The datatype has to be functional compatible to 
// the double datatype like the new xdouble datatype
// +, -, *, /, =, >, <, sqrt, fabs needed
//
    void lll(dense_alg<E>&, lattice_info&);
    void lll_var(dense_alg<E>&, lattice_info&);
//
// Versions modified for working with a Gram - matrix
//
    void lll_gram(dense_alg<E>&, lattice_info&);
    void lll_var_gram(dense_alg<E>&, lattice_info&);
};

//
// This class is working with function
//
template <class E, class A, class VectorOp, class AlgParts>
class lll_kernel_fu
{
  protected :
    VectorOp vector;
    AlgParts alg;

  public :
    lll_kernel_fu() { };
    ~lll_kernel_fu() { };

    VectorOp& vector_operations() { return (vector); };

//
// Dense Lattice :
// ~~~~~~~~~~~~~~~
// Schnorr - Euchner - lll algorithms using a datatype
// with variable precision for approximation of the lattice 
// The computation is done with implemented functions
// (like the bigfloat datatype)
//
    void lll(dense_alg<E>&, lattice_info&);
    void lll_var(dense_alg<E>&, lattice_info&);
//
// Versions modified for working with a Gram - matrix
//
    void lll_gram(dense_alg<E>&, lattice_info&);
    void lll_var_gram(dense_alg<E>&, lattice_info&);
};

#endif
