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