Similarly to the previous section an anonymous conditional kernel is constructed by using an external function that takes a C++ function or class method as parameter, the prototypes are the following:
plProbValue user_function(const plValues &input_values)or
plProbValue object_class::class_method(const plValues &input_values)
Particularly for an anonymous kernel the parameter input_values
contains search and known variables values. Generally speaking and
having search variables and
known variables the index from
to
on
input_values
correspond to the search
variables; and the index from to
correspond to the
known variables.
To follow our previous example here we show the construction of an anonymous conditional kernel representing a family of Laplace distributions, see Figure 4.5.
Program 16 implements our example. Lines 22 to 28
corresponds the C++ function coding the conditional Laplace
distribution. In this case there is only one search variable and one
known variable: x[0]
and x[1]
respectively. The
distribution of yesterdays_weight
, a dirac, is constructed at
line 55 followed of the construction of the todays_weight
a
normal distribution. The variable list_of_Pm_tw
contains the
product of all M(i)
Wt
that is
Note that each of the is constructed by using a
probability external function and an anonymous kernel, lines
70-73. The first parameter of the external function includes the search and known variables and they must be concatenated in
that order. That is, the know variables are concatenated after
the search variables. In effect, before calling the C++ function
(or method) the external function will arrange the variables values in
the same order established at its construction. That is why the order
is so important. At the construction of the anonymous conditional
kernel the search and known variables are indicated by
the first and second parameter
measure(i)
and
todays_weight
. Finally, lines 79 to 112 corresponds to the
joint distribution and computation of the result.
1 /*============================================================================= 2 * File : weight.cpp 3 *============================================================================= 4 * 5 *------------------------- Description --------------------------------------- 6 * The main goal of this program is to show how to construct a conditional 7 * anonymous kernel. The program consists in writing the joint distribution for 8 * a set of n bathroom scales readings and the yesterday and todays weights. 9 * The system is asked for the more probable todays weight given the set of 10 * readings and the yesterdays weight. The reading of the bathroom scales is 11 * suposed to be a random variable with a laplace distribution centered at the 12 * real weight. 13 *----------------------------------------------------------------------------- 14 */ 15 16 #include <pl.h> 17 18 #define N_MEASURES 4 19 #define B 1.118 20 #define WEIGHT_STD 0.25 21 22 plProbValue laplace(const plValues &x) 23 { 24 double xx = x[0]; 25 double mu = x[1]; 26 27 return (1.0/(2.0*B)*exp(-fabs(xx-mu)/B)); 28 } 29 30 31 main() 32 { 33 int i; 34 double ith_measure,y_weight; 35 36 /********************************************************************** 37 Defining the variable type, set and values 38 ***********************************************************************/ 39 40 plRealType weight_type(14,150,1500); 41 plSymbol todays_weight("todays_weight",weight_type); 42 plSymbol yesterdays_weight("yesterdays_weight",weight_type); 43 plArray measure("measure",weight_type,1,N_MEASURES); 44 plValues values(todays_weight^yesterdays_weight^measure); 45 46 /********************************************************************** 47 Creating the parametric variables distributions and the 48 joint distribution 49 ***********************************************************************/ 50 51 cout<<"Give me your yesterdays weight : "; 52 cin>>y_weight; 53 values[yesterdays_weight] = y_weight; 54 55 //P(yesterdays_weight) is a dirac 56 plDirac Pyw(yesterdays_weight,values); 57 58 // P(todays_weight) = Normal(todays_weight,weight,WEIGHT_STD); 59 plNormal Ptw(todays_weight,y_weight,WEIGHT_STD); 60 61 // Pm_tw is a vector containing all the P(measure_i | todays_weight) 62 plCndAnonymousKernel *Pm_tw[N_MEASURES]; 63 64 // list_of_Pm_tw is the product of all P(measure_i | todays_weight) 65 plComputableObjectList list_of_Pm_tw; 66 for(i=0;i<N_MEASURES;i++) 67 { 68 // Each of the P(measure_i | todays_weight) is a Laplace distribution 69 // on measure_i with mean equal to todays_weight 70 plExternalProbFunction laplace_distrib(measure(i)^todays_weight, 71 laplace); 72 Pm_tw[i] = new plCndAnonymousKernel(measure(i), 73 todays_weight,laplace_distrib); 74 75 // Add the new distribution to the list 76 list_of_Pm_tw *= *Pm_tw[i]; 77 } 78 79 // Construction of the joint distribution 80 plJointDistribution jd(todays_weight^yesterdays_weight^measure, 81 Pyw*Ptw*list_of_Pm_tw); 82 83 /********************************************************************** 84 Reading the measures 85 ***********************************************************************/ 86 87 for(i=0;i<N_MEASURES;i++) 88 { 89 cout<<"Measure "<<i+1<<"th ? : "; 90 cin>>ith_measure; 91 values[measure(i)] = ith_measure; 92 } 93 94 /********************************************************************** 95 Making the question and showing the result 96 ***********************************************************************/ 97 98 // Getting the conditional distribution 99 // P(todays_weight | yesterdays_weight measure) 100 plCndKernel cnd_question; 101 jd.ask(cnd_question,todays_weight,yesterdays_weight^measure); 102 103 // Getting the distribution 104 // P(todays_weight | yesterdays_weight=y_weight measure= [m1,m2,m3,...,mn]) 105 plKernel P_todays_weight; 106 cnd_question.instantiate(P_todays_weight,values); 107 108 // Showing the result 109 P_todays_weight.best(values); 110 cout<<"Your more probable weight is : "<<values[todays_weight]; 111 cout<<endl; 112 }
One output of Program 16 shows as follows;
Give me your yesterdays weight : 77.2 Measure 1th ? : 76.00 Measure 2th ? : 78.98 Measure 3th ? : 78.27 Measure 4th ? : 78.51 Your more probable weight is : 77.3118.
In this example you can perceive the influence of . In fact, if
we limit our model to the information given by the bathroom scale (we
do not use that of
), then the result is completely
different. For instance, if we change line 59, the distribution of
, by an uniform distribution
plCUniform Ptw(Wy);
then the result becomes 78.4273.