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