00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <iostream>
00019 #include <fstream>
00020 #include <cmath>
00021 #include <sstream>
00022 #include <string>
00023 #include <limits>
00024
00025
00026
00027 #include "solutions_error.h"
00028
00029
00030
00031 #include "../../parsers/tinyxml/tinyxml.h"
00032
00033
00034 namespace OpenNN
00035 {
00036
00037
00038
00039
00043
00044 SolutionsError::SolutionsError(void) : PerformanceTerm()
00045 {
00046 construct_numerical_differentiation();
00047
00048 set_default();
00049 }
00050
00051
00052
00053
00058
00059 SolutionsError::SolutionsError(NeuralNetwork* new_neural_network_pointer)
00060 : PerformanceTerm(new_neural_network_pointer)
00061 {
00062 construct_numerical_differentiation();
00063
00064 set_default();
00065 }
00066
00067
00068
00069
00074
00075 SolutionsError::SolutionsError(MathematicalModel* new_mathematical_model_pointer)
00076 : PerformanceTerm(new_mathematical_model_pointer)
00077 {
00078 construct_numerical_differentiation();
00079
00080 set_default();
00081 }
00082
00083
00084
00085
00091
00092 SolutionsError::SolutionsError(NeuralNetwork* new_neural_network_pointer, MathematicalModel* new_mathematical_model_pointer)
00093 : PerformanceTerm(new_neural_network_pointer, new_mathematical_model_pointer)
00094 {
00095 construct_numerical_differentiation();
00096
00097 set_default();
00098 }
00099
00100
00101
00102
00107
00108 SolutionsError::SolutionsError(TiXmlElement* solutions_error_element)
00109 : PerformanceTerm(solutions_error_element)
00110 {
00111 set_default();
00112
00113 from_XML(solutions_error_element);
00114 }
00115
00116
00117
00118
00122
00123 SolutionsError::SolutionsError(const SolutionsError& other_solutions_error)
00124 : PerformanceTerm()
00125 {
00126 set_default();
00127
00128 set(other_solutions_error);
00129 }
00130
00131
00132
00133
00137
00138 SolutionsError::~SolutionsError(void)
00139 {
00140 }
00141
00142
00143
00144
00145
00146
00150
00151 SolutionsError& SolutionsError::operator = (const SolutionsError& other_solutions_error)
00152 {
00153 if(this != &other_solutions_error)
00154 {
00155 *neural_network_pointer = *other_solutions_error.neural_network_pointer;
00156 *data_set_pointer = *other_solutions_error.data_set_pointer;
00157 *mathematical_model_pointer = *other_solutions_error.mathematical_model_pointer;
00158 *numerical_differentiation_pointer = *other_solutions_error.numerical_differentiation_pointer;
00159 display = other_solutions_error.display;
00160
00161 solutions_error_method = other_solutions_error.solutions_error_method;
00162 solutions_errors_weights = other_solutions_error.solutions_errors_weights;
00163 }
00164
00165 return(*this);
00166 }
00167
00168
00169
00170
00171
00172
00175
00176 bool SolutionsError::operator == (const SolutionsError& other_solutions_error) const
00177 {
00178 if(*neural_network_pointer == *other_solutions_error.neural_network_pointer
00179 && *mathematical_model_pointer == *other_solutions_error.mathematical_model_pointer
00180 && *numerical_differentiation_pointer == *other_solutions_error.numerical_differentiation_pointer
00181 && display == other_solutions_error.display
00182 && solutions_errors_weights == other_solutions_error.solutions_errors_weights)
00183 {
00184 return(true);
00185 }
00186 else
00187 {
00188 return(false);
00189 }
00190 }
00191
00192
00193
00194
00195
00196
00198
00199 const SolutionsError::SolutionsErrorMethod& SolutionsError::get_solutions_error_method(void) const
00200 {
00201 return(solutions_error_method);
00202 }
00203
00204
00205
00206
00208
00209 std::string SolutionsError::write_solutions_error_method(void) const
00210 {
00211 if(solutions_error_method == SolutionsErrorSum)
00212 {
00213 return("SolutionsErrorSum");
00214 }
00215 else if(solutions_error_method == SolutionsErrorIntegral)
00216 {
00217 return("SolutionsErrorIntegral");
00218 }
00219 else
00220 {
00221 std::ostringstream buffer;
00222
00223 buffer << "OpenNN Exception: SolutionsError class.\n"
00224 << "std::string write_solutions_error_method(void) const method.\n"
00225 << "Unknown solutions error method.\n";
00226
00227 throw std::logic_error(buffer.str());
00228 }
00229 }
00230
00231
00232
00233
00235
00236 const Vector<double>& SolutionsError::get_solutions_errors_weights(void) const
00237 {
00238 return(solutions_errors_weights);
00239 }
00240
00241
00242
00243
00245
00246 const double& SolutionsError::get_solution_error_weight(const unsigned int& i) const
00247 {
00248 return(solutions_errors_weights[i]);
00249 }
00250
00251
00252
00253
00256
00257 void SolutionsError::set(const SolutionsError& other_solutions_error)
00258 {
00259 neural_network_pointer = other_solutions_error.neural_network_pointer;
00260
00261 data_set_pointer = other_solutions_error.data_set_pointer;
00262
00263 mathematical_model_pointer = other_solutions_error.mathematical_model_pointer;
00264
00265 if(other_solutions_error.numerical_differentiation_pointer)
00266 {
00267 numerical_differentiation_pointer = new NumericalDifferentiation(*other_solutions_error.numerical_differentiation_pointer);
00268 }
00269
00270 display = other_solutions_error.display;
00271
00272 solutions_errors_weights = other_solutions_error.solutions_errors_weights;
00273 }
00274
00275
00276
00277
00280
00281 void SolutionsError::set_solutions_error_method(const SolutionsErrorMethod& new_solutions_error_method)
00282 {
00283 solutions_error_method = new_solutions_error_method;
00284 }
00285
00286
00287
00288
00291
00292 void SolutionsError::set_solutions_error_method(const std::string& new_solutions_error_method)
00293 {
00294 if(new_solutions_error_method == "SolutionsErrorSum")
00295 {
00296 set_solutions_error_method(SolutionsErrorSum);
00297 }
00298 else if(new_solutions_error_method == "SolutionsErrorIntegral")
00299 {
00300 set_solutions_error_method(SolutionsErrorIntegral);
00301 }
00302 else
00303 {
00304 std::ostringstream buffer;
00305
00306 buffer << "OpenNN Exception: SolutionsError class.\n"
00307 << "void set_solutions_error_method(const std::string&) method.\n"
00308 << "Unknown solutions error method: " << new_solutions_error_method << ".\n";
00309
00310 throw std::logic_error(buffer.str());
00311 }
00312 }
00313
00314
00315
00316
00319
00320 void SolutionsError::set_solutions_errors_weights(const Vector<double>& new_solutions_errors_weights)
00321 {
00322 solutions_errors_weights = new_solutions_errors_weights;
00323 }
00324
00325
00326
00327
00331
00332 void SolutionsError::set_solution_error_weight(const unsigned int& i, const double& new_solution_error_weight)
00333 {
00334 solutions_errors_weights[i] = new_solution_error_weight;
00335 }
00336
00337
00338
00339
00346
00347 void SolutionsError::set_default(void)
00348 {
00349 solutions_error_method = SolutionsErrorSum;
00350
00351 if(mathematical_model_pointer)
00352 {
00353 const unsigned int dependent_variables_number = mathematical_model_pointer->get_dependent_variables_number();
00354
00355 solutions_errors_weights.set(dependent_variables_number, 1.0);
00356 }
00357
00358 if(numerical_differentiation_pointer)
00359 {
00360 numerical_differentiation_pointer->set_default();
00361 }
00362
00363 numerical_integration.set_default();
00364
00365 display = true;
00366 }
00367
00368
00369
00370
00372
00373 Matrix<double> SolutionsError::calculate_target_dependent_variables(const Matrix<double>& independent_variables) const
00374 {
00375 #ifdef _DEBUG
00376
00377 check();
00378
00379 #endif
00380
00381 const unsigned int& rows_number = independent_variables.get_rows_number();
00382 const unsigned int& dependent_variables_number = mathematical_model_pointer->get_dependent_variables_number();
00383
00384 const Matrix<double> target_dependent_variables(rows_number, dependent_variables_number, 0.0);
00385
00386 return(target_dependent_variables);
00387 }
00388
00389
00390
00391
00400
00401 void SolutionsError::check(void) const
00402 {
00403 std::ostringstream buffer;
00404
00405
00406
00407 if(!neural_network_pointer)
00408 {
00409 buffer << "OpenNN Exception: SolutionsError class.\n"
00410 << "void check(void) const method.\n"
00411 << "Pointer to neural network is NULL.\n";
00412
00413 throw std::logic_error(buffer.str().c_str());
00414 }
00415
00416 const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
00417
00418 if(!multilayer_perceptron_pointer)
00419 {
00420 buffer << "OpenNN Exception: SolutionsError class.\n"
00421 << "void check(void) const method.\n"
00422 << "Pointer to multilayer perceptron is NULL.\n";
00423
00424 throw std::logic_error(buffer.str().c_str());
00425 }
00426
00427 const unsigned int inputs_number = multilayer_perceptron_pointer->count_inputs_number();
00428 const unsigned int outputs_number = multilayer_perceptron_pointer->count_outputs_number();
00429
00430 if(inputs_number == 0)
00431 {
00432 buffer << "OpenNN Exception: SolutionsError class.\n"
00433 << "void check(void) const method.\n"
00434 << "Number of inputs in multilayer perceptron object is zero.\n";
00435
00436 throw std::logic_error(buffer.str().c_str());
00437 }
00438
00439 if(outputs_number == 0)
00440 {
00441 buffer << "OpenNN Exception: SolutionsError class.\n"
00442 << "void check(void) const method.\n"
00443 << "Number of outputs in multilayer perceptron object is zero.\n";
00444
00445 throw std::logic_error(buffer.str().c_str());
00446 }
00447
00448
00449
00450 if(!mathematical_model_pointer)
00451 {
00452 buffer << "OpenNN Exception: SolutionsError class.\n"
00453 << "void check(void) const method.\n"
00454 << "Pointer to mathematical model is NULL.\n";
00455
00456 throw std::logic_error(buffer.str().c_str());
00457 }
00458
00459 const unsigned int& dependent_variables_number = mathematical_model_pointer->get_dependent_variables_number();
00460
00461
00462
00463 const unsigned int solutions_errors_weights_size = solutions_errors_weights.size();
00464
00465 if(solutions_errors_weights_size != dependent_variables_number)
00466 {
00467 buffer << "OpenNN Exception: SolutionsError class.\n"
00468 << "void check(void) const method.\n"
00469 << "Size of solutions errors weights (" << solutions_errors_weights_size << ") is not equal to number of dependent variables (" << dependent_variables_number << ").\n";
00470
00471 throw std::logic_error(buffer.str().c_str());
00472 }
00473 }
00474
00475
00476
00477
00480
00481 double SolutionsError::calculate_solutions_error_sum(void) const
00482 {
00483
00484
00485 #ifdef _DEBUG
00486
00487 check();
00488
00489 #endif
00490
00491 const unsigned int independent_variables_number = mathematical_model_pointer->get_independent_variables_number();
00492 const unsigned int dependent_variables_number = mathematical_model_pointer->get_dependent_variables_number();
00493
00494 const unsigned int variables_number = mathematical_model_pointer->count_variables_number();
00495
00496 const Matrix<double> solution = mathematical_model_pointer->calculate_solutions(*neural_network_pointer);
00497
00498 const Vector<unsigned int> independent_variables_indices(0, 1, independent_variables_number-1);
00499 const Vector<unsigned int> dependent_variables_indices(independent_variables_number, 1, variables_number-1);
00500
00501 const Matrix<double> independent_variables = solution.arrange_submatrix_columns(independent_variables_indices);
00502 const Matrix<double> dependent_variables = solution.arrange_submatrix_columns(dependent_variables_indices);
00503
00504 const Matrix<double> target_dependent_variables = calculate_target_dependent_variables(independent_variables);
00505
00506 double evaluation = 0.0;
00507
00508 for(unsigned int i = 0; i < dependent_variables_number; i++)
00509 {
00510 if(solutions_errors_weights[i] != 0.0)
00511 {
00512 const Vector<double> dependent_variable = dependent_variables.arrange_column(i);
00513 const Vector<double> target_dependent_variable = target_dependent_variables.arrange_column(i);
00514
00515 evaluation += solutions_errors_weights[i]*(dependent_variable-target_dependent_variable).calculate_norm();
00516 }
00517 }
00518
00519 const unsigned int rows_number = independent_variables.get_rows_number();
00520
00521 return(evaluation/(double)rows_number);
00522 }
00523
00524
00525
00526
00528
00529 double SolutionsError::calculate_solutions_error_integral(void) const
00530 {
00531 return(0.0);
00532 }
00533
00534
00535
00536
00538
00539 double SolutionsError::calculate_evaluation(void) const
00540 {
00541
00542
00543 #ifdef _DEBUG
00544
00545 check();
00546
00547 #endif
00548
00549 switch(solutions_error_method)
00550 {
00551 case SolutionsErrorSum:
00552 {
00553 return(calculate_solutions_error_sum());
00554 }
00555 break;
00556
00557 case SolutionsErrorIntegral:
00558 {
00559 return(calculate_solutions_error_integral());
00560 }
00561 break;
00562
00563 default:
00564 {
00565 std::ostringstream buffer;
00566
00567 buffer << "OpenNN Exception: SolutionsError class\n"
00568 << "double calculate_evaluation(void) const method.\n"
00569 << "Unknown solutions error method.\n";
00570
00571 throw std::logic_error(buffer.str());
00572 }
00573 break;
00574 }
00575 }
00576
00577
00578
00579
00582
00583 double SolutionsError::calculate_evaluation(const Vector<double>& parameters) const
00584 {
00585
00586
00587 #ifdef _DEBUG
00588
00589 check();
00590
00591 #endif
00592
00593 NeuralNetwork neural_network_copy(*neural_network_pointer);
00594
00595 neural_network_copy.set_parameters(parameters);
00596
00597 SolutionsError solutions_error_copy(*this);
00598
00599 solutions_error_copy.set_neural_network_pointer(&neural_network_copy);
00600 solutions_error_copy.set_mathematical_model_pointer(mathematical_model_pointer);
00601
00602 return(solutions_error_copy.calculate_evaluation());
00603 }
00604
00605
00606
00607
00609
00610 std::string SolutionsError::write_performance_term_type(void) const
00611 {
00612 return("SOLUTION_ERROR");
00613 }
00614
00615
00616
00617
00618 std::string SolutionsError::write_information(void) const
00619 {
00620 std::ostringstream buffer;
00621
00622 buffer << "Solutions error: " << calculate_evaluation() << "\n";
00623
00624 return(buffer.str());
00625 }
00626
00627
00628
00629
00631
00632 void SolutionsError::print(void) const
00633 {
00634 if(display)
00635 {
00636 std::cout << "Solutions error:\n"
00637 << "Solutions error method: " << write_solutions_error_method() << "\n"
00638 << "Solutions errors weights: " << solutions_errors_weights << std::endl;
00639 }
00640 }
00641
00642
00643
00644
00646
00647 TiXmlElement* SolutionsError::to_XML(void) const
00648 {
00649 std::ostringstream buffer;
00650
00651
00652
00653 TiXmlElement* solutions_error_element = new TiXmlElement("SolutionsError");
00654 solutions_error_element->SetAttribute("Version", 4);
00655
00656
00657
00658 if(numerical_differentiation_pointer)
00659 {
00660 TiXmlElement* element = numerical_differentiation_pointer->to_XML();
00661 solutions_error_element->LinkEndChild(element);
00662 }
00663
00664
00665 {
00666 TiXmlElement* element = numerical_integration.to_XML();
00667 solutions_error_element->LinkEndChild(element);
00668 }
00669
00670
00671 {
00672 TiXmlElement* element = new TiXmlElement("SolutionsErrorMethod");
00673 solutions_error_element->LinkEndChild(element);
00674
00675 TiXmlText* text = new TiXmlText(write_solutions_error_method().c_str());
00676 element->LinkEndChild(text);
00677 }
00678
00679
00680
00681 {
00682 TiXmlElement* constraints_weights_element = new TiXmlElement("SolutionsErrorWeights");
00683 solutions_error_element->LinkEndChild(constraints_weights_element);
00684
00685 buffer.str("");
00686 buffer << solutions_errors_weights;
00687
00688 TiXmlText* constraints_weights_text = new TiXmlText(buffer.str().c_str());
00689 constraints_weights_element->LinkEndChild(constraints_weights_text);
00690 }
00691
00692
00693 {
00694 TiXmlElement* display_element = new TiXmlElement("Display");
00695 solutions_error_element->LinkEndChild(display_element);
00696
00697 buffer.str("");
00698 buffer << display;
00699
00700 TiXmlText* display_text = new TiXmlText(buffer.str().c_str());
00701 display_element->LinkEndChild(display_text);
00702 }
00703
00704 return(solutions_error_element);
00705 }
00706
00707
00708
00709
00711
00712
00713 void SolutionsError::from_XML(TiXmlElement* solutions_error_element)
00714 {
00715 if(solutions_error_element)
00716 {
00717
00718 {
00719 TiXmlElement* display_element = solutions_error_element->FirstChildElement("Display");
00720
00721 if(display_element)
00722 {
00723 std::string new_display_string = display_element->GetText();
00724
00725 try
00726 {
00727 set_display(new_display_string != "0");
00728 }
00729 catch(std::exception& e)
00730 {
00731 std::cout << e.what() << std::endl;
00732 }
00733 }
00734 }
00735 }
00736 }
00737
00738
00739 }
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756