]> www.ginac.de Git - ginac.git/blob - ginac/flags.h
Copyright goes 2010.
[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-2010 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         };
36 };
37
38 /** Flags to control the behavior of has(). */
39 class has_options {
40 public:
41         enum {
42                 algebraic = 0x0001              ///< enable algebraic matching
43         };
44 };
45
46 /** Flags to control the behavior of subs(). */
47 class subs_options {
48 public:
49         enum {
50                 no_pattern = 0x0001,             ///< disable pattern matching
51                 subs_no_pattern = 0x0001, // for backwards compatibility
52                 algebraic = 0x0002,              ///< enable algebraic substitutions
53                 subs_algebraic = 0x0002,  // for backwards compatibility
54                 pattern_is_product = 0x0004,     ///< used internally by expairseq::subschildren()
55                 pattern_is_not_product = 0x0008, ///< used internally by expairseq::subschildren()
56                 no_index_renaming = 0x0010,
57                 // To indicate that we want to substitue an index by something that is
58                 // is not an index. Without this flag the index value would be
59                 // substituted in that case.
60                 really_subs_idx = 0x0020
61         };
62 };
63
64 /** Domain of an object */
65 class domain {
66 public:
67         enum {
68                 complex,
69                 real,
70                 positive
71         };
72 };
73
74 /** Flags to control series expansion. */
75 class series_options {
76 public:
77         enum {
78                 /** Suppress branch cuts in series expansion.  Branch cuts manifest
79                  *  themselves as step functions, if this option is not passed.  If
80                  *  it is passed and expansion at a point on a cut is performed, then
81                  *  the analytic continuation of the function is expanded. */
82                 suppress_branchcut = 0x0001
83         };
84 };
85
86 /** Switch to control algorithm for determinant computation. */
87 class determinant_algo {
88 public:
89         enum {
90                 /** Let the system choose.  A heuristics is applied for automatic
91                  *  determination of a suitable algorithm. */
92                 automatic,
93                 /** Gauss elimination.  If \f$m_{i,j}^{(0)}\f$ are the entries of the
94                  *  original matrix, then the matrix is transformed into triangular
95                  *  form by applying the rules
96                  *  \f[
97                  *      m_{i,j}^{(k+1)} = m_{i,j}^{(k)} - m_{i,k}^{(k)} m_{k,j}^{(k)} / m_{k,k}^{(k)}
98                  *  \f]
99                  *  The determinant is then just the product of diagonal elements.
100                  *  Choose this algorithm only for purely numerical matrices. */
101                 gauss,
102                 /** Division-free elimination.  This is a modification of Gauss
103                  *  elimination where the division by the pivot element is not
104                  *  carried out.  If \f$m_{i,j}^{(0)}\f$ are the entries of the
105                  *  original matrix, then the matrix is transformed into triangular
106                  *  form by applying the rules
107                  *  \f[
108                  *      m_{i,j}^{(k+1)} = m_{i,j}^{(k)} m_{k,k}^{(k)} - m_{i,k}^{(k)} m_{k,j}^{(k)}
109                  *  \f]
110                  *  The determinant can later be computed by inspecting the diagonal
111                  *  elements only.  This algorithm is only there for the purpose of
112                  *  cross-checks.  It is never fast. */
113                 divfree,
114                 /** Laplace elimination.  This is plain recursive elimination along
115                  *  minors although multiple minors are avoided by the algorithm.
116                  *  Although the algorithm is exponential in complexity it is
117                  *  frequently the fastest one when the matrix is populated by
118                  *  complicated symbolic expressions. */
119                 laplace,
120                 /** Bareiss fraction-free elimination.  This is a modification of
121                  *  Gauss elimination where the division by the pivot element is
122                  *  <EM>delayed</EM> until it can be carried out without computing
123                  *  GCDs.  If \f$m_{i,j}^{(0)}\f$ are the entries of the original
124                  *  matrix, then the matrix is transformed into triangular form by
125                  *  applying the rules
126                  *  \f[
127                  *      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)}
128                  *  \f]
129                  *  (We have set \f$m_{-1,-1}^{(-1)}=1\f$ in order to avoid a case
130                  *  distinction in above formula.)  It can be shown that nothing more
131                  *  than polynomial long division is needed for carrying out the
132                  *  division.  The determinant can then be read of from the lower
133                  *  right entry.  This algorithm is rarely fast for computing
134                  *  determinants. */
135                 bareiss
136         };
137 };
138
139 /** Switch to control algorithm for linear system solving. */
140 class solve_algo {
141 public:
142         enum {
143                 /** Let the system choose.  A heuristics is applied for automatic
144                  *  determination of a suitable algorithm. */
145                 automatic,
146                 /** Gauss elimination.  If \f$m_{i,j}^{(0)}\f$ are the entries of the
147                  *  original matrix, then the matrix is transformed into triangular
148                  *  form by applying the rules
149                  *  \f[
150                  *      m_{i,j}^{(k+1)} = m_{i,j}^{(k)} - m_{i,k}^{(k)} m_{k,j}^{(k)} / m_{k,k}^{(k)}
151                  *  \f]
152                  *  This algorithm is well-suited for numerical matrices but generally
153                  *  suffers from the expensive division (and computation of GCDs) at
154                  *  each step. */
155                 gauss,
156                 /** Division-free elimination.  This is a modification of Gauss
157                  *  elimination where the division by the pivot element is not
158                  *  carried out.  If \f$m_{i,j}^{(0)}\f$ are the entries of the
159                  *  original matrix, then the matrix is transformed into triangular
160                  *  form by applying the rules
161                  *  \f[
162                  *      m_{i,j}^{(k+1)} = m_{i,j}^{(k)} m_{k,k}^{(k)} - m_{i,k}^{(k)} m_{k,j}^{(k)}
163                  *  \f]
164                  *  This algorithm is only there for the purpose of cross-checks.
165                  *  It suffers from exponential intermediate expression swell.  Use it
166                  *  only for small systems. */
167                 divfree,
168                 /** Bareiss fraction-free elimination.  This is a modification of
169                  *  Gauss elimination where the division by the pivot element is
170                  *  <EM>delayed</EM> until it can be carried out without computing
171                  *  GCDs.  If \f$m_{i,j}^{(0)}\f$ are the entries of the original
172                  *  matrix, then the matrix is transformed into triangular form by
173                  *  applying the rules
174                  *  \f[
175                  *      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)}
176                  *  \f]
177                  *  (We have set \f$m_{-1,-1}^{(-1)}=1\f$ in order to avoid a case
178                  *  distinction in above formula.)  It can be shown that nothing more
179                  *  than polynomial long division is needed for carrying out the
180                  *  division.  This is generally the fastest algorithm for solving
181                  *  linear systems.  In contrast to division-free elimination it only
182                  *  has a linear expression swell.  For two-dimensional systems, the
183                  *  two algorithms are equivalent, however. */
184                 bareiss
185         };
186 };
187
188 /** Flags to store information about the state of an object.
189  *  @see basic::flags */
190 class status_flags {
191 public:
192         enum {
193                 dynallocated    = 0x0001, ///< heap-allocated (i.e. created by new if we want to be clever and bypass the stack, @see ex::construct_from_basic() )
194                 evaluated       = 0x0002, ///< .eval() has already done its job
195                 expanded        = 0x0004, ///< .expand(0) has already done its job (other expand() options ignore this flag)
196                 hash_calculated = 0x0008, ///< .calchash() has already done its job
197                 not_shareable   = 0x0010, ///< don't share instances of this object between different expressions unless explicitly asked to (used by ex::compare())
198                 has_indices     = 0x0020,
199                 has_no_indices  = 0x0040  // ! (has_indices || has_no_indices) means "don't know"
200         };
201 };
202
203 /** Possible attributes an object can have. */
204 class info_flags {
205 public:
206         enum {
207                 // answered by class numeric, add, mul and symbols/constants in particular domains
208                 numeric,
209                 real,
210                 rational,
211                 integer,
212                 crational,
213                 cinteger,
214                 positive,
215                 negative,
216                 nonnegative,
217                 posint,
218                 negint,
219                 nonnegint,
220                 even,
221                 odd,
222                 prime,
223
224                 // answered by class relation
225                 relation,
226                 relation_equal,
227                 relation_not_equal,
228                 relation_less,
229                 relation_less_or_equal,
230                 relation_greater,
231                 relation_greater_or_equal,
232
233                 // answered by class symbol
234                 symbol,
235
236                 // answered by class lst
237                 list,
238
239                 // answered by class exprseq
240                 exprseq,
241
242                 // answered by classes numeric, symbol, add, mul, power
243                 polynomial,
244                 integer_polynomial,
245                 cinteger_polynomial,
246                 rational_polynomial,
247                 crational_polynomial,
248                 rational_function,
249                 algebraic,
250
251                 // answered by class indexed
252                 indexed,      // class can carry indices
253                 has_indices,  // object has at least one index
254
255                 // answered by class idx
256                 idx,
257
258                 // answered by classes numeric, symbol, add, mul, power
259                 expanded
260         };
261 };
262
263 class return_types {
264 public:
265         enum {
266                 commutative,
267                 noncommutative,
268                 noncommutative_composite
269         };
270 };
271
272 /** Strategies how to clean up the function remember cache.
273  *  @see remember_table */
274 class remember_strategies {
275 public:
276         enum {
277                 delete_never,   ///< Let table grow undefinitely
278                 delete_lru,     ///< Least recently used
279                 delete_lfu,     ///< Least frequently used
280                 delete_cyclic   ///< First (oldest) one in list
281         };
282 };
283
284 /** Flags to control the polynomial factorization. */
285 class factor_options {
286 public:
287         enum {
288                 polynomial = 0x0000, ///< factor only expressions that are polynomials
289                 all        = 0x0001  ///< factor all polynomial subexpressions
290         };
291 };
292
293 } // namespace GiNaC
294
295 #endif // ndef GINAC_FLAGS_H