carl  24.04
Computer ARithmetic Library
Sign.h
Go to the documentation of this file.
1 /**
2  * @file Sign.h
3  * @author Sebastian Junges
4  *
5  * @since August 23, 2013
6  */
7 
8 #pragma once
9 
12 
13 #include <functional>
14 #include <iostream>
15 
16 namespace carl {
17 /**
18  * This class represents the sign of a number \f$n\f$.
19  */
20 enum class Sign {
21  /// Indicates that \f$n < 0\f$.
22  NEGATIVE = -1,
23  /// Indicates that \f$n = 0\f$.
24  ZERO = 0,
25  /// Indicates that \f$n > 0\f$.
26  POSITIVE = 1
27 };
28 
29 inline std::ostream& operator<<(std::ostream& os, const Sign& sign) {
30  switch (sign) {
31  case Sign::NEGATIVE:
32  os << "NEGATIVE";
33  break;
34  case Sign::ZERO:
35  os << "ZERO";
36  break;
37  case Sign::POSITIVE:
38  os << "POSITIVE";
39  break;
40  default:
41  CARL_LOG_ERROR("carl.sign", "Invalid sign " << std::underlying_type_t<Sign>(sign));
42  assert(false && "Invalid sign");
43  }
44  return os;
45 }
46 
47 /**
48  * Obtain the sign of the given number.
49  * This method relies on the comparison operators for the type of the given number.
50  * @param n Number
51  * @return Sign of n
52  */
53 template<typename Number>
54 Sign sgn(const Number& n) {
57  return Sign::ZERO;
58 }
59 
60 /**
61  * Counts the number of sign variations in the given object range.
62  *
63  * The function accepts an range of Sign objects.
64  * @param begin Start of object range.
65  * @param end End of object range.
66  * @return Sign variations of objects.
67  */
68 template<typename InputIterator>
69 std::size_t sign_variations(InputIterator begin, InputIterator end) {
70  while ((*begin == Sign::ZERO) && (begin != end))
71  ++begin;
72 
73  std::size_t changes = 0;
74  for (Sign last = *begin; begin != end; ++begin) {
75  if (*begin == Sign::ZERO) continue;
76  if (*begin != last) ++changes;
77  last = *begin;
78  }
79  return changes;
80 }
81 
82 /**
83  * Counts the number of sign variations in the given object range.
84  *
85  * The function accepts an object range and an additional function f.
86  * If the objects are not of type Sign, the function f can be used to convert the objects to a Sign on the fly.
87  * As for the number of sign variations in the evaluations of polynomials <code>p</code> at a position <code>x</code>, this might look like this:
88  * `signVariations(p.begin(), p.end(), [&x](const Polynomial& p){ return sgn(p.evaluate(x)); });`
89  * @param begin Start of object range.
90  * @param end End of object range.
91  * @param f Function object to convert objects to Sign.
92  * @return Sign variations of objects.
93  */
94 template<typename InputIterator, typename Function>
95 std::size_t sign_variations(InputIterator begin, InputIterator end, const Function& f) {
96  while ((begin != end) && (f(*begin) == Sign::ZERO))
97  ++begin;
98  if (begin == end) return 0;
99 
100  std::size_t changes = 0;
101  for (Sign last = f(*begin); begin != end; ++begin) {
102  if (f(*begin) == Sign::ZERO) continue;
103  if (f(*begin) != last) ++changes;
104  last = f(*begin);
105  }
106  return changes;
107 }
108 
109 } // namespace carl
A small wrapper that configures logging for carl.
#define CARL_LOG_ERROR(channel, msg)
Definition: carl-logging.h:40
carl is the main namespace for the library.
std::ostream & operator<<(std::ostream &os, const BasicConstraint< Poly > &c)
Prints the given constraint on the given stream.
std::size_t sign_variations(InputIterator begin, InputIterator end)
Counts the number of sign variations in the given object range.
Definition: Sign.h:69
Sign
This class represents the sign of a number .
Definition: Sign.h:20
@ NEGATIVE
Indicates that .
@ ZERO
Indicates that .
@ POSITIVE
Indicates that .
Sign sgn(const Number &n)
Obtain the sign of the given number.
Definition: Sign.h:54