OpenNN  2.2
Open Neural Networks Library
numerical_differentiation.cpp
1 /****************************************************************************************************************/
2 /* */
3 /* OpenNN: Open Neural Networks Library */
4 /* www.artelnics.com/opennn */
5 /* */
6 /* N U M E R I C A L D I F F E R E N T I A T I O N C L A S S */
7 /* */
8 /* Roberto Lopez */
9 /* Artelnics - Making intelligent use of data */
11 /* */
12 /****************************************************************************************************************/
13 
14 // OpenNN includes
15 
16 #include "numerical_differentiation.h"
17 
18 namespace OpenNN
19 {
20 
21 // DEFAULT CONSTRUCTOR
22 
25 
27 {
28  set_default();
29 }
30 
31 
32 // COPY CONSTRUCTOR
33 
35 
37 {
38  set(other_numerical_differentiation);
39 }
40 
41 
42 // DESTRUCTOR
43 
45 
47 {
48 
49 }
50 
51 
52 // ASSIGNMENT OPERATOR
53 
54 // NumericalDifferentiation& operator = (const NumericalDifferentiation&) method
55 
59 
61 {
62  if(this != &other_numerical_differentiation)
63  {
65 
66  precision_digits = other_numerical_differentiation.precision_digits;
67 
68  display = other_numerical_differentiation.display;
69  }
70 
71  return(*this);
72 }
73 
74 
75 // EQUAL TO OPERATOR
76 
77 // bool operator == (const NumericalDifferentiation&) const method
78 
83 
84 bool NumericalDifferentiation::operator == (const NumericalDifferentiation& other_numerical_differentiation) const
85 {
86  if(numerical_differentiation_method == other_numerical_differentiation.numerical_differentiation_method
87  && precision_digits == other_numerical_differentiation.precision_digits
88  && display == other_numerical_differentiation.display)
89  {
90  return(true);
91  }
92  else
93  {
94  return(false);
95  }
96 }
97 
98 
99 // METHODS
100 
101 // const NumericalDifferentiationMethod& get_numerical_differentiation_method(void) const method
102 
104 
106 {
108 }
109 
110 
111 // std::string write_numerical_differentiation_method(void) const method
112 
114 
116 {
118  {
119  case ForwardDifferences:
120  {
121  return("ForwardDifferences");
122  }
123  break;
124 
125  case CentralDifferences:
126  {
127  return("CentralDifferences");
128  }
129  break;
130 
131  default:
132  {
133  std::ostringstream buffer;
134 
135  buffer << "OpenNN Exception: NumericalDifferentiation class.\n"
136  << "std::string write_numerical_differentiation_method(void) const method.\n"
137  << "Unknown numerical differentiation method.\n";
138 
139  throw std::logic_error(buffer.str());
140  }
141  break;
142  }
143 }
144 
145 
146 // const size_t& get_precision_digits(void) const method
147 
149 
151 {
152  return(precision_digits);
153 }
154 
155 
156 // const bool& get_display(void) const method
157 
159 
161 {
162  return(display);
163 }
164 
165 
166 // void set(const NumericalDifferentiation&) method
167 
170 
171 void NumericalDifferentiation::set(const NumericalDifferentiation& other_numerical_differentiation)
172 {
173  numerical_differentiation_method = other_numerical_differentiation.numerical_differentiation_method;
174 
175  precision_digits = other_numerical_differentiation.precision_digits;
176 
177  display = other_numerical_differentiation.display;
178 
179 }
180 
181 
182 // void set_numerical_differentiation_method(const NumericalDifferentiationMethod&)
183 
186 
188 (const NumericalDifferentiation::NumericalDifferentiationMethod& new_numerical_differentiation_method)
189 {
190  numerical_differentiation_method = new_numerical_differentiation_method;
191 }
192 
193 
194 // void set_numerical_differentiation_method(const std::string&) method
195 
199 
200 void NumericalDifferentiation::set_numerical_differentiation_method(const std::string& new_numerical_differentiation_method)
201 {
202  if(new_numerical_differentiation_method == "ForwardDifferences")
203  {
204  numerical_differentiation_method = ForwardDifferences;
205  }
206  else if(new_numerical_differentiation_method == "CentralDifferences")
207  {
208  numerical_differentiation_method = CentralDifferences;
209  }
210  else
211  {
212  std::ostringstream buffer;
213 
214  buffer << "OpenNN Exception: NumericalDifferentiation class.\n"
215  << "void set_numerical_differentiation_method(const std::string&) method.\n"
216  << "Unknown numerical differentiation method: " << new_numerical_differentiation_method << ".\n";
217 
218  throw std::logic_error(buffer.str());
219  }
220 }
221 
222 
223 // void set_display(const bool&) method
224 
227 
228 void NumericalDifferentiation::set_display(const bool& new_display)
229 {
230  display = new_display;
231 }
232 
233 
234 // void set_precision_digits(const size_t&) method
235 
238 
239 void NumericalDifferentiation::set_precision_digits(const size_t& new_precision_digits)
240 {
241  precision_digits = new_precision_digits;
242 }
243 
244 
245 // void set_default(void) method
246 
253 
255 {
256  numerical_differentiation_method = CentralDifferences;
257 
258  precision_digits = 6;
259 
260  display = true;
261 }
262 
263 
264 // double calculate_h(const double&) const method
265 
268 
269 double NumericalDifferentiation::calculate_h(const double& x) const
270 {
271  const double eta = pow(10.0, (int)(-1*precision_digits));
272 
273  return(sqrt(eta)*(1.0 + fabs(x)));
274 }
275 
276 
277 // Vector<double> calculate_h(const Vector<double>&) const method
278 
281 
283 {
284  const double eta = pow(10.0, (int)(-1*precision_digits));
285 
286  const size_t n = x.size();
287 
288  Vector<double> h(n);
289 
290  for(size_t i = 0; i < n; i++)
291  {
292  h[i] = sqrt(eta)*(1.0 + fabs(x[i]));
293  }
294 
295  return(h);
296 }
297 
298 
299 // tinyxml2::XMLDocument* to_XML(void) const method
300 
302 
303 tinyxml2::XMLDocument* NumericalDifferentiation::to_XML(void) const
304 {
305  tinyxml2::XMLDocument* document = new tinyxml2::XMLDocument;
306 /*
307  tinyxml2::XMLElement* element = NULL;
308  tinyxml2::XMLText* text = NULL;
309 
310  std::ostringstream buffer;
311 
312  // Numerical differentiation
313 
314  tinyxml2::XMLElement* root_element = document->NewElement("NumericalDifferentiation");
315 
316  document->InsertFirstChild(root_element);
317 
318  // Numerical differentiation method
319 
320  element = document->NewElement("NumericalDifferentiationMethod");
321  root_element->LinkEndChild(element);
322 
323  text = document->NewText(write_numerical_differentiation_method().c_str());
324  element->LinkEndChild(text);
325 
326  // Precision digits
327 
328  element = document->NewElement("PrecisionDigits");
329  root_element->LinkEndChild(element);
330 
331  buffer.str("");
332  buffer << precision_digits;
333 
334  text = document->NewText(buffer.str().c_str());
335  element->LinkEndChild(text);
336 
337  // Display
338 
339  element = document->NewElement("Display");
340  root_element->LinkEndChild(element);
341 
342  buffer.str("");
343  buffer << display;
344 
345  text = document->NewText(buffer.str().c_str());
346  element->LinkEndChild(text);
347  */
348  return(document);
349 }
350 
351 
352 // void from_XML(const tinyxml2::XMLDocument&) method
353 
356 
357 void NumericalDifferentiation::from_XML(const tinyxml2::XMLDocument& document)
358 {
359  const tinyxml2::XMLElement* root_element = document.FirstChildElement("NumericalDifferentiation");
360 
361  if(!root_element)
362  {
363  std::ostringstream buffer;
364 
365  buffer << "OpenNN Exception: NumericalDifferentiation class.\n"
366  << "void from_XML(const tinyxml2::XMLDocument&) method.\n"
367  << "Numerical differentiation element is NULL.\n";
368 
369  throw std::logic_error(buffer.str());
370  }
371 
372  // Numerical differentiation method
373  {
374  const tinyxml2::XMLElement* element = root_element->FirstChildElement("NumericalDifferentiationMethod");
375 
376  if(element)
377  {
378  const std::string new_numerical_differentiation_method = element->GetText();
379 
380  try
381  {
382  set_numerical_differentiation_method(new_numerical_differentiation_method);
383  }
384  catch(const std::logic_error& e)
385  {
386  std::cout << e.what() << std::endl;
387  }
388  }
389  }
390 
391  // Precision digits
392  {
393  const tinyxml2::XMLElement* element = root_element->FirstChildElement("PrecisionDigits");
394 
395  if(element)
396  {
397  const size_t new_precision_digits = atoi(element->GetText());
398 
399  try
400  {
401  set_precision_digits(new_precision_digits);
402  }
403  catch(const std::logic_error& e)
404  {
405  std::cout << e.what() << std::endl;
406  }
407  }
408  }
409 
410 
411  // Display
412  {
413  const tinyxml2::XMLElement* element = root_element->FirstChildElement("Display");
414 
415  if(element)
416  {
417  const std::string new_display = element->GetText();
418 
419  try
420  {
421  set_display(new_display != "0");
422  }
423  catch(const std::logic_error& e)
424  {
425  std::cout << e.what() << std::endl;
426  }
427  }
428  }
429 }
430 
431 }
432 
433 // OpenNN: Open Neural Networks Library.
434 // Copyright (c) 2005-2015 Roberto Lopez.
435 //
436 // This library is free software; you can redistribute it and/or
437 // modify it under the terms of the GNU Lesser General Public
438 // License as published by the Free Software Foundation; either
439 // version 2.1 of the License, or any later version.
440 //
441 // This library is distributed in the hope that it will be useful,
442 // but WITHOUT ANY WARRANTY; without even the implied warranty of
443 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
444 // Lesser General Public License for more details.
445 
446 // You should have received a copy of the GNU Lesser General Public
447 // License along with this library; if not, write to the Free Software
448 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
size_t precision_digits
Number of precision digits.
bool operator==(const NumericalDifferentiation &) const
double calculate_h(const double &) const
void set_numerical_differentiation_method(const NumericalDifferentiationMethod &)
const bool & get_display(void) const
Returns the flag used by this class for displaying or not displaying warnings.
virtual ~NumericalDifferentiation(void)
Destructor.
NumericalDifferentiationMethod numerical_differentiation_method
Numerical differentiation method variable.
void set(const NumericalDifferentiation &)
const size_t & get_precision_digits(void) const
Returns the number of precision digits required for the derivatives.
std::string write_numerical_differentiation_method(void) const
Returns a string with the name of the method to be used for numerical differentiation.
bool display
Flag for displaying warning messages from this class.
NumericalDifferentiationMethod
Enumeration of available methods for numerical differentiation.
const NumericalDifferentiationMethod & get_numerical_differentiation_method(void) const
Returns the method used for numerical differentiation (forward differences or central differences)...
tinyxml2::XMLDocument * to_XML(void) const
Serializes this numerical differentiation object into a XML document->
void from_XML(const tinyxml2::XMLDocument &)
NumericalDifferentiation & operator=(const NumericalDifferentiation &)