You are on page 1of 64

Bayesian Programming

c
with ProBT!
and some dice

Juan Manuel Ahuactzin


Pierre B`
essiere

Kamel Mekhnacha
Emmanuel Mazer

July 2012

Chapter 1

Variables
Program 1:Multiple type variables sets.
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

/*=======================================================================
* Product
:
* File
: multipleTypes.cpp
* Author
: Juan-Manuel Ahuactzin
* Creation
: 2002-Oct-30 19:29
*
*=======================================================================
*
(c) Copyright 2008, Probayes SAS,
*
all rights reserved
*=======================================================================
*
*------------------------- Description --------------------------------* This file gives an example to define multiple type variables
* conjunctions
*----------------------------------------------------------------------*/
#include <pl.h>

using namespace std;

int main()
{
//Definig types
plIntegerType rank_type(0,10);
plIntegerType age_type(0,120);
plRealType weight_type(40.0,140.0);
plRealType height_type(0.2,2.30, 200);
//Defining single type variables conjunctions
plSymbol rank("rank",rank_type);
plSymbol age("age",age_type);

4
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 }

CHAPTER 1. VARIABLES
plSymbol height("height",height_type);
plSymbol weight("weight",weight_type);
plArray ancestors_height("anc_height",height_type,1,2);
//Defining a multiple type variable
plVariable physical_info(weight^height^ancestors_height);
cout<<"physical_info = "<<physical_info<<"\n";
//Defining a multiple type variable
plVariable athlet_info(physical_info^age);
cout<<"athlet_info = "<<athlet_info<<"\n\n";
//The previous two variables can also be constructed as follows
plVariable physical_info2;
physical_info2 = weight^height^ancestors_height;
cout<<"physical_info2 = "<<physical_info2<<"\n";
plVariable athlet_info2;
athlet_info2 = physical_info2;
athlet_info2 ^= age;
cout<<"athlet_info2 = "<<athlet_info2<<"\n";
return 0;

5
Program 2:Grouping variables.

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

/*=======================================================================
* Product
:
* File
: groupingVars.cpp
* Author
: Juan-Manuel Ahuactzin
* Creation
: 2002-Oct-30 19:29
*
*=======================================================================
*
(c) Copyright 2008, Probayes SAS,
*
all rights reserved
*=======================================================================
*
*------------------------- Description --------------------------------* This is a simple example showing how to group a set of
* variables. We assume having n sensors giving a lecture of a moving
* object. A lectures is composed by an angle, a distance and a
* velocity in x and y. A set of Left an right lectures is also
* constructed. We assume that odd sensors are left sensors and that
* even sensors are right sensors
* *----------------------------------------------------------------------*/
#include <pl.h>
using namespace std;
int main ()
{
/**********************************************************************
Defining types and variables
***********************************************************************/
//Defining types
plIntegerType angle_lecture(0,360);
plRealType distance_lecture(0,100.0,50);
plRealType velocity_lecture(-50,50,20);
const unsigned int n_sensors = 6;
//Defining a plArrays angle(n_sensors) for angles
plArray angle("T",angle_lecture,1,n_sensors);
//Defining a plArrays distance(n_sensors) for distances
plArray distance("D",distance_lecture,1,n_sensors);
//Defining a plArrays velocity(n_sensors, 2). The "2" corresponds to
//the x and y components
plArray velocity("V",velocity_lecture,2,n_sensors,2);
/**********************************************************************
Joining variables conjunctions by means of the ^ operator
***********************************************************************/
unsigned int i;

6
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 }

CHAPTER 1. VARIABLES
vector <plVariable> lecture(n_sensors);
for(i=0;i<n_sensors;i++)
{
//Lectire_i = {angle_i, distance_i, velocity_x; velocity_y}
lecture[i] = angle(i)^distance(i)^velocity(i,0)^velocity(i,1);
cout<<"sensor_"<<i<<" = "<<lecture[i]<<"\n";
}
/**********************************************************************
Joining variables conjunctions by means of the ^= operator
***********************************************************************/
plVariable left_lectures;
plVariable right_lectures;
// constructing the sets of left and right lectures
for(i=0;i<n_sensors-1;i+=2)
{
left_lectures ^= lecture[i];
right_lectures ^= lecture[i+1];
}
cout<<"\nleft readings = "<<left_lectures<<"\n";
cout<<"right readings = "<<right_lectures<<"\n";
return 0;

7
Program 3:Variable values loops.

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

/*=======================================================================
* Product
:
* File
: iterateValues.cpp
* Author
: Juan-Manuel Ahuactzin
* Creation
: 2002-Oct-30 19:29
*
*=======================================================================
*
(c) Copyright 2008, Probayes SAS,
*
all rights reserved
*=======================================================================
*
*------------------------- Description --------------------------------* This program shows how to cover all the values of a conjunction of
* discrete variables (i.e. creation of loops). Three examples
* consisting in the more typical circumstances are shown.
*----------------------------------------------------------------------*/

#include <pl.h>
using namespace std;
int main ()
{
/**********************************************************************
Defining the variable type and symbols
***********************************************************************/
plIntegerType minuteType(0,59);
plIntegerType hourType(0,23);
plSymbol minute("minute",minuteType);
plSymbol hour("hour",hourType);
plRealType temperature(-20,40,100);
plRealType humidity(0.0,1.0,25);
plRealType speed(0,70,20);
plSymbol
plSymbol
plSymbol
plSymbol

hi("Hi",temperature);
lo("Lo",temperature);
wind_speed("wind_speed",speed);
wind_humidity("wind_humidity",humidity);

/**********************************************************************
First example: A loop for all the variables in the plValues
with the order of iteration given by the order used at the creation
of the plValues.
***********************************************************************/
cout<<"Fist example output : \n";
plValues time(hour^minute);

// "time" is {hour, minute}

8
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106 }

CHAPTER 1. VARIABLES

time.reset();
do
cout<<time<<endl;
while(time.next());
cout<<"\n\n";

// Reset all values in "time"

// Set the next value for {hour, time}

/*** The result is not the same for "time2": Note that minute and hour
are inversed w.r.t. to "time" ***/
plValues time2(minute^hour); // "time2" contains : minute and hour
time2.reset();
do
cout<<time2<<endl;
while(time2.next());
cout<<"\n\n";

// Reset all values in "time"

// Set the next value for {time, hour}

/**********************************************************************
Second example: Shows a loop that iterates one explicit variable at
a time
***********************************************************************/
cout<<"Second example output : \n";
time2.reset(hour);
// Reset the value of {hour}
do {
time2.reset(minute);
// Resets the value of {minute}
do
cout<<time2<<endl;
while (time2.next(minute));// Set the next value for {minute}
} while(time2.next(hour));
// Set the next value for {hour}
/**********************************************************************
Third example: A loop for a subset of variables of the plValues
with a particular order of iteration. Note that this example is
presented with discrete plReals to show that loop are also possible
for this type of variables.
***********************************************************************/
cout<<"Third example output : \n";
plValues forecast(hi^lo^wind_speed^wind_humidity);
forecast[hi] = 61.5;
forecast[lo] = 51.0;
forecast.reset(wind_humidity^wind_speed);

// Reset the values of


// {wind_humidity, wind_speed}

do
cout<<forecast<<endl;
while(forecast.next(wind_humidity^wind_speed)); // Set the next value for
// {wind_humidity, wind_speed}
return 0;

Chapter 2

Distributions
2.1

Unconditional distributions

10

CHAPTER 2. DISTRIBUTIONS
Program 4:Throwing a die.

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

/*=======================================================================
* Product
:
* File
: die.cpp
* Author
: Juan-Manuel Ahuactzin
* Creation
: 2002-Oct-30 19:29
*
*=======================================================================
*
(c) Copyright 2008, Probayes SAS,
*
all rights reserved
*=======================================================================
*
*------------------------- Description --------------------------------* This program simulates throwing a symmetric 6 sides die
*----------------------------------------------------------------------*/
#include <pl.h>
using namespace std;
int main()
{
/**********************************************************************
Defining the variable type, a symbol and values.
**********************************************************************/
plIntegerType Points_type(1,6);
plSymbol Points("Points",Points_type);
plValues values(Points);

// Type for Points [1,2,...,6]


// Variable set for Points
// Values for Points

/**********************************************************************
Definig P(Die) = uniform
**********************************************************************/
plUniform P_Points(Points);

// Distribution of the variable space

/**********************************************************************
Displaying the defined data
**********************************************************************/
cerr<<"Points_type = "<<Points_type<<"\n";
cerr<<"Points = "<<Points<<"\n";
cerr<<"values = "<<values<<"\n";
cerr<<"P_Points : "<<P_Points<<"\n\n";

//
//
//
//

Print
Print
Print
Print

the
the
the
the

type
symbol
variable values
distribution

/**********************************************************************
Throwing the die
**********************************************************************/
int i,n_times;
cout<<"How many times shall I throw the die? : ";
cin>>n_times;
// Read the number of times to throw the die
cout<<"\n";

2.2. CONDITIONAL DISTRIBUTIONS

11

54
55
for (i=0;i<n_times;i++) { // Throw the die
56
cout<<i+1<<"th throw ";
57
P_Points.draw(values);
58
cout<<values<<endl;
59
}
60
61
return 0;
62 }

Exercise 1: Modify the program die.cpp for every one of the following
situations: (i) having two dice, (ii) having five dice, (iii) having a 3 5 dice
table, and (iv) having a 3 5 2 dice table.

2.2

Conditional distributions
Program 5:A collection of biased dice.

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

/*=======================================================================
* Product
:
* File
: biased_dice.cpp
* Author
: Juan-Manuel Ahuactzin
* Creation
: 2003-Sep-05 17:58
*
*=======================================================================
*
(c) Copyright 2008, Probayes SAS,
*
all rights reserved
*=======================================================================
*
*------------------------- Description --------------------------------* This program simulates a set of 4 dice, 3 non symmetric and one
* symmetric. The program first asks to select one of the dice then
* it simulates a given number of throws.
*----------------------------------------------------------------------*/
#include <pl.h>
using namespace std;
int main()
{
/**********************************************************************
Defining the variable type, symbols and values.
**********************************************************************/
plIntegerType Points_type(1,6);
plIntegerType Die_type(1,4);

// Type for Points [1,2,...,6]


// Type for the Die

12
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84 }

CHAPTER 2. DISTRIBUTIONS
plSymbol Points("Points",Points_type);// Variable set for Points
plSymbol Die("Die",Die_type);
// Variable set for the Die
plValues values(Points^Die);
// Values for Points and Die
/**********************************************************************
Definig P(Points | Die)
**********************************************************************/
// Distributions of dice 1,3 and 4
plProbValue distDie1[6] = {0.3, 0.2, 0.1, 0.1, 0.2, 0.1};
plProbValue distDie3[6] = {0.4, 0.15, 0.1, 0.15, 0.1, 0.1};
plProbValue distDie4[6] = {0.2, 0.2, 0.1, 0.1, 0.35, 0.05};
// The conditional distribution P(Points | Die)
plDistributionTable P_PointsKDie(Points,Die);
P_PointsKDie.push(1,plProbTable(Points,distDie1));
P_PointsKDie.push(2,plUniform(Points)); // Die 2 is a symmetric die
P_PointsKDie.push(3,plProbTable(Points,distDie3));
P_PointsKDie.push(4,plProbTable(Points,distDie4));
// Printing the created objects
cerr<<"Points_type = "<<Points_type<<"\n";
cerr<<"Die_type = "<<Die_type<<"\n";
cerr<<"points = "<<Points<<"\n";
cerr<<"die = "<<Die<<"\n";
cerr<<"values = "<<values<<"\n";
cerr<<"P_PointsKDie : "<<P_PointsKDie<<"\n\n";
/**********************************************************************
Selecting and Throwing the a die
**********************************************************************/
int i,n_times;
cout<<"Select a die (1,2,3 or 4): "; // Select the die to trow
cin>>values[Die];
plDistribution P_Points;
P_PointsKDie.instantiate(P_Points,values);
cout<<"Selected die distribution : "<<P_Points<<"\n\n";
cout<<"How many times shall I throw the die? : ";
cin>>n_times;
// Read the number of times to throw the die
cout<<"\n";
for (i=0;i<n_times;i++) { // Throw the die
cout<<i+1<<"th throw ";
P_Points.draw(values);
cout<<values[Points]<<endl;
}
return 0;

Chapter 3

Bayesian Networks

13

14

CHAPTER 3. BAYESIAN NETWORKS

Die
0
0.36

1
0.64

P oints
Die
0
1

1
0.3
0.16

2
0.2
0.16

P oints
3
4
0.1
0.1
0.16 0.16

5
0.2
0.16

6
0.1
0.16

Figure 3.1: The two dice Bayesian network.


Program 6:Two dice..
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

/*=======================================================================
* Product
:
* File
: twoDice.cpp
* Author
: Juan-Manuel Ahuactzin
* Creation
: Tue Mar 8 15:12:38 2005
*
*=======================================================================
*(c) Copyright 2000-2004, Centre National de la Recherche Scientifique,
*
all rights reserved
*=======================================================================
*
*------------------------- Description --------------------------------*
*
*----------------------------------------------------------------------*/

#include <pl.h>
using namespace std;
int main() {
/**********************************************************************
VARIABLES SPECIFICATION
**********************************************************************/
plIntegerType Die_type(0,1);
// Two dice 0 and 1
plIntegerType Points_type(1,6);
// Type for Points [1,2,...,6]
plSymbol Die("Die",Die_type);

15

Specification

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
:

8
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
<

8
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
<

Relevant Variables:
Die, P oints
Decomposition:
P (Die P oints | ) =
P (Die | )P (P oints | Die )
Parametric Forms:
0
1
> P (Die | ) =
>
>
0.36
0.64
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
Die
>
>
>
>
>
>
>
>
1
>
>
>
>
P (P oints | Die ) =
>
>
>
>
0
0.3
>
>
>
>
:
>
>
>
1
0.16
>
>
>
>
Identification:
>
:
All tables provided by the user
Question:
P (Die|P oints)

Description

twoDice() =

8
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
<

2
0.2
0.16

P oints
3
4
0.1
0.1
0.16 0.16

Figure 3.2: The two dice Bayesian program.

30
plSymbol Points("Points",Points_type);
31
32 /**********************************************************************
33
PARAMETRIC FORM SPECIFICATION
34 **********************************************************************/
35
// P(Die)
36
plProbValue Die_table[] = {0.36, 0.64};
37
plProbTable P_Die(Die, Die_table);
38
39
// Distributions of dice 0
40
plProbValue distDie0[] = {0.3, 0.2, 0.1, 0.1, 0.2, 0.1};
41
42
// The conditional distribution P(Points | Die)
43
plDistributionTable P_PointsKDie(Points,Die);
44
45
P_PointsKDie.push(0,plProbTable(Points,distDie0));
46
P_PointsKDie.push(1,plUniform(Points)); // Die 1 is a symmetric die
47
48 /**********************************************************************
49
DECOMPOSITION
50 **********************************************************************/
51
// P(Die Points) = P(Die) P(Point | Die)
52
plJointDistribution jd(Die^Points, P_Die*P_PointsKDie);
53
jd.draw_graph("twoDice.fig");
54 /**********************************************************************
55
PROGRAM QUESTION
56 **********************************************************************/
57
plCndDistribution question, compiled_question;
58

5
0.2
0.16

6
0.1
0.16

16
59
60
61
62
63
64
65 }

CHAPTER 3. BAYESIAN NETWORKS


jd.ask(question, Die, Points);
// Compute P(Die | Points)
question.compile(compiled_question);
cout<<"Result\n";
cout<<compiled_question<<endl;
return 0;

Exercise 2: Compute P (Die = die|P oints = points) for all values of die
and points. Use the method compute and the class plValues to iterate Die
and P oints.
Exercise 3: Analyse the following code and explain the output.
74
75
76
77
78
79
80
81
82
83
84
85

//Exercise 2
plDistribution instantiated_question;
PntsDieValues.reset();
do {
question.instantiate(instantiated_question, PntsDieValues);
PntsDieValues.reset(Die);
do{
cout<<"P(Die="<<PntsDieValues[Die];
cout<<" | Points="<<PntsDieValues[Points]<<")= ";
cout<<instantiated_question.compute(PntsDieValues)<<endl;
}while(PntsDieValues.next(Die));
}while(PntsDieValues.next(Points));

Exercise 4: Compute P (P oints = points) for all values of P oints use the
class plValues to iterate points.

17

B
P (B | )
0
1
0.18 0.82

P (A | )
0
1
0.4 0.6
D

C
P (C | )
0
1
0.75 0.25
E
C
0
0
1
1

P (E | C D )
D
E
0
1
0 0.59 0.41
1 0.25 0.75
0 0.8
0.2
1 0.35 0.65

P (D | A B )
A B
D
0
1
0 0 0.6 0.4
0 1 0.3 0.7
1 0 0.1 0.9
1 1 0.5 0.5

Figure 3.3: A simple Bayesian network.

18

CHAPTER 3. BAYESIAN NETWORKS

Specification

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
:

8
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
<

8
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
<

Relevant Variables:
A, B, C, D, E IB
Decomposition:
P (A B C D E | ) =
P (A | )P (B | )P (C | )P (D | A B )P (E | C D )
Parametric Forms:
P (A | ) = {0.4, 0.6}
P (B | ) = {0.18, 0.82}
P (C | ) = {0.75,80.25}
>
9
>
>
>
>
> 0.6, 0.4 >
>
>
>
>
>
=
<
>
>
>
>
0.3, 0.7
>
>
>
>
|
A
B
)
=
P
(D
>
>
>
>
>
>
>
>
> 0.1, 0.9 >
>
>
;
:
>
>
>
>
>
>
8 0.5, 0.5
9
>
>
>
>
>
>
> 0.59, 0.41 >
>
>
>
>
>
>
<
=
>
>
>
>
0.25, 0.75
>
>
>
>
P
(E
|
C
D
)
=
>
>
>
>
>
>
>
> 0.80, 0.20 >
>
:
>
:
;
>
>
0.35, 0.65
>
>
>
>
>
: Identification:
All tables provided by the user
Question:
P (C B|[E = true] [D = f alse])

Description

BN () =

8
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
<

Figure 3.4: The Bayesian program specification of Figure 3.3.

19
Program 7:A simple bayesian network.

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

/*=======================================================================
* Product
:
* File
: BayesianNetwork.cpp
* Author
: Juan-Manuel Ahuactzin
* Creation
: 2004-Feb-05 15:51
*
*=======================================================================
*
(c) Copyright 2000, Centre National de la Recherche Scientifique,
*
all rights reserved
*=======================================================================
*
*------------------------- Description --------------------------------*
*
*----------------------------------------------------------------------*/
#include <pl.h>
#include <iostream>
using namespace std;
int main()
{
/**********************************************************************
VARIABLES SPECIFICATION
**********************************************************************/
plSymbol A("A",PL_BINARY_TYPE);
plSymbol B("B",PL_BINARY_TYPE);
plSymbol C("C",PL_BINARY_TYPE);
plSymbol D("D",PL_BINARY_TYPE);
plSymbol E("E",PL_BINARY_TYPE);
/**********************************************************************
PARAMETRIC FORM SPECIFICATION
**********************************************************************/
// Specification of P(A)
plProbValue tableA[] = {0.4, 0.6};
plProbTable P_A(A, tableA);
// Specification of P(B)
plProbValue tableB[] = {0.18, 0.82};
plProbTable P_B(B, tableB);
// Specification of P(C)
plProbValue tableC[] = {0.75, 0.25};
plProbTable P_C(C, tableC);
// Specification of P(D | A B)
plProbValue tableD_knowingA_B[] = {0.6, 0.4, // P(D
0.3, 0.7, // P(D
0.1, 0.9, // P(D
0.5, 0.5}; // P(D
plDistributionTable P_D(D,A^B,tableD_knowingA_B);

|
|
|
|

[A=f]^[B=f])
[A=f]^[B=t])
[A=t]^[B=f])
[A=t]^[B=t])

20

CHAPTER 3. BAYESIAN NETWORKS

54
55
// Specification of P(E | C D)
56
plProbValue tableE_knowingC_D[] = {0.59, 0.41, // P(E | [C=f]^[D=f])
57
0.25, 0.75, // P(E | [C=f]^[D=t])
58
0.8, 0.2,
// P(E | [C=t]^[D=f])
59
0.35, 0.65}; // P(E | [C=t]^[D=t])
60
plDistributionTable P_E(E,C^D,tableE_knowingC_D);
61
62
/**********************************************************************
63
DECOMPOSITION
64
**********************************************************************/
65
plJointDistribution jd(A^B^C^D^E, P_A*P_B*P_C*P_D*P_E);
66
jd.draw_graph("bayesian_network.fig");
67
cout<<"OK\n";
68
/**********************************************************************
69
PROGRAM QUESTION
70
**********************************************************************/
71
// Get the inferred conditional distribution representing P(C B | E D)
72
plCndDistribution CndP_CB;
73
jd.ask(CndP_CB, C^B, E^D);
74
75
// Create the value representing the evidence = [E=true]^[D=false]
76
plValues evidence(E^D);
77
evidence[E] = true;
78
evidence[D] = false;
79
80
// Get the distribution representing P(C B | [E=true]^[D=false] )
81
plDistribution P_CB;
82
CndP_CB.instantiate(P_CB,evidence);
83
84
// Get the normalized distribution representing P(C B | [E=true]^[D=false] )
85
plDistribution T_P_CB;
86
P_CB.compile(T_P_CB);
87
88
// Display the result
89
cout << T_P_CB << endl;
90
91
// On Windowx (Visual C++, MinGW, Borlan) only.
92 #if defined(WIN32) || defined(_WIN32)
93
cout << "Press any key to terminate..." << endl;
94
getchar();
95 #endif
96
97
return 0;
98 }

Exercise 5: Write a ProBT Bayesian Program for the water-sprinkler


model shown in Figure 3.5 and ask the question P (GC|W G = true S =
f alse).

21

Gray Clouds
(GC)

Sprinkler
(S)

P (GC | )
0
1
0.5
0.5

Rain
(R)

P (S | GC )
GC
S
0
1
0
0.5 0.5
1
0.9 0.1

Wet Grass
(WG)

P (R | GC )
GC
R
0
1
0
0.8
0.2
1
0.35 0.65

P (W G | S R )
R
WG
0
1
0 0 1.0
0.0
0 1 0.1
0.9
1 0 0.1
0.9
1 1 0.01 0.99

Figure 3.5: The water-sprinkler Bayesian network.

22

CHAPTER 3. BAYESIAN NETWORKS

Exercise 6: A complicated situation for Peter.


Peter will hold a party at home and he invited his best friends: Mary,
Alice, John, Victor, and Bill. Peter would like to have everyone at the party.
However, there are various factors that will influence the party attendance.
1. Mary, Alice, John, and Bill will accept the invitation in function of
different events.
John is rainophobe, if he receives the invitation on a rainy
day he will refuse it with a probability of 0.6. If he receives the
invitation on a non rainy day he will accept it with a probability
0.9.
Alice will accept a weekend invitation with a probability of 0.8
and a weekday invitation with a probability of 0.4.
Bill is a very busy man and will not accept a late invitation with
a probability 0.7. He will accept an in time invitation with a
probability of 0.95.
Mary best friends are John and Alice. Nevertheless, from Marys
point of view John and Alice are always fighting. Consequently,
Mary will accept the invitation with a probability 0.05 if both
John and Alice accepted the invitation. She will accept with a
probability of 0.95 if John accepted but Alice didnt. Similarly, if
Alice accepted but John didnt she will accept with a probability
of 0.85. If neither Alice nor John accepted then she will leave
that to chance by flipping a coin.
2. Victor lives with Peter and does not need to accept or refuse the invitation. However, the day of the party he will stay at home depending
on Alice and Bill response. In fact there is some competition between
Bill and Victor for Alice, consequently if both of them accepted then
Victor would be present. If this is not the case, he will decide between
staying at home and going to a pub for watching a football game. If
none of them accepted then he will stay at home with a probability of
0.7. If Alice accepted but Bill didnt then he will stays at home with
a probability of 0.9. If Bill accepted and Alice didnt then he will go
to the pub with a probability of 0.6.
3. One thing is to accept or to refuse the invitation and another thing is
to attend or not to the party. Except for Victor, everyone can change
his or her mind. Peter will accept the attendance of a friend even

23
if a he or she gave a negative response. In the past, Mary changed
her mind 3% of the time. If Alice accepted an invitation then you
can be sure at 80% that she will be present, if she refused then the
probabilities for attendance and non-attendance are equals.
4. John and Bill have extra constraints.
The day of the party John will not come if it rains and if he didnt
accept the invitation. However, in the past, when it was raining
and he accepted the invitation he showed up at the party 70% of
the time. If the day of the party is not raining and he refused the
invitation then he will show up at the party with a probability of
0.4; if he accepted then he will show up with a probability of 0.9.
Bill works at the hospital. Hence, if the day of the party there
is an emergency he will not come. If no emergency is present
and he accepted the invitation he will come with a probability
of 0.95; on the contrary, if he refused, then he will come with a
probability of 0.2.
5. The probability of rain is 0.22.
6. The probability of organizing the party at weekend is 0.28
7. The probability of receiving a late invitation is 0.3.
8. The probability of having an emergency at the hospital is 0.65
For the previous description:
i. Identify the variables of the problem
ii. Write Bayesian program: Description + Question. Where the question
is the probability of presence of each of the Peters friends.
iii. Draw the Bayesian network
iv. Write the expressions for the following questions:
(a) What is the probability that it was raining when John received
the invitation knowing that Mary didnt attend the party and
that the party is on Monday?

24

CHAPTER 3. BAYESIAN NETWORKS


(b) What is the probability that all Peters friends attend the party
knowing that it will take place on a sunny Saturday, knowing
that Bill received the invitation in time and no emergency was
present at the hospital?
(c) What is the probability that Alice, Victor and Bill attend the
party?
(d) Alice answer the phone at Peters house, Hi John. What is
the probability that Mary and Victor attended the party? (Note:
No, no, no, John is not calling from a cell phone).
v. Write the ProBT Bayesian program modeling the Peters problem and
solving the previous questions.

Program 8:The addition of two dice.


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

/*=======================================================================
* Product
:
* File
: addTwoDice.cpp
* Author
: Juan-Manuel Ahuactzin
* Creation
: 2008-Oct-02 17:27
*
*=======================================================================
*
(c) Copyright 2008, Probayes SAS,
*
all rights reserved
*=======================================================================
*
*------------------------- Description --------------------------------* This program shows the use of external functions by means of C++
* functions The construction of a functional dirac is also shown.
* The program gives the possible values of two dice given the sum of
* points.
*----------------------------------------------------------------------*/
#include <pl.h>
using namespace std;
void add_dice(plValues &addition, const plValues &die) {
addition[0] = die[0]+die[1];
}

int main()
{
/**********************************************************************
VARIABLES SPECIFICATION

25
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

**********************************************************************/
plIntegerType die_type(1,6);
// Type for a die [1,2,...,6]
plIntegerType dice_sum(2,12);
// Type for the sum [2,3,...,12]
plArray dice_set("Die",die_type,1,2); // Variable space for the dice
plSymbol points("Addition",dice_sum); // Variable space for the addition
plValues result(dice_set^points);

// Values storing the result of the


// dice and the addition
/**********************************************************************
PARAMETRIC FORM SPECIFICATION
**********************************************************************/
// Defining P(Die1 Die2) as an uniform distribution
plUniform p_dice(dice_set);
// Defining P(Addition | Die1 Die2) = 1 if
// Addition = add_dice(Die1,Die2) else 0
plExternalFunction sum(points,dice_set,add_dice);
plFunctionalDirac p_addition(points,dice_set,sum);
/**********************************************************************
DECOMPOSITION
**********************************************************************/
// Defining P(Die1 Die2 Addition) = P(Die1 Die2) P(Addition | Die1 Die2)
plJointDistribution dice_jd(dice_set^points,p_dice*p_addition);
/**********************************************************************
PROGRAM QUESTION
**********************************************************************/
plCndDistribution cnd_question;
plDistribution question;
int v;
// Get P(Die1 Die2 | Addition )
dice_jd.ask(cnd_question,dice_set,points);
cout<<"Give me the addition of the two dice: ";
result[points] = v;

cin>>v;

// Get P(Die1 Die2 | Addition=v)


cnd_question.instantiate(question,result);
question.tabulate(cout,false);
return 0;
}

Exercise 7: Modify the program addTwoDice.cpp so that it accepts a


number n of dice as input? That is, write a program to compute
P (P oints|Die1 Die2 ...Dien ).
Exercise 8:
For the Peters party model introduce a new variable N
representing the number of persons that attend the Party and compute:

26

CHAPTER 3. BAYESIAN NETWORKS


1. the probability distribution for the number of persons that attend the
party (plot the distribution),
2. the probability that it rained on the invitation day knowing that three
persons attended the party.

Consider that your fellow has a box with m dice; secretly she takes
N M dice and throw them on the table. She lets you know that the sum
of all points is s. What is the most probable number N of dice.
Program 9:How many dice do I have?.
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

/*=======================================================================
* Product
:
* File
: addDice3.cpp
* Author
: Juan-Manuel Ahuactzin
* Creation
: 2002-Oct-30 19:29
*
*=======================================================================
*
(c) Copyright 2008, Probayes SAS,
*
all rights reserved
*=======================================================================
*
*------------------------- Description --------------------------------* This program computes the more probable number of dice that where
* thrown given that we know the total number of points
*----------------------------------------------------------------------*/
#include <pl.h>
using namespace std;
#define SQRT_DIV35_12 1.7078251
// User function for computing the mean
void f_mean(plValues &mean, const plValues &n) {
mean[0] = 7*n[0]/2;
}
// User function for computing the standard deviation
void f_std(plValues &std, const plValues &n) {
std[0] = SQRT_DIV35_12*sqrt(double(n[0]));
}
int main()
{
/**********************************************************************
VARIABLES SPECIFICATION

27
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

**********************************************************************/
plIntegerType die_number(1,10);
// Type for the # of dice [1,2,...,100]
plIntegerType dice_sum(1,60);
// Type for the sum [2,3,...,n*6]
plSymbol points("Addition",dice_sum); // Variable space for the addition
plSymbol number("n",die_number);
// Variable space for the # of dice
plValues result(number^points);

// Values storing the # of dice


// and the addition

/**********************************************************************
PARAMETRIC FORM SPECIFICATION
**********************************************************************/
// P(number) = uniform(number)
plUniform p_number(number);
// Create the external functions to compute the mean and the
// standard deviation
plExternalFunction f_mu(number,f_mean);
plExternalFunction f_sigma(number,f_std);
// P(points | number) = CndBellShape(points,f_mu(number),f_sigma(number))
plCndBellShape p_addition(points,number,f_mu,f_sigma);
/**********************************************************************
DECOMPOSITION
**********************************************************************/
// P(points number) = P(points | number) P(number)
plJointDistribution dice_jd(number^points,p_number*p_addition);
/**********************************************************************
PROGRAM QUESTION
**********************************************************************/
plCndDistribution cnd_question;
plDistribution question;
int v;
// Get P(number | points)
dice_jd.ask(cnd_question,number,points);
cout<<"Give me the addition of the dice: ";
cin>>v;
result[points] = v;
// Get P(number | points = v)
cnd_question.instantiate(question,result);
plDistribution compiled_question;
question.compile(compiled_question);
cout << "The distribution is:\n" << compiled_question << endl;
compiled_question.best(result);
cout<<"\nThe more probable is: "<<result[number]<<"\n";
return 0;
}

28

CHAPTER 3. BAYESIAN NETWORKS

Chapter 4

Mixture models
Exercise 9: The population of a region on Equatorial Africa is composed
of a non-Pygmy majority (84%) and a substantial Pygmy minority (16%).
A non-pygmy adult has an average height of 1.55 meters with a standard
deviation of 7.5 cm. In contrast, a pygmy adult has an average height of
1.30 meters with a standard deviation of 9.5 cm. The distribution of height
is assumed to be Gaussian.
Compute P (Height) for this region of Equatorial Africa.

29

30

CHAPTER 4. MIXTURE MODELS

Chapter 5

Nave Bayes
P (D | M1 M2 ) =

P (D)P (M1 M2 | D)
P (M1 M2 )

P (D)P (M1 M2 | D) is the joint distribution P (D M1 M2 ) and P (M1 M2 )


is a constant without effect.
P (D M1 M2 ) = P (D)P (M1 M2 | D)

= P (D)P (M1 | D)P (M2 | D M1 ).

The naive conditional independence assumption consists in supposing that


M1 is conditionally independent of M2 . Other wise stated that:
P (M2 | D M1 ) = P (M2 | D).

The joint distribution of the same model with n sensors will be writen
as:
P (D M1 M2 ...Mn ) = P (D)P (M1 M2 ...Mn | D)

= P (D)P (M1 | D)P (M2 ...Mn | D M1 )

= P (D)P (M1 | D)P (M2 | D M1 )P (M3 ...Mn | D M1 )


..
.
= P (D)P (M1 | D)P (M2 | D M1 ) . . . P (Mn | D M1 M2 . . . Mn ).
31

CHAPTER 5. NAIVE BAYES

32

The assuming that each Mi is conditionally independent of every other Mj


with i #= j leads to:
P (D | M1 M2 ...Mn ) P (D)

n
!
i=1

P (Mi | D)

Program 10:A sensor fusion program.


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

/*=======================================================================
* Product
:
* File
: sensors.cpp
* Author
: Juan-Manuel Ahuactzin
* Creation
: Fri Nov 21 18:14:13 2008
*
*=======================================================================
*
(c) Copyright 2008, Probayes SAS,
*
all rights reserved
*=======================================================================
*
*------------------------- Description --------------------------------* This program simulates reading the distance of and object with two
* sensors. The two measures has a bellshape like distribution with
* two different variances. The goal is to find the more probable real
* distance
*----------------------------------------------------------------------*/
#define
#define
#define
#define

MIN_DIST 0
MAX_DIST 100
STD_DEV_1 10
STD_DEV_2 15

//#define MIN_MES_1 0
#define MIN_MES_1 (MIN_DIST-3*STD_DEV_1)
#define MAX_MES_1 (MAX_DIST+3*STD_DEV_1)
//#define MIN_MES_2 0
#define MIN_MES_2 (MIN_DIST-3*STD_DEV_2)
#define MAX_MES_2 (MAX_DIST+3*STD_DEV_2)
#include <pl.h>
using namespace std;
int main ()
{
/**********************************************************************
VARIABLES SPECIFICATION
**********************************************************************/
plIntegerType distance(MIN_DIST,MAX_DIST); // Distance type

33
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

plIntegerType measure1(MIN_MES_1,
MAX_MES_1);
plIntegerType measure2(MIN_MES_2,
MAX_MES_2);
plSymbol D("D",distance);
plSymbol M1("M1",measure1);
plSymbol M2("M2",measure2);

plVariable model_vars;
model_vars = D^M1^M2;

// Measure type for sensor 1


// Measure type for sensor 2

// Real distance variable


// sensor 1 measure
// sensor 2 measure

// The variables of the model are the distance {D}


// union measures 1 and 2 {M1, M2}

plValues model_values(model_vars);

// A variable values for storing


// our data
/**********************************************************************
PARAMETRIC FORM SPECIFICATION
**********************************************************************/
plUniform P_dist(D);
// D has an uniform distribution
plCndBellShape P_dist1(M1,D,STD_DEV_1); // M1 and M2 are bellshape like
plCndBellShape P_dist2(M2,D,STD_DEV_2); // distribution with a
// predefined variance
/**********************************************************************
DECOMPOSITION
**********************************************************************/
// Defining the joint distribution P(D M1 M2) = P(D) P(M1|D) P(M2|D)
plJointDistribution my_model(model_vars,P_dist*P_dist1*P_dist2);

/**********************************************************************
PROGRAM QUESTION
**********************************************************************/
//Ask P( D | M1 M2)
plCndDistribution P_Cnd_dist;
my_model.ask(P_Cnd_dist,D,M1^M2);
// Get P( D | M1 M2)
// Read measures from sensor A and B, then get P( D | M1=va M1=va)
int v1, v2;
do {
cout<<"Please enter the measure of sensor 1 : ";
cin>>v1;
}while (v1 < MIN_MES_1 || v1 > MAX_MES_1);
do {
cout<<"Please enter the measure of sensor 2 : ";
cin>>v2;
}while (v2 < MIN_MES_2 || v2 > MAX_MES_2);
model_values[M1]=v1;
model_values[M2]=v2;
plDistribution P_dist_after_measure;

CHAPTER 5. NAIVE BAYES

34

99
P_Cnd_dist.instantiate(P_dist_after_measure,
100 model_values);
//Get P( D | M1=v1 M2=v2)
101
102
P_dist_after_measure.best(model_values);
//Get the most probable distance
103
104
cout<<"\nThe more probable distance is : ";
105
cout<<model_values[D]<<"\n\n";
106
107
return 0;
108 }

Exercise 10: Add a third sensor to Program 10.


Program 11:spamer.cpp.
The spamer bayesian fusion (and not filter)
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

/*=======================================================================
* Product
:
* File
: spamer.cpp
* Author
: Juan-Manuel Ahuactzin
* Creation
: Wed Mar 19 09:47:59 2004
*
*=======================================================================
*
(c) Copyright 2000, Centre National de la Recherche Scientifique,
*
all rights reserved
*=======================================================================
*
*------------------------- Description --------------------------------* This is the spamer Bayesian program presented in the first chapter
* of the book.
*----------------------------------------------------------------------*/
#include
#include
#include
#include

<pl.h>
<map>
<vector>
<spamer_dictionary.h>

using namespace std;

int main(int argc, char **argv) {


unsigned int i;
if (argc < 3 || argc > 3){
cout<<"Ussage: spam <dictionary filename> <filename>\n";
cout<<"Example: spamer spamer.dico spam_test1.txt \n";
exit(1);
}

35
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

// Set the spamer dictionary from the indicated file


spamer_dictionary my_dictionary(argv[1]);
/**********************************************************************
VARIABLES SPECIFICATION
**********************************************************************/
plSymbol Spam("Spam",PL_BINARY_TYPE);
plArray W("W",PL_BINARY_TYPE,1,my_dictionary.get_number_of_words());
/**********************************************************************
PARAMETRIC FORM SPECIFICATION
**********************************************************************/
// Construct P(Spam) from the the data on the dictionary
plProbTable P_Spam(Spam,my_dictionary.spams);
// A tabable containing all the P(Wi | Spam)
vector <plDistributionTable> P_W(my_dictionary.get_number_of_words());
// A list containig the product of
//
P(W0 | Spam)*P(W1 | Spam)*...P(Wn | Spam)
plComputableObjectList all_PW;
// Construct each of the P(Wi | Spam) from the data on the dictionary
for (i=0; i<my_dictionary.get_number_of_words();i++) {
P_W[i] =
plDistributionTable(W(i),Spam,my_dictionary.laplace_distribution[i]);
all_PW *= P_W[i];
cout<<P_W[i]<<endl;
}
/**********************************************************************
DECOMPOSITION
**********************************************************************/
// Construct
// P(Spam W1 W2 ... Wn) =
//
P(Spam)P(W0 | Spam)P(W1 | Spam)...P(Wn | Spam)
plJointDistribution jd(Spam^W,P_Spam*all_PW);
/**********************************************************************
PROGRAM QUESTION
**********************************************************************/
// Values storing W0 W2 W3
plValues W_values(W);
// Conditional distribution to store P(Spam | W0 W1 ....Wn)
plCndDistribution CndQuestion;
// Distributions used to storeP(Spam | W0=w0 W1=w1 ....Wn=wn)
plDistribution Question;
plDistribution CompiledQuestion;
// Ask P(Spam | W0 W1 ....Wn)
jd.ask(CndQuestion,Spam,W);
// Set the values of W0 W1 ....Wn from the file to be analized
my_dictionary.set_values_from_file(argv[2],W_values);

CHAPTER 5. NAIVE BAYES

36
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

// Instantiate and compile the question


CndQuestion.instantiate(Question,W_values);
Question.compile(CompiledQuestion);
// Display the result
cout<<W_values<<" ";
cout<<CompiledQuestion<<endl;
// Ask if all possibilities sould be displayed
char response;
cout<<"Display all posibilities of P(Spam | W0 W1 ....Wn) ? (y/n) :";
cin>>response;
if (response == y || response== Y)
{
W_values.reset();
do{
// Instantiate and compile the question
CndQuestion.instantiate(Question,W_values);
Question.compile(CompiledQuestion);
// Display the result
cout<<W_values<<" ";
cout<<CompiledQuestion.compute(0)<<" "<<CompiledQuestion.compute(1)<<endl;
}while(W_values.next());
}
return 0;
}

Chapter 6

Dynamic Bayesian
Programming
6.1

Bayesian filters

Exercise 11: Use Program 9 to write a program that accepts a sequence


of throws of N dice with N 6. That is, your fellow takes the N dice
and throw them t times. She let you know the number of points for each of
the throws (without changing the number of dice). Write a ProBT program
computing P (N | points1 points2 ... pointst).

6.2

Hidden Markov Models

For the previous exercise, consider that the number of dice from throw i
to throw i + 1 could change according to a random hidden variable Action.
The hiden variable Action indicates one of three cases: add one die, take
out one die or stay with the same number of dice. Given a sequence of
number of points (corresponding to throwing the dice t times) we wold like
to computes the more probable number of dice at throw 1, 2, ..., t. Otherwise
stated, P (Nt | ponts1 points2 ...pointsn ) is to be computed. The bayesian
network representing this model is shown in Figure 6.1. The distribution
of P (Nt | Nt1 Action ) and that of P (Action) are shown in Figure 6.2.
Assume that the initial number of dice (N0 ) is 3.

37

38

CHAPTER 6. DYNAMIC BAYESIAN PROGRAMMING


Program 12:The dice Hidden Markov Model.

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

/*=======================================================================
* Product
:
* File
: diceHMM.cpp
* Author
: Juan-Manuel Ahuactzin
* Creation
: 2008-Oct-02 16:16
*
*=======================================================================
*
(c) Copyright 2008, Probayes SAS,
*
all rights reserved
*=======================================================================
*
*------------------------- Description --------------------------------* Given a sequence of number of points (corresponding to throwing the
* dice t times). This program computes the more probable number of dice
* at throw 1,2,...,t. The number of dice from throw i to throw i+1
* could change according to a random hidden variable "Action". The hiden
* variable "Action" indicates one of three cases: add one die, reduce one
* die or stay with the same number of dice.
*----------------------------------------------------------------------*/
#include <pl.h>
using namespace std;
#define SQRT_DIV35_12 1.7078251
// User function for computing the mean
void f_mean(plValues &mean, const plValues &n) {
mean[0] = 7*n[0]/2;
}
// User function for computing the standard deviation
void f_std(plValues &std, const plValues &n) {
std[0] = SQRT_DIV35_12*sqrt(double(n[0]));
}
const unsigned int max_n = 6;
int main()
{
/**********************************************************************
VARIABLES SPECIFICATION
**********************************************************************/
plIntegerType die_number(1,max_n);
// Type for the maximum number
// of dice [1,2,...,max_n]
plIntegerType dice_sum(1,max_n*6);
// Type for the sum [2,3,...,n*6]
plIntegerType HiddenVarType (-1, 1);
// The type for the hidden variable
plSymbol Points("Points",dice_sum); // Variable space for the addition
plSymbol Previous_N("Prev_N",die_number);// Previous number of dice

6.2. HIDDEN MARKOV MODELS

39

54
plSymbol Current_N("Curr_N",die_number); // Current number of dice
55
56
plSymbol Action("Action", HiddenVarType); // The hidden variable
57
58
plValues result(Current_N^Points);
// Values storing the # of dice
59
// and the addition
60 /**********************************************************************
61
PARAMETRIC FORM SPECIFICATION
62
**********************************************************************/
63
// P(Prevoius_N) at the begining we start with 3 dice
64
plProbValue tablePrevious[] = {0.0, 0.0, 1.0, 0.0, 0.0, 0.0};
65
plProbTable P_Previous_N(Previous_N, tablePrevious);
66
67
plProbValue tableAction[] = {0.333, 0.166, 0.5};
68
plProbTable P_Action(Action, tableAction);
69
70
71
plProbValue tableCurrent_N[] =
72
{ 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, // N=1 A = -1
73
1.0, 0.0, 0.0, 0.0, 0.0, 0.0, // N=1 A = 0
74
0.0, 1.0, 0.0, 0.0, 0.0, 0.0, // N=1 A = 1
75
1.0, 0.0, 0.0, 0.0, 0.0, 0.0, // N=2 A = -1
76
0.0, 1.0, 0.0, 0.0, 0.0, 0.0, // N=2 A = 0
77
0.0, 0.0, 1.0, 0.0, 0.0, 0.0, // N=2 A = 1
78
0.0, 1.0, 0.0, 0.0, 0.0, 0.0, // N=3 A = -1
79
0.0, 0.0, 1.0, 0.0, 0.0, 0.0, // N=3 A = 0
80
0.0, 0.0, 0.0, 1.0, 0.0, 0.0, // N=3 A = 1
81
0.0, 0.0, 1.0, 0.0, 0.0, 0.0, // N=4 A = -1
82
0.0, 0.0, 0.0, 1.0, 0.0, 0.0, // N=4 A = 0
83
0.0, 0.0, 0.0, 0.0, 1.0, 0.0, // N=4 A = 1
84
0.0, 0.0, 0.0, 1.0, 0.0, 0.0, // N=5 A = -1
85
0.0, 0.0, 0.0, 0.0, 1.0, 0.0, // N=5 A = 0
86
0.0, 0.0, 0.0, 0.0, 0.0, 1.0, // N=5 A = 1
87
0.0, 0.0, 0.0, 0.0, 1.0, 0.0, // N=6 A = -1
88
0.0, 0.0, 0.0, 0.0, 0.0, 1.0, // N=6 A = 0
89
0.0, 0.0, 0.0, 0.0, 0.0, 1.0, // N=6 A = 1
90
};
91
plDistributionTable P_Current_N(Current_N, Previous_N^Action, tableCurrent_N);
92
93
cout<<P_Current_N<<endl;
94
95
// Create the external functions to compute the mean and the
96
// standard deviation
97
plExternalFunction f_mu(Current_N,f_mean);
98
plExternalFunction f_sigma(Current_N,f_std);
99
100
// P(Points | Current_N)
101
//
= CndBellShape(Points,f_mu(Current_N), f_sigma(Current_N))
102
plCndBellShape P_addition(Points,Current_N,f_mu,f_sigma);
103
104 /**********************************************************************
105
DECOMPOSITION
106 **********************************************************************/
107
// P(Points Current_N) = P(Points | Current_N) P(Current_N)
108
plJointDistribution dice_jd(Previous_N^Action^Current_N^Points,
109
P_Previous_N*P_Action*P_Current_N*P_addition);

40

CHAPTER 6. DYNAMIC BAYESIAN PROGRAMMING

110
111 /**********************************************************************
112
PROGRAM QUESTION
113 **********************************************************************/
114
plCndDistribution cnd_question;
115
plDistribution question;
116
int v;
117
118
// Get P(Current_N | Points)
119
dice_jd.ask(cnd_question,Current_N,Points);
120
121
unsigned int n=0;
122
123
cout<<"Give me the number of throws? ";
124
cin>>n;
125
126
do {
127
n--;
128
cout<<"Give me the number of points: ";
129
cin>>v;
130
result[Points] = v;
131
132
// Get P(Current_N | Points = v)
133
cnd_question.instantiate(question,result);
134
plDistribution compiled_question;
135
136
question.compile(compiled_question);
137
cout << "The distribution is:\n" << compiled_question << endl;
138
compiled_question.best(result);
139
140
cout<<"\nThe more probable is: "<<result[Current_N]<<"\n";
141
142
compiled_question.rename(Previous_N);
143
cnd_question.replace(Previous_N, compiled_question);
144
145
} while (n > 0);
146
147
return 0;
148 }

41

6.2. HIDDEN MARKOV MODELS

Actiont

Nt1

Nt

P ointst
Figure 6.1: The dice Hidden Markov Model.

42

CHAPTER 6. DYNAMIC BAYESIAN PROGRAMMING

Nt1
1
1
1
2
2
2
3
3
3
4
4
4
5
5
5
6
6
6

P (Nt | Nt1
Action
1
-1
1
0
1
1
0
-1
1
0
0
1
0
-1
0
0
0
1
0
-1
0
0
0
1
0
-1
0
0
0
1
0
-1
0
0
0
1
0

Action )
Nt
2 3 4
0 0 0
0 0 0
1 0 0
0 0 0
1 0 0
0 1 0
1 0 0
0 1 0
0 0 1
0 1 0
0 0 1
0 0 0
0 0 1
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0

5
0
0
0
0
0
0
0
0
0
0
0
1
0
1
0
1
0
0

6
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
1
1

P (Action)
-1
0
1
0.333 0.166 0.5

Figure 6.2: The distributions P (Nt | Nt1 Action ) and P (Action) used for
the Bayesian Network on Figure 6.1.

Appendix A

Answers to exercises
Exercise 1: For each one of the cases, Line 20 of program dice.cpp must
be changed as shown below:
i. plArray dice_set("Die",die_type,1,2);
ii. plArray dice_set("Die",die_type,1,5);
iii. plArray dice_set("Die",die_type,2,3,5);
iv. plArray dice_set("Die",die_type,3,3,5,2);
Exercise 2: Add the following code at the end of the file twoDice.cpp:
plValues PntsDieValues(Points^Die);
PntsDieValues.reset();
do{
cout<<"P(Die="<<PntsDieValues[Die];
cout<<" | Points="<<PntsDieValues[Points]<<")= ";
cout<<question.compute(PntsDieValues)<<endl;
}while(PntsDieValues.next());
Exercise 3: The output is similar to that of Exercise 2 however, in this
case the resulting probabilities are not normalized.
Output for Exercise 2:
P(Die=0 | Points=1)= 0.503106
P(Die=1 | Points=1)= 0.496894
P(Die=0 | Points=2)= 0.402985
43

44

APPENDIX A. ANSWERS TO EXERCISES

P(Die=1
P(Die=0
P(Die=1
P(Die=0
P(Die=1
P(Die=0
P(Die=1
P(Die=0
P(Die=1

|
|
|
|
|
|
|
|
|

Points=2)=
Points=3)=
Points=3)=
Points=4)=
Points=4)=
Points=5)=
Points=5)=
Points=6)=
Points=6)=

0.597015
0.252336
0.747664
0.252336
0.747664
0.402985
0.597015
0.252336
0.747664

Output for Exercise 3:


P(Die=0
P(Die=1
P(Die=0
P(Die=1
P(Die=0
P(Die=1
P(Die=0
P(Die=1
P(Die=0
P(Die=1
P(Die=0
P(Die=1

|
|
|
|
|
|
|
|
|
|
|
|

Points=1)=
Points=1)=
Points=2)=
Points=2)=
Points=3)=
Points=3)=
Points=4)=
Points=4)=
Points=5)=
Points=5)=
Points=6)=
Points=6)=

0.108
0.106667
0.072
0.106667
0.036
0.106667
0.036
0.106667
0.072
0.106667
0.036
0.106667

Exercise 4:
plDistribution question2;
jd.ask(question2, Points);
cout<<question2<<endl;
pvalues.reset();
do{
cout<<"P("<<pvalues[Points]<<")= "<<question2.compute(pvalues)<<endl;
}while(pvalues.next(Points));

45
Exercise 5:
Program 13:The water-sprinkler program.
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

/*=======================================================================
* Product
:
* File
: sprinkler.cpp
* Author
: Juan-Manuel Ahuactzin
* Creation
: Fri Nov 21 18:06:08 2008
*
*=======================================================================
*
(c) Copyright 2008, Probayes SAS,
*
all rights reserved
*=======================================================================
*
*------------------------- Description --------------------------------* This contains the water-sprinkler model
*----------------------------------------------------------------------*/
#include <pl.h>
#include <iostream>
using namespace std;
int main() {
/**********************************************************************
VARIABLES SPECIFICATION
**********************************************************************/
plSymbol GC("GC",PL_BINARY_TYPE);
plSymbol R("R",PL_BINARY_TYPE);
plSymbol WG("WG",PL_BINARY_TYPE);
plSymbol S("S",PL_BINARY_TYPE);
/**********************************************************************
PARAMETRIC FORM SPECIFICATION
**********************************************************************/
plProbValue T_GC[] = {0.5, 0.5};
plProbTable P_GC(GC,T_GC);
plProbValue T_R[] = {0.8, 0.2,
0.35, 0.65};
plDistributionTable P_R(R,GC,T_R);
plProbValue T_S[] = {0.5, 0.5,
0.9, 0.1};
plDistributionTable P_S(S,GC,T_S);
plProbValue T_WG[] = {1.0, 0.0,
0.1, 0.9,
0.1, 0.9,
0.01, 0.99};
plDistributionTable P_WG(WG,S^R,T_WG);
/**********************************************************************

46

APPENDIX A. ANSWERS TO EXERCISES

52
DECOMPOSITION
53 **********************************************************************/
54
plJointDistribution jd(GC^R^S^WG, P_GC*P_R*P_S*P_WG);
55
56 /**********************************************************************
57
PROGRAM QUESTION
58 **********************************************************************/
59
plCndDistribution question;
60
plDistribution inst_question, comp_question;
61
62
jd.ask(question, GC, WG^S);
63
64
plValues evidence(WG^S);
65
evidence[WG] = true;
66
evidence[S] = false;
67
68
question.instantiate(inst_question, evidence);
69
inst_question.compile(comp_question);
70
71
cout<<" Result of "<<question<<endl;
72
cout<<endl<<comp_question<<endl;
73 }

The output of the program and solution to the question P (GC|W G =


true S = f alse) is the following:
Result of P(GC|WG S) =
{ { { P(GC)Sum_{R} {P(R|GC)P(WG|S R) } P(S|GC) } } /
{ { Sum_{GC} {P(GC)Sum_{R} {P(R|GC)P(WG|S R) } P(S|GC) }
P(GC) =
GC
0
1

Probability
0.145985
0.854015

Exercise 6:
i. The variables are the following:
RI Rain on invitations day
RP Rain on Partys day

We Invitation for aWeekend

LI Late invitation

} }

47
E Emergency

JA John accepted

MA Mary accepted

AA Alice accepted

BA Bill accepted

JP John is present

MP Mary is present

AP Alice is present

VP Victor is present

BP Bill is present

ii. The Bayesian program for Peters party is show in Figure A.1
8
Relevant Variables:
>
>
>
>
RI , RP, We, LI , E , JA, MA, AA, BA, JP , MP , AP , VP, BP
>
>
>
>
Decomposition:
>
>
>
>
P (RI RP W e LI E JA M A AA BA JP M P AP V P BP | ) =
>
>
>
<
P (RI | )P (RP | )P (We | )P (LI | )P (E | )
>
P (JA | RI )P (BA | LI )P (AA | We )P (AP | AA )
>
>
Decomposition
>
>
>
P
(MA | JA AA )P (MP | MA )P (VP | AA BA )
>
>
>
>
>
>
>
>
>
>
P
(JP
| JA RP )P (BP | BA E )
>
>
>
>
>
>
>
>
Parametric
Forms:
>
>
:
>
>
>
See FigureA.2
>
>
>
>
Identification:
>
:
All tables provided by the user
Question:
P (JP MP AP VP BP | )

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
:

8
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
<

Specification

Description

P artyBN () =

8
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
<

Figure A.1: Peters party Bayesian program. The variables are Rain on
invitations day (RI ), Rain on Partys day (RP ), Weekend invitation (We),
Late invitation (LI ), Emergency (E ), John accepted (JA), Mary accepted
(MA), Alice accepted (AA),Bill accepted (BA), John is present (JP ), Mary
is present (MP ), Alice is present (AP ), Victor is present (VP ), Bill is present
(BP )
iii. The Bayesian network is shown in Figure A.3
iv. The expressions for the questions are:

48

APPENDIX A. ANSWERS TO EXERCISES

P (RI | )
0
1
0.78 0.22

P (RP | )
0
1
0.78 0.22

P (E | )
0
1
0.35 0.65

P (JA | RI )
RI
JA
0
1
0 0.1 0.9
1 0.6 0.4

P (AP | AA )
AA
AP
0
1
0
0.5 0.5
1
0.2 0.8

P (We | )
0
1
0.72 0.28

P (BA | LI )
LI
BA
0
1
0 0.05 0.95
1
0.7
0.3

P (MA | JA AA )
JA AA
MA
0
1
0
0
0.5
0.5
0
1
0.15 0.85
1
0
0.05 0.95
1
1
0.95 0.05

P (VP | AA BA )
AA BA
VP
0
1
0
0
0.3 0.7
0
1
0.6 0.4
1
0
0.1 0.9
1
1
0.0 1.0

P (LI | )
0
1
0.7 0.3

P (JP | JA RP )
JA RP
JP
0
1
0
0
0.6 0.4
0
1
1.0 0.0
1
0
0.1 0.9
1
1
0.3 0.7

P (AA | We )
We
AA
0
1
0
0.6 0.4
1
0.2 0.8

P (MP | MA )
MA
MP
0
1
0
0.97 0.03
1
0.03 0.97

P (BP | BA E )
BA E
BP
0
1
0
0 0.8
0.2
0
1 1.0
0.0
1
0 0.05 0.95
1
1 1.0
0.0

Figure A.2: Parametrical forms of Peters party Bayesian program (See


Figure A.1).

49
It rains the
day of the
invitation

Invitation
on weekend

Late invitation

John
accepted

Alice
accepted

Bill
accepted

It rains the
day of the
party

Urgency in
the hospital

Mary
accepted

John is present

Mary is present

Alice is present

Victor is present

Bill is present

Figure A.3: The Peters party Bayesian network.

(a) What is the probability that it was raining when John received
the invitation knowing that Mary didnt attend the party and
that the party is on Monday?
P (RI = true | MP = true We = false )
(b) What is the probability that all Peters friends attend the party
knowing that it will take place on a sunny Saturday, knowing
that Bill received the invitation in time and no emergency was
present at the hospital?
P (JP = true MP = true AP = true AP = true BP = true |RP = false We = true LI = false E = false )

(c) What is the probability that Alice, Victor and Bill attend the
party?
P (AP = true VP = true BP = true | )

50

APPENDIX A. ANSWERS TO EXERCISES


(d) Alice answer the phone at Peters house, Hi John. What is
the probability that Mary and Victor attended the party? (Note:
No, no, no, John is not calling from a cell phone).
P (MP = true VP = true | AP = true JP = false )
v. The ProBT Bayesian program modeling the Peters problem appears
below:

51
Program 14:Peters problem .

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

/*=======================================================================
* Product
:
* File
: PartyBN.cpp
* Author
: Juan-Manuel Ahuactzin
* Creation
: Wed Nov 26 16:54:59 2008
*
*=======================================================================
*
(c) Copyright 2008, Probayes SAS,
*
all rights reserved
*=======================================================================
*
*------------------------- Description --------------------------------* This program solves the Peters party problem
*----------------------------------------------------------------------*/
#include <pl.h>
#include <iostream>
using namespace std;
int main() {
/**********************************************************************
VARIABLES SPECIFICATION
**********************************************************************/
plSymbol RainOnInv("RainOnInv", PL_BINARY_TYPE);
plSymbol RainOnParty("RainOnParty",PL_BINARY_TYPE);
plSymbol WE_Invitation("WE_Invitation",PL_BINARY_TYPE);
plSymbol LateInv("LateInv",PL_BINARY_TYPE);
plSymbol Emergency("Emergency",PL_BINARY_TYPE);
plSymbol JohnAccepted("JohnAccepted",PL_BINARY_TYPE);
plSymbol MaryAccepted("MaryAccepted",PL_BINARY_TYPE);
plSymbol AliceAccepted("AliceAccepted",PL_BINARY_TYPE);
plSymbol BillAccepted("BillAccepted",PL_BINARY_TYPE);
plSymbol JohnIsPresent("JohnIsPresent",PL_BINARY_TYPE);
plSymbol MaryIsPresent("MaryIsPresent",PL_BINARY_TYPE);
plSymbol AliceIsPresent("AliceIsPresent",PL_BINARY_TYPE);
plSymbol VictorIsPresent("VictorIsPresent",PL_BINARY_TYPE);
plSymbol BillIsPresent("BillIsPresent",PL_BINARY_TYPE);
/**********************************************************************
PARAMETRIC FORM SPECIFICATION
**********************************************************************/
plProbValue tableRain[] = {0.78, 0.22};
plProbTable P_RI(RainOnInv, tableRain);
cout<<P_RI<<endl;
plProbTable P_RP(RainOnParty, tableRain);
cout<<P_RP<<endl;
plProbValue tableWE[] = {0.72, 0.28};
plProbTable P_WE(WE_Invitation, tableWE);

52

APPENDIX A. ANSWERS TO EXERCISES


54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

cout<<P_WE<<endl;
plProbValue tableLateInv[] = {0.7, 0.3};
plProbTable P_Late(LateInv, tableLateInv);
cout<<P_Late<<endl;
plProbValue tableEmergency[] = {0.35, 0.65};
plProbTable P_Emergency(Emergency, tableEmergency);
cout<<P_Emergency<<endl;
plProbValue tableJA[] = {0.1, 0.9,
0.6, 0.4};
plDistributionTable P_JA(JohnAccepted, RainOnInv, tableJA);
cout<<P_JA<<endl;
plProbValue tableAA[] = {0.6, 0.4,
0.2, 0.8};
plDistributionTable P_AA(AliceAccepted, WE_Invitation, tableAA);
cout<<P_AA<<endl;
plProbValue tableBA[] = {0.05, 0.95,
0.7, 0.3};
plDistributionTable P_BA(BillAccepted, LateInv, tableBA);
cout<<P_BA<<endl;
plProbValue tableMA[] = {0.5, 0.5,
0.15, 0.85,
0.05, 0.95,
0.95, 0.05};
plDistributionTable P_MA(MaryAccepted, JohnAccepted^AliceAccepted, tableMA);
cout<<P_MA<<endl;
plProbValue tableJP[] = {0.6, 0.4,
1.0, 0.0,
0.1, 0.9,
0.3, 0.7};
plDistributionTable P_JP(JohnIsPresent, JohnAccepted^RainOnParty, tableJP);
cout<<P_JP<<endl;
plProbValue tableMP[] = {0.97, 0.03,
0.03, 0.97};
plDistributionTable P_MP(MaryIsPresent, MaryAccepted, tableMP);
cout<<P_MP<<endl;
plProbValue tableAP[] = {0.5, 0.5,
0.2, 0.8};
plDistributionTable P_AP(AliceIsPresent, AliceAccepted, tableAP);
cout<<P_AP<<endl;
plProbValue tableVP[] = {0.3, 0.7,
0.6, 0.4,
0.1, 0.9,
0.0, 1.0};
plDistributionTable P_VP(VictorIsPresent,AliceAccepted^BillAccepted, tableVP);
cout<<P_VP<<endl;

53
110
plProbValue tableBP[] = {0.8, 0.2,
111
1.0, 0.0,
112
0.05, 0.95,
113
1.0, 0.0};
114
plDistributionTable P_BP(BillIsPresent, BillAccepted^Emergency, tableBP);
115
cout<<P_BP<<endl;
116
117 /**********************************************************************
118
DECOMPOSITION
119 **********************************************************************/
120
plVariable Aleas(RainOnParty^RainOnInv^WE_Invitation^LateInv^Emergency);
121
plVariable Acceptations(JohnAccepted^MaryAccepted^AliceAccepted
122
^BillAccepted);
123
plVariable Presence(JohnIsPresent^MaryIsPresent^AliceIsPresent^
124
VictorIsPresent^BillIsPresent);
125
plVariable AllVars(Aleas^Acceptations^Presence);
126
127
plJointDistribution jd(AllVars,P_RI*P_RP*P_WE*P_Late*P_Emergency*P_JA
128 *P_AA*P_BA*P_MA*P_JP*P_MP*P_AP*P_VP*P_BP);
129
130
jd.draw_graph("party_network.fig");
131 /**********************************************************************
132
PROGRAM QUESTION
133
**********************************************************************/
134
plCndDistribution Question;
135
plDistribution InstQuest;
136
plDistribution Result;
137
138
plValues values(AllVars);
139
140
// Question 1
141
jd.ask(Question,RainOnInv, MaryIsPresent^WE_Invitation);
142
143
values[MaryIsPresent]=false;
144
values[WE_Invitation]=false;
145
146
Question.instantiate(InstQuest, values);
147
InstQuest.compile(Result);
148
149
values[RainOnInv]=1;
150
151
cout<<"Sol1 = "<<Result.compute(values)<<endl;
152
153
// Question 2
154
jd.ask(Question, Presence, WE_Invitation^LateInv^RainOnParty^Emergency);
155
156
values[WE_Invitation]=true;
157
values[RainOnParty]=false;
158
values[Emergency]=false;
159
values[LateInv]=false;
160
161
Question.instantiate(InstQuest, values);
162
InstQuest.compile(Result);
163
164
values[JohnIsPresent]=true;
165
values[MaryIsPresent]=true;

54

APPENDIX A. ANSWERS TO EXERCISES


166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197 }

values[AliceIsPresent]=true;
values[BillIsPresent]=true;
values[VictorIsPresent]=true;
cout<<"Sol2 = "<<Result.compute(values)<<endl;
// Question 3
jd.ask(InstQuest, AliceIsPresent^VictorIsPresent^BillIsPresent);
InstQuest.compile(Result);
values[AliceIsPresent]=true;
values[VictorIsPresent]=true;
values[BillIsPresent]=true;
cout<<"Sol3 = "<<Result.compute(values)<<endl;
// Question 4
jd.ask(Question, MaryIsPresent^VictorIsPresent, AliceIsPresent^JohnIsPresent);
values[AliceIsPresent]=true;
values[JohnIsPresent]=false;
Question.instantiate(InstQuest, values);
InstQuest.compile(Result);
values[MaryIsPresent]=true;
values[VictorIsPresent]=true;;
cout<<"Sol4 = "<<Result.compute(values)<<endl;

The solutions to the questions are the followings:


Sol1
Sol2
Sol3
Sol4

=
=
=
=

0.210056
0.0982558
0.136578
0.425597

55
Exercise 7:
Program 15:The sum of N dice.
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

/*=======================================================================
* Product
:
* File
: addDice.cpp
* Author
: Juan-Manuel Ahuactzin
* Creation
: 2002-Oct-30 19:29
*
*=======================================================================
*
(c) Copyright 2008, Probayes SAS,
*
all rights reserved
*=======================================================================
*
*------------------------- Description --------------------------------* This program shows the use of external functions by means of C++ functions
* The construction of a functional dirac is also shown.
* The program gives the possible values of each of the dice given the sum of
* points.
*----------------------------------------------------------------------*/
#include <pl.h>
using namespace std;
void add_dice(plValues &dice_addition, const plValues &die) {
unsigned int n_dice;
// Number of dice
unsigned int sum=0;
// sum of points
unsigned int i;
n_dice = die.size();

// Get the number of dice

for(i=0;i<n_dice;i++)
sum = sum+die[i];

// Compute the sum of points

dice_addition[0] = sum;

// Set the output values

int main()
{
/**********************************************************************
Defining the variable type, set and values plus the distribution for the
variable set
***********************************************************************/
unsigned int number_of_dice;

// Stores the number of dice

cout<<"Give me the number of dice: ";


cin>>number_of_dice;
plIntegerType die_type(1,6);
// die type [1,2,...,6]
plIntegerType dice_sum(number_of_dice,

56

APPENDIX A. ANSWERS TO EXERCISES

52 number_of_dice*6);// Sum type [n,n+1,...,n*6]


53
plSymbol points("Addition",dice_sum); // Variable space for the addition
54
plArray dice("Die",die_type,1,
55
number_of_dice);
// Variable space for the dice
56
57
plValues result(dice^points);
// Values storing the result of the
58
// dice and the addition
59
60
/**********************************************************************
61
Writing the joint distribution
62
***********************************************************************/
63
64
// P(Die0 Die1 ... Die(n-1)) = Uniform(Die0 Die1 ... Die(n-1))
65
plUniform p_dice(dice);
66
67
// Create the external function
68
plExternalFunction sum(points,dice,add_dice);
69
70
// P(points=p | Die0=die0 Die1=die1 ... Die(n-1)=die(n-1)) =
71
//
1 if points = add_dice(die0,die1,...,die(n-1)) else 0
72
plFunctionalDirac p_addition(points,dice,sum);
73
74
// P(Die0 Die1...Die(n-1) points)=
75
//
P(Die0 Die1 ... Die(n-1))
76
//
P(points | Die0 Die1...Die(n-1))
77
plJointDistribution dice_jd(dice^points,p_dice*p_addition);
78
79
/**********************************************************************
80
Making a question P(Die0 Die1 ... Die(n-1)| points = v)
81
***********************************************************************/
82
83
plCndDistribution cnd_question;
84
plDistribution question;
85
int v;
86
87
// Get P(Die0 Die1 ... Die(n-1) | points )
88
dice_jd.ask(cnd_question,dice,points);
89
cout<<"Give me the total number of points: ";
90
cin>>v;
91
result[points] = v;
92
93
// Get P(Die0 Die1 ... Die(n-1) | points=v)
94
cnd_question.instantiate(question,result);
95
96
/**********************************************************************
97
Tabulate the result of the question
98
***********************************************************************/
99
100
cout<<"\nThe possibilities are :\n";
101
question.tabulate(cout,false);
102 }

57
Exercise 8: At the beginning of Program 14 (before the main) add the
following lines:
void f_N_persons(plValues &tot_attended, const plValues &attended) {
unsigned int i, n;
// Count the total number of persons who attended the party
n = 0;
for(i=0; i<attended.size(); i++) {
if (attended[i] != 0)
n++;
}
// set the total number of persons who attended to n
tot_attended[0] = n;
}

then add the following lines at the end of the program:


plDistribution Question, comp_question;
jd.ask(Question,Attendance);
Question.compile(comp_question);
comp_question.plot("attendance.gnu");
cout<<comp_question<<endl;

58

APPENDIX A. ANSWERS TO EXERCISES

Exercise 9:
Program 16:The pygmy mixture model (Estimated programming
time: 25 minuts).
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

/*=======================================================================
* Product
:
* File
: pygmy.cpp
* Author
: Juan-Manuel Ahuactzin
* Creation
: Jauary 2006
*
*=======================================================================
*
(c) Copyright 2008, Probayes SAS,
*
all rights reserved
*=======================================================================
*
*------------------------- Description --------------------------------*
*
*----------------------------------------------------------------------*/
#include <pl.h>
#include <iostream>
using namespace std;

int main() {
/**********************************************************************
VARIABLES SPECIFICATION
**********************************************************************/
plIntegerType Height_type(40,200);
plSymbol Pygmy("Pygmy", PL_BINARY_TYPE);
plSymbol Height("Height", Height_type);
/**********************************************************************
PARAMETRIC FORM SPECIFICATION
**********************************************************************/
// P(Pygmy)
plProbValue Pygmy_table[] = {0.84, 0.16};
plProbTable P_Pygmy(Pygmy, Pygmy_table);
// P(Height | Pygmy)
plDistributionTable P_Height(Height, Pygmy);
P_Height.push(0, plBellShape(Height, 155, 7.5));
P_Height.push(1, plBellShape(Height, 130, 9.5));
/**********************************************************************
DECOMPOSITION
**********************************************************************/
// P(Pygmy Height) = P(Pygmy) P(Height | Pygmy)
plJointDistribution jd(Pygmy^Height, P_Pygmy*P_Height);

59
P(Height) = { Sum_{Pygmy} {P(Pygmy)P(Height | Pygmy) } }
0.045
0.04
0.035

P(Height)

0.03
0.025
0.02
0.015
0.01
0.005
0
40

60

80

100

120
Height

140

160

180

200

Figure A.4: Output of Program 16: the distribution of P (Height) for the
region of Equatorial Africa described on Exercise 9.
51 /**********************************************************************
52
PROGRAM QUESTION
53 **********************************************************************/
54
// Compute and plot P(Height)
55
plDistribution question;
56
57
jd.ask(question, Height);
58
59
question.plot("Height.gplot");
60 }

The output of Program 16 is shown in Figure A.4.


Exercise 10 A third sensor id added easily mainly by adding the following
lines:
plIntegerType measure3(MIN_MES_3,
MAX_MES_3);
plSymbol M3("M3",measure3);
model_vars = D^M1^M2^M3;

// Measure type for sensor 3

// sensor 3 measure
// union measures 1,2 and 3

{M1, M2, M3}

60

APPENDIX A. ANSWERS TO EXERCISES

plCndBellShape P_dist3(M3,D,STD_DEV_3); // distribution with a


// predefined variance

then in the joint distribution you must add:


plJointDistribution my_model(model_vars,P_dist*P_dist1*P_dist2*P_dist3);

Exercise 11
Program 17:The dice filter program.
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

/*=======================================================================
* Product
:
* File
: diceFilter.cpp
* Author
: Juan-Manuel Ahuactzin
* Creation
: 2008-Oct-02 16:16
*
*=======================================================================
*
(c) Copyright 2008, Probayes SAS,
*
all rights reserved
*=======================================================================
*
*------------------------- Description --------------------------------* This program computes the more probable number of dice given the
* sequence of number of points corresponding to throwing the dice t
* times.
*----------------------------------------------------------------------*/
#include <pl.h>
using namespace std;
#define SQRT_DIV35_12 1.7078251

// User function for computing the mean


void f_mean(plValues &mean, const plValues &n) {
mean[0] = 7*n[0]/2;
}
// User function for computing the standard deviation
void f_std(plValues &std, const plValues &n) {
std[0] = SQRT_DIV35_12*sqrt(double(n[0]));
}
int main() {
/**********************************************************************
VARIABLES SPECIFICATION
**********************************************************************/

61
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

unsigned int max_n;


cout<<"Give me the maximum number of dice: ";
cin>>max_n;
plIntegerType die_number(1,max_n);
// of dice [1,2,...,max_n]
plIntegerType dice_sum(1,max_n*6);
plSymbol points("Addition",dice_sum);
plSymbol number("n",die_number);
// selected number of dice

// Type for the maximum number


// Type for the sum [2,3,...,n*6]
// Variable space for the addition
// Variable space for the

plValues result(number^points);

// Values storing the # of dice


// and the addition
/**********************************************************************
PARAMETRIC FORM SPECIFICATION
**********************************************************************/
// P(number) = uniform(number)
plUniform p_number(number);
// Create the external functions to compute the mean and the
// standard deviation
plExternalFunction f_mu(number,f_mean);
plExternalFunction f_sigma(number,f_std);
// P(points | number) = CndBellShape(points,f_mu(number),f_sigma(number))
plCndBellShape p_addition(points,number,f_mu,f_sigma);
/**********************************************************************
DECOMPOSITION
**********************************************************************/
// P(points number) = P(points | number) P(number)
plJointDistribution dice_jd(number^points,p_number*p_addition);
dice_jd.draw_graph("addDice3.fig");
/**********************************************************************
PROGRAM QUESTION
**********************************************************************/
plCndDistribution cnd_question;
plDistribution question;
int v;
// Get P(number | points)
dice_jd.ask(cnd_question,number,points);
unsigned int t=0;
cout<<"Give me the number of throws? ";
cin>>t;
do {
t--;
cout<<"Give me the number of points: ";
cin>>v;
result[points] = v;
// Get P(number | points = v)

62

APPENDIX A. ANSWERS TO EXERCISES

96
cnd_question.instantiate(question,result);
97
plDistribution compiled_question;
98
99
question.compile(compiled_question);
100
cout << "The distribution is:\n" << compiled_question << endl;
101
compiled_question.best(result);
102
103
cout<<"\nThe more probable is: "<<result[number]<<"\n";
104
105
cnd_question.replace(number, compiled_question);
106
} while (t > 0);
107
108
return 0;
109 }

63

64

APPENDIX A. ANSWERS TO EXERCISES

P (RI | )
0
1

P (E | )
0
1

P (RP | )
0
1

P (JA | RI )
RI
JA
0
1
0
1

P (AP | AA )
AA
AP
0
1
0
1

P (VP | AA BA )
AA BA
VP
0
1
0
0
0
1
1
0
1
1

P (We | )
0
1

P (LI | )
0
1

P (BA | LI )
LI
BA
0
1
0
1

P (MA | JA AA )
JA AA
MA
0
1
0
0
0
1
1
0
1
1
P (JP | JA RP )
JA RP
JP
0
1
0
0
0
1
1
0
1
1

P (AA | We )
We
AA
0
1
0
1

P (MP | MA )
MA
MP
0
1
0
1

P (BP | BA E )
BA E
BP
0
1
0
0
0
1
1
0
1
1

Figure A.5: Parametric Al forms of Peters party Bayesian program (See


Figure A.1).

You might also like