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