OpenCog Framework  Branch: master, revision 6f0b7fc776b08468cf1b74aa9db028f387b4f0c0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
IndefiniteTruthValue.cc
Go to the documentation of this file.
1 /*
2  * opencog/atomspace/IndefiniteTruthValue.cc
3  *
4  * Copyright (C) 2002-2007 Novamente LLC
5  * All Rights Reserved
6  *
7  * Written by Fabricio Silva <fabricio@vettalabs.com>
8  * Welter Silva <welter@vettalabs.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU Affero General Public License v3 as
12  * published by the Free Software Foundation and including the exceptions
13  * at http://opencog.org/wiki/Licenses
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU Affero General Public License
21  * along with this program; if not, write to:
22  * Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 
26 #include <gsl/gsl_math.h>
27 #include <gsl/gsl_integration.h>
28 
29 #include "IndefiniteTruthValue.h"
30 
31 #include <opencog/util/platform.h>
32 #include <opencog/util/exceptions.h>
33 
34 #define W() getU()-getL();
35 
36 //#define DPRINTF printf
37 #define DPRINTF(...)
38 
39 using namespace opencog;
40 
45 
46 
47 // Formula defined in the integral of step one [(x-L1)^ks * (U1-x)^k(1-s)
48 static double integralFormula (double x, void * params)
49 {
50  double L_, U_, k_, s_;
51  double *in_params = static_cast<double*>(params);
52  L_ = in_params[0];
53  U_ = in_params[1];
54  k_ = in_params[2];
55  s_ = in_params[3];
56  double f = (pow((x - L_), (k_ * s_))) * pow((U_ -x), (k_ * (1 - s_)));
57  return f;
58 }
59 
61  strength_t L_, strength_t U_,
62  count_t k_, strength_t s_)
63 {
64  double params[4];
65  size_t neval = 0;
66  double result = 0.0, abserr = 0.0;
67  gsl_function F;
68 
69  params[0] = static_cast<double>(L_);
70  params[1] = static_cast<double>(U_);
71  params[2] = static_cast<double>(k_);
72  params[3] = static_cast<double>(s_);
73 
74  F.function = &integralFormula;
75  F.params = &params;
76 
77  gsl_integration_qng (&F, lower, upper,
78  1e-1, 0.0, &result, &abserr, &neval);
79  return (strength_t) result;
80 }
81 
83 {
84  L = l;
85  U = u;
86  confidenceLevel = c;
87 
88  // the next 4 variables are initalized to -1 to indicate that they must
89  // be calculated when accessed (using getDiff, etc)
90  diff = -1.0;
91  mean = -1.0;
92  count = -1.0;
93  confidence = -1.0;
94 
95  firstOrderDistribution.clear();
96  symmetric = true;
97 }
98 
100 {
101  L = source.L;
102  U = source.U;
104  diff = source.diff;
105  mean = source.mean;
106  count = source.count;
107  confidence = source.confidence;
108  symmetric = source.symmetric;
109 }
110 
112 {
113  init();
114 }
115 
117  confidence_t c)
118 {
119  init(l, u, c);
120 }
121 
123 {
124  copy(source);
125 }
126 
128 {
129  const IndefiniteTruthValue* itv = dynamic_cast<const IndefiniteTruthValue*>(&rhs);
130  if (NULL == itv) {
131  return false;
132  } else {
133  return (U == itv->U && L == itv->L
134  && confidenceLevel == itv->confidenceLevel);
135  }
136 }
137 
139 {
140  return L;
141 }
143 {
144  return U;
145 }
146 
148 {
149  if (diff >= 0) return diff; // previously calculated
150  else {
151  if (U == L) { //Nil: I'm not sure returning 0 is the right thing to do
152  diff = 0.0;
153  return diff;
154  } else {
155  strength_t idiff = 0.01; //initial diff suggestion
156  diff = findDiff(idiff);
157  return diff;
158  }
159  }
160 }
161 
163 {
164  strength_t min = 0.0;
165  strength_t max = 0.5; //diff cannot be larger than 1/2 cause symmetric case
166  strength_t L1, U1;
167  strength_t numerator, denominator, result;
168  strength_t expected = (1 - confidenceLevel) / 2;
169  bool lte, gte; //smaller than expected, greater than expected
170 
171  //loop until convergence
172  do {
173  U1 = U + idiff;
174  L1 = L - idiff;
175 
176  numerator = DensityIntegral(U, U1, L1, U1, DEFAULT_K, s);
177  denominator = DensityIntegral(L1, U1, L1, U1, DEFAULT_K, s);
178 
179  if (denominator > 0) result = numerator / denominator;
180  else result = 0.0;
181 
182  lte = result < expected - diffError;
183  gte = result > expected + diffError;
184 
185  if (lte) {
186  min = idiff;
187  idiff = (idiff + max) / 2;
188  }
189  if (gte) {
190  max = idiff;
191  idiff = (min + idiff) / 2;
192  }
193  } while (lte || gte);
194 
195  return idiff;
196 }
197 
199 {
200  return confidenceLevel;
201 }
202 
203 const std::vector<strength_t*>& IndefiniteTruthValue::getFirstOrderDistribution() const
204 {
205  return firstOrderDistribution;
206 }
207 
209 {
210  strength_t u = U + diff;
211 // return (u > 1.0)?1.0f:u;
212  return u;
213 }
215 {
216  strength_t l = L - diff;
217 // return (l < 0.0)?0.0f:l;
218  return l;
219 }
220 
222 {
223  this->L = l;
224 
225  // the next 4 variables are set to -1 to indicate that they must
226  // be recalculated
227  diff = -1.0;
228  mean = -1.0;
229  count = -1.0;
230  confidence = -1.0;
231 }
232 
234 {
235  this->U = u;
236 
237  // the next 4 variables are set to -1 to indicate that they must
238  // be recalculated
239  diff = -1.0;
240  mean = -1.0;
241  count = -1.0;
242  confidence = -1.0;
243 }
244 
246 {
247  this->confidenceLevel = c;
248 }
249 
251 {
252  this->diff = diff;
253 }
254 
255 void IndefiniteTruthValue::setFirstOrderDistribution(const std::vector<strength_t*>& v)
256 {
257  this->firstOrderDistribution = v;
258 }
259 
261 {
262  return INDEFINITE_TRUTH_VALUE;
263 }
264 
266 {
267  mean = m;
268 }
269 
271 {
272  if (mean < 0) { // mean must be updated
273  mean = (L + U) / 2;
274  }
275  return mean;
276 }
277 
279 {
280  if (count < 0) { // count must be updated
281  strength_t W = W();
282  // to avoid division by zero
283  W = std::max(W, static_cast<strength_t>(0.0000001));
284  count = (DEFAULT_K * (1 - W) / W);
285  }
286  return count;
287 }
288 
290 {
291  if (confidence < 0) { // confidence must be updated
292  count_t c = getCount();
293  confidence = c / (c + DEFAULT_K);
294  }
295  return confidence;
296 }
297 
299 {
300  return symmetric;
301 }
302 
303 // Merge formula, as specified by PLN.
305 {
306  if (other->getConfidence() > getConfidence()) {
307  return other->clone();
308  }
309  return clone();
310 }
311 
313 {
314  char buf[1024];
315  sprintf(buf, "[%f,%f,%f,%f,%f,%d]",
316  static_cast<float>(mean),
317  static_cast<float>(L),
318  static_cast<float>(U),
319  static_cast<float>(confidenceLevel),
320  static_cast<float>(diff),
321  symmetric);
322  return buf;
323 }
strength_t findDiff(strength_t idiff)
find diff by dichotomy
void setFirstOrderDistribution(const std::vector< strength_t * > &)
void init(strength_t l=0.0f, strength_t u=0.0f, confidence_t c=DEFAULT_CONFIDENCE_LEVEL)
const std::vector< strength_t * > & getFirstOrderDistribution() const
TruthValueType
Definition: TruthValue.h:63
std::shared_ptr< TruthValue > TruthValuePtr
Definition: TruthValue.h:85
static double integralFormula(double x, void *params)
std::vector< strength_t * > firstOrderDistribution
static confidence_t DEFAULT_CONFIDENCE_LEVEL
float strength_t
float confidence_t
double count_t
confidence_t getConfidenceLevel() const
#define W()
confidence_t confidenceLevel
referred as "b" in the paper
void copy(const IndefiniteTruthValue &)
TruthValuePtr merge(TruthValuePtr, TVMergeStyle ms=DEFAULT) const
static strength_t DensityIntegral(strength_t lower, strength_t upper, strength_t L_, strength_t U_, count_t k_, strength_t s_)
virtual bool operator==(const TruthValue &rhs) const
it is a strict equality comparison, without error interval tolerance
TVMergeStyle
Definition: TruthValue.h:76