24 #ifndef PPL_linearize_hh
25 #define PPL_linearize_hh 1
108 template <
typename Target,
typename FP_Interval_Type>
119 if (!linearize(*(bop_expr.left_hand_side()), oracle, lf_store, result)) {
124 bop_expr.type().floating_point_format();
125 FP_Linear_Form rel_error;
128 FP_Linear_Form linearized_second_operand;
129 if (!linearize(*(bop_expr.right_hand_side()), oracle, lf_store,
130 linearized_second_operand)) {
134 result += linearized_second_operand;
135 linearized_second_operand.
relative_error(analyzed_format, rel_error);
137 FP_Interval_Type absolute_error =
138 compute_absolute_error<FP_Interval_Type>(analyzed_format);
139 result += absolute_error;
222 template <
typename Target,
typename FP_Interval_Type>
232 if (!linearize(*(bop_expr.left_hand_side()), oracle, lf_store, result)) {
237 bop_expr.type().floating_point_format();
238 FP_Linear_Form rel_error;
241 FP_Linear_Form linearized_second_operand;
242 if (!linearize(*(bop_expr.right_hand_side()), oracle, lf_store,
243 linearized_second_operand)) {
247 result -= linearized_second_operand;
248 linearized_second_operand.
relative_error(analyzed_format, rel_error);
250 FP_Interval_Type absolute_error =
251 compute_absolute_error<FP_Interval_Type>(analyzed_format);
252 result += absolute_error;
364 template <
typename Target,
typename FP_Interval_Type>
372 typedef typename FP_Interval_Type::boundary_type analyzer_format;
388 bool intervalize_first;
389 FP_Linear_Form linearized_first_operand;
390 if (!linearize(*(bop_expr.left_hand_side()), oracle, lf_store,
391 linearized_first_operand)) {
394 FP_Interval_Type intervalized_first_operand;
395 if (!linearized_first_operand.intervalize(oracle,
396 intervalized_first_operand)) {
399 FP_Linear_Form linearized_second_operand;
400 if (!linearize(*(bop_expr.right_hand_side()), oracle, lf_store,
401 linearized_second_operand)) {
404 FP_Interval_Type intervalized_second_operand;
405 if (!linearized_second_operand.intervalize(oracle,
406 intervalized_second_operand)) {
411 if (intervalized_first_operand.is_bounded()) {
412 if (intervalized_second_operand.is_bounded()) {
413 analyzer_format first_interval_size
414 = intervalized_first_operand.upper()
415 - intervalized_first_operand.lower();
416 analyzer_format second_interval_size
417 = intervalized_second_operand.upper()
418 - intervalized_second_operand.lower();
419 if (first_interval_size <= second_interval_size) {
420 intervalize_first =
true;
423 intervalize_first =
false;
427 intervalize_first =
true;
431 if (intervalized_second_operand.is_bounded()) {
432 intervalize_first =
false;
442 bop_expr.type().floating_point_format();
443 if (intervalize_first) {
444 linearized_second_operand.relative_error(analyzed_format, result);
445 linearized_second_operand *= intervalized_first_operand;
446 result *= intervalized_first_operand;
447 result += linearized_second_operand;
451 linearized_first_operand *= intervalized_second_operand;
452 result *= intervalized_second_operand;
453 result += linearized_first_operand;
456 FP_Interval_Type absolute_error =
457 compute_absolute_error<FP_Interval_Type>(analyzed_format);
458 result += absolute_error;
558 template <
typename Target,
typename FP_Interval_Type>
568 FP_Linear_Form linearized_second_operand;
569 if (!linearize(*(bop_expr.right_hand_side()), oracle, lf_store,
570 linearized_second_operand)) {
573 FP_Interval_Type intervalized_second_operand;
574 if (!linearized_second_operand.intervalize(oracle,
575 intervalized_second_operand)) {
579 if ((intervalized_second_operand.lower_is_boundary_infinity()
580 || intervalized_second_operand.lower() <= 0) &&
581 (intervalized_second_operand.upper_is_boundary_infinity()
582 || intervalized_second_operand.upper() >= 0)) {
585 if (!linearize(*(bop_expr.left_hand_side()), oracle, lf_store, result)) {
590 bop_expr.type().floating_point_format();
591 FP_Linear_Form rel_error;
593 result /= intervalized_second_operand;
594 rel_error /= intervalized_second_operand;
596 FP_Interval_Type absolute_error =
597 compute_absolute_error<FP_Interval_Type>(analyzed_format);
598 result += absolute_error;
633 template <
typename Target,
typename FP_Interval_Type>
639 typedef typename FP_Interval_Type::boundary_type analyzer_format;
643 cast_expr.type().floating_point_format();
645 if (cast_arg->type().is_floating_point()) {
646 if (!linearize(*cast_arg, oracle, lf_store, result)) {
650 cast_arg->type().floating_point_format())
651 || result == FP_Linear_Form(FP_Interval_Type(0))
652 || result == FP_Linear_Form(FP_Interval_Type(1))) {
665 FP_Interval_Type expr_value;
668 result = FP_Linear_Form(expr_value);
670 || result == FP_Linear_Form(FP_Interval_Type(0))
671 || result == FP_Linear_Form(FP_Interval_Type(1))) {
684 FP_Linear_Form rel_error;
687 FP_Interval_Type absolute_error =
688 compute_absolute_error<FP_Interval_Type>(analyzed_format);
689 result += absolute_error;
727 template <
typename Target,
typename FP_Interval_Type>
733 typedef typename FP_Interval_Type::boundary_type analyzer_format;
735 typedef std::map<dimension_type, FP_Linear_Form>
736 FP_Linear_Form_Abstract_Store;
738 PPL_ASSERT(expr.type().is_floating_point());
741 "linearize<Target, FP_Interval_Type>:"
742 " FP_Interval_Type is not the type of an interval with floating point boundaries.");
744 switch(expr.kind()) {
751 expr.template as<Floating_Point_Constant>();
752 FP_Interval_Type constant_value;
756 result = FP_Linear_Form(constant_value);
762 expr.template as<Unary_Operator>();
763 switch (uop_expr->unary_operator()) {
765 return linearize(*(uop_expr->argument()), oracle, lf_store, result);
767 if (!linearize(*(uop_expr->argument()), oracle, lf_store, result)) {
774 throw std::runtime_error(
"PPL internal error: unimplemented");
785 expr.template as<Binary_Operator>();
786 switch (bop_expr->binary_operator()) {
788 return add_linearize(*bop_expr, oracle, lf_store, result);
790 return sub_linearize(*bop_expr, oracle, lf_store, result);
792 return mul_linearize(*bop_expr, oracle, lf_store, result);
794 return div_linearize(*bop_expr, oracle, lf_store, result);
812 expr.template as<Approximable_Reference>();
813 std::set<dimension_type> associated_dimensions;
815 || associated_dimensions.empty()) {
823 if (associated_dimensions.size() == 1) {
830 typename FP_Linear_Form_Abstract_Store::const_iterator
831 variable_value = lf_store.find(variable_index);
832 if (variable_value == lf_store.end()) {
833 result = FP_Linear_Form(
Variable(variable_index));
837 result = FP_Linear_Form(variable_value->second);
847 PPL_ASSERT(associated_dimensions.size() > 1);
848 std::set<dimension_type>::const_iterator i
849 = associated_dimensions.begin();
850 std::set<dimension_type>::const_iterator i_end
851 = associated_dimensions.end();
852 FP_Interval_Type lub(
EMPTY);
853 for (; i != i_end; ++i) {
854 FP_Interval_Type curr_int;
860 lub.join_assign(curr_int);
863 result = FP_Linear_Form(lub);
869 expr.template as<Cast_Operator>();
870 return cast_linearize(*cast_expr, oracle, lf_store, result);
883 #endif // !defined(PPL_linearize_hh)
A cast operator converting one concrete expression to some type.
The empty element, i.e., the empty set.
virtual bool get_interval(dimension_type dim, FP_Interval_Type &result) const =0
Asks the external analyzer for an interval that correctly approximates the floating point entity refe...
virtual bool get_fp_constant_value(const Floating_Point_Constant< Target > &expr, FP_Interval_Type &result) const =0
Asks the external analyzer for an interval that correctly approximates the value of floating point co...
An abstract class to be implemented by an external analyzer such as ECLAIR in order to provide to the...
size_t dimension_type
An unsigned integral type for representing space dimensions.
static bool cast_linearize(const Cast_Operator< Target > &cast_expr, const FP_Oracle< Target, FP_Interval_Type > &oracle, const std::map< dimension_type, Linear_Form< FP_Interval_Type > > &lf_store, Linear_Form< FP_Interval_Type > &result)
dimension_type not_a_dimension()
Returns a value that does not designate a valid dimension.
static bool sub_linearize(const Binary_Operator< Target > &bop_expr, const FP_Oracle< Target, FP_Interval_Type > &oracle, const std::map< dimension_type, Linear_Form< FP_Interval_Type > > &lf_store, Linear_Form< FP_Interval_Type > &result)
An integer constant concrete expression.
A binary operator applied to two concrete expressions.
A dimension of the vector space.
A unary operator applied to one concrete expression.
#define PPL_COMPILE_TIME_CHECK(e, msg)
Produces a compilation error if the compile-time constant e does not evaluate to true ...
bool is_less_precise_than(Floating_Point_Format f1, Floating_Point_Format f2)
A concrete expression representing a reference to some approximable.
virtual bool get_associated_dimensions(const Approximable_Reference< Target > &expr, std::set< dimension_type > &result) const =0
Asks the external analyzer for the possible space dimensions that are associated to the approximable ...
static bool add_linearize(const Binary_Operator< Target > &bop_expr, const FP_Oracle< Target, FP_Interval_Type > &oracle, const std::map< dimension_type, Linear_Form< FP_Interval_Type > > &lf_store, Linear_Form< FP_Interval_Type > &result)
bool linearize(const Concrete_Expression< Target > &expr, const FP_Oracle< Target, FP_Interval_Type > &oracle, const std::map< dimension_type, Linear_Form< FP_Interval_Type > > &lf_store, Linear_Form< FP_Interval_Type > &result)
Linearizes a floating point expression.
The base class of all concrete expressions.
virtual bool get_integer_expr_value(const Concrete_Expression< Target > &expr, FP_Interval_Type &result) const =0
Asks the external analyzer for an interval that correctly approximates the value of expr...
The entire library is confined to this namespace.
A floating-point constant concrete expression.
static bool mul_linearize(const Binary_Operator< Target > &bop_expr, const FP_Oracle< Target, FP_Interval_Type > &oracle, const std::map< dimension_type, Linear_Form< FP_Interval_Type > > &lf_store, Linear_Form< FP_Interval_Type > &result)
static bool div_linearize(const Binary_Operator< Target > &bop_expr, const FP_Oracle< Target, FP_Interval_Type > &oracle, const std::map< dimension_type, Linear_Form< FP_Interval_Type > > &lf_store, Linear_Form< FP_Interval_Type > &result)