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