In many cases it happens that a conditional kernel
is defined in terms of a couple
where
is a built-in conditional kernel
and
is a function
. If this is the case we say
that we have a functional kernel.
| (4.5) |
| (4.6) |
where
,
,
and
. Given that
is a built-in conditional kernel,
in ProBT the construction of a functional kernel is achieved by a
constructor of
accepting the function
as one of its
arguments4.1. In follow we illustrate this with an example.
There are several ways to tackle this problem; at first sight it
could seem that the implementation of the model is almost that of
Program 12. However, in this case, the number
of
dice is a variable on the model. In other words, we have the following
joint distribution:
We can assume
uniform; in contrast, notice that the
distribution of
depends on the value of
. In effect, it is
well known that when
is particularly large, we have that
tends to a normal curve with mean
and
standard deviation
. In other words in ProBT we
can represent this distribution as follows
with
Finally, in order to find the more probable value
given
the kernel
is required.
Program 14 shows how to solve our problem with ProBT
and introduces the use of functional kernels.
1 /*=============================================================================
2 * File : addDice3.cpp
3 *=============================================================================
4 *
5 *------------------------- Description ---------------------------------------
6 * This program computes the more probable number of dice that where thrown
7 * given that we know the total number of points
8 *-----------------------------------------------------------------------------
9 */
10
11 #include <pl.h>
12 #define SQRT_DIV35_12 1.7078251
13
14 // User function for computing the mean
15 void f_mean(plValues &mean, const plValues &n) {
16 mean[0] = 7*n[0]/2;
17
18 }
19
20
21 // User function for computing the standard deviation
22 void f_std(plValues &std, const plValues &n) {
23 std[0] = SQRT_DIV35_12*sqrt(n[0]);
24
25 }
26
27
28 main()
29 {
30 /**********************************************************************
31 Defining the variable type, set and values plus the kernel for the
32 variable set
33 ***********************************************************************/
34
35 plIntegerType die_number(1,10); // Type for the # of dice [1,2,...,100]
36 plIntegerType dice_sum(1,60); // Type for the sum [2,3,...,n*6]
37 plSymbol points("Addition",dice_sum); // Variable space for the addition
38 plSymbol number("n",die_number); // Variable space for the # of dice
39
40 plValues result(number^points); // Values storing the # of dice
41 // and the addition
42
43 /**********************************************************************
44 Writing the joint distribution
45 ***********************************************************************/
46
47 // P(number) = uniform(number)
48 plUniform p_number(number);
49
50 // Create the external functions to compute the mean and the
51 // standard deviation
52 plExternalFunction f_mu(number,f_mean);
53 plExternalFunction f_sigma(number,f_std);
54
55 // P(points | number) = CndBellShape(points,f_mu(number),f_sigma(number))
56 plCndBellShape p_addition(points,number,f_mu,f_sigma);
57
58 // P(points number) = P(points | number) P(number)
59 plJointDistribution dice_jd(number^points,p_number*p_addition);
60
61 /**********************************************************************
62 Making a question P( number | points = v) and getting the more
63 probable
64 ***********************************************************************/
65
66 plCndKernel cnd_question;
67 plKernel question;
68 int v;
69
70 // Get P(number | points)
71 dice_jd.ask(cnd_question,number,points);
72 cout<<"Give me the addition of the dice: ";
73 cin>>v;
74 result[points] = v;
75
76 // Get P(number | points = v)
77 cnd_question.instantiate(question,result);
78 plKernel compiled_question;
79
80 question.compile(compiled_question);
81 compiled_question.best(result);
82
83 cout<<"\nThe more probale is: "<<result[number]<<"\n";
84 }
The external function
and
are constructed at
lines 52 and 53 respectively. Note that the two C++ functions defined
at lines 14 to 25 are used for this purpose. In comparation with
Example 15, only the input parameter (and not the
output parameter) has been passed to the external function
constructor. This is because it turns out that the output parameter is
fixe by the functional kernel. For example, in this case it is
fixe to an intermediary variable of real type in the external function
representing
. This because the mean of a bell-shape
distribution is a real value.
The output of Program 14 shows as follow:
Give me the addition of the dice: 18 The more probable is: 5