
//
// LiDIA - a library for computational number theory
//   Copyright (c) 1995 by the LiDIA Group
//
// File        : crt.h
//		
// Author      : Frank J. Lehmann (FL), Thomas Pfahler (TPF)
// Last change : FL, Dec 5 1995, initial version
//




#ifndef LIDIA_CRT_H
#define LIDIA_CRT_H

#include <LiDIA/bigint.h>
#include <LiDIA/bigmod.h>
#include <LiDIA/base_vector.h>
#include <LiDIA/base_matrix.h>


#include <LiDIA/crt_table.h>



/***************************************************************

					class crt

****************************************************************/


class crt
{
      private :

	static const char INIT    ;
        static const char SINGLE  ;
        static const char VECTOR  ;
        static const char POINTER ;
        static const char MATRIX  ;

        static const char MODULAR ;
        static const char INTEGER ;
         

	crt_table *m ;

	lidia_size_t used ;                  // number of used primes when combining
	unsigned char *ix ;                  // ix[i] == 1 iff primes[i] has been used already
			
	char mode ;

	bigint H ;
	double d ;

	lidia_size_t size ;
	bigint* Hv ;
	double* dv ;

	base_vector< bigint > Hvec ;
	base_vector< double > dvec ;


	base_matrix< bigint > Hmat ;
	base_matrix< double > dmat ;
    
	

	void init_single ( void ) ;
	void init_pointer( lidia_size_t sz ) ;
	void init_vector ( lidia_size_t sz ) ; 
	void init_matrix ( lidia_size_t row, lidia_size_t col ) ; 

	void clear_pointer( void ) ;
	void clear_vector ( void ) ; 
	void clear_matrix ( void ) ; 

	bool test_mode ( char m ) ;

	
      public:

	crt () ;
	crt ( crt_table &M ) ;
       ~crt ();


	void init  ( crt_table & M ) ;
	void reset ( void ) ;
	void clear ( void ) ;

	sdigit get_prime ( lidia_size_t index ) const ;


	void reduce ( sdigit &small, const bigint &big, lidia_size_t index ) const ;
	void reduce ( sdigit* small_vec, const bigint* big_vec, lidia_size_t bsize, lidia_size_t index ) const ;
	void reduce ( base_vector<sdigit> & small_vec, const base_vector<bigint> & big_vec, lidia_size_t index ) const ;

	void reduce ( base_matrix<sdigit> & small_mat, const base_matrix<bigint> & big_mat, lidia_size_t index ) const ;


	void reduce ( sdigit &small, const bigmod &big, lidia_size_t index ) const ;
	void reduce ( sdigit* small_vec, const bigmod* big_vec, lidia_size_t bsize, lidia_size_t index ) const ;
	void reduce ( base_vector<sdigit> & small_vec, const base_vector<bigmod> & big_vec, lidia_size_t index ) const ;

	void reduce ( base_matrix<sdigit> & small_mat, const base_matrix<bigmod> & big_mat, lidia_size_t index ) const ;


	void combine ( const sdigit &  small_vec, lidia_size_t index ) ;
	void combine ( const sdigit* small_vec, lidia_size_t l, lidia_size_t index ) ;
	void combine ( const base_vector<sdigit> & small_vec, lidia_size_t index ) ;

	void combine ( const base_matrix<sdigit> & small_vec, lidia_size_t index ) ;


	void get_result ( bigint & big ) ;
	void get_result ( bigint*& big_vec, lidia_size_t & l ) ;
	void get_result ( base_vector<bigint> & big_vec ) ;

	void get_result ( base_matrix<bigint> & big_mat ) ;


	void get_result ( bigmod & big ) ;
	void get_result ( bigmod*& big_vec, lidia_size_t & l ) ;
	void get_result ( base_vector<bigmod> & big_vec ) ;

	void get_result ( base_matrix<bigmod> & big_mat ) ;


	lidia_size_t number_of_primes() const ; 
	lidia_size_t how_much_to_use (const bigint &B) const ;

	void info ( void ) const ;

}; 
// class crt



#endif
