carl  24.04
Computer ARithmetic Library
SqrtEx.h
Go to the documentation of this file.
1 /**
2  * Class to create a square root expression object.
3  * @author Florian Corzilius
4  * @since 2011-05-26
5  * @version 2013-10-22
6  */
7 
8 #pragma once
9 
11 
14 
15 #include <cassert>
16 #include <iostream>
17 
18 namespace carl
19 {
20  template<typename Poly>
21  class SqrtEx {
22  public:
24  private:
25  /// The constant part c of this square root expression (c + f * sqrt(r))/d.
27  /// The factor f of this square root expression (c + f * sqrt(r))/d.
28  Poly m_factor;
29  /// The denominator d of this square root expression (c + f * sqrt(r))/d.
31  /// The radicand r of this square root expression (c + f * sqrt(r))/d.
32  Poly m_radicand;
33 
34  public:
35  /**
36  * Default Constructor. ( constructs (0 + 0 * sqrt( 0 )) / 1 )
37  */
38  SqrtEx();
39 
40  /**
41  * Constructs a square root expression from a polynomial p leading to (p + 0 * sqrt( 0 )) / 1
42  * @param _poly The polynomial to construct a square root expression for.
43  */
44  explicit SqrtEx( Poly&& _poly );
45  explicit SqrtEx( const Poly& _poly ) :
46  SqrtEx::SqrtEx( Poly( _poly ) )
47  {}
48 
49  explicit SqrtEx( Variable::Arg _var ) :
50  SqrtEx( Poly( _var ) )
51  {}
52 
53  /**
54  * Constructs a square root expression from given constant part, factor, denominator and radicand.
55  * @param _constantPart The constant part of the square root expression to construct.
56  * @param _factor The factor of the square root expression to construct.
57  * @param _denominator The denominator of the square root expression to construct.
58  * @param _radicand The radicand of the square root expression to construct.
59  */
60  SqrtEx( const Poly& _constantPart, const Poly& _factor, const Poly& _denominator, const Poly& _radicand ):
61  SqrtEx( Poly( _constantPart ), Poly( _factor ), Poly( _denominator ), Poly( _radicand ) )
62  {}
63 
64  SqrtEx( Poly&& _constantPart, Poly&& _factor, Poly&& _denominator, Poly&& _radicand );
65 
66  /**
67  * @return A constant reference to the constant part of this square root expression.
68  */
69  const Poly& constant_part() const
70  {
71  return m_constant_part;
72  }
73 
74  /**
75  * @return A constant reference to the factor of this square root expression.
76  */
77  const Poly& factor() const
78  {
79  return m_factor;
80  }
81 
82  /**
83  * @return A constant reference to the denominator of this square root expression.
84  */
85  const Poly& denominator() const
86  {
87  return m_denominator;
88  }
89 
90  /**
91  * @return A constant reference to the radicand of this square root expression.
92  */
93  const Poly& radicand() const
94  {
95  return m_radicand;
96  }
97 
98  /**
99  * @return true, if the square root expression has a non trivial radicand;
100  * false, otherwise.
101  */
102  bool has_sqrt() const
103  {
104  return !carl::is_zero(m_factor);
105  }
106 
107  /**
108  * @return true, if the square root expression can be expressed as a polynomial;
109  * false, otherwise.
110  */
111  bool is_polynomial() const
112  {
113  return carl::is_zero(m_factor) && m_denominator.is_constant();
114  }
115 
116  /**
117  * @return The square root expression as a polynomial (note that there must be no square root nor denominator
118  */
119  Poly as_polynomial() const
120  {
121  assert( is_polynomial() );
122  assert( !carl::is_zero(m_denominator) );
123  return m_constant_part / m_denominator.constant_part();
124  }
125 
126  /**
127  * @return true, if there is no variable in this square root expression;
128  * false, otherwise.
129  */
130  bool is_constant() const
131  {
132  return m_constant_part.is_constant() && m_denominator.is_constant() && m_factor.is_constant() && m_radicand.is_constant();
133  }
134 
135  /**
136  * @return This sqrtEx as an integer (note, that it must actually represent an integer then).
137  */
139  {
140  assert( is_constant() );
141  return m_constant_part.constant_part();
142  }
143 
144  /**
145  * @return true, if there is no variable in this square root expression;
146  * false, otherwise.
147  */
148  bool isRational() const
149  {
150  return m_constant_part.is_constant() && m_denominator.is_constant() && carl::is_zero(m_radicand);
151  }
152 
153  /**
154  * @return This sqrtEx as a rational (note, that it must actually represent a rational then).
155  */
157  {
158  if( is_constant() )
159  return asConstant();
160  assert( isRational() );
161  return m_constant_part.constant_part()/m_factor.constant_part();
162  }
163 
164  private:
165 
166  /**
167  * Normalizes this object, that is extracts as much as possible from the radicand into the factor
168  * and cancels the enumerator and denominator afterwards.
169  */
170  void normalize();
171 
172  public:
173 
174  /**
175  * @return true, if the this square root expression corresponds to an integer value;
176  * false, otherwise.
177  */
178  bool is_integer() const
179  {
180  return carl::is_zero(radicand()) && carl::is_one(denominator()) &&
181  (carl::is_zero(constant_part()) || (constant_part().is_constant() && carl::is_integer( constant_part().lcoeff() ) ) );
182  }
183 
184  /**
185  * @param _sqrtEx Square root expression to compare with.
186  * @return true, if this square root expression and the given one are equal;
187  * false, otherwise.
188  */
189  bool operator==( const SqrtEx& _toCompareWith ) const;
190 
191  /**
192  * @param _sqrtEx A square root expression, which gets the new content of this square root expression.
193  * @return A reference to this object.
194  */
195  //SqrtEx& operator=( const SqrtEx& _sqrtEx );
196 
197  /**
198  * @param _poly A polynomial, which gets the new content of this square root expression.
199  * @return A reference to this object.
200  */
201  SqrtEx& operator=( const Poly& _poly );
202 
203  /**
204  * @param _summandA First summand.
205  * @param _summandB Second summand.
206  * @return The sum of the given square root expressions.
207  */
208  SqrtEx operator+( const SqrtEx& rhs ) const;
209 
210  /**
211  * @param _minuend Minuend.
212  * @param _subtrahend Subtrahend.
213  * @return The difference of the given square root expressions.
214  */
215  SqrtEx operator-( const SqrtEx& rhs ) const;
216 
217  /**
218  * @param _factorA First factor.
219  * @param _factorB Second factor.
220  * @return The product of the given square root expressions.
221  */
222  SqrtEx operator*( const SqrtEx& rhs ) const;
223 
224  /**
225  * @param _dividend Dividend.
226  * @param _divisor Divisor.
227  * @return The result of the first given square root expression divided by the second one
228  * Note that the second argument is not allowed to contain a square root.
229  */
230  SqrtEx operator/( const SqrtEx& rhs ) const;
231 
232  /**
233  * Prints the given square root expression on the given stream.
234  * @param _out The stream to print on.
235  * @param _sqrtEx The square root expression to print.
236  * @return The stream after printing the square root expression on it.
237  */
238  template<typename P>
239  friend std::ostream& operator<<( std::ostream& _out, const SqrtEx<P>& _sqrtEx );
240 
241  /**
242  * @param _infix A string which is printed in the beginning of each row.
243  * @param _friendlyNames A flag that indicates whether to print the variables with their internal representation (false)
244  * or with their dedicated names.
245  * @return The string representation of this square root expression.
246  */
247  std::string toString( bool _infix = false, bool _friendlyNames = true ) const;
248  };
249 
250  template<typename Poly>
251  void variables(const SqrtEx<Poly>& ex, carlVariables& vars) {
252  variables(ex.constant_part(), vars);
253  variables(ex.factor(), vars);
254  variables(ex.denominator(), vars);
255  variables(ex.radicand(), vars);
256  }
257 
258 } // end namspace vs
259 
260 namespace std
261 {
262  /**
263  * Implements std::hash for square root expressions.
264  */
265  template<typename Poly>
266  struct hash<carl::SqrtEx<Poly>>
267  {
268  public:
269  /**
270  * @param _sqrtEx The square root expression to get the hash for.
271  * @return The hash of the given square root expression.
272  */
273  std::size_t operator()( const carl::SqrtEx<Poly>& _sqrtEx ) const
274  {
275  return ((hash<Poly>()(_sqrtEx.radicand()) ^ hash<Poly>()(_sqrtEx.denominator())) ^ hash<Poly>()(_sqrtEx.factor())) ^ hash<Poly>()(_sqrtEx.constant_part());
276  }
277  };
278 } // namespace std
279 
280 #include "SqrtEx.tpp"
carl is the main namespace for the library.
bool is_zero(const Interval< Number > &i)
Check if this interval is a point-interval containing 0.
Definition: Interval.h:1453
bool is_integer(const Interval< Number > &n)
Definition: Interval.h:1445
void variables(const BasicConstraint< Pol > &c, carlVariables &vars)
bool is_one(const Interval< Number > &i)
Check if this interval is a point-interval containing 1.
Definition: Interval.h:1462
A Variable represents an algebraic variable that can be used throughout carl.
Definition: Variable.h:85
T type
A type associated with the type.
Definition: typetraits.h:77
Poly m_denominator
The denominator d of this square root expression (c + f * sqrt(r))/d.
Definition: SqrtEx.h:30
SqrtEx operator-(const SqrtEx &rhs) const
bool is_polynomial() const
Definition: SqrtEx.h:111
Poly m_radicand
The radicand r of this square root expression (c + f * sqrt(r))/d.
Definition: SqrtEx.h:32
const Poly & radicand() const
Definition: SqrtEx.h:93
SqrtEx(const Poly &_constantPart, const Poly &_factor, const Poly &_denominator, const Poly &_radicand)
Constructs a square root expression from given constant part, factor, denominator and radicand.
Definition: SqrtEx.h:60
SqrtEx(Poly &&_poly)
Constructs a square root expression from a polynomial p leading to (p + 0 * sqrt( 0 )) / 1.
bool is_integer() const
Definition: SqrtEx.h:178
SqrtEx(const Poly &_poly)
Definition: SqrtEx.h:45
bool has_sqrt() const
Definition: SqrtEx.h:102
Rational asRational() const
Definition: SqrtEx.h:156
Poly as_polynomial() const
Definition: SqrtEx.h:119
SqrtEx & operator=(const Poly &_poly)
bool is_constant() const
Definition: SqrtEx.h:130
const Poly & constant_part() const
Definition: SqrtEx.h:69
const Poly & denominator() const
Definition: SqrtEx.h:85
friend std::ostream & operator<<(std::ostream &_out, const SqrtEx< P > &_sqrtEx)
Prints the given square root expression on the given stream.
Poly m_factor
The factor f of this square root expression (c + f * sqrt(r))/d.
Definition: SqrtEx.h:28
bool isRational() const
Definition: SqrtEx.h:148
void normalize()
Normalizes this object, that is extracts as much as possible from the radicand into the factor and ca...
typename UnderlyingNumberType< Poly >::type Rational
Definition: SqrtEx.h:23
std::string toString(bool _infix=false, bool _friendlyNames=true) const
SqrtEx operator*(const SqrtEx &rhs) const
const Poly & factor() const
Definition: SqrtEx.h:77
bool operator==(const SqrtEx &_toCompareWith) const
SqrtEx(Variable::Arg _var)
Definition: SqrtEx.h:49
SqrtEx operator/(const SqrtEx &rhs) const
Poly m_constant_part
The constant part c of this square root expression (c + f * sqrt(r))/d.
Definition: SqrtEx.h:26
SqrtEx()
Default Constructor.
SqrtEx operator+(const SqrtEx &rhs) const
Rational asConstant() const
Definition: SqrtEx.h:138
SqrtEx(Poly &&_constantPart, Poly &&_factor, Poly &&_denominator, Poly &&_radicand)
std::size_t operator()(const carl::SqrtEx< Poly > &_sqrtEx) const
Definition: SqrtEx.h:273