]> www.ginac.de Git - ginac.git/blob - ginac/flags.h
Make it possible to override info() for functions.
[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-2011 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                 is_positive     = 0x0080,
201                 is_negative     = 0x0100,
202                 purely_indefinite = 0x0200  // If set in a mul, then it does not contains any terms with determined signs, used in power::expand()
203         };
204 };
205
206 /** Possible attributes an object can have. */
207 class info_flags {
208 public:
209         enum {
210                 // answered by class numeric, add, mul, function and symbols/constants in particular domains
211                 numeric,
212                 real,
213                 rational,
214                 integer,
215                 crational,
216                 cinteger,
217                 positive,
218                 negative,
219                 nonnegative,
220                 posint,
221                 negint,
222                 nonnegint,
223                 even,
224                 odd,
225                 prime,
226
227                 // answered by class relation
228                 relation,
229                 relation_equal,
230                 relation_not_equal,
231                 relation_less,
232                 relation_less_or_equal,
233                 relation_greater,
234                 relation_greater_or_equal,
235
236                 // answered by class symbol
237                 symbol,
238
239                 // answered by class lst
240                 list,
241
242                 // answered by class exprseq
243                 exprseq,
244
245                 // answered by classes numeric, symbol, add, mul, power
246                 polynomial,
247                 integer_polynomial,
248                 cinteger_polynomial,
249                 rational_polynomial,
250                 crational_polynomial,
251                 rational_function,
252                 algebraic,
253
254                 // answered by class indexed
255                 indexed,      // class can carry indices
256                 has_indices,  // object has at least one index
257
258                 // answered by class idx
259                 idx,
260
261                 // answered by classes numeric, symbol, add, mul, power
262                 expanded,
263
264                 // is meaningful for mul only
265                 indefinite
266         };
267 };
268
269 class return_types {
270 public:
271         enum {
272                 commutative,
273                 noncommutative,
274                 noncommutative_composite
275         };
276 };
277
278 /** Strategies how to clean up the function remember cache.
279  *  @see remember_table */
280 class remember_strategies {
281 public:
282         enum {
283                 delete_never,   ///< Let table grow undefinitely
284                 delete_lru,     ///< Least recently used
285                 delete_lfu,     ///< Least frequently used
286                 delete_cyclic   ///< First (oldest) one in list
287         };
288 };
289
290 /** Flags to control the polynomial factorization. */
291 class factor_options {
292 public:
293         enum {
294                 polynomial = 0x0000, ///< factor only expressions that are polynomials
295                 all        = 0x0001  ///< factor all polynomial subexpressions
296         };
297 };
298
299 } // namespace GiNaC
300
301 #endif // ndef GINAC_FLAGS_H