random.hpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002     
00003     random.hpp -- file for the random generation Arageli objects.
00004     
00005     
00006 
00007     Now this file isn't a part of the Arageli library.
00008 
00009     Copyright (C) Kamaev Andrey, 2005
00010     University of Nizhni Novgorod, Russia
00011 
00012 *****************************************************************************/
00013 
00014 #ifndef _ARAGELI_random_hpp_
00015 #define _ARAGELI_random_hpp_
00016 
00017 #include <cstdlib>
00018 
00019 #include "big_int.hpp"
00020 #include "rational.hpp"
00021 #include "vector.hpp"
00022 #include "matrix.hpp"
00023 #include "sparse_polynom.hpp"
00024 
00025 namespace Arageli{
00026 
00027     struct rand_config
00028     {
00029         enum {
00030             integer_min = -100,
00031             integer_max = 100,
00032             degree_max = 10,
00033             vector_len_max = 10,
00034             matrix_dim_max = 6
00035         };
00036     };
00037 
00038 namespace _Internal
00039 {
00040     template<bool cond, class _then, class _else>
00041         struct IF {typedef _then ret;};
00042     template<class _then, class _else>
00043         struct IF<false,_then,_else> {typedef _else ret;};
00044 
00045     template<typename T> struct IS_TYPE_BASE {enum{ret = false};};
00046 
00047     template<> struct IS_TYPE_BASE<signed char> {enum{ret = true};};
00048     template<> struct IS_TYPE_BASE<unsigned char> {enum{ret = true};};
00049     template<> struct IS_TYPE_BASE<signed short> {enum{ret = true};};
00050     template<> struct IS_TYPE_BASE<unsigned short> {enum{ret = true};};
00051     template<> struct IS_TYPE_BASE<signed int> {enum{ret = true};};
00052     template<> struct IS_TYPE_BASE<unsigned int> {enum{ret = true};};
00053     template<> struct IS_TYPE_BASE<signed long> {enum{ret = true};};
00054     template<> struct IS_TYPE_BASE<unsigned long> {enum{ret = true};};
00055     #if defined(ARAGELI_LONG_LONG_SUPPORT)
00056     template<> struct IS_TYPE_BASE<signed long long> {enum{ret = true};};
00057     template<> struct IS_TYPE_BASE<unsigned long long> {enum{ret = true};};
00058     #endif // ARAGELI_LONG_LONG_SUPPORT
00059     #if defined(ARAGELI_INT64_SUPPORT)
00060     template<> struct IS_TYPE_BASE<signed __int64> {enum{ret = true};};
00061     template<> struct IS_TYPE_BASE<unsigned __int64> {enum{ret = true};};
00062     #endif // ARAGELI_INT64_SUPPORT
00063     template<> struct IS_TYPE_BASE<float> {enum{ret = true};};
00064     template<> struct IS_TYPE_BASE<double> {enum{ret = true};};
00065     template<> struct IS_TYPE_BASE<long double> {enum{ret = true};};
00066 
00067     template<> struct IS_TYPE_BASE<big_int> {enum{ret = true};};
00068 
00069 
00070     template<typename T, class Conf>
00071     struct rand_nolimited{
00072         static T rand(void) {return T();}
00073     };
00074     template<typename T, int min, int max>
00075     struct rand_limited{
00076         static T rand(void) {return T();}
00077     };
00078 #define RAND (std::rand())
00079 #define SPECIALIZE_RAND(type,gen_alg,lim_gen_alg) \
00080     template<class Conf> \
00081     struct rand_nolimited<type,Conf>{\
00082         static type rand(void) {return (type)(gen_alg);}\
00083     };\
00084     template<int min, int max>\
00085     struct rand_limited<type,min,max>{\
00086         static type rand(void) {return (type)(lim_gen_alg);}\
00087     }
00088 
00089     SPECIALIZE_RAND(signed int,(Conf::integer_min + RAND % (Conf::integer_max - Conf::integer_min)),(min + RAND % (max - min)));
00090     SPECIALIZE_RAND(unsigned int,(RAND % Conf::integer_max),(min + RAND % (max - min)));
00091     SPECIALIZE_RAND(signed char,(Conf::integer_min + RAND % (Conf::integer_max - Conf::integer_min)),(min + RAND % (max - min)));
00092     SPECIALIZE_RAND(unsigned char,(RAND % Conf::integer_max),(min + RAND % (max - min)));
00093     SPECIALIZE_RAND(signed short,(Conf::integer_min + RAND % (Conf::integer_max - Conf::integer_min)),(min + RAND % (max - min)));
00094     SPECIALIZE_RAND(unsigned short,(RAND % Conf::integer_max),(min + RAND % (max - min)));
00095     SPECIALIZE_RAND(signed long,(Conf::integer_min + RAND % (Conf::integer_max - Conf::integer_min)),(min + RAND % (max - min)));
00096     SPECIALIZE_RAND(unsigned long,(RAND % Conf::integer_max),(min + RAND % (max - min)));
00097     #if defined(ARAGELI_LONG_LONG_SUPPORT)
00098     SPECIALIZE_RAND(signed long long,(Conf::integer_min + RAND % (Conf::integer_max - Conf::integer_min)),(min + RAND % (max - min)));
00099     SPECIALIZE_RAND(unsigned long long,(RAND % Conf::integer_max),(min + RAND % (max - min)));
00100     #endif // ARAGELI_LONG_LONG_SUPPORT
00101     #if defined(ARAGELI_INT64_SUPPORT)
00102     SPECIALIZE_RAND(signed __int64,(Conf::integer_min + RAND % (Conf::integer_max - Conf::integer_min)),(min + RAND % (max - min)));
00103     SPECIALIZE_RAND(unsigned __int64,(RAND % Conf::integer_max),(min + RAND % (max - min)));
00104     #endif // ARAGELI_INT64_SUPPORT
00105     SPECIALIZE_RAND(float,(RAND / (1. + RAND)),(RAND / (1. + RAND)));
00106     SPECIALIZE_RAND(double,(RAND / (1. + RAND)),(RAND / (1. + RAND)));
00107     SPECIALIZE_RAND(long double,(RAND / (1. + RAND)),(RAND / (1. + RAND)));
00108 
00109     SPECIALIZE_RAND(big_int,(big_int::random_in_range(big_int(Conf::integer_max - Conf::integer_min)) + Conf::integer_min),
00110         (big_int::random_in_range(big_int(max - min)) + min));
00111     
00112     template<typename T, class Conf> 
00113     struct rand_nolimited<rational<T>,Conf>{
00114         typedef typename IF<IS_TYPE_BASE<T>::ret,rand_limited<T,Conf::integer_min,Conf::integer_max>,rand_nolimited<T,Conf> >::ret r_type;
00115         static rational<T> rand(void) 
00116         {
00117             T den;
00118             do{den = r_type::rand(); }while(is_null(den));
00119             return rational<T>(r_type::rand(),den);
00120         }
00121     };
00122 
00123     template<typename F, typename I, class Conf> 
00124     struct rand_nolimited<monom<F, I>,Conf>{
00125         typedef typename IF<IS_TYPE_BASE<F>::ret,rand_limited<F,Conf::integer_min,Conf::integer_max>,rand_nolimited<F,Conf> >::ret F_type;
00126         typedef typename IF<IS_TYPE_BASE<I>::ret,rand_limited<I,0,Conf::degree_max>,rand_nolimited<I,Conf> >::ret I_type;
00127         static monom<F, I> rand(void) 
00128         {
00129             return monom<F, I>(F_type::rand(),I_type::rand());
00130         }
00131     };
00132 
00133     template<typename F, typename I, bool REFCNT, class Conf> 
00134     struct rand_nolimited<sparse_polynom<F, I, REFCNT>,Conf>{
00135         static sparse_polynom<F, I, REFCNT> rand(void) 
00136         {
00137             sparse_polynom<F, I, REFCNT> res;
00138             for (int i = 0; i < Conf::degree_max; ++i)
00139             {
00140                 monom<F,I> mon = rand_nolimited<monom<F, I>,Conf>::rand();
00141                 bool fl = true;
00142                 for(typename sparse_polynom<F, I, REFCNT>::degree_iterator i = res.degrees_begin(), j = res.degrees_end(); i != j && fl; ++i)
00143                     if(*i == mon.degree()) fl = false;
00144                 if(fl)res += mon;
00145             }
00146             return res;
00147         }
00148     };
00149 
00150     template<typename T, bool REFCNT, class Conf> 
00151     struct rand_nolimited<matrix<T, REFCNT>,Conf>{
00152         typedef typename IF<IS_TYPE_BASE<T>::ret,rand_limited<T,Conf::integer_min,Conf::integer_max>,rand_nolimited<T,Conf> >::ret r_type;
00153         static matrix<T, REFCNT> rand(void) 
00154         {
00155             matrix<T, REFCNT> res
00156             (
00157                 rand_limited<typename matrix<T, REFCNT>::size_type,1,Conf::matrix_dim_max>::rand(),
00158                 rand_limited<typename matrix<T, REFCNT>::size_type,1,Conf::matrix_dim_max>::rand()
00159             );
00160             
00161             for (typename matrix<T, REFCNT>::size_type i = 0; i < res.nrows(); i++)
00162                 for (typename matrix<T, REFCNT>::size_type j = 0; j < res.ncols(); j++)
00163                     res.el(i,j) = r_type::rand(); 
00164             return res;
00165         }
00166     };
00167 
00168     template<typename T, bool REFCNT, class Conf> 
00169     struct rand_nolimited<vector<T, REFCNT>,Conf>{
00170         typedef typename IF<IS_TYPE_BASE<T>::ret,rand_limited<T,Conf::integer_min,Conf::integer_max>,rand_nolimited<T,Conf> >::ret r_type;
00171         static vector<T, REFCNT> rand(void) 
00172         {
00173             vector<T, REFCNT> res(rand_limited<typename vector<T, REFCNT>::size_type,1,Conf::vector_len_max>::rand());
00174             for (typename vector<T, REFCNT>::size_type i = 0; i < res.size(); i++)
00175                     res.el(i) = r_type::rand(); 
00176             return res;
00177         }
00178     };
00179     
00180 }//_Internal
00181 
00182 template<typename T, class Conf = rand_config>
00183 struct rnd
00184 {
00185 static T rand() {return _Internal::rand_nolimited<T,Conf>::rand();}
00186 };
00187 
00188 }//Arageli
00189 
00190 
00191 #endif //_ARAGELI_random_hpp_

Generated on Thu Aug 31 17:38:08 2006 for Arageli by  doxygen 1.4.7