]> www.ginac.de Git - ginac.git/blob - ginac/flags.h
cebc3fd449966d647c6e745081f71bd286ca956b
[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-2018 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                  *  selection pivots that minimize fill-in. Much faster than the
189                  *  methods above for large sparse matrices, marginally slower
190                  *  than Gaussian elimination otherwise. */
191                 markowitz
192         };
193 };
194
195 /** Flags to store information about the state of an object.
196  *  @see basic::flags */
197 class status_flags {
198 public:
199         enum {
200                 dynallocated    = 0x0001, ///< heap-allocated (i.e. created by new if we want to be clever and bypass the stack, @see ex::construct_from_basic() )
201                 evaluated       = 0x0002, ///< .eval() has already done its job
202                 expanded        = 0x0004, ///< .expand(0) has already done its job (other expand() options ignore this flag)
203                 hash_calculated = 0x0008, ///< .calchash() has already done its job
204                 not_shareable   = 0x0010, ///< don't share instances of this object between different expressions unless explicitly asked to (used by ex::compare())
205                 has_indices     = 0x0020,
206                 has_no_indices  = 0x0040, // ! (has_indices || has_no_indices) means "don't know"
207                 is_positive     = 0x0080,
208                 is_negative     = 0x0100,
209                 purely_indefinite = 0x0200  // If set in a mul, then it does not contains any terms with determined signs, used in power::expand()
210         };
211 };
212
213 /** Possible attributes an object can have. */
214 class info_flags {
215 public:
216         enum {
217                 // answered by class numeric, add, mul, function and symbols/constants in particular domains
218                 numeric,
219                 real,
220                 rational,
221                 integer,
222                 crational,
223                 cinteger,
224                 positive,
225                 negative,
226                 nonnegative,
227                 posint,
228                 negint,
229                 nonnegint,
230                 even,
231                 odd,
232                 prime,
233
234                 // answered by class relation
235                 relation,
236                 relation_equal,
237                 relation_not_equal,
238                 relation_less,
239                 relation_less_or_equal,
240                 relation_greater,
241                 relation_greater_or_equal,
242
243                 // answered by class symbol
244                 symbol,
245
246                 // answered by class lst
247                 list,
248
249                 // answered by class exprseq
250                 exprseq,
251
252                 // answered by classes numeric, symbol, add, mul, power
253                 polynomial,
254                 integer_polynomial,
255                 cinteger_polynomial,
256                 rational_polynomial,
257                 crational_polynomial,
258                 rational_function,
259
260                 // answered by class indexed
261                 indexed,      // class can carry indices
262                 has_indices,  // object has at least one index
263
264                 // answered by class idx
265                 idx,
266
267                 // answered by classes numeric, symbol, add, mul, power
268                 expanded,
269
270                 // is meaningful for mul only
271                 indefinite
272         };
273 };
274
275 class return_types {
276 public:
277         enum {
278                 commutative,
279                 noncommutative,
280                 noncommutative_composite
281         };
282 };
283
284 /** Strategies how to clean up the function remember cache.
285  *  @see remember_table */
286 class remember_strategies {
287 public:
288         enum {
289                 delete_never,   ///< Let table grow undefinitely
290                 delete_lru,     ///< Least recently used
291                 delete_lfu,     ///< Least frequently used
292                 delete_cyclic   ///< First (oldest) one in list
293         };
294 };
295
296 /** Flags to control the polynomial factorization. */
297 class factor_options {
298 public:
299         enum {
300                 polynomial = 0x0000, ///< factor only expressions that are polynomials
301                 all        = 0x0001  ///< factor all polynomial subexpressions
302         };
303 };
304
305 } // namespace GiNaC
306
307 #endif // ndef GINAC_FLAGS_H