Happy New Year!
[ginac.git] / ginac / flags.h
1 /** @file flags.h
2  *
3  *  Collection of all flags used through the GiNaC framework. */
4
5 /*
6  *  GiNaC Copyright (C) 1999-2019 Johannes Gutenberg University Mainz, Germany
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22
23 #ifndef GINAC_FLAGS_H
24 #define GINAC_FLAGS_H
25
26 namespace GiNaC {
27
28 /** Flags to control the behavior of expand(). */
29 class expand_options {
30 public:
31         enum {
32                 expand_indexed = 0x0001,      ///< expands (a+b).i to a.i+b.i
33                 expand_function_args = 0x0002, ///< expands the arguments of functions
34                 expand_rename_idx = 0x0004, ///< used internally by mul::expand()
35                 expand_transcendental = 0x0008 ///< expands transcendental functions like log and exp
36         };
37 };
38
39 /** Flags to control the behavior of has(). */
40 class has_options {
41 public:
42         enum {
43                 algebraic = 0x0001              ///< enable algebraic matching
44         };
45 };
46
47 /** Flags to control the behavior of subs(). */
48 class subs_options {
49 public:
50         enum {
51                 no_pattern = 0x0001,             ///< disable pattern matching
52                 subs_no_pattern = 0x0001, // for backwards compatibility
53                 algebraic = 0x0002,              ///< enable algebraic substitutions
54                 subs_algebraic = 0x0002,  // for backwards compatibility
55                 pattern_is_product = 0x0004,     ///< used internally by expairseq::subschildren()
56                 pattern_is_not_product = 0x0008, ///< used internally by expairseq::subschildren()
57                 no_index_renaming = 0x0010,
58                 // To indicate that we want to substitute an index by something that
59                 // is not an index. Without this flag the index value would be
60                 // substituted in that case.
61                 really_subs_idx = 0x0020
62         };
63 };
64
65 /** Domain of an object */
66 class domain {
67 public:
68         enum {
69                 complex,
70                 real,
71                 positive
72         };
73 };
74
75 /** Flags to control series expansion. */
76 class series_options {
77 public:
78         enum {
79                 /** Suppress branch cuts in series expansion.  Branch cuts manifest
80                  *  themselves as step functions, if this option is not passed.  If
81                  *  it is passed and expansion at a point on a cut is performed, then
82                  *  the analytic continuation of the function is expanded. */
83                 suppress_branchcut = 0x0001
84         };
85 };
86
87 /** Switch to control algorithm for determinant computation. */
88 class determinant_algo {
89 public:
90         enum {
91                 /** Let the system choose.  A heuristics is applied for automatic
92                  *  determination of a suitable algorithm. */
93                 automatic,
94                 /** Gauss elimination.  If \f$m_{i,j}^{(0)}\f$ are the entries of the
95                  *  original matrix, then the matrix is transformed into triangular
96                  *  form by applying the rules
97                  *  \f[
98                  *      m_{i,j}^{(k+1)} = m_{i,j}^{(k)} - m_{i,k}^{(k)} m_{k,j}^{(k)} / m_{k,k}^{(k)}
99                  *  \f]
100                  *  The determinant is then just the product of diagonal elements.
101                  *  Choose this algorithm only for purely numerical matrices. */
102                 gauss,
103                 /** Division-free elimination.  This is a modification of Gauss
104                  *  elimination where the division by the pivot element is not
105                  *  carried out.  If \f$m_{i,j}^{(0)}\f$ are the entries of the
106                  *  original matrix, then the matrix is transformed into triangular
107                  *  form by applying the rules
108                  *  \f[
109                  *      m_{i,j}^{(k+1)} = m_{i,j}^{(k)} m_{k,k}^{(k)} - m_{i,k}^{(k)} m_{k,j}^{(k)}
110                  *  \f]
111                  *  The determinant can later be computed by inspecting the diagonal
112                  *  elements only.  This algorithm is only there for the purpose of
113                  *  cross-checks.  It is never fast. */
114                 divfree,
115                 /** Laplace elimination.  This is plain recursive elimination along
116                  *  minors although multiple minors are avoided by the algorithm.
117                  *  Although the algorithm is exponential in complexity it is
118                  *  frequently the fastest one when the matrix is populated by
119                  *  complicated symbolic expressions. */
120                 laplace,
121                 /** Bareiss fraction-free elimination.  This is a modification of
122                  *  Gauss elimination where the division by the pivot element is
123                  *  <EM>delayed</EM> until it can be carried out without computing
124                  *  GCDs.  If \f$m_{i,j}^{(0)}\f$ are the entries of the original
125                  *  matrix, then the matrix is transformed into triangular form by
126                  *  applying the rules
127                  *  \f[
128                  *      m_{i,j}^{(k+1)} = (m_{i,j}^{(k)} m_{k,k}^{(k)} - m_{i,k}^{(k)} m_{k,j}^{(k)}) / m_{k-1,k-1}^{(k-1)}
129                  *  \f]
130                  *  (We have set \f$m_{-1,-1}^{(-1)}=1\f$ in order to avoid a case
131                  *  distinction in above formula.)  It can be shown that nothing more
132                  *  than polynomial long division is needed for carrying out the
133                  *  division.  The determinant can then be read of from the lower
134                  *  right entry.  This algorithm is rarely fast for computing
135                  *  determinants. */
136                 bareiss
137         };
138 };
139
140 /** Switch to control algorithm for linear system solving. */
141 class solve_algo {
142 public:
143         enum {
144                 /** Let the system choose.  A heuristics is applied for automatic
145                  *  determination of a suitable algorithm. */
146                 automatic,
147                 /** Gauss elimination.  If \f$m_{i,j}^{(0)}\f$ are the entries of the
148                  *  original matrix, then the matrix is transformed into triangular
149                  *  form by applying the rules
150                  *  \f[
151                  *      m_{i,j}^{(k+1)} = m_{i,j}^{(k)} - m_{i,k}^{(k)} m_{k,j}^{(k)} / m_{k,k}^{(k)}
152                  *  \f]
153                  *  This algorithm is well-suited for numerical matrices but generally
154                  *  suffers from the expensive division (and computation of GCDs) at
155                  *  each step. */
156                 gauss,
157                 /** Division-free elimination.  This is a modification of Gauss
158                  *  elimination where the division by the pivot element is not
159                  *  carried out.  If \f$m_{i,j}^{(0)}\f$ are the entries of the
160                  *  original matrix, then the matrix is transformed into triangular
161                  *  form by applying the rules
162                  *  \f[
163                  *      m_{i,j}^{(k+1)} = m_{i,j}^{(k)} m_{k,k}^{(k)} - m_{i,k}^{(k)} m_{k,j}^{(k)}
164                  *  \f]
165                  *  This algorithm is only there for the purpose of cross-checks.
166                  *  It suffers from exponential intermediate expression swell.  Use it
167                  *  only for small systems. */
168                 divfree,
169                 /** Bareiss fraction-free elimination.  This is a modification of
170                  *  Gauss elimination where the division by the pivot element is
171                  *  <EM>delayed</EM> until it can be carried out without computing
172                  *  GCDs.  If \f$m_{i,j}^{(0)}\f$ are the entries of the original
173                  *  matrix, then the matrix is transformed into triangular form by
174                  *  applying the rules
175                  *  \f[
176                  *      m_{i,j}^{(k+1)} = (m_{i,j}^{(k)} m_{k,k}^{(k)} - m_{i,k}^{(k)} m_{k,j}^{(k)}) / m_{k-1,k-1}^{(k-1)}
177                  *  \f]
178                  *  (We have set \f$m_{-1,-1}^{(-1)}=1\f$ in order to avoid a case
179                  *  distinction in above formula.)  It can be shown that nothing more
180                  *  than polynomial long division is needed for carrying out the
181                  *  division.  This is generally the fastest algorithm for solving
182                  *  linear systems.  In contrast to division-free elimination it only
183                  *  has a linear expression swell.  For two-dimensional systems, the
184                  *  two algorithms are equivalent, however. */
185                 bareiss,
186                 /** Markowitz-ordered Gaussian elimination. Same as the usual
187                  *  Gaussian elimination, but with additional effort spent on
188                  *  selecting pivots that minimize fill-in. Faster than the
189                  *  methods above for large sparse matrices (particularly with
190                  *  symbolic coefficients), otherwise slightly slower than
191                  *  Gaussian elimination.
192                  */
193                 markowitz
194         };
195 };
196
197 /** Flags to store information about the state of an object.
198  *  @see basic::flags */
199 class status_flags {
200 public:
201         enum {
202                 dynallocated    = 0x0001, ///< heap-allocated (i.e. created by new if we want to be clever and bypass the stack, @see ex::construct_from_basic() )
203                 evaluated       = 0x0002, ///< .eval() has already done its job
204                 expanded        = 0x0004, ///< .expand(0) has already done its job (other expand() options ignore this flag)
205                 hash_calculated = 0x0008, ///< .calchash() has already done its job
206                 not_shareable   = 0x0010, ///< don't share instances of this object between different expressions unless explicitly asked to (used by ex::compare())
207                 has_indices     = 0x0020,
208                 has_no_indices  = 0x0040, // ! (has_indices || has_no_indices) means "don't know"
209                 is_positive     = 0x0080,
210                 is_negative     = 0x0100,
211                 purely_indefinite = 0x0200  // If set in a mul, then it does not contains any terms with determined signs, used in power::expand()
212         };
213 };
214
215 /** Possible attributes an object can have. */
216 class info_flags {
217 public:
218         enum {
219                 // answered by class numeric, add, mul, function and symbols/constants in particular domains
220                 numeric,
221                 real,
222                 rational,
223                 integer,
224                 crational,
225                 cinteger,
226                 positive,
227                 negative,
228                 nonnegative,
229                 posint,
230                 negint,
231                 nonnegint,
232                 even,
233                 odd,
234                 prime,
235
236                 // answered by class relation
237                 relation,
238                 relation_equal,
239                 relation_not_equal,
240                 relation_less,
241                 relation_less_or_equal,
242                 relation_greater,
243                 relation_greater_or_equal,
244
245                 // answered by class symbol
246                 symbol,
247
248                 // answered by class lst
249                 list,
250
251                 // answered by class exprseq
252                 exprseq,
253
254                 // answered by classes numeric, symbol, add, mul, power
255                 polynomial,
256                 integer_polynomial,
257                 cinteger_polynomial,
258                 rational_polynomial,
259                 crational_polynomial,
260                 rational_function,
261
262                 // answered by class indexed
263                 indexed,      // class can carry indices
264                 has_indices,  // object has at least one index
265
266                 // answered by class idx
267                 idx,
268
269                 // answered by classes numeric, symbol, add, mul, power
270                 expanded,
271
272                 // is meaningful for mul only
273                 indefinite
274         };
275 };
276
277 class return_types {
278 public:
279         enum {
280                 commutative,
281                 noncommutative,
282                 noncommutative_composite
283         };
284 };
285
286 /** Strategies how to clean up the function remember cache.
287  *  @see remember_table */
288 class remember_strategies {
289 public:
290         enum {
291                 delete_never,   ///< Let table grow undefinitely
292                 delete_lru,     ///< Least recently used
293                 delete_lfu,     ///< Least frequently used
294                 delete_cyclic   ///< First (oldest) one in list
295         };
296 };
297
298 /** Flags to control the polynomial factorization. */
299 class factor_options {
300 public:
301         enum {
302                 polynomial = 0x0000, ///< factor only expressions that are polynomials
303                 all        = 0x0001  ///< factor all polynomial subexpressions
304         };
305 };
306
307 } // namespace GiNaC
308
309 #endif // ndef GINAC_FLAGS_H