9#include "bounding_layer.h"
83 buffer <<
"OpenNN Exception: BoundingLayer class.\n"
84 <<
"string write_bounding_method() const method.\n"
85 <<
"Unknown bounding method.\n";
87 throw logic_error(buffer.str());
125 if(i >= neurons_number)
127 ostringstream buffer;
129 buffer <<
"OpenNN Exception: BoundingLayer class.\n"
130 <<
"type get_lower_bound(const Index&) const method.\n"
131 <<
"Index must be less than number of bounding neurons.\n";
133 throw logic_error(buffer.str());
159 if(neurons_number == 0)
161 ostringstream buffer;
163 buffer <<
"OpenNN Exception: BoundingLayer class.\n"
164 <<
"type get_upper_bound(const Index&) const method.\n"
165 <<
"Number of bounding neurons is zero.\n";
167 throw logic_error(buffer.str());
169 else if(i >= neurons_number)
171 ostringstream buffer;
173 buffer <<
"OpenNN Exception: BoundingLayer class.\n"
174 <<
"type get_upper_bound(const Index&) const method.\n"
175 <<
"Index must be less than number of bounding neurons.\n";
177 throw logic_error(buffer.str());
273 if(new_method_string ==
"NoBounding")
277 else if(new_method_string ==
"Bounding")
283 ostringstream buffer;
285 buffer <<
"OpenNN Exception: BoundingLayer class.\n"
286 <<
"void set_bounding_method(const string&) method.\n"
287 <<
"Unknown bounding method: " << new_method_string <<
".\n";
289 throw logic_error(buffer.str());
303 if(new_lower_bounds.size() != neurons_number)
305 ostringstream buffer;
307 buffer <<
"OpenNN Exception: BoundingLayer class.\n"
308 <<
"void set_lower_bounds(const Tensor<type, 1>&) method.\n"
309 <<
"Size must be equal to number of bounding neurons number.\n";
311 throw logic_error(buffer.str());
333 if(index >= neurons_number)
335 ostringstream buffer;
337 buffer <<
"OpenNN Exception: BoundingLayer class.\n"
338 <<
"void set_lower_bound(const Index&, const type&) method.\n"
339 <<
"Index of bounding neurons must be less than number of bounding neurons.\n";
341 throw logic_error(buffer.str());
385 if(index >= neurons_number)
387 ostringstream buffer;
389 buffer <<
"OpenNN Exception: BoundingLayer class.\n"
390 <<
"void set_upper_bound(const Index&, const type&) method.\n"
391 <<
"Index of bounding neuron must be less than number of bounding neurons.\n";
393 throw logic_error(buffer.str());
446 case BoundingMethod::NoBounding:
return inputs;
448 case BoundingMethod::Bounding:
450 const Index rows_number = inputs.dimension(0);
451 const Index columns_number = inputs.dimension(1);
453 Tensor<type, 2> outputs(rows_number, columns_number);
455 for(Index i = 0; i < rows_number; i++)
457 for(Index j = 0; j < columns_number; j++)
461 else outputs(i,j) = inputs(i,j);
469 return Tensor<type, 2>();
477 ostringstream buffer;
479 buffer.precision(10);
485 for(Index i = 0; i < neurons_number; i++)
487 buffer << outputs_names[i] <<
" = max(" <<
lower_bounds[i] <<
", " << inputs_names[i] <<
")\n";
488 buffer << outputs_names[i] <<
" = min(" <<
upper_bounds[i] <<
", " << inputs_names[i] <<
")\n";
508 ostringstream buffer;
510 buffer <<
"vector<float> " <<
layer_name <<
"(const vector<float>& inputs)\n{" << endl;
512 buffer <<
"\tvector<float> outputs(" << neurons_number <<
");\n" << endl;
517 for(Index i = 0; i < neurons_number; i++)
519 buffer <<
"\tif(inputs[" << i <<
"] < " <<
lower_bounds[i] <<
")" << endl;
520 buffer <<
"\t{" << endl;
521 buffer <<
"\t outputs[" << i <<
"] = " <<
lower_bounds[i] << endl;
522 buffer <<
"\t}" << endl;
523 buffer <<
"\telse if(inputs[" << i <<
"] > " <<
upper_bounds[i] <<
")" << endl;
524 buffer <<
"\t{" << endl;
525 buffer <<
"\t outputs[" << i <<
"] = " <<
upper_bounds[i] << endl;
526 buffer <<
"\t}" << endl;
527 buffer <<
"\telse" << endl;
528 buffer <<
"\t{" << endl;
529 buffer <<
"\t outputs[" << i <<
"] = inputs[" << i <<
"];" << endl;
530 buffer <<
"\t}" << endl;
535 for(Index i = 0; i < neurons_number; i++)
537 buffer <<
"\toutputs[" << i <<
"] = inputs[" << i <<
"];" << endl;
541 buffer <<
"\n\treturn outputs;\n}" << endl;
555 ostringstream buffer;
557 buffer <<
"\tdef " <<
layer_name <<
"(self,inputs):\n" << endl;
559 buffer <<
"\t\toutputs = [None] * "<<neurons_number<<
"\n" << endl;
563 for(Index i = 0; i < neurons_number; i++)
565 buffer <<
"\t\tif inputs[" << i <<
"] < " <<
lower_bounds[i] <<
":\n" << endl;
566 buffer <<
"\t\t\toutputs[" << i <<
"] = " <<
lower_bounds[i] <<
"\n" << endl;
567 buffer <<
"\t\telif inputs[" << i <<
"] >" <<
upper_bounds[i] <<
":\n" << endl;
568 buffer <<
"\t\t\toutputs[" << i <<
"] = " <<
upper_bounds[i] <<
"\n" << endl;
569 buffer <<
"\t\telse:\n" << endl;
570 buffer <<
"\t\t\toutputs[" << i <<
"] = inputs[" << i <<
"]\n"<< endl;
575 for(Index i = 0; i < neurons_number; i++)
577 buffer <<
"\t\toutputs[" << i <<
"] = inputs[" << i <<
"]" << endl;
581 buffer <<
"\n\t\treturn outputs\n" << endl;
592 ostringstream buffer;
594 file_stream.OpenElement(
"BoundingLayer");
598 file_stream.OpenElement(
"BoundingNeuronsNumber");
603 buffer << neurons_number;
605 file_stream.
PushText(buffer.str().c_str());
609 for(Index i = 0; i < neurons_number; i++)
611 file_stream.OpenElement(
"Item");
613 file_stream.
PushAttribute(
"Index",
static_cast<unsigned>(i+1));
617 file_stream.OpenElement(
"LowerBound");
622 file_stream.
PushText(buffer.str().c_str());
628 file_stream.OpenElement(
"UpperBound");
633 file_stream.
PushText(buffer.str().c_str());
643 file_stream.OpenElement(
"UseBoundingLayer");
659 buffer <<
"OpenNN Exception: BoundingLayer class.\n"
660 <<
"void write_XML(tinyxml2::XMLPrinter&) const method.\n"
661 <<
"Unknown bounding method type.\n";
663 throw logic_error(buffer.str());
666 file_stream.
PushText(buffer.str().c_str());
692 ostringstream buffer;
694 const tinyxml2::XMLElement* bounding_layer_element = document.FirstChildElement(
"BoundingLayer");
696 if(!bounding_layer_element)
698 buffer <<
"OpenNN Exception: BoundingLayer class.\n"
699 <<
"void from_XML(const tinyxml2::XMLDocument&) method.\n"
700 <<
"BoundingLayer element is nullptr.\n";
702 throw logic_error(buffer.str());
707 const tinyxml2::XMLElement* neurons_number_element = bounding_layer_element->FirstChildElement(
"BoundingNeuronsNumber");
709 if(!neurons_number_element)
711 buffer <<
"OpenNN Exception: BoundingLayer class.\n"
712 <<
"void from_XML(const tinyxml2::XMLDocument&) method.\n"
713 <<
"BoundingNeuronsNumber element is nullptr.\n";
715 throw logic_error(buffer.str());
718 const Index neurons_number =
static_cast<Index
>(atoi(neurons_number_element->GetText()));
724 if(neurons_number > 0)
731 start_element = item_element;
735 buffer <<
"OpenNN Exception: BoundingLayer class.\n"
736 <<
"void from_XML(const tinyxml2::XMLElement*) method.\n"
737 <<
"Item " << i+1 <<
" is nullptr.\n";
739 throw logic_error(buffer.str());
746 buffer <<
"OpenNN Exception: BoundingLayer class.\n"
747 <<
"void from_XML(const tinyxml2::XMLElement*) method.\n"
748 <<
"Index " << index <<
" is not correct.\n";
750 throw logic_error(buffer.str());
755 const tinyxml2::XMLElement* lower_bound_element = item_element->FirstChildElement(
"LowerBound");
757 if(lower_bound_element)
759 if(lower_bound_element->GetText())
761 lower_bounds[index-1] =
static_cast<type
>(atof(lower_bound_element->GetText()));
767 const tinyxml2::XMLElement* upper_bound_element = item_element->FirstChildElement(
"UpperBound");
769 if(upper_bound_element)
771 if(upper_bound_element->GetText())
773 upper_bounds[index-1] =
static_cast<type
>(atof(upper_bound_element->GetText()));
781 const tinyxml2::XMLElement* use_bounding_layer_element = bounding_layer_element->FirstChildElement(
"UseBoundingLayer");
783 if(use_bounding_layer_element)
785 Index new_method =
static_cast<Index
>(atoi(use_bounding_layer_element->GetText()));
791 else if(new_method == 0)
797 buffer <<
"OpenNN Exception: BoundingLayer class.\n"
798 <<
"void from_XML(const tinyxml2::XMLElement*) method.\n"
799 <<
"Unknown bounding method.\n";
801 throw logic_error(buffer.str());
This class represents a layer of bounding neurons.
void set_lower_bounds(const Tensor< type, 1 > &)
string write_expression_c() const
BoundingLayer::write_expression_c.
void set_upper_bound(const Index &, const type &)
type get_upper_bound(const Index &) const
void set_lower_bound(const Index &, const type &)
Index get_inputs_number() const
Get number of inputs.
string write_expression(const Tensor< string, 1 > &, const Tensor< string, 1 > &) const
Returns a string with the expression of the lower and upper bounds functions.
void from_XML(const tinyxml2::XMLDocument &)
string write_expression_python() const
BoundingLayer::write_expression_python.
bool display
Display messages to screen.
Tensor< type, 1 > lower_bounds
Lower bounds of output variables.
bool is_empty() const
Returns true if the size of the layer is zero, and false otherwise.
BoundingMethod
Enumeration of available methods for bounding the output variables.
const BoundingMethod & get_bounding_method() const
Returns the method used for bounding layer.
void set_inputs_number(const Index &)
Tensor< type, 2 > calculate_outputs(const Tensor< type, 2 > &)
Index get_neurons_number() const
Return the neurons number in the bounding layer.
void set_upper_bounds(const Tensor< type, 1 > &)
const Tensor< type, 1 > & get_upper_bounds() const
Returns the upper bounds values of all the bounding neurons in the layer.
const Tensor< type, 1 > & get_lower_bounds() const
Returns the lower bounds values of all the bounding neurons in the layer.
BoundingMethod bounding_method
Method used to bound the values.
void set_display(const bool &)
void write_XML(tinyxml2::XMLPrinter &) const
string write_bounding_method() const
Returns a string writing if use bounding layer or not.
void set_bounding_method(const BoundingMethod &)
void set_neurons_number(const Index &)
Tensor< type, 1 > upper_bounds
Upper bounds of output variables.
type get_lower_bound(const Index &) const
This abstract class represents the concept of layer of neurons in OpenNN.
string layer_name
Layer name.
Type layer_type
Layer type.
XMLError QueryUnsignedAttribute(const char *name, unsigned int *value) const
See QueryIntAttribute()
const XMLElement * NextSiblingElement(const char *name=nullptr) const
Get the next(right) sibling element of this node, with an optionally supplied name.
void PushText(const char *text, bool cdata=false)
Add a text node.
void PushAttribute(const char *name, const char *value)
If streaming, add an attribute to an open element.
virtual void CloseElement(bool compactMode=false)
If streaming, close the Element.