2.1.2 : Les implémentations templates de la bibliothèque

Écrivons le fichier randinit_impl.h :



Encore une fois, ce fichier est aussi un header, donc, on comence par éviter les inclusions multiples :

1
2
#ifndef __RANDINIT_IMPL_H__
#define __RANDINIT_IMPL_H__


Nous aurons aussi besoin de quelques fonctionnalités supplémentaires :

1
2
3
#include <cmath>
#include <limits>
#include "randinit.h"


Implémentons la fonction qui renvoie une valeur pseudo-aléatoire uniforme entre deux autres. Basiquement, la fonction rand() renvoie un nombre entre 0 et RAND_MAX, et la documentation précise qu'il convient de diviser cet interval pour le ramener à un autre plus petit. Cette documentation précise également qu'il ne faut pas utiliser un modulo sinon les valeurs seront moins aléatoires.

1
2
3
4
5
6
7
8
9
10
11
12
///Generates random value
/**	@param val : random value between inf and sup
 * 	@param inf : minimum value of the random uniform value
 * 	@param sup : maximum value of the random uniform value
*/
template<typename T>
void setRandValue(T & val, const T & inf, const T & sup){
	T fourchette = sup - inf;
	//l'utilisation de double est nécéssaire pour permettre de bons tirages aléatoires avec des nombres entiers
	T alea = (T)((((double)fourchette)*((double)rand()))/((double)(RAND_MAX)));
	val = alea + inf;
}


Basiquement la même fonction que précédemment mais qui renvoie la valeur pseudo-aléatoire :

1
2
3
4
5
6
7
8
9
10
11
///Generates random value
/**	@param inf : minimum value of the random uniform value
 * 	@param sup : maximum value of the random uniform value
 * 	@return random value between inf and sup
*/
template<typename T>
T getRandValue(const T & inf, const T & sup){
	T val;
	setRandValue(val, inf, sup);
	return val;
}


Enfin la fonction qui initialise les valeurs à des positionnement aléatoire dans le tableau donné. Si le nombre de valeurs demandés (nbNan) est supérieur ou égal au nombre de valeurs total, alors nous faisons une copie de la valeur value sur tous les éléments du tableau tabValue :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
///Set values at random places in the given table
/**	@param[out] tabValue : table to be modified
 * 	@param nbValue : number of value in the table
 * 	@param nbNan : number of NaN to be put in the table
 * 	@param value : 
 * 	NaN concerns only float and double
*/
template<typename T>
void setValueInTable(T * tabValue, size_t nbValue, size_t nbNan, T value){
	if(nbNan >= nbValue){
		for(size_t i(0lu); i < nbValue; ++i){
			tabValue[i] = value;
		}
		return;
	}
	for(size_t i(0lu); i < nbNan; ++i){
		size_t index(getRandValue(0lu, nbValue));
		tabValue[index] = value;
	}
}


Enfin, nous fermons la conditions sur l'inclusion multiple :

1
#endif


Le fichier randinit_impl.h complet :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/***************************************
	Auteur : Pierre Aubert
	Mail : pierre.aubert@lapp.in2p3.fr
	Licence : CeCILL-C
****************************************/
#ifndef __RANDINIT_IMPL_H__
#define __RANDINIT_IMPL_H__
#include <cmath>
#include <limits>
#include "randinit.h"
///Generates random value
/**	@param val : random value between inf and sup
 * 	@param inf : minimum value of the random uniform value
 * 	@param sup : maximum value of the random uniform value
*/
template<typename T>
void setRandValue(T & val, const T & inf, const T & sup){
	T fourchette = sup - inf;
	//l'utilisation de double est nécéssaire pour permettre de bons tirages aléatoires avec des nombres entiers
	T alea = (T)((((double)fourchette)*((double)rand()))/((double)(RAND_MAX)));
	val = alea + inf;
}
///Generates random value
/**	@param inf : minimum value of the random uniform value
 * 	@param sup : maximum value of the random uniform value
 * 	@return random value between inf and sup
*/
template<typename T>
T getRandValue(const T & inf, const T & sup){
	T val;
	setRandValue(val, inf, sup);
	return val;
}
///Set values at random places in the given table
/**	@param[out] tabValue : table to be modified
 * 	@param nbValue : number of value in the table
 * 	@param nbNan : number of NaN to be put in the table
 * 	@param value : 
 * 	NaN concerns only float and double
*/
template<typename T>
void setValueInTable(T * tabValue, size_t nbValue, size_t nbNan, T value){
	if(nbNan >= nbValue){
		for(size_t i(0lu); i < nbValue; ++i){
			tabValue[i] = value;
		}
		return;
	}
	for(size_t i(0lu); i < nbNan; ++i){
		size_t index(getRandValue(0lu, nbValue));
		tabValue[index] = value;
	}
}
#endif


Vous pouvez le télécharger ici.